Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
641a529
První iterace dat, serializace do json a výpis struktury
jankrcal Apr 21, 2026
e1dc5ea
Oprava dat
jankrcal Apr 22, 2026
e98a98d
Add costs & benefits calculator JS
katkolouchova Apr 22, 2026
7c6c261
WIP
jankrcal Apr 22, 2026
cdf44d9
Minor edits
katkolouchova Apr 22, 2026
2387dcf
More minor edits
katkolouchova Apr 22, 2026
6b8d2fa
Drobné ladění
jankrcal Apr 23, 2026
7653387
Zjednodušení popisů
jankrcal Apr 24, 2026
19e2da6
Odstranění ceny uhlíku a wacc z nejistot
jankrcal Apr 24, 2026
f61cc5c
Tooltips a okno s detaily
jankrcal Apr 24, 2026
fb974c5
Přejmenování parametrů
jankrcal Apr 24, 2026
f03a405
NPV timeline
jankrcal Apr 24, 2026
f102bd7
Oprava boxů s emisemi
jankrcal Apr 28, 2026
6d033a8
Doplnění úspor paliv a měrných úspor
jankrcal Apr 28, 2026
0f15a0c
Separátní soubory pro grafy
katkolouchova Apr 28, 2026
43f76ce
Update vstupních dat
katkolouchova Apr 28, 2026
0fecabc
Odstranění carbon costs pro elektřinu
katkolouchova Apr 28, 2026
7b1a2d9
Add quadrant chart and simple MAC chart
marcel-otruba Apr 28, 2026
3cf5489
Grafiky pro cenu uhlíku a diskontní míru
katkolouchova Apr 28, 2026
bb8f8a8
Scénář pro cenu uhlíku v NZ, grafy
katkolouchova Apr 29, 2026
0979dff
Oprava biomasového kotle plyn C
jankrcal Apr 29, 2026
0b35066
Ladění a oprava parametrů u paneláku
jankrcal Apr 29, 2026
8b62e63
Oprava yaml struktury
katkolouchova Apr 30, 2026
0572d68
Úprava parametru pto výpočet poptávky po elektřině
katkolouchova Apr 30, 2026
a93a033
Grafy
katkolouchova Apr 30, 2026
f0627d4
Drobné úpravy
katkolouchova May 6, 2026
a65537a
Přidání FoK d3 stylingu
marcel-otruba May 12, 2026
2d2cc53
Added download button
marcel-otruba May 12, 2026
f2d9731
Update dat u dopravy
katkolouchova May 12, 2026
0772e18
Vylepšení beeswarm toolu
marcel-otruba May 14, 2026
f3be36f
Merge branch 'preview-costs-and-benefits' of https://github.com/fakta…
marcel-otruba May 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,348 changes: 2,348 additions & 0 deletions _data/costs-and-benefits.yaml

Large diffs are not rendered by default.

151 changes: 151 additions & 0 deletions assets-local/charts/_charts.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// _charts.scss — FoK chart CSS
//
// Handles layout and positioning that D3 can't easily do in JS.
// All color/font values are set in fok-theme.js and applied via inline styles by D3.
// This file only deals with structural CSS: display, position, overflow, cursor.

// ── Chart wrapper ──────────────────────────────────────────────────────────

.fok-chart {
position: relative;
width: 100%;

&__title {
margin-bottom: 0.5rem;
}
}

.fok-chart-svg {
display: block;
width: 100%;
height: auto;
overflow: visible; // allow axis labels outside viewBox
}

// ── Axes ───────────────────────────────────────────────────────────────────

.fok-axis {
.domain {
shape-rendering: crispEdges;
}

.tick line {
shape-rendering: crispEdges;
}

.tick text {
user-select: none;
}
}

// ── Bars ───────────────────────────────────────────────────────────────────

.fok-bar {
cursor: default;
transition: opacity 0.15s ease;
}

// ── Lines ──────────────────────────────────────────────────────────────────

.fok-line {
pointer-events: none;
}

.fok-area {
pointer-events: none;
}

.fok-voronoi-cell {
cursor: crosshair;
}

// ── Map ────────────────────────────────────────────────────────────────────

.cz-region {
transition: fill 0.2s ease;
}

.cz-point {
cursor: pointer;
transition: r 0.1s ease;
}

// ── Tooltip ────────────────────────────────────────────────────────────────

.fok-tooltip {
// Structural only — colors/fonts are set via fok-theme.js in JS
position: fixed;
pointer-events: none;
z-index: 9999;
max-width: 220px;
word-wrap: break-word;

strong {
display: block;
margin-bottom: 2px;
}
}

// ── Legend ─────────────────────────────────────────────────────────────────

.fok-legend {
display: flex;
flex-wrap: wrap;
gap: 4px 16px;
margin-top: 0.5rem;

&--vertical {
flex-direction: column;
gap: 8px;
}

&__item {
display: flex;
align-items: center;
gap: 6px;
}

&__swatch {
display: inline-block;
border-radius: 2px;
flex-shrink: 0;
}

&__label {
white-space: nowrap;
}
}

// ── Small multiples grid ───────────────────────────────────────────────────

.fok-small-multiples {
display: grid;
gap: 24px 32px;
grid-template-columns: repeat(2, 1fr);

@media (max-width: 600px) {
grid-template-columns: 1fr;
}
}

.fok-small-multiples--3col {
grid-template-columns: repeat(3, 1fr);
}

.fok-small-multiples--4col {
grid-template-columns: repeat(4, 1fr);
}

// ── Annotation ─────────────────────────────────────────────────────────────

.fok-annotation {
pointer-events: none;
user-select: none;
}

// ── Axis label ─────────────────────────────────────────────────────────────

.fok-axis-label {
pointer-events: none;
user-select: none;
}
148 changes: 148 additions & 0 deletions assets-local/charts/ai-prototyping-guidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Datavis AI Prototyping Guidelines

Rules for AI-assisted chart prototyping in the FoK design system (D3 + fok-theme.js).

---

## Chart types and when to use them

| Chart type | Use when |
|---|---|
| Stacked bar (horizontal, proportional) | Share of total — single row breakdown |
| Stacked bar (vertical, small multiples) | Compare base + delta across categories |
| Stacked area (proportional) | Geographic/categorical mix evolving over time |
| Line chart | Time series, trends over years |
| Choropleth map (world) | Geographic comparison of a single variable |

---

## Connecting historical data to targets

**Rule: use a dashed line to bridge the gap between the last measured value and the target.**

This pattern separates fact (solid line = measured data) from plan (dashed line = projected/required trajectory).

```
Historical data ────────────── ╌╌╌╌╌╌╌╌╌○ Target
^last ^target year
data point
```

### Implementation

```js
// Dashed projection segment
g.append('path')
.datum([
{ date: new Date(lastYear, 0, 1), value: lastValue },
{ date: new Date(targetYear, 0, 1), value: targetValue },
])
.attr('fill', 'none')
.attr('stroke', lineColor)
.attr('stroke-width', 1.2) // slightly thinner than the solid line
.attr('stroke-dasharray', '5 4')
.attr('d', d3.line().x(d => xSc(d.date)).y(d => ySc(d.value)));
```

### Target marker: open circle

Target values are always drawn as an **open circle** (white fill, colored stroke) — not a filled dot. Filled dots are used for actual data points.

```js
g.append('circle')
.attr('cx', xSc(new Date(targetYear, 0, 1)))
.attr('cy', ySc(targetValue))
.attr('r', 5)
.attr('fill', '#fff') // open = projected, not measured
.attr('stroke', lineColor)
.attr('stroke-width', 2);
```

### Annotation placement

- Last data point label: anchored to the **left/above** the point (`text-anchor: end`) so it doesn't run into the dashed segment
- Target label: anchored to the **right** of the circle (`text-anchor: start`, `x + 8`)
- Use `FoKTheme.colors.grey` for the target annotation, the series color for the data annotation

---

## General rules

### SVG width must match rendered column width

The chart `width` option sets the SVG `viewBox`. Because the SVG is responsive (`width: 100%`), it scales to fit its container. Text in SVG scales proportionally with the viewBox — **if the viewBox is wider than the container, all text shrinks; if narrower, it grows.**

**The only way to get consistent font sizes across all charts is to set `width` to the actual rendered pixel width of the chart's container** — not a generic default. This is what makes a 12 px axis label look 12 px everywhere.

| Layout | Approx. rendered width | Correct `width` option |
|---|---|---|
| Full-width content column | ~800 px | `800` (default) |
| `.col-md-6` (half column) | ~420 px | `420` |
| `.col-6` inside `.col-md-6` (quarter) | ~200 px | `200` |

```js
// Wrong — default 800px viewBox in a 420px column → text appears ~63% of intended size
fokBarChartStacked('#chart', data, { height: 340 });

// Wrong — 280px viewBox in a 200px column → text appears ~71% of intended size
fokLineChart('#chart', data, { width: 280, height: 220 });

// Correct — viewBox matches the actual rendered column width
fokBarChartStacked('#chart-half', data, { width: 420, height: 340 });
fokLineChart('#chart-quarter', data, { width: 200, height: 220 });
```

> **To verify**: measure the rendered container with DevTools. The rendered pixel width of the container and the `width` option must match for text to appear at the intended size.

### Fonts

- Titles: **Inter Bold** (`FoKTheme.fontTitle`, weight 700)
- Everything else: **Roboto** (`FoKTheme.font`, weight 400/700)
- Minimum readable font size in SVG coordinates: **12px** — but only meaningful if the viewBox width is set correctly (see above)

### Colors

Line charts use `theme.colors.categorical[0]` for the first (or only) series — **not** `theme.colors.primary`. To override the line color, override `categorical`:

```js
// Wrong — primary is not used by line charts
theme: { ...FoKTheme, colors: { ...FoKTheme.colors, primary: '#3b3b93' } }

// Correct
theme: { ...FoKTheme, colors: { ...FoKTheme.colors, categorical: ['#3b3b93', ...FoKTheme.colors.categorical.slice(1)] } }
```

Named sector colors from `FoKTheme.colors.sectors`:

| Sector | Color |
|---|---|
| energetika | `#f4465b` |
| průmysl | `#3b3b93` |
| doprava | `#8546af` |
| budovy | `#0d80d8` |
| zemědělství | `#00aa95` |
| odpady | `#fab519` |
| ostatní | `#b5b8bd` |

### Small multiples

- Set `width: 420` (or match the actual column width) on each chart — the SVG viewBox scaling will otherwise make text illegible
- Shared legend below the grid, not repeated per chart (`legend: false` on each chart, render once manually)

### Y-axis ticks

- Prefer explicit `yTickValues` over automatic ticks for cleaner grids
- Round to natural intervals: 500 or 1000 for large absolute values, 10 for small (e.g. Kč/litr)

### Axis styling

- No domain lines (axis baseline) — set via `_styleAxis()` in fok-utils.js, applies globally
- Y-axis label: horizontal text above the chart, left-aligned, not rotated
- Tick padding: 12px (set in `FoKTheme.axis.tickPadding`)

### Lines

**Never use smoothed curves.** All lines must use `d3.curveLinear` (the D3 default). Do not pass any curve option to `d3.line()` or `d3.area()`. This applies to fokLineChart, fokBarChartStacked, and any custom D3 code in this project. `curveMonotoneX`, `curveBasis`, `curveCardinal`, and all other interpolators are forbidden.

- Solid line for measured/historical data
- Dashed line (`stroke-dasharray: '5 4'`, `stroke-width` slightly reduced) for projections and trajectories
Loading