@aaqu/fromcubes-portal-react 0.1.0-alpha.12 → 0.1.0-alpha.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -25
- package/examples/001-shared-components-flow.json +68 -0
- package/examples/{sensor-portal-flow.json → 002-sensor-portal-flow.json} +2 -28
- package/examples/003-chart-portal-flow.json +93 -0
- package/examples/004-d3-poland-flow.json +80 -0
- package/examples/005-threejs-portal-flow.json +87 -0
- package/examples/006-pixi-portal-flow.json +86 -0
- package/examples/007-webgpu-tsl-flow.json +85 -0
- package/nodes/portal-react.html +508 -9
- package/nodes/portal-react.js +341 -175
- package/package.json +1 -1
- package/examples/chart-portal-flow.json +0 -74
- package/examples/d3-poland-flow.json +0 -80
- package/examples/threejs-portal-flow.json +0 -61
package/README.md
CHANGED
|
@@ -12,26 +12,24 @@ React portal node for Node-RED. Server-side JSX transpilation via esbuild. Tailw
|
|
|
12
12
|
┌─ Deploy time (Node-RED server) ───────────────────────────┐
|
|
13
13
|
│ │
|
|
14
14
|
│ npm packages ──► auto-installed at deploy │
|
|
15
|
-
│ (d3, three,
|
|
15
|
+
│ (d3, three, @react-three/fiber…) │
|
|
16
|
+
│ via dynamicModuleList │
|
|
16
17
|
│ │
|
|
17
|
-
│ React + packages ──► esbuild
|
|
18
|
-
│
|
|
19
|
-
│
|
|
20
|
-
│
|
|
21
|
-
│ JSX (editor) ──► esbuild transpile ──► cached JS │
|
|
22
|
-
│ packages marked external → require() shim │
|
|
18
|
+
│ React + packages + JSX ──► single esbuild pass │
|
|
19
|
+
│ one IIFE, one React instance (alias) │
|
|
20
|
+
│ tree-shaking removes unused exports │
|
|
21
|
+
│ React peer deps share same instance │
|
|
23
22
|
│ │
|
|
24
23
|
│ Tailwind classes ──► server-side compile ──► CSS │
|
|
25
|
-
│
|
|
24
|
+
│ stored per-page in pageState │
|
|
26
25
|
│ │
|
|
27
|
-
│ Unchanged
|
|
28
|
-
│ Changed
|
|
26
|
+
│ Unchanged JSX on redeploy = reuse CSS, 0ms │
|
|
27
|
+
│ Changed JSX = retranspile, ~5ms │
|
|
29
28
|
└───────────────────────────────────────────────────────────┘
|
|
30
29
|
|
|
31
30
|
┌─ Runtime (browser) ───────────────────────────────────────┐
|
|
32
31
|
│ │
|
|
33
|
-
│ GET /endpoint ──► HTML +
|
|
34
|
-
│ vendor bundle (React + packages) │
|
|
32
|
+
│ GET /endpoint ──► HTML + single inlined JS bundle │
|
|
35
33
|
│ Tailwind CSS (server-compiled) │
|
|
36
34
|
│ NO Babel, NO Sucrase, NO compiler │
|
|
37
35
|
│ │
|
|
@@ -63,7 +61,7 @@ Dependencies install automatically. No build step needed.
|
|
|
63
61
|
|---|------------------------------------------------------------------|
|
|
64
62
|
| Endpoint | HTTP path, e.g. `/fromcubes/page1` |
|
|
65
63
|
| Page Title | Browser tab title |
|
|
66
|
-
| npm Packages | Comma-separated packages, e.g. `d3, three,
|
|
64
|
+
| npm Packages | Comma-separated packages, e.g. `d3, three, @react-three/fiber` |
|
|
67
65
|
| Portal Auth | Enable portal user header extraction |
|
|
68
66
|
| Head HTML | Extra `<head>` tags (CDN, fonts, CSS) |
|
|
69
67
|
| Code Editor | Monaco with JSX — must define `<App />` |
|
|
@@ -80,15 +78,17 @@ Referenced components (with transitive dependencies) are selectively injected at
|
|
|
80
78
|
- **JSX tag completion** — type tag name, Tab to expand (open+close and self-closing variants)
|
|
81
79
|
- **Self-close collapse** — type `/` inside empty `<tag></tag>` to convert to `<tag />`
|
|
82
80
|
- **Component completion** — registry components + any PascalCase word
|
|
81
|
+
- **Portal Assets sidebar** — file manager for static assets (GLB models, textures, fonts, etc.)
|
|
83
82
|
|
|
84
83
|
## Hook API
|
|
85
84
|
|
|
86
85
|
```jsx
|
|
87
86
|
function App() {
|
|
88
|
-
const { data, send, user } = useNodeRed();
|
|
89
|
-
// data
|
|
87
|
+
const { data, send, user, portalClient } = useNodeRed();
|
|
88
|
+
// data = last msg.payload from input wire (reactive)
|
|
90
89
|
// send(payload, topic?) = emit msg on output wire
|
|
91
|
-
// user
|
|
90
|
+
// user = portal user object (when Portal Auth enabled), or null
|
|
91
|
+
// portalClient = unique session/tab ID (assigned by server on WS connect)
|
|
92
92
|
return <div className="p-4 text-lg">{JSON.stringify(data)}</div>;
|
|
93
93
|
}
|
|
94
94
|
```
|
|
@@ -107,7 +107,24 @@ When **Portal Auth** is checked, the node extracts user identity from incoming r
|
|
|
107
107
|
| `x-portal-user-groups` | `groups` (JSON array) |
|
|
108
108
|
|
|
109
109
|
- In the browser, `useNodeRed().user` returns the extracted user object (or `null` if auth is disabled or no headers present).
|
|
110
|
-
-
|
|
110
|
+
- Every WebSocket message includes `msg._client = { portalClient, ...userFields }`. The `portalClient` is always present (unique per tab/session); user fields are added when Portal Auth is enabled.
|
|
111
|
+
- To send a response to a specific tab, keep `msg._client` on the return message (or set `msg._client = { portalClient: "..." }`).
|
|
112
|
+
- To send to all sessions of a user, set `msg._client = { userId: "..." }` (omit `portalClient`).
|
|
113
|
+
- To broadcast to all clients, remove `msg._client` from the message.
|
|
114
|
+
|
|
115
|
+
## Portal Assets
|
|
116
|
+
|
|
117
|
+
Static files (3D models, textures, fonts, etc.) can be uploaded and served from a public endpoint.
|
|
118
|
+
|
|
119
|
+
- Open the **Portal Assets** tab in the Node-RED sidebar
|
|
120
|
+
- Upload files via button or drag & drop
|
|
121
|
+
- Organize in folders (create, rename, move between folders)
|
|
122
|
+
- Copy public path with one click — use in JSX: `/fromcubes/public/models/scene.glb`
|
|
123
|
+
- Download and delete files from the context menu
|
|
124
|
+
|
|
125
|
+
All uploads require Node-RED admin authentication. Files are served publicly at `/fromcubes/public/`.
|
|
126
|
+
|
|
127
|
+
Limits: 100 MB per file, 500 MB total, 1000 files max.
|
|
111
128
|
|
|
112
129
|
## Deploy lifecycle
|
|
113
130
|
|
|
@@ -138,21 +155,27 @@ Transpile errors:
|
|
|
138
155
|
|
|
139
156
|
| Asset | Size (gzip) |
|
|
140
157
|
|---|---|
|
|
141
|
-
|
|
|
142
|
-
|
|
|
143
|
-
| Tailwind CSS (server-compiled) | cached per content hash |
|
|
158
|
+
| Single JS bundle (React + packages + your code) | ~45 KB React only, grows with packages |
|
|
159
|
+
| Tailwind CSS (server-compiled) | stored per-page, reused if JSX unchanged |
|
|
144
160
|
| WebSocket bridge | <1 KB |
|
|
145
161
|
|
|
146
|
-
|
|
162
|
+
Single-pass esbuild bundle — React, npm packages, and your JSX compiled into one IIFE. Tree-shaking removes unused exports. React `alias` ensures packages with React peer deps (e.g. `@react-three/fiber`, `@pixi/react`) share the same React instance — no duplicate React, no hooks errors.
|
|
163
|
+
|
|
164
|
+
No Babel, no Sucrase, no runtime compiler in the browser.
|
|
147
165
|
|
|
148
166
|
## Examples
|
|
149
167
|
|
|
168
|
+
Import `001-shared-components-flow.json` first — it provides shared UI components (Page, Header, Stat, Button, ValueBadge) used by all examples.
|
|
169
|
+
|
|
150
170
|
| Flow | npm packages | Description |
|
|
151
171
|
|---|---|---|
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
172
|
+
| `001-shared-components-flow.json` | — | Shared components: Page, Header, Stat, Button, ValueBadge |
|
|
173
|
+
| `002-sensor-portal-flow.json` | — | Sensor gauge with live WebSocket data |
|
|
174
|
+
| `003-chart-portal-flow.json` | `chart.js/auto` | Live updating Chart.js charts |
|
|
175
|
+
| `004-d3-poland-flow.json` | `d3` | Interactive SVG map of Poland (simulated data) |
|
|
176
|
+
| `005-threejs-portal-flow.json` | `three` | 3D scene with Three.js |
|
|
177
|
+
| `006-pixi-portal-flow.json` | `pixi.js`, `@pixi/react` | Clickable bunny sprites with PixiJS |
|
|
178
|
+
| `007-webgpu-tsl-flow.json` | `three` | WebGPU renderer + TSL animated shaders |
|
|
156
179
|
|
|
157
180
|
## License
|
|
158
181
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "fc-shared-flow",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "Shared Components",
|
|
6
|
+
"disabled": false
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "fc-shared-comp-header",
|
|
10
|
+
"type": "fc-portal-component",
|
|
11
|
+
"z": "fc-shared-flow",
|
|
12
|
+
"compName": "Header",
|
|
13
|
+
"compCode": "function Header({ title = 'fromcubes', subtitle = '', children }) {\n return (\n <div className=\"flex items-center justify-between px-6 py-4\">\n <div>\n <h1 className=\"text-xl font-semibold text-zinc-100 tracking-tight\">{title}</h1>\n {subtitle && <p className=\"text-xs text-zinc-600 mt-0.5\">{subtitle}</p>}\n </div>\n <div className=\"flex items-center gap-2\">\n {children || (\n <>\n <span className=\"inline-block w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse\" />\n <span className=\"text-xs text-zinc-500\">streaming</span>\n </>\n )}\n </div>\n </div>\n );\n}",
|
|
14
|
+
"compInputs": "title,subtitle,children",
|
|
15
|
+
"compOutputs": "",
|
|
16
|
+
"x": 160,
|
|
17
|
+
"y": 160,
|
|
18
|
+
"wires": []
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "fc-shared-comp-stat",
|
|
22
|
+
"type": "fc-portal-component",
|
|
23
|
+
"z": "fc-shared-flow",
|
|
24
|
+
"compName": "Stat",
|
|
25
|
+
"compCode": "function Stat({ label, children }) {\n return (\n <div className=\"flex items-center gap-3\">\n <span className=\"text-xs text-zinc-500\">{label}</span>\n {children}\n </div>\n );\n}",
|
|
26
|
+
"compInputs": "label,children",
|
|
27
|
+
"compOutputs": "",
|
|
28
|
+
"x": 360,
|
|
29
|
+
"y": 160,
|
|
30
|
+
"wires": []
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "fc-shared-comp-button",
|
|
34
|
+
"type": "fc-portal-component",
|
|
35
|
+
"z": "fc-shared-flow",
|
|
36
|
+
"compName": "Button",
|
|
37
|
+
"compCode": "function Button({ onClick, children, variant = 'primary', className = '' }) {\n const base = 'px-4 py-2 rounded-lg font-medium transition-colors';\n const variants = {\n primary: 'bg-blue-600 text-white hover:bg-blue-500',\n secondary: 'bg-zinc-700 text-zinc-200 hover:bg-zinc-600',\n danger: 'bg-red-600 text-white hover:bg-red-500'\n };\n return (\n <button\n className={`${base} ${variants[variant] || variants.primary} ${className}`}\n onClick={onClick}\n >{children}</button>\n );\n}",
|
|
38
|
+
"compInputs": "onClick,children,variant,className",
|
|
39
|
+
"compOutputs": "",
|
|
40
|
+
"x": 560,
|
|
41
|
+
"y": 160,
|
|
42
|
+
"wires": []
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "fc-shared-comp-valuebadge",
|
|
46
|
+
"type": "fc-portal-component",
|
|
47
|
+
"z": "fc-shared-flow",
|
|
48
|
+
"compName": "ValueBadge",
|
|
49
|
+
"compCode": "function ValueBadge({ label, value, className = '' }) {\n if (value == null) return null;\n return (\n <span className={`text-zinc-600 text-xs ${className}`}>\n {label && <>{label}: </>}{value}\n </span>\n );\n}",
|
|
50
|
+
"compInputs": "label,value,className",
|
|
51
|
+
"compOutputs": "",
|
|
52
|
+
"x": 760,
|
|
53
|
+
"y": 160,
|
|
54
|
+
"wires": []
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "fc-shared-comp-page",
|
|
58
|
+
"type": "fc-portal-component",
|
|
59
|
+
"z": "fc-shared-flow",
|
|
60
|
+
"compName": "Page",
|
|
61
|
+
"compCode": "function Page({ children, className = '' }) {\n return (\n <div className={`min-h-screen bg-zinc-950 text-zinc-100 flex flex-col ${className}`}>\n {children}\n </div>\n );\n}",
|
|
62
|
+
"compInputs": "children,className",
|
|
63
|
+
"compOutputs": "",
|
|
64
|
+
"x": 160,
|
|
65
|
+
"y": 240,
|
|
66
|
+
"wires": []
|
|
67
|
+
}
|
|
68
|
+
]
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
{
|
|
3
3
|
"id": "fc-demo-flow",
|
|
4
4
|
"type": "tab",
|
|
5
|
-
"label": "Portal
|
|
5
|
+
"label": "Sensor Portal",
|
|
6
6
|
"disabled": false
|
|
7
7
|
},
|
|
8
8
|
{
|
|
@@ -42,32 +42,6 @@
|
|
|
42
42
|
"y": 280,
|
|
43
43
|
"wires": []
|
|
44
44
|
},
|
|
45
|
-
{
|
|
46
|
-
"id": "fc-button-comp",
|
|
47
|
-
"type": "fc-portal-component",
|
|
48
|
-
"z": "fc-demo-flow",
|
|
49
|
-
"name": "Button",
|
|
50
|
-
"compName": "Button",
|
|
51
|
-
"compCode": "function Button({ onClick, children, variant = 'primary', className = '' }) {\n const base = 'px-4 py-2 rounded-lg font-medium transition-colors';\n const variants = {\n primary: 'bg-blue-600 text-white hover:bg-blue-500',\n secondary: 'bg-zinc-700 text-zinc-200 hover:bg-zinc-600',\n danger: 'bg-red-600 text-white hover:bg-red-500'\n };\n return (\n <button\n className={`${base} ${variants[variant] || variants.primary} ${className}`}\n onClick={onClick}\n >{children}</button>\n );\n}",
|
|
52
|
-
"compInputs": "onClick,children,variant,className",
|
|
53
|
-
"compOutputs": "",
|
|
54
|
-
"x": 160,
|
|
55
|
-
"y": 340,
|
|
56
|
-
"wires": []
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"id": "fc-valuebadge-comp",
|
|
60
|
-
"type": "fc-portal-component",
|
|
61
|
-
"z": "fc-demo-flow",
|
|
62
|
-
"name": "ValueBadge",
|
|
63
|
-
"compName": "ValueBadge",
|
|
64
|
-
"compCode": "function ValueBadge({ label, value, className = '' }) {\n if (value == null) return null;\n return (\n <span className={`text-zinc-600 text-xs ${className}`}>\n {label && <>{label}: </>}{value}\n </span>\n );\n}",
|
|
65
|
-
"compInputs": "label,value,className",
|
|
66
|
-
"compOutputs": "",
|
|
67
|
-
"x": 160,
|
|
68
|
-
"y": 400,
|
|
69
|
-
"wires": []
|
|
70
|
-
},
|
|
71
45
|
{
|
|
72
46
|
"id": "fc-portal",
|
|
73
47
|
"type": "portal-react",
|
|
@@ -78,7 +52,7 @@
|
|
|
78
52
|
"customHead": "",
|
|
79
53
|
"inputSchema": "[{\"name\":\"temp\",\"type\":\"number\"},{\"name\":\"humidity\",\"type\":\"number\"},{\"name\":\"pressure\",\"type\":\"number\"},{\"name\":\"ts\",\"type\":\"number\"}]",
|
|
80
54
|
"outputSchema": "[{\"name\":\"action\",\"type\":\"string\"}]",
|
|
81
|
-
"componentCode": "function App() {\n const { data, send } = useNodeRed();\n const s = data || { temp: 0, humidity: 0, pressure: 0 };\n\n return (\n <div className=\"
|
|
55
|
+
"componentCode": "function App() {\n const { data, send } = useNodeRed();\n const s = data || { temp: 0, humidity: 0, pressure: 0 };\n\n return (\n <Page>\n <Header title=\"Sensor Portal\" subtitle=\"live sensor data\" />\n <div className=\"flex-1 flex flex-col items-center justify-center p-8\">\n <div className=\"flex gap-10 flex-wrap justify-center\">\n <Gauge value={s.temp} min={-10} max={50} label=\"Temperature\" unit=\"°C\" />\n <Gauge value={s.humidity} min={0} max={100} label=\"Humidity\" unit=\"%\" />\n <Gauge value={s.pressure} min={950} max={1050} label=\"Pressure\" unit=\"hPa\" />\n </div>\n <div className=\"mt-10 flex gap-3 items-center\">\n <Button onClick={() => send({ action: 'refresh' })}>Refresh</Button>\n <ValueBadge label=\"Last\" value={s.ts ? new Date(s.ts).toLocaleTimeString() : null} />\n </div>\n </div>\n </Page>\n );\n}",
|
|
82
56
|
"x": 560,
|
|
83
57
|
"y": 160,
|
|
84
58
|
"wires": [["fc-debug"]]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "fc-chart-flow",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "Chart.js Demo",
|
|
6
|
+
"disabled": false
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "fc-chart-linechart-comp",
|
|
10
|
+
"type": "fc-portal-component",
|
|
11
|
+
"z": "fc-chart-flow",
|
|
12
|
+
"name": "LineChart",
|
|
13
|
+
"compName": "LineChart",
|
|
14
|
+
"compInputs": "data,labelKey,datasets,title,height",
|
|
15
|
+
"compOutputs": "",
|
|
16
|
+
"compCode": "import ChartJS from 'chart.js/auto';\n\nfunction LineChart({ data = [], labelKey = 'time', datasets = [], title = '', height = 'h-64' }) {\n const canvasRef = useRef(null);\n const chartRef = useRef(null);\n\n useEffect(() => {\n if (!canvasRef.current || data.length === 0) return;\n\n if (chartRef.current) {\n const chart = chartRef.current;\n chart.data.labels = data.map(p => p[labelKey]);\n datasets.forEach((ds, i) => {\n chart.data.datasets[i].data = data.map(p => p[ds.key]);\n });\n chart.update('none');\n return;\n }\n\n\n chartRef.current = new ChartJS(canvasRef.current, {\n type: 'line',\n data: {\n labels: data.map(p => p[labelKey]),\n datasets: datasets.map(ds => ({\n label: ds.label,\n data: data.map(p => p[ds.key]),\n borderColor: ds.color,\n backgroundColor: ds.color + '18',\n tension: 0.35,\n fill: true,\n pointRadius: 2,\n borderWidth: 2\n }))\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n animation: false,\n plugins: {\n legend: { labels: { color: '#a1a1aa', usePointStyle: true, pointStyle: 'circle', padding: 16 } }\n },\n scales: {\n x: { ticks: { color: '#52525b', font: { size: 10 } }, grid: { color: '#27272a' } },\n y: { ticks: { color: '#52525b', font: { size: 10 } }, grid: { color: '#27272a' } }\n }\n }\n });\n\n return () => {\n if (chartRef.current) {\n chartRef.current.destroy();\n chartRef.current = null;\n }\n };\n }, [data, datasets]);\n\n return (\n <div className=\"bg-zinc-900/50 rounded-xl border border-zinc-800/50 p-5\">\n {title && <h3 className=\"text-sm font-medium text-zinc-300 mb-3\">{title}</h3>}\n <div className={height}>\n <canvas ref={canvasRef} />\n </div>\n </div>\n );\n}",
|
|
17
|
+
"x": 380,
|
|
18
|
+
"y": 80,
|
|
19
|
+
"wires": []
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "fc-chart-inject",
|
|
23
|
+
"type": "inject",
|
|
24
|
+
"z": "fc-chart-flow",
|
|
25
|
+
"name": "Sensor tick",
|
|
26
|
+
"props": [
|
|
27
|
+
{
|
|
28
|
+
"p": "payload"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"repeat": "2",
|
|
32
|
+
"payload": "{}",
|
|
33
|
+
"payloadType": "json",
|
|
34
|
+
"x": 160,
|
|
35
|
+
"y": 160,
|
|
36
|
+
"wires": [
|
|
37
|
+
[
|
|
38
|
+
"fc-chart-func"
|
|
39
|
+
]
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "fc-chart-func",
|
|
44
|
+
"type": "function",
|
|
45
|
+
"z": "fc-chart-flow",
|
|
46
|
+
"name": "Random data point",
|
|
47
|
+
"func": "var history = flow.get('chartHistory') || [];\nvar now = new Date();\nhistory.push({\n time: now.toLocaleTimeString(),\n temp: +(18 + Math.random() * 12).toFixed(1),\n humidity: Math.round(35 + Math.random() * 40),\n cpu: Math.round(15 + Math.random() * 60),\n memory: Math.round(40 + Math.random() * 45)\n});\nif (history.length > 20) history.shift();\nflow.set('chartHistory', history);\nmsg.payload = history;\nreturn msg;",
|
|
48
|
+
"outputs": 1,
|
|
49
|
+
"x": 380,
|
|
50
|
+
"y": 160,
|
|
51
|
+
"wires": [
|
|
52
|
+
[
|
|
53
|
+
"fc-chart-portal"
|
|
54
|
+
]
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "fc-chart-portal",
|
|
59
|
+
"type": "portal-react",
|
|
60
|
+
"z": "fc-chart-flow",
|
|
61
|
+
"name": "Chart Portal",
|
|
62
|
+
"endpoint": "/fromcubes/chart",
|
|
63
|
+
"pageTitle": "fromcubes charts",
|
|
64
|
+
"customHead": "",
|
|
65
|
+
"portalAuth": false,
|
|
66
|
+
"showWsStatus": false,
|
|
67
|
+
"libs": [
|
|
68
|
+
{
|
|
69
|
+
"module": "chart.js/auto",
|
|
70
|
+
"var": "Chart"
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
"componentCode": "function App() {\n const { data } = useNodeRed();\n const [tab, setTab] = useState(0);\n const points = data || [];\n\n const tabs = [\n { label: 'Overview', icon: '\\u25a6' },\n { label: 'Environment', icon: '\\u25cb' },\n { label: 'System', icon: '\\u25a1' }\n ];\n\n return (\n <Page>\n <div className=\"max-w-5xl mx-auto px-6 py-8\">\n\n <Header title=\"fromcubes charts\" subtitle={points.length + ' data points \\u2022 live'} />\n\n <div className=\"flex gap-1 mb-6 bg-zinc-900/50 rounded-lg p-1 w-fit\">\n {tabs.map((t, i) => (\n <button\n key={i}\n onClick={() => setTab(i)}\n className={`px-4 py-2 rounded-md text-sm transition-all ${\n tab === i\n ? 'bg-zinc-800 text-zinc-100 shadow-sm'\n : 'text-zinc-500 hover:text-zinc-300'\n }`}\n >{t.icon} {t.label}</button>\n ))}\n </div>\n\n {tab === 0 && (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\n <LineChart\n data={points}\n title=\"Temperature\"\n datasets={[{ key: 'temp', label: 'Temp (\\u00b0C)', color: '#22d3ee' }]}\n />\n <LineChart\n data={points}\n title=\"Humidity\"\n datasets={[{ key: 'humidity', label: 'Humidity (%)', color: '#a78bfa' }]}\n />\n <LineChart\n data={points}\n title=\"CPU Usage\"\n datasets={[{ key: 'cpu', label: 'CPU (%)', color: '#f97316' }]}\n />\n <LineChart\n data={points}\n title=\"Memory\"\n datasets={[{ key: 'memory', label: 'Memory (%)', color: '#34d399' }]}\n />\n </div>\n )}\n\n {tab === 1 && (\n <div className=\"space-y-4\">\n <LineChart\n data={points}\n title=\"Temperature & Humidity\"\n height=\"h-80\"\n datasets={[\n { key: 'temp', label: 'Temp (\\u00b0C)', color: '#22d3ee' },\n { key: 'humidity', label: 'Humidity (%)', color: '#a78bfa' }\n ]}\n />\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"bg-zinc-900/50 rounded-xl border border-zinc-800/50 p-5\">\n <div className=\"text-xs text-zinc-500 uppercase tracking-wider\">Current Temp</div>\n <div className=\"text-3xl font-bold text-cyan-400 mt-2\">\n {points.length > 0 ? points[points.length - 1].temp : '--'}\n <span className=\"text-sm font-normal text-zinc-500 ml-1\">\\u00b0C</span>\n </div>\n </div>\n <div className=\"bg-zinc-900/50 rounded-xl border border-zinc-800/50 p-5\">\n <div className=\"text-xs text-zinc-500 uppercase tracking-wider\">Current Humidity</div>\n <div className=\"text-3xl font-bold text-violet-400 mt-2\">\n {points.length > 0 ? points[points.length - 1].humidity : '--'}\n <span className=\"text-sm font-normal text-zinc-500 ml-1\">%</span>\n </div>\n </div>\n </div>\n </div>\n )}\n\n {tab === 2 && (\n <div className=\"space-y-4\">\n <LineChart\n data={points}\n title=\"CPU & Memory\"\n height=\"h-80\"\n datasets={[\n { key: 'cpu', label: 'CPU (%)', color: '#f97316' },\n { key: 'memory', label: 'Memory (%)', color: '#34d399' }\n ]}\n />\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"bg-zinc-900/50 rounded-xl border border-zinc-800/50 p-5\">\n <div className=\"text-xs text-zinc-500 uppercase tracking-wider\">Current CPU</div>\n <div className=\"text-3xl font-bold text-orange-400 mt-2\">\n {points.length > 0 ? points[points.length - 1].cpu : '--'}\n <span className=\"text-sm font-normal text-zinc-500 ml-1\">%</span>\n </div>\n </div>\n <div className=\"bg-zinc-900/50 rounded-xl border border-zinc-800/50 p-5\">\n <div className=\"text-xs text-zinc-500 uppercase tracking-wider\">Current Memory</div>\n <div className=\"text-3xl font-bold text-emerald-400 mt-2\">\n {points.length > 0 ? points[points.length - 1].memory : '--'}\n <span className=\"text-sm font-normal text-zinc-500 ml-1\">%</span>\n </div>\n </div>\n </div>\n </div>\n )}\n\n </div>\n </Page>\n );\n}",
|
|
74
|
+
"x": 600,
|
|
75
|
+
"y": 160,
|
|
76
|
+
"wires": [
|
|
77
|
+
[
|
|
78
|
+
"fc-chart-debug"
|
|
79
|
+
]
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"id": "fc-chart-debug",
|
|
84
|
+
"type": "debug",
|
|
85
|
+
"z": "fc-chart-flow",
|
|
86
|
+
"name": "Chart output",
|
|
87
|
+
"active": true,
|
|
88
|
+
"tosidebar": true,
|
|
89
|
+
"x": 790,
|
|
90
|
+
"y": 160,
|
|
91
|
+
"wires": []
|
|
92
|
+
}
|
|
93
|
+
]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "fc-d3-flow",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "D3.js Poland Map",
|
|
6
|
+
"disabled": false
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "fc-d3-inject",
|
|
10
|
+
"type": "inject",
|
|
11
|
+
"z": "fc-d3-flow",
|
|
12
|
+
"name": "Tick",
|
|
13
|
+
"props": [
|
|
14
|
+
{
|
|
15
|
+
"p": "payload"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"repeat": "3",
|
|
19
|
+
"payload": "{}",
|
|
20
|
+
"payloadType": "json",
|
|
21
|
+
"x": 160,
|
|
22
|
+
"y": 160,
|
|
23
|
+
"wires": [
|
|
24
|
+
[
|
|
25
|
+
"fc-d3-func"
|
|
26
|
+
]
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "fc-d3-func",
|
|
31
|
+
"type": "function",
|
|
32
|
+
"z": "fc-d3-flow",
|
|
33
|
+
"name": "Region data",
|
|
34
|
+
"func": "var ids = ['ZP','PM','WM','LB','WP','KP','PD','DS','LD','MZ','LU','OP','SL','SK','PK','MP'];\nvar prev = flow.get('energyData') || {};\nvar data = {};\nids.forEach(function(id) {\n var base = prev[id] || (20 + Math.random() * 60);\n var delta = (Math.random() - 0.5) * 8;\n data[id] = +Math.max(5, Math.min(95, base + delta)).toFixed(1);\n});\nflow.set('energyData', data);\nmsg.payload = data;\nreturn msg;",
|
|
35
|
+
"outputs": 1,
|
|
36
|
+
"x": 360,
|
|
37
|
+
"y": 160,
|
|
38
|
+
"wires": [
|
|
39
|
+
[
|
|
40
|
+
"fc-d3-portal"
|
|
41
|
+
]
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "fc-d3-portal",
|
|
46
|
+
"type": "portal-react",
|
|
47
|
+
"z": "fc-d3-flow",
|
|
48
|
+
"name": "Poland Map",
|
|
49
|
+
"endpoint": "/fromcubes/poland",
|
|
50
|
+
"pageTitle": "Poland Energy Grid",
|
|
51
|
+
"customHead": "",
|
|
52
|
+
"portalAuth": false,
|
|
53
|
+
"showWsStatus": false,
|
|
54
|
+
"libs": [
|
|
55
|
+
{
|
|
56
|
+
"module": "d3",
|
|
57
|
+
"var": "d3"
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"componentCode": "import { interpolateRdYlGn, scaleSequential } from 'd3';\n\nfunction App() {\n const { data, send } = useNodeRed();\n const [hover, setHover] = useState(null);\n const regions = [{\"id\":\"PK\",\"name\":\"Podkarpackie\",\"d\":\"M 426.61049,454.21254 C 422.73561,452.87262 418.41239,451.44727 417.00334,451.04511 C 415.5943,450.64296 413.00036,449.38387 411.23906,448.24723 C 409.47775,447.11049 405.90262,445.52727 403.29431,444.72876 C 400.57281,443.89564 398.20751,442.25259 397.74367,440.87297 C 396.4103,436.90723 388.37664,430.12509 385.01243,430.12509 C 383.31619,430.12509 381.54176,429.53456 381.06926,428.81288 C 380.57611,428.05959 377.40659,427.65944 373.6282,427.87341 C 370.0081,428.07839 366.14833,427.71665 365.05095,427.0695 C 362.79914,425.74149 358.26583,414.57395 356.10082,405.02135 C 355.18344,400.97367 353.76714,398.20979 352.20627,397.42119 C 349.27697,395.94129 348.99505,393.17284 351.67477,392.20211 C 352.73157,391.81931 353.5962,390.73942 353.5962,389.8024 C 353.5962,388.86535 352.73157,387.42127 351.67477,386.59333 C 350.39213,385.58845 349.75334,382.87232 349.75334,378.42336 C 349.75334,374.75782 349.10208,369.70672 348.30606,367.19866 C 346.97799,363.0142 347.16451,362.20888 350.57058,357.42139 C 352.61206,354.55192 357.61692,349.99689 361.69248,347.29911 C 365.76804,344.60131 370.3692,340.4549 371.91726,338.08486 C 381.09936,324.0273 382.39673,322.58162 385.86465,322.54317 C 387.76051,322.52216 389.66793,321.96081 390.10335,321.29573 C 390.53877,320.63067 392.01387,320.08652 393.38133,320.08652 C 395.48519,320.08652 395.86763,320.94953 395.86763,325.69699 C 395.86763,332.14896 398.10739,334.49844 404.31552,334.55866 C 407.74054,334.59187 412.52001,337.59393 412.52001,339.71203 C 412.52001,340.09277 410.50251,341.52797 408.03668,342.90138 C 404.33842,344.9612 403.55335,346.10436 403.55335,349.42967 C 403.55335,354.75142 405.51183,356.36295 411.9793,356.36295 C 414.92271,356.36295 419.40033,357.1792 421.92958,358.17677 C 424.45883,359.17438 429.86861,359.99061 433.9513,359.99061 C 440.32361,359.99061 441.55341,359.61946 442.63888,357.36878 C 445.42018,351.60185 451.16844,351.45568 457.75723,356.9844 L 461.36348,360.01044 L 455.64182,367.11257 C 452.49492,371.01875 449.20063,375.50348 448.32119,377.07868 C 447.44175,378.65385 446.31527,380.21473 445.81794,380.54726 C 444.45591,381.45792 434.29621,397.56095 434.29621,398.80906 C 434.29621,399.40616 433.81388,399.8947 433.22439,399.8947 C 432.63491,399.8947 430.20548,403.40582 427.82569,407.69719 L 423.49877,415.49972 L 425.79669,421.53215 C 427.52111,426.05901 427.87584,429.21734 427.21808,434.18706 C 426.2037,441.85125 428.83115,447.61678 433.88367,448.81384 C 436.16344,449.35396 436.85811,450.36045 436.85811,453.12322 C 436.85811,457.37617 436.01753,457.46551 426.61049,454.21254 z\",\"cx\":400.4,\"cy\":387.3},{\"id\":\"MP\",\"name\":\"Ma\u0142opolskie\",\"d\":\"M 290.12055,445.77337 C 287.80951,443.36273 286.73166,443.3031 281.22239,445.28108 C 279.11574,446.03737 278.94502,445.91132 280.26167,444.5718 C 281.14234,443.67575 281.86287,440.33085 281.86287,437.13851 C 281.86287,431.34006 281.85851,431.33426 277.4934,431.33426 C 272.17015,431.33426 266.49143,425.73588 266.49143,420.48795 C 266.49143,418.5763 265.64857,416.7771 264.57001,416.38646 C 263.51322,416.00361 262.64858,414.66619 262.64858,413.41441 C 262.64858,407.82413 259.89149,403.71123 254.87359,401.81589 C 250.2406,400.06595 249.83905,399.54453 249.83905,395.2784 C 249.83905,391.91625 248.97273,389.87425 246.68589,387.84619 L 243.53271,385.04983 L 246.36565,381.57858 C 247.92376,379.66939 251.36019,375.89118 254.00215,373.18253 C 259.06818,367.98868 260.10394,364.34727 256.85048,363.16872 C 253.32964,361.89332 264.03493,353.94453 269.27345,353.94453 C 274.71889,353.94453 280.36064,351.57811 281.27534,348.91035 C 281.79495,347.39491 283.8713,346.79882 289.69935,346.49192 C 300.11483,345.94346 301.07715,346.63361 301.07715,354.65177 C 301.07715,360.90476 303.29615,366.35566 306.81185,368.7389 C 309.01455,370.23208 317.77504,369.76435 321.37475,367.96139 C 324.77282,366.2594 341.13079,361.19983 343.23534,361.19983 C 344.77357,361.19983 346.1688,368.71586 346.40502,378.2748 C 346.52092,382.96438 347.32035,387.09678 348.33495,388.25084 C 349.47057,389.54253 349.57192,390.22098 348.62922,390.22098 C 346.05233,390.22098 346.93718,398.47194 349.66171,399.8484 C 351.293,400.67253 352.64342,403.42212 353.63791,407.94428 C 354.46618,411.71064 356.25119,417.23079 357.60461,420.21134 C 358.95801,423.1919 359.75573,425.92275 359.37733,426.28 C 358.9989,426.63724 354.94941,426.83221 350.37846,426.71337 C 342.44881,426.50709 342.06764,426.62723 342.06764,429.33288 C 342.06764,435.50929 333.55373,438.46563 330.62808,433.30513 C 329.13021,430.6631 328.17283,430.42841 318.37582,430.30236 C 308.39624,430.17401 307.6213,430.34878 305.66418,433.16837 C 304.51789,434.81991 302.56702,436.17114 301.32894,436.17114 C 299.91891,436.17114 297.85153,438.43121 295.79555,442.22019 C 292.52105,448.25473 292.50749,448.26324 290.12055,445.77337 z\",\"cx\":301.4,\"cy\":403.4},{\"id\":\"SL\",\"name\":\"\u015al\u0105skie\",\"d\":\"M 239.59143,430.22703 C 239.59143,429.61809 237.31353,427.08211 234.52942,424.59164 C 230.31518,420.82188 229.40343,419.15483 229.08537,414.63758 C 228.84832,411.27057 227.97422,408.89455 226.7819,408.37605 C 216.86068,404.06227 217.17478,404.42071 217.17478,397.4126 C 217.17478,390.98769 217.08019,390.81585 213.33191,390.43023 C 211.21834,390.21279 208.94145,389.5326 208.27215,388.91871 C 207.60285,388.30481 205.7019,387.80254 204.0478,387.80254 C 200.42308,387.80254 189.50537,377.43457 190.51491,374.95107 C 190.88584,374.03857 192.51553,373.29196 194.13646,373.29196 C 195.75738,373.29196 200.06582,371.83139 203.71078,370.04621 C 209.63227,367.14607 210.25597,366.47007 209.56779,363.69783 C 207.37568,354.86714 207.33012,352.00832 209.35622,350.42097 C 210.48606,349.53579 211.41048,348.07593 211.41048,347.17684 C 211.41048,346.27775 213.13977,344.69798 215.25334,343.66621 C 217.36691,342.63444 219.0962,341.46038 219.0962,341.05715 C 219.0962,339.81029 213.50471,331.59897 212.34745,331.14635 C 211.74598,330.91112 212.1784,329.75427 213.30835,328.57561 C 214.43832,327.39691 215.70817,324.32451 216.13024,321.74802 C 216.55231,319.17152 218.03429,316.03237 219.42353,314.77214 C 221.42812,312.95371 221.81881,311.38671 221.31648,307.1797 C 220.58661,301.06695 222.30537,299.52987 229.87055,299.52987 C 233.30778,299.52987 234.92187,300.2694 236.52465,302.57858 C 238.37224,305.24042 239.47774,305.60146 245.23665,305.42382 C 253.03378,305.18329 257.14302,307.22854 258.2275,311.8896 C 258.85638,314.59252 259.71413,315.24966 262.61331,315.24966 C 264.63523,315.24966 266.54102,316.04591 266.95467,317.06348 C 267.36019,318.06108 268.51986,318.8773 269.53173,318.8773 C 270.93141,318.8773 271.21089,320.00752 270.70011,323.60235 C 270.1017,327.81397 270.49612,328.72161 274.32991,331.95527 C 278.4572,335.43646 278.54103,335.677 276.4041,337.90604 C 273.66804,340.76006 273.5246,344.11035 276.09858,345.04274 C 281.52152,347.00718 273.67972,352.06098 267.02858,350.8881 C 263.86303,350.32988 262.35514,351.08672 257.20453,355.81897 C 250.71822,361.77841 249.98707,363.28374 253.04144,364.39018 C 255.88188,365.4191 255.42405,366.86664 250.79977,371.4778 C 240.17067,382.07675 238.58394,386.33131 244.00883,389.68678 C 246.45077,391.19719 247.23079,392.85437 247.53146,397.17063 C 247.88932,402.30816 248.24541,402.81822 252.38978,404.1297 C 255.74289,405.19071 257.3043,406.64197 258.62983,409.92965 C 260.87069,415.48761 260.00859,417.5306 254.34666,420.07929 C 251.34019,421.43272 249.08214,423.67669 247.65592,426.72827 C 246.0587,430.14569 244.7404,431.33426 242.5473,431.33426 C 240.92158,431.33426 239.59143,430.83607 239.59143,430.22703 z\",\"cx\":236.0,\"cy\":361.9},{\"id\":\"OP\",\"name\":\"Opolskie\",\"d\":\"M 178.329,382.58544 C 176.79715,381.04618 175.54382,379.1608 175.54382,378.39574 C 175.54382,377.63067 174.39096,376.42227 172.98191,375.71039 C 171.57287,374.99854 170.42001,373.84017 170.42001,373.13623 C 170.42001,372.43229 171.57287,371.57175 172.98191,371.22392 C 174.88503,370.75411 175.54382,369.57451 175.54382,366.63671 L 175.54382,362.68194 L 166.71246,362.21089 C 158.39772,361.76738 157.58174,361.45721 152.76345,356.90877 C 147.5538,351.99086 144.54339,350.1675 137.83536,347.86699 L 134.07213,346.57641 L 138.1556,344.23216 C 140.49559,342.88881 142.23905,340.88369 142.23905,339.53583 C 142.23905,338.08532 143.25831,337.03562 144.89813,336.79732 C 147.37031,336.43809 150.91714,329.61948 153.30937,320.62714 C 153.67257,319.26182 156.51821,315.52457 159.63297,312.32216 C 162.74776,309.11973 165.29619,305.49467 165.29619,304.26648 C 165.29619,303.03827 166.44905,301.45097 167.8581,300.73909 C 170.5859,299.36095 171.38972,295.90222 168.98222,295.90222 C 167.98883,295.90222 168.03731,295.34159 169.13905,294.0884 C 170.01612,293.09081 172.3924,292.27459 174.41971,292.27459 C 177.25175,292.27459 178.10571,292.83489 178.10571,294.69301 C 178.10571,296.78089 178.95969,297.11144 184.35365,297.11144 C 188.34464,297.11144 191.17758,296.45625 192.1962,295.29762 C 193.98433,293.26371 201.86213,292.82626 203.0843,294.69301 C 203.51971,295.35808 205.77011,295.90222 208.08516,295.90222 C 212.82429,295.90222 216.53429,298.96574 216.53429,302.87905 C 216.53429,304.28385 217.11073,305.76951 217.81524,306.18055 C 219.81068,307.34474 219.32875,310.10724 216.71596,312.48181 C 215.40684,313.67161 213.9904,316.75309 213.56835,319.32959 C 213.14627,321.90609 211.91165,324.94174 210.82476,326.07547 C 208.77631,328.21223 208.08874,333.38787 209.85335,333.38787 C 210.40598,333.38787 211.82965,334.94045 213.01709,336.83805 C 215.12921,340.21334 215.10742,340.31776 212.01233,341.64899 C 210.27227,342.39741 208.84857,343.77102 208.84857,344.70144 C 208.84857,345.63186 207.91131,347.12742 206.76575,348.02492 C 205.07087,349.35275 204.81839,351.1822 205.41026,357.8467 C 205.96856,364.13313 205.74851,366.03668 204.46347,366.03668 C 203.54268,366.03668 201.3237,367.12498 199.53238,368.45511 C 197.74106,369.78526 194.53181,370.87355 192.40071,370.87355 C 188.27364,370.87355 186.27659,373.74924 187.57215,377.82653 C 188.25059,379.96163 184.45838,385.38412 182.28677,385.38412 C 181.64186,385.38412 179.86086,384.12473 178.329,382.58544 z\",\"cx\":184.3,\"cy\":335.9},{\"id\":\"DS\",\"name\":\"Dolno\u015bl\u0105skie\",\"d\":\"M 116.66556,371.52392 C 115.23145,370.08289 114.0581,367.64449 114.0581,366.10532 C 114.0581,363.59442 109.84459,357.989 102.54897,350.79424 C 98.935846,347.23105 99.330248,344.81344 103.81048,343.0616 C 107.13674,341.761 107.65333,340.93483 107.65333,336.91592 C 107.65333,333.69671 106.79365,331.51679 104.84988,329.80734 C 101.84817,327.16744 98.056794,326.57827 96.765239,328.55103 C 94.458287,332.0747 80.753341,327.34674 80.753341,323.02724 C 80.753341,321.87576 79.342358,321.29573 76.541434,321.29573 C 67.098264,321.29573 55.134285,312.0241 55.134285,304.70597 C 55.134285,302.3886 54.531067,301.83472 52.252144,302.05945 C 50.666962,302.21574 47.740051,301.60396 45.747897,300.69988 C 40.849356,298.47683 37.95535,300.32421 37.44386,306.00072 C 37.10431,309.76911 36.590391,310.4128 33.921236,310.4128 C 30.137901,310.4128 30.002598,309.27289 33.314226,305.29863 C 34.699151,303.63659 36.781033,299.61813 37.94061,296.36875 C 39.100196,293.11936 41.137428,288.318 42.467811,285.69909 C 45.260872,280.20075 45.496103,277.61378 43.384263,275.62021 C 42.24499,274.54475 42.238362,273.46338 43.356812,271.14612 C 44.854357,268.04342 47.929389,267.09909 49.370002,269.2995 C 51.788806,272.99405 61.539051,268.85728 61.539051,264.13649 C 61.539051,260.77762 64.04819,260.54655 65.352604,263.78529 C 66.038373,265.48796 67.334242,266.87365 68.232351,266.86458 C 72.947486,266.8169 75.620603,265.12909 76.934851,261.36987 C 77.713034,259.14404 79.466334,256.98836 80.831064,256.57946 C 82.520316,256.07333 83.573166,254.29678 84.129206,251.01422 C 84.702515,247.62972 85.466615,246.381 86.692529,246.82505 C 87.653104,247.17304 88.439051,246.93065 88.439051,246.28647 C 88.439051,245.64228 88.516536,244.7071 88.61123,244.20829 C 88.926992,242.54514 93.074044,240.44031 96.7947,240.05477 C 100.19778,239.70218 100.5556,240.06251 101.59131,244.88512 C 103.03211,251.59374 106.01053,251.31792 109.66289,244.13767 L 112.31293,238.92788 L 117.66885,244.41296 C 120.6146,247.42974 123.02477,250.99292 123.02477,252.33113 C 123.02477,253.93216 125.37991,256.24038 129.91164,259.08077 C 139.14181,264.86603 148.85625,266.01013 155.81925,262.13192 L 160.58478,259.47765 L 163.26072,262.11169 C 165.14763,263.96908 165.46454,264.912 164.33548,265.30957 C 163.45483,265.61968 162.73429,267.12381 162.73429,268.65212 C 162.73429,270.92719 163.75651,271.67381 168.37408,272.77142 C 173.93428,274.09308 174.02133,274.19323 174.54237,279.86795 C 174.83306,283.03374 175.32139,286.44013 175.62759,287.43771 C 176.03805,288.7751 175.1749,289.22952 172.34144,289.16772 C 168.07437,289.07465 165.39882,291.50432 165.33693,295.52856 C 165.31453,296.98571 164.71977,298.51423 164.01525,298.92527 C 163.31072,299.33629 162.73429,300.66451 162.73429,301.87686 C 162.73429,303.0892 160.18585,306.70132 157.07107,309.90372 C 153.95631,313.10614 151.11067,316.84339 150.74746,318.20872 C 148.35523,327.20106 144.8084,334.01966 142.33622,334.37889 C 140.67948,334.61964 139.67715,335.66642 139.67715,337.15587 C 139.67715,338.54608 138.07245,340.40844 135.84238,341.60634 C 133.73327,342.73926 132.00399,344.38528 131.99953,345.2641 C 131.99507,346.14294 131.12678,347.67821 130.07,348.67581 C 127.10011,351.47939 127.75298,353.88092 132.63191,358.09955 C 138.24637,362.95421 138.27148,364.51312 132.75097,365.49077 C 130.35064,365.91585 126.33613,368.03675 123.82985,370.20382 L 119.273,374.14399 L 116.66556,371.52392 z\",\"cx\":106.1,\"cy\":297.1},{\"id\":\"SK\",\"name\":\"\u015awi\u0119tokrzyskie\",\"d\":\"M 309.37376,366.32047 C 305.85406,363.93451 303.63906,358.48663 303.63906,352.21581 C 303.63906,343.90599 302.09629,342.94847 290.06202,343.78948 C 280.54398,344.45463 276.15332,343.13085 278.99144,340.45168 C 281.91155,337.69509 280.84062,332.59915 276.63995,329.26246 C 272.91408,326.30293 272.77909,325.89931 274.17738,321.89969 C 274.99107,319.5723 276.09598,317.66808 276.63279,317.66808 C 277.91157,317.66808 280.58192,312.08884 280.58192,309.41705 C 280.58192,307.7066 281.51479,307.40985 285.70573,307.78714 L 290.82954,308.24841 L 290.82954,303.41389 C 290.82954,300.25647 290.17049,298.34067 288.92971,297.89118 C 287.84866,297.49961 287.35565,296.40154 287.7858,295.34339 C 288.32349,294.02068 290.35124,293.4838 294.80944,293.4838 C 300.15033,293.4838 301.07715,293.13823 301.07715,291.14685 C 301.07715,289.86153 302.23,288.46451 303.63906,288.04232 C 305.04811,287.62015 306.20097,286.28977 306.20097,285.08588 C 306.20097,279.68509 313.02254,279.18603 314.43105,284.48378 C 314.88832,286.20362 316.4551,287.69668 318.24849,288.12158 C 319.92149,288.51796 322.56749,290.22889 324.12846,291.92364 C 326.71189,294.72846 327.59945,294.94337 334.017,294.31811 C 340.0949,293.72593 341.15076,293.93227 341.67205,295.8141 C 342.01823,297.0637 344.3578,298.58558 347.14406,299.3736 C 349.82105,300.13075 352.72673,301.56394 353.60109,302.55847 C 355.65318,304.89263 361.78976,304.88927 363.84382,302.5529 C 364.72088,301.55531 367.25789,300.73909 369.48163,300.73909 C 373.46416,300.73909 373.57094,300.89435 376.60049,311.09048 C 379.62871,321.28204 379.63956,321.5014 377.30422,325.29875 C 375.99964,327.42004 374.1626,329.59291 373.22189,330.1274 C 372.28118,330.66185 370.39087,333.17276 369.0212,335.7072 C 367.52796,338.47028 364.02819,341.83127 360.28014,344.1017 C 353.84546,347.9996 347.19144,354.2159 347.19144,356.32946 C 347.19144,356.98761 345.60627,357.8583 343.66882,358.26427 C 335.69152,359.93594 321.99023,363.9468 318.81285,365.54051 C 315.09771,367.40396 311.42034,367.70782 309.37376,366.32047 z\",\"cx\":320.8,\"cy\":316.6},{\"id\":\"LU\",\"name\":\"Lubelskie\",\"d\":\"M 424.04858,355.75835 C 421.58275,354.86195 417.23071,354.08714 414.37739,354.03653 C 405.13933,353.87271 403.20563,348.76792 410.90716,344.87543 C 413.5389,343.54529 415.89523,341.45621 416.14343,340.23301 C 416.82742,336.8623 411.45791,332.18517 406.85268,332.14023 C 400.66921,332.07985 398.42953,329.7236 398.42953,323.27857 L 398.42953,317.66808 L 393.38133,317.66808 C 390.60481,317.66808 387.97686,318.21224 387.54145,318.8773 C 387.10602,319.54237 385.71377,320.08652 384.44753,320.08652 C 380.90566,320.08652 377.36417,306.24933 377.79648,294.09969 C 377.98557,288.78534 378.74928,284.08194 379.49361,283.64768 C 380.28875,283.18378 380.48367,281.43347 379.9662,279.40414 C 379.48178,277.50446 378.52541,272.95739 377.84096,269.2995 C 376.96419,264.61392 375.65866,261.92082 373.42253,260.18498 C 369.38316,257.04931 369.36464,254.78891 373.37833,254.78891 C 377.89847,254.78891 380.4962,250.5243 380.4962,243.1037 C 380.4962,239.63305 381.07263,236.45713 381.77715,236.04609 C 383.61257,234.97529 383.36123,228.49989 381.45692,227.79541 C 380.57626,227.46963 381.7411,226.80987 384.04548,226.32925 C 386.34984,225.84862 388.54547,224.98154 388.92465,224.40237 C 389.30383,223.82322 393.03862,223.34933 397.22419,223.34933 C 401.44363,223.34933 404.83429,222.81059 404.83429,222.14012 C 404.83429,221.47506 407.17885,220.93091 410.04444,220.93091 C 414.67163,220.93091 415.16358,220.66032 414.44144,218.51247 C 413.87365,216.8237 414.21125,216.09405 415.56049,216.09405 C 416.62316,216.09405 417.84888,216.6382 418.2843,217.30327 C 419.4018,219.01016 424.26914,218.73637 426.95009,216.81584 C 428.19364,215.92499 430.54173,212.81347 432.16806,209.90132 C 435.50169,203.93201 439.89524,202.48508 444.81322,205.73682 C 446.38762,206.77782 448.61071,207.62954 449.75342,207.62954 C 450.89612,207.62954 453.50589,208.98925 455.55292,210.65112 C 457.59995,212.31297 459.78946,213.67334 460.41853,213.67416 C 461.05155,213.67496 461.2525,217.94209 460.86856,223.23002 C 460.42815,229.29552 460.67769,233.25912 461.55193,234.08438 C 462.53406,235.01152 462.31315,236.02673 460.78166,237.62427 C 459.26027,239.21123 458.6343,242.04183 458.6343,247.33454 C 458.6343,253.79588 459.06685,255.15997 461.83668,257.43342 C 464.61024,259.70995 465.03906,261.06807 465.03906,267.57586 C 465.03906,274.23161 465.47176,275.52708 468.82756,278.91831 C 472.88703,283.02059 480.41049,295.33074 480.41049,297.8707 C 480.41049,298.71716 481.19704,299.84487 482.15838,300.37668 C 483.11972,300.90855 484.87279,303.12858 486.05409,305.31009 C 487.98887,308.88301 488.00608,309.46143 486.22764,311.14024 C 483.4978,313.7172 483.74213,315.64036 487.45573,320.80618 C 491.09826,325.87314 491.347,328.39195 488.86859,335.11358 C 486.99726,340.18875 483.87705,343.0616 480.23619,343.0616 C 478.24213,343.0616 470.16077,350.17761 465.88288,355.70034 C 464.45426,357.54468 463.87412,357.39495 459.3768,354.02107 C 455.55394,351.15318 453.16407,350.31689 448.79145,350.31689 C 443.85874,350.31689 442.86745,350.77519 440.96163,353.93689 C 439.08997,357.04189 438.05062,357.5449 433.65573,357.47255 C 430.83763,357.42615 426.51441,356.65476 424.04858,355.75835 z\",\"cx\":428.0,\"cy\":277.1},{\"id\":\"LD\",\"name\":\"\u0141\u00f3dzkie\",\"d\":\"M 270.10363,315.35036 C 269.07351,313.79322 267.09657,312.83124 264.92677,312.83124 C 262.27912,312.83124 261.22472,312.1102 260.63636,309.89719 C 259.27526,304.77789 255.38897,302.5529 247.80834,302.5529 C 242.12125,302.5529 240.57252,302.07969 238.90404,299.83217 C 237.19866,297.53495 235.71102,297.11144 229.34678,297.11144 C 225.20117,297.11144 221.43545,297.68247 220.97853,298.38039 C 220.47538,299.1489 218.95417,298.43358 217.12123,296.56656 C 215.17805,294.58729 212.72433,293.4838 210.2663,293.4838 C 208.16065,293.4838 206.08162,292.93966 205.6462,292.27459 C 205.21078,291.6095 203.44747,291.06536 201.72774,291.06536 C 200.008,291.06536 198.60096,290.60448 198.60096,290.04116 C 198.60096,289.47788 197.4481,287.76217 196.03905,286.22849 C 192.95106,282.86742 192.70631,277.45483 195.54188,275.23333 C 196.67749,274.34364 199.48257,273.76829 201.77544,273.95477 C 206.87252,274.36932 207.47019,272.85721 207.67783,259.02118 C 207.89595,244.48616 208.4348,243.37282 215.4615,242.93915 C 223.61455,242.43594 227.96915,238.21523 225.83693,232.88269 C 223.78298,227.7459 225.64044,223.6313 230.23804,223.13342 C 233.20953,222.81162 233.89398,222.09681 234.21552,218.97958 C 234.48519,216.36531 235.56196,214.80234 237.73814,213.86635 C 239.7116,213.01754 240.87966,211.50102 240.89201,209.7716 C 240.91918,205.96507 242.58467,203.84633 246.84137,202.20314 C 250.07675,200.95417 251.04679,201.18664 255.60335,204.30303 C 260.27049,207.49506 261.41214,207.75007 268.41286,207.16446 C 272.64,206.81084 278.04474,206.36272 280.42339,206.16864 C 285.03986,205.79193 286.2742,206.92818 287.56943,212.74671 C 288.0215,214.77761 289.77789,216.7692 292.12904,217.91693 C 295.56398,219.59374 295.95335,220.37158 295.95335,225.55699 C 295.95335,228.73225 296.64506,231.98314 297.49048,232.78124 C 298.3838,233.6245 302.6658,234.23227 307.7137,234.23227 C 316.1501,234.23227 316.42174,234.32786 317.1643,237.55762 C 317.58479,239.38655 318.55484,242.10199 319.31994,243.59193 C 321.39187,247.62676 317.3454,251.53937 312.20326,250.47323 C 306.13239,249.21451 303.7563,255.95326 308.76287,260.2304 C 310.17192,261.43416 311.32478,263.58626 311.32478,265.01282 C 311.32478,266.4394 311.95923,268.20551 312.73466,268.93754 C 313.76056,269.90598 313.41169,270.48806 311.45371,271.07468 C 309.97375,271.51812 308.75004,272.52443 308.73438,273.31093 C 308.71871,274.09745 307.57869,276.10133 306.20097,277.764 C 304.82325,279.42667 303.68321,281.70263 303.66755,282.82168 C 303.65189,283.94073 302.4862,285.20173 301.07715,285.62389 C 299.6681,286.04607 298.51525,287.4431 298.51525,288.72842 C 298.51525,290.71981 297.58842,291.06536 292.24753,291.06536 C 287.71386,291.06536 285.76471,291.59455 285.2023,292.9781 C 283.84752,296.31084 284.35842,299.58173 286.34621,300.30179 C 288.80325,301.19187 288.86608,305.57593 286.4218,305.57593 C 285.40659,305.57593 284.21972,305.03181 283.7843,304.36673 C 282.06282,301.73733 279.3367,303.37838 278.07432,307.80399 C 277.34535,310.35955 275.62872,313.66971 274.25955,315.15996 L 271.7702,317.86949 L 270.10363,315.35036 z\",\"cx\":263.6,\"cy\":265.9},{\"id\":\"MZ\",\"name\":\"Mazowieckie\",\"d\":\"M 356.163,300.14005 C 355.28863,299.14551 352.38296,297.71233 349.70596,296.95517 C 346.84358,296.14562 344.58186,294.65153 344.21524,293.32806 C 343.3879,290.34151 339.74047,289.13603 336.79151,290.87454 C 333.09725,293.05244 329.39656,292.53852 326.3148,289.4196 C 324.76325,287.84936 322.19821,286.18067 320.61465,285.71137 C 319.03111,285.24207 317.3822,283.52928 316.95037,281.90514 C 316.49053,280.17563 314.93248,278.6601 313.18981,278.24722 C 309.76044,277.43469 310.2428,274.62351 314.00502,273.49631 C 316.61059,272.71564 317.43453,267.59901 315.16763,266.27646 C 314.46311,265.86542 313.88668,264.2852 313.88668,262.76488 C 313.88668,261.24454 312.74741,259.02733 311.35497,257.83776 C 308.08499,255.04419 309.13371,253.57971 314.40423,253.57971 C 316.85523,253.57971 319.49895,252.65602 320.73339,251.36838 C 322.97734,249.02771 323.63424,242.08588 321.7176,240.96768 C 321.09294,240.60324 320.20218,238.39454 319.73813,236.05947 L 318.89439,231.81384 L 310.24197,231.81384 C 305.22023,231.81384 300.94452,231.20496 300.05239,230.3628 C 299.20697,229.56471 298.51525,226.32952 298.51525,223.1735 C 298.51525,218.11796 298.09967,217.2472 295.02242,215.85492 C 292.99646,214.93829 291.05073,212.75233 290.38935,210.64977 C 288.22276,203.76229 287.71955,203.38295 281.07217,203.6259 C 277.63217,203.75161 272.36842,204.21681 269.37494,204.65967 C 264.64027,205.36016 263.09896,204.96011 257.52615,201.58432 C 250.64088,197.41348 249.62209,195.17005 253.68192,193.11897 C 256.39678,191.74739 257.11972,187.17422 254.94604,185.12228 C 253.20945,183.48292 255.91799,176.10124 259.02522,174.00528 C 261.53038,172.3154 262.25472,165.96731 260.08667,164.70242 C 259.38215,164.29138 258.80573,162.62684 258.80573,161.00342 C 258.80573,158.89334 259.51079,158.05174 261.27854,158.05174 C 262.85184,158.05174 263.90025,157.08008 264.16068,155.38058 C 264.41864,153.69722 265.75425,152.44318 267.7724,151.98948 C 270.6529,151.3419 270.97477,150.66944 270.97477,145.299 C 270.97477,139.36695 271.00965,139.31702 276.38567,137.55293 C 280.78351,136.10983 282.5992,136.0514 286.08375,137.24085 C 288.44171,138.04576 292.92396,138.69026 296.04429,138.6731 C 301.39787,138.64367 301.84993,138.37106 304.06479,133.83624 C 306.31214,129.23493 306.66689,129.03058 312.40747,129.03058 C 317.39642,129.03058 318.61527,128.5738 319.66744,126.30985 C 320.52129,124.47266 322.24029,123.46913 324.96086,123.21965 C 327.1768,123.01645 330.00417,121.79211 331.24393,120.49891 C 332.79861,118.87721 335.17633,118.14764 338.90693,118.14764 C 341.99237,118.14764 344.95815,117.41706 345.8111,116.44687 C 346.6335,115.51144 350.09159,114.55919 353.49577,114.33075 L 359.68518,113.91541 L 360.33935,124.77137 C 360.86051,133.41988 361.45076,135.87871 363.24208,136.86352 C 367.76735,139.35138 372.81049,144.7314 372.81049,147.07114 C 372.81049,153.18502 380.52126,160.47017 386.99234,160.47017 C 388.74029,160.47017 390.83552,161.54029 391.7275,162.88859 C 392.83116,164.55688 394.71471,165.30702 397.79991,165.30702 C 401.61288,165.30702 402.27239,165.71714 402.27239,168.08823 C 402.27239,169.61788 402.94681,171.50605 403.77106,172.28416 C 404.91533,173.36434 404.88116,174.8104 403.62655,178.399 C 401.35029,184.90988 402.55243,187.31236 410.61531,192.36601 C 416.4827,196.04356 418.71312,196.74661 424.51251,196.74661 C 429.09034,196.74661 431.95851,197.35846 433.01525,198.56043 C 433.89231,199.55804 435.83627,200.43865 437.33518,200.51732 C 439.37306,200.62432 439.13814,200.85306 436.40378,201.42423 C 433.78843,201.97056 431.89783,203.68906 429.76499,207.45871 C 426.48324,213.25894 422.15018,216.87656 420.8547,214.89779 C 420.4146,214.22562 418.01709,213.67562 415.52687,213.67562 C 412.0765,213.67562 410.83981,214.25105 410.32926,216.09405 C 409.85472,217.80708 408.58202,218.51247 405.96585,218.51247 C 403.93445,218.51247 402.27239,219.05663 402.27239,219.72169 C 402.27239,220.39216 398.88172,220.93091 394.66228,220.93091 C 390.47672,220.93091 386.74192,221.40478 386.36274,221.98394 C 385.98356,222.56312 383.93204,223.36572 381.80381,223.76755 C 377.69278,224.54369 376.59512,227.64756 379.47145,230.3628 C 380.66699,231.49139 380.66699,232.13632 379.47145,233.2649 C 378.62601,234.06299 377.9343,237.47886 377.9343,240.85573 C 377.9343,248.10109 375.29515,252.37049 370.81643,252.37049 C 366.15394,252.37049 366.3714,259.1495 371.14925,262.74589 C 373.89082,264.80952 374.64889,266.45565 374.78972,270.6512 C 374.88757,273.56565 375.12498,276.49431 375.31734,277.1594 C 375.86954,279.06868 375.28798,293.86202 374.56864,296.20453 C 374.07938,297.7977 372.55436,298.32065 368.39769,298.32065 C 365.05272,298.32065 362.24803,299.03556 361.28191,300.13447 C 359.27512,302.41711 358.16597,302.41833 356.163,300.14005 z\",\"cx\":342.2,\"cy\":208.4},{\"id\":\"WP\",\"name\":\"Wielkopolskie\",\"d\":\"M 179.57514,288.94923 C 178.6539,285.79016 177.60217,280.6153 177.23796,277.44952 C 176.58314,271.75763 176.50979,271.67788 170.64859,270.28465 C 167.38863,269.50978 165.42715,268.65369 166.28974,268.38228 C 168.93871,267.54873 168.06419,261.43934 164.8934,258.62734 C 161.14035,255.299 159.18326,255.31778 155.34818,258.71887 C 150.30128,263.19464 141.79436,262.50442 132.84108,256.89271 C 127.94874,253.82628 125.58667,251.53881 125.58667,249.86733 C 125.58667,248.50416 122.74968,244.55717 119.28225,241.09619 C 115.81482,237.63524 112.56841,233.26362 112.06801,231.3815 C 111.2026,228.12653 110.89246,227.99705 105.7157,228.72991 C 100.72685,229.43612 100.20893,229.25842 99.501471,226.59757 C 99.077011,225.00105 96.12609,221.42929 92.943907,218.6603 C 86.611999,213.15064 86.320392,211.97056 88.619829,201.16203 C 89.915117,195.07348 89.822065,194.02049 87.80256,191.91392 C 85.915152,189.94516 85.806912,189.21441 87.172627,187.66097 C 88.504055,186.14655 88.514057,184.80294 87.224563,180.68531 C 86.346161,177.88034 85.133017,174.6795 84.528714,173.57235 C 83.811881,172.25903 84.031317,171.0882 85.160029,170.20393 C 86.111576,169.45845 87.270427,166.9348 87.735247,164.59577 C 88.200077,162.25678 89.434561,160.03366 90.478532,159.65547 C 93.160387,158.68399 96.124766,152.79463 96.124766,148.43808 C 96.124766,145.14139 96.534924,144.75037 99.993075,144.75037 C 104.94556,144.75037 113.80245,139.49649 115.3571,135.63645 C 116.01681,133.99843 117.29139,132.65776 118.1895,132.65716 C 120.79539,132.65544 129.42952,123.55408 129.42952,120.80889 C 129.42952,119.43142 128.35598,117.98897 127.03656,117.59366 C 125.72043,117.19933 123.61358,115.80229 122.35468,114.48914 C 120.13598,112.17478 120.16025,112.10144 123.14647,112.09706 C 128.51162,112.08919 134.33174,107.85136 134.78709,103.62113 C 135.18675,99.908406 135.23836,99.881523 137.75572,102.07505 C 144.82547,108.23538 148.73561,109.97838 153.77804,109.21723 C 159.32273,108.38025 161.91572,110.32605 158.44666,112.72062 C 155.10783,115.02531 155.73305,121.3506 159.53191,123.70031 C 163.55472,126.18853 163.6206,128.70121 159.70716,130.38444 C 157.0635,131.52152 156.58343,132.77401 155.91761,140.27127 C 155.09388,149.54622 155.69738,151.00964 161.51746,153.85079 C 166.33657,156.20328 167.08888,159.87549 163.2395,162.25646 C 158.75573,165.02983 158.85715,172.20462 163.39533,173.27985 C 165.16794,173.69982 167.76187,173.76113 169.15962,173.41608 C 171.18086,172.91714 171.70096,173.39202 171.70096,175.7365 C 171.70096,179.47729 174.93958,180.70864 177.96975,178.11993 C 180.56877,175.8996 182.18077,176.94833 183.79049,181.90677 C 184.37729,183.71434 186.27611,185.01007 189.56233,185.84539 C 192.25587,186.53006 195.17383,187.90257 196.04669,188.89539 C 198.1866,191.32942 206.28667,191.32257 206.28667,188.88671 C 206.28667,186.31144 208.54092,186.64067 210.42681,189.49132 C 211.4044,190.96903 213.41402,191.90975 215.59318,191.90975 C 218.11113,191.90975 219.48365,192.70961 220.26185,194.63048 C 222.3989,199.9055 226.19714,201.98084 232.08716,201.09174 C 235.59592,200.56209 237.77151,200.76024 238.36277,201.66332 C 239.57679,203.51766 236.92057,210.27704 234.23113,212.17731 C 233.04426,213.01592 231.8914,215.18992 231.66922,217.00842 C 231.35171,219.60719 230.45279,220.44636 227.46905,220.9294 C 222.7625,221.69141 220.38367,227.61284 222.57873,233.10251 C 223.79386,236.14149 223.59431,236.75958 220.85,238.45701 C 218.77205,239.74229 216.35691,240.12967 213.53618,239.63015 C 207.041,238.47988 205.89782,240.77441 205.07618,256.61053 C 204.68517,264.14683 203.98906,270.66672 203.52927,271.09919 C 203.06949,271.53166 201.4644,271.16763 199.96242,270.2902 C 197.49858,268.85089 196.87489,269.07921 193.58447,272.62484 C 191.57858,274.78631 189.29277,276.55479 188.50489,276.55479 C 186.56444,276.55479 186.69838,278.44742 188.77776,280.41033 C 189.71571,281.29578 190.87956,283.51123 191.36407,285.33357 C 191.84859,287.15593 192.81045,288.64693 193.50155,288.64693 C 194.19265,288.64693 194.7581,289.19109 194.7581,289.85614 C 194.7581,290.52124 194.1405,291.06536 193.38565,291.06536 C 192.63081,291.06536 191.14855,291.8816 190.09177,292.87919 C 189.03499,293.87679 186.61329,294.69301 184.71023,294.69301 C 181.6714,294.69301 181.04616,293.99366 179.57514,288.94923 z\",\"cx\":160.5,\"cy\":203.7},{\"id\":\"LB\",\"name\":\"Lubuskie\",\"d\":\"M 51.857582,266.76757 C 51.380988,266.0396 48.755079,265.64618 46.017696,265.89259 C 42.922578,266.17124 41.043809,265.82966 41.043809,264.9883 C 41.043809,264.24468 38.80647,263.00347 36.071953,262.23007 C 29.439481,260.35421 27.820369,258.3925 29.487694,254.25269 C 31.793809,248.52684 31.04657,244.58493 26.953334,240.88295 C 24.839762,238.97143 23.126503,236.82908 23.146101,236.12216 C 23.165719,235.41527 24.934844,232.66029 27.077539,230.00003 L 30.973315,225.16316 L 30.091897,212.46641 C 29.508645,204.06495 28.406816,198.18124 26.834932,195.07439 C 24.505447,190.47011 24.508413,190.31419 26.987324,187.02784 C 29.829802,183.25951 30.333678,176.23703 27.924757,173.96303 C 26.658065,172.76729 26.723278,172.22944 28.244999,171.32127 C 29.295888,170.69409 31.122631,170.17258 32.304413,170.1624 C 35.112115,170.1382 39.762854,164.50134 39.762854,161.1225 C 39.762854,159.66544 41.201845,157.19715 42.960599,155.63742 C 45.859521,153.06655 46.46469,152.9563 49.436588,154.45773 C 52.376607,155.94306 53.310358,155.80845 58.486712,153.1529 C 61.661225,151.52432 65.177081,149.23959 66.299712,148.07571 C 67.422347,146.91186 69.333812,145.95959 70.547404,145.95959 C 71.760986,145.95959 73.471527,145.14338 74.348575,144.14577 C 75.225633,143.14818 77.529877,142.33194 79.469101,142.33194 C 81.408355,142.33194 84.796343,141.99185 86.99798,141.57619 C 90.367436,140.94004 91.000961,140.27024 91.000961,137.34394 C 91.000961,135.10998 91.666117,133.86743 92.862023,133.86743 C 94.335526,133.86743 94.588026,135.18951 94.074496,140.21582 C 92.853274,152.16884 92.195314,154.31286 89.026145,156.66613 C 87.287854,157.95689 85.510548,160.689 85.076543,162.73749 C 84.642547,164.78596 83.492267,167.08499 82.520385,167.84641 C 80.359446,169.53938 80.214151,173.98807 82.256827,175.91635 C 83.127674,176.73843 83.707463,180.62605 83.634716,185.15518 C 83.553856,190.18888 84.097047,193.43534 85.159362,194.26761 C 86.357169,195.20605 86.521495,196.96635 85.758699,200.68813 C 85.180682,203.50831 84.682658,208.11713 84.651983,210.92997 C 84.602406,215.4743 85.240988,216.60531 90.381997,221.07874 C 93.56419,223.84772 96.521875,227.44499 96.954636,229.07271 C 97.661307,231.73059 98.304984,231.98986 103.27121,231.61698 C 109.95074,231.11549 111.00594,233.04598 108.00039,240.2689 C 105.88632,245.3494 103.81048,245.6536 103.81048,240.88295 C 103.81048,239.29881 103.21289,237.654 102.48252,237.2279 C 99.967536,235.76059 90.585747,238.14193 87.534801,241.02203 C 85.854527,242.6082 84.00319,243.90599 83.420734,243.90599 C 82.838278,243.90599 81.983714,246.13749 81.521721,248.86489 C 80.932865,252.34113 79.942809,254.0062 78.210381,254.43388 C 76.828462,254.77501 75.106445,256.85343 74.304005,259.14869 C 72.57943,264.08154 69.006543,264.60326 66.895927,260.2304 C 66.093424,258.56771 64.675116,257.20734 63.744132,257.20734 C 61.410805,257.20734 58.977141,259.70446 58.977141,262.09864 C 58.977141,263.97218 55.21805,268.09028 53.507818,268.09028 C 53.07648,268.09028 52.333878,267.49507 51.857582,266.76757 z\",\"cx\":66.1,\"cy\":205.2},{\"id\":\"KP\",\"name\":\"Kujawsko-Pomorskie\",\"d\":\"M 240.87239,199.0112 C 240.87239,198.09619 238.66989,197.84793 234.17189,198.25591 C 227.07431,198.89971 225.51985,198.06422 222.92697,192.21205 C 222.05811,190.25103 220.65221,189.49132 217.89201,189.49132 C 215.37352,189.49132 213.59315,188.66341 212.69143,187.07289 C 210.98405,184.0613 202.44382,183.55742 202.44382,186.46828 C 202.44382,188.98563 199.43376,188.73662 196.81258,186.00247 C 195.61058,184.74866 193.05294,183.42562 191.12891,183.06237 C 188.72566,182.60862 186.94835,181.05119 185.45083,178.0867 C 183.15736,173.54663 178.91053,172.28627 175.80001,175.22259 C 174.60446,176.35118 174.26287,175.91294 174.26287,173.25057 C 174.26287,170.07146 173.96613,169.8703 170.09977,170.4285 C 162.1962,171.56953 160.1625,168.48647 166.11754,164.39146 C 171.03522,161.00979 169.64235,154.71733 163.08341,150.68439 C 158.47941,147.8535 158.35956,147.59305 158.72693,141.21757 C 159.02914,135.97316 159.72396,134.20193 162.20044,132.36302 C 166.40335,129.24217 166.35209,123.91576 162.09381,121.28187 C 158.50004,119.05903 157.91865,116.34035 160.81286,115.29194 C 161.86965,114.90913 162.73429,113.86483 162.73429,112.97126 C 162.73429,110.89343 167.47646,101.58403 168.98246,100.7054 C 169.61124,100.33854 171.94751,100.6379 174.17413,101.37063 C 177.55672,102.48378 178.63428,102.35114 180.72604,100.56413 C 182.10296,99.387822 183.22953,97.75172 183.22953,96.928348 C 183.22953,95.241023 186.05195,93.963353 189.77925,93.963353 C 191.15279,93.963353 192.6084,93.147122 193.01393,92.149532 C 194.09406,89.492387 201.47786,89.807112 203.31807,92.588714 C 204.4383,94.282032 207.06265,95.051407 213.88215,95.685736 C 221.6249,96.405984 223.47116,97.044668 226.46999,100.04043 C 229.34317,102.91061 231.50327,103.72437 238.31048,104.50099 L 246.63667,105.4509 L 247.03627,110.01757 C 247.46521,114.91962 250.46398,117.35923 263.29304,123.24301 C 268.33288,125.55443 269.05334,126.36787 269.05334,129.74678 C 269.05334,132.2929 269.81709,133.90003 271.29501,134.46379 C 273.30873,135.23194 273.25587,135.42129 270.77519,136.32589 C 267.42364,137.54806 265.54757,144.03357 267.80335,146.59942 C 269.36346,148.37397 269.16213,148.52679 262.96882,150.26989 C 262.08816,150.51775 261.36762,151.82592 261.36762,153.17694 C 261.36762,154.76983 260.52599,155.6333 258.97332,155.6333 C 255.47812,155.6333 254.22248,163.73969 257.23151,166.87843 C 259.31186,169.04845 259.27717,169.27756 256.55292,171.35998 C 254.97386,172.56702 253.68192,174.14753 253.68192,174.87227 C 253.68192,175.597 253.10549,176.18996 252.40095,176.18996 C 250.64574,176.18996 250.7752,186.26371 252.55198,187.94099 C 253.60731,188.93722 253.2704,189.71344 251.27103,190.89213 C 249.77891,191.77178 248.5581,193.70182 248.5581,195.18113 C 248.5581,196.66042 247.44313,198.43403 246.0804,199.12251 C 242.85158,200.75374 240.87239,200.71143 240.87239,199.0112 z\",\"cx\":215.6,\"cy\":149.3},{\"id\":\"PD\",\"name\":\"Podlaskie\",\"d\":\"M 435.57716,196.142 C 434.52042,194.94004 431.65224,194.32818 427.07441,194.32818 C 421.28493,194.32818 419.04334,193.62433 413.2313,189.98148 C 409.41704,187.59076 405.9694,184.83061 405.56989,183.84778 C 404.73539,181.79491 406.88419,177.39918 408.72222,177.39918 C 410.70955,177.39918 410.09888,174.61478 407.3962,171.35309 C 406.01849,169.69043 404.87846,167.10574 404.86279,165.60932 C 404.83401,162.86029 404.22016,162.55212 398.42953,162.37946 C 396.11838,162.31057 395.3319,161.69509 395.60355,160.16786 C 395.90606,158.46705 395.04171,158.05174 391.19948,158.05174 C 383.1633,158.05174 375.37239,151.45605 375.37239,144.65271 C 375.37239,142.31297 370.32926,136.93294 365.80399,134.44509 C 364.0087,133.45811 363.42121,130.9866 362.88953,122.18398 L 362.22363,111.15905 L 367.51034,110.31588 C 370.41804,109.85214 373.0812,109.0387 373.4285,108.50825 C 373.77579,107.97778 376.73333,107.16533 380.00081,106.70278 C 386.09131,105.84061 387.47353,104.85241 395.83867,95.37979 C 398.28858,92.60555 400.91877,90.335701 401.68354,90.335701 C 404.11175,90.335701 410.34214,83.282355 412.08358,78.561943 C 414.45296,72.139439 414.22328,70.318412 410.77487,68.185454 C 408.55054,66.80964 407.57295,64.841205 407.08518,60.756029 C 406.63314,56.97021 405.46755,54.417249 403.42918,52.74838 L 400.43679,50.298439 L 406.32706,45.22586 C 409.56671,42.435947 412.55555,39.201031 412.96894,38.037159 C 414.03889,35.02482 417.97814,35.420133 422.0061,38.944072 C 423.90659,40.606747 426.03237,41.967105 426.73005,41.967105 C 427.42774,41.967105 429.23601,43.055397 430.74843,44.385534 C 432.26088,45.71567 434.45316,46.803973 435.62016,46.803973 C 440.5791,46.803973 446.04407,58.055411 444.92175,65.954358 C 444.47431,69.10346 444.71208,70.988262 445.55677,70.988262 C 447.82244,70.988262 449.80747,78.805957 448.90083,84.158255 C 448.27161,87.872818 448.56711,89.733535 450.03079,91.273482 C 451.12087,92.420359 452.42906,95.475553 452.93786,98.062754 C 453.44668,100.64997 455.21778,105.00315 456.87368,107.73649 C 458.52957,110.46982 459.89134,113.81547 459.89981,115.17123 C 459.90831,116.52703 461.08659,119.7919 462.51822,122.42652 C 465.59969,128.09733 469.61297,142.50931 470.87246,152.42714 C 472.01968,161.46109 469.91671,167.96816 465.23098,169.88304 C 458.71748,172.54484 453.2173,176.04729 451.18214,178.82912 C 450.05458,180.37039 448.38787,182.35049 447.47838,183.22933 C 446.5689,184.10816 445.82478,185.87664 445.82478,187.15927 C 445.82478,188.44189 445.35512,189.49132 444.78107,189.49132 C 444.20704,189.49132 442.77528,191.39584 441.59941,193.72358 C 439.25161,198.37125 437.98441,198.88013 435.57716,196.142 z\",\"cx\":420.9,\"cy\":122.1},{\"id\":\"ZP\",\"name\":\"Zachodniopomorskie\",\"d\":\"M 24.391424,169.42485 C 24.391424,168.76337 20.375355,164.43741 15.46683,159.8116 C 10.558296,155.18582 6.5232955,150.64127 6.5001546,149.71262 C 6.4770235,148.784 9.0520215,145.4064 12.222376,142.20687 C 15.39274,139.0073 17.986669,135.78778 17.986669,135.05234 C 17.986669,134.31692 19.520512,130.75813 21.39522,127.14388 C 24.417869,121.31652 24.642501,120.05886 23.379422,116.03477 C 22.596043,113.53899 21.591346,109.0483 21.14678,106.0555 C 20.702195,103.0627 19.924718,97.893303 19.41905,94.567954 C 18.913383,91.242617 17.81244,87.341513 16.972527,85.898841 C 16.027728,84.276051 15.752096,81.163572 16.249672,77.736642 C 17.006944,72.521157 17.287035,72.19438 21.04291,72.1444 C 23.236863,72.11521 27.337614,71.259877 30.155707,70.243653 C 32.97381,69.227428 37.873456,67.61085 41.043809,66.651258 C 44.214163,65.691666 48.249163,63.920288 50.010475,62.71487 C 53.638671,60.231776 60.479234,58.296685 74.180477,55.877555 C 80.043216,54.842413 84.685167,53.265922 86.432086,51.71668 C 88.424907,49.949374 90.948369,49.222402 95.09017,49.222402 C 105.63343,49.222402 114.70589,43.657172 120.32755,33.741262 C 121.88272,30.998156 127.9713,27.456532 131.13194,27.456532 C 133.60549,27.456532 135.55073,32.679239 136.16224,40.962215 C 136.62224,47.192974 136.39704,47.933891 133.6894,49.098494 C 129.99324,50.688261 129.71311,55.536163 133.13097,58.762625 C 135.03446,60.559513 135.41233,62.212835 134.90008,66.503021 C 134.34241,71.173474 134.63925,72.155795 136.96293,73.329741 C 140.01319,74.870769 140.77788,80.661988 137.9311,80.661988 C 136.69882,80.661988 135.9818,83.052156 135.49434,88.784802 C 135.11445,93.25236 134.17088,97.10674 133.39754,97.350071 C 132.62417,97.593421 131.99143,99.340132 131.99143,101.23164 C 131.99143,105.67091 126.74046,109.68316 120.93058,109.68316 C 114.7852,109.68316 115.12598,113.48318 121.67283,117.9601 L 126.72565,121.41536 L 121.93906,125.82758 C 119.30643,128.25431 116.44197,130.2398 115.57358,130.2398 C 114.70519,130.2398 113.45575,131.57794 112.79704,133.21345 C 111.34412,136.82088 102.31534,142.7032 99.122238,142.12272 C 97.256663,141.78354 96.892031,140.72628 97.209446,136.57636 L 97.601618,131.44901 L 93.020347,131.44901 C 88.828247,131.44901 88.439051,131.74436 88.439051,134.9255 C 88.439051,137.85181 87.805536,138.52161 84.43607,139.15775 C 82.234443,139.57342 78.846445,139.91351 76.907201,139.91351 C 74.967967,139.91351 72.663733,140.72975 71.786665,141.72734 C 70.909617,142.72496 69.142443,143.54116 67.859607,143.54116 C 66.576757,143.54116 64.764216,144.49343 63.83171,145.65728 C 60.68171,149.58883 54.515391,151.77904 48.421999,151.13069 C 43.191153,150.57412 42.4722,150.83227 39.953407,154.17148 C 38.439559,156.17843 37.200944,158.61534 37.200944,159.58686 C 37.200944,162.28412 32.171539,167.72545 29.678455,167.72545 C 28.461449,167.72545 26.773999,168.37845 25.928562,169.17651 C 25.083145,169.9746 24.391424,170.08636 24.391424,169.42485 z\",\"cx\":73.6,\"cy\":108.2},{\"id\":\"WM\",\"name\":\"Warmi\u0144sko-Mazurskie\",\"d\":\"M 288.31176,134.94256 C 286.5747,134.28805 283.11615,133.91443 280.62605,134.1123 C 275.16155,134.54651 271.61782,131.7176 271.60946,126.91445 C 271.6043,123.96117 270.38611,123.00208 260.72135,118.34234 C 249.84569,113.09877 249.83905,113.09266 249.83905,108.32836 C 249.83905,103.63217 249.59636,103.36669 243.85396,101.78121 C 241.18013,101.04297 243.57088,96.621779 247.46792,95.097971 C 250.03969,94.092365 251.4928,92.506075 251.9894,90.162096 C 252.45694,87.955376 253.52383,86.708065 254.9438,86.708065 C 258.08008,86.708065 266.49143,78.892 266.49143,75.977689 C 266.49143,73.161976 265.01232,72.101084 259.64065,71.063991 C 256.79041,70.513697 255.51392,69.417402 254.80347,66.909678 C 254.27263,65.035971 252.94747,62.874512 251.85867,62.106434 C 249.81342,60.663653 250.35917,55.268469 252.55036,55.268469 C 253.17271,55.268469 253.68192,53.091884 253.68192,50.431612 C 253.68192,46.099999 254.01092,45.594754 256.83165,45.594754 C 261.61829,45.594754 268.98558,41.69567 269.02184,39.143199 C 269.04993,37.16375 269.91861,36.990113 277.0593,37.536555 C 281.46258,37.873526 288.52382,38.68147 292.75096,39.331992 C 317.71023,43.173004 324.09716,43.714963 343.34858,43.625438 C 354.97323,43.571378 369.96037,42.901618 376.65335,42.137071 C 383.34632,41.372524 393.1456,40.447315 398.42953,40.081063 L 408.03668,39.415145 L 403.23306,43.411856 C 397.58011,48.115222 397.13855,51.521434 401.63192,55.763151 C 403.98627,57.985654 404.83429,60.074215 404.83429,63.650134 C 404.83429,67.433752 405.50905,68.931423 407.87215,70.393081 C 410.67484,72.126634 410.79202,72.596086 409.38568,76.457686 C 407.64242,81.244514 403.43606,85.831905 397.74621,89.151482 C 395.58503,90.412356 391.94791,93.900638 389.66369,96.903215 C 386.46568,101.10697 384.27116,102.66626 380.12124,103.68355 C 377.15712,104.41016 370.69692,106.39519 365.76525,108.09476 C 360.83359,109.79434 354.08641,111.44202 350.77152,111.75628 C 347.45663,112.07054 344.0716,113.09302 343.2492,114.02844 C 342.39624,114.99863 339.43047,115.72921 336.34502,115.72921 C 332.56293,115.72921 330.2388,116.4566 328.61762,118.14764 C 327.34245,119.4778 325.19773,120.56608 323.85155,120.56608 C 320.30087,120.56608 316.44859,122.79055 316.44859,124.84088 C 316.44859,126.12467 314.91678,126.61215 310.88283,126.61215 C 304.9952,126.61215 302.12607,128.53383 300.50187,133.56514 C 299.82292,135.66835 298.69826,136.26846 295.54678,136.20923 C 293.30457,136.16708 290.04879,135.59707 288.31176,134.94256 z\",\"cx\":313.3,\"cy\":87.7},{\"id\":\"PM\",\"name\":\"Pomorskie\",\"d\":\"M 146.72239,104.53182 C 138.20322,98.623566 137.55255,97.527799 138.11317,90.033396 C 138.48261,85.094889 139.15564,83.080416 140.43618,83.080416 C 141.71685,83.080416 142.23905,81.516599 142.23905,77.68149 C 142.23905,73.540453 141.64881,71.984378 139.70575,71.002708 C 137.56586,69.921618 137.29188,68.900031 137.94167,64.424834 C 138.58631,59.985 138.27046,58.770809 135.99165,56.928913 C 132.47631,54.08754 132.56483,53.102529 136.48713,51.415493 C 139.6398,50.059486 139.68638,49.844053 138.89948,40.25618 C 138.45816,34.879043 137.32533,29.311251 136.38208,27.883307 C 134.79845,25.485936 134.98165,25.172525 138.7733,23.792299 C 148.48096,20.258527 152.42266,18.299337 152.45363,16.992609 C 152.4718,16.225462 155.2247,15.302192 158.5712,14.940912 C 170.70503,13.630944 161.81151,13.309168 166.53504,10.358353 C 171.24085,7.4185921 190.0151,5.8792644 205.74288,6.7355969 C 220.72864,7.5515434 232.66127,21.948533 231.94383,24.082382 C 231.57788,25.170825 232.0071,29.830543 228.62279,27.818182 C 225.2385,25.80582 213.93793,12.208812 211.82721,13.665016 C 207.98951,16.312685 218.39682,25.291651 218.39682,27.81285 C 218.39682,31.447551 218.76387,38.608351 222.06484,41.433358 C 225.99419,44.796154 229.22634,42.485876 238.01821,42.111481 C 250.90332,41.562769 254.06854,44.818232 249.20647,53.618728 C 246.56974,58.391322 246.79081,62.864508 249.74963,64.608845 C 251.10949,65.410536 252.40645,67.560591 252.63178,69.38676 C 252.97576,72.174773 253.85066,72.86472 258.08922,73.690491 C 260.86551,74.231371 263.40376,74.925721 263.72978,75.23349 C 264.9488,76.384237 255.49563,84.264386 252.88132,84.276751 C 250.91686,84.286044 249.95563,85.250919 249.42749,87.743665 C 248.92586,90.111449 247.47538,91.674869 244.81537,92.714981 C 241.91466,93.849196 240.72996,95.264184 240.12271,98.319803 C 239.39031,102.00518 238.97764,102.33355 235.92829,101.65722 C 234.06815,101.24467 231.02538,99.573234 229.16659,97.942944 C 225.67484,94.880417 218.83603,92.833232 211.92926,92.782976 C 209.62245,92.766191 206.99522,91.742865 205.6462,90.335701 C 202.72831,87.292042 191.62313,86.85015 190.45202,89.731101 C 190.0465,90.728701 188.39964,91.553249 186.79235,91.563427 C 183.3321,91.585361 181.81111,92.511506 179.87226,95.777175 C 178.74257,97.679952 177.10383,98.195608 172.18655,98.195608 C 166.47901,98.195608 165.77212,98.517243 164.04028,101.90236 C 162.5417,104.83154 161.33253,105.60625 158.27601,105.59552 C 156.14866,105.58805 153.54346,105.9453 152.48668,106.38943 C 151.38108,106.85407 148.93358,106.06533 146.72239,104.53182 z\",\"cx\":192.7,\"cy\":65.8}];\n\n const vals = data || {};\n const color = scaleSequential(interpolateRdYlGn).domain([0, 100]);\n\n const hovered = hover ? regions.find(r => r.id === hover) : null;\n const sorted = [...regions].map(r => ({ ...r, value: vals[r.id] || 0 })).sort((a, b) => b.value - a.value);\n const maxVal = Math.max(...sorted.map(r => r.value), 1);\n const avg = sorted.length > 0\n ? (sorted.reduce((sum, r) => sum + r.value, 0) / sorted.length).toFixed(1)\n : '0';\n\n return (\n <Page>\n <Header title=\"Poland Energy Grid\" subtitle=\"D3.js \u2022 simulated data\">\n <div className=\"flex items-center gap-4\">\n <div className=\"text-right\">\n <div className=\"text-xs text-zinc-500\">National Average</div>\n <div className=\"text-2xl font-bold text-emerald-400\">{avg}%</div>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"inline-block w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse\" />\n <span className=\"text-xs text-zinc-500\">streaming</span>\n </div>\n </div>\n </Header>\n\n <div className=\"flex-1 flex\">\n <div className=\"flex-1 relative flex items-center justify-center p-4\">\n <svg viewBox=\"-10 -10 517 483\" className=\"w-full h-full\" style={{maxHeight: '75vh'}}>\n {regions.map(r => {\n const v = vals[r.id] || 0;\n const isHovered = hover === r.id;\n return (\n <g key={r.id}\n onMouseEnter={() => setHover(r.id)}\n onMouseLeave={() => setHover(null)}\n onClick={() => send({ region: r.id, name: r.name, value: v })}\n style={{cursor: 'pointer'}}>\n <path\n d={r.d}\n fill={color(v)}\n stroke={isHovered ? '#22d3ee' : '#18181b'}\n strokeWidth={isHovered ? 2.5 : 1.2}\n fillOpacity={isHovered ? 1 : 0.85}\n style={{transition: 'all 0.2s ease'}}\n />\n <text x={r.cx} y={r.cy - 6} textAnchor=\"middle\" fill=\"#fff\" fontSize=\"11\" fontWeight=\"bold\"\n style={{pointerEvents: 'none', textShadow: '0 1px 3px rgba(0,0,0,0.8)'}}>{r.id}</text>\n <text x={r.cx} y={r.cy + 8} textAnchor=\"middle\" fill=\"#e4e4e7\" fontSize=\"10\"\n style={{pointerEvents: 'none', textShadow: '0 1px 3px rgba(0,0,0,0.8)'}}>{v}%</text>\n </g>\n );\n })}\n </svg>\n\n {hovered && (() => {\n const h = regions.find(r => r.id === hover);\n const v = vals[hover] || 0;\n return (\n <div className=\"absolute top-4 left-4 bg-zinc-800/90 border border-zinc-700 rounded-lg px-4 py-3 backdrop-blur\">\n <div className=\"text-sm font-semibold\">{h.name}</div>\n <div className=\"text-xs text-zinc-400 mt-1\">woj. {h.id}</div>\n <div className=\"text-lg font-bold mt-1\" style={{color: color(v)}}>{v}%</div>\n <div className=\"text-xs text-zinc-500\">renewable energy</div>\n </div>\n );\n })()}\n </div>\n\n <div className=\"w-64 border-l border-zinc-800/50 px-4 py-4 overflow-y-auto\">\n <h2 className=\"text-xs text-zinc-500 uppercase tracking-wider mb-3\">Ranking</h2>\n <div className=\"space-y-1.5\">\n {sorted.map((r, i) => (\n <div key={r.id}\n className={`flex items-center gap-2 px-2 py-1 rounded transition-colors ${hover === r.id ? 'bg-zinc-800' : ''}`}\n onMouseEnter={() => setHover(r.id)}\n onMouseLeave={() => setHover(null)}>\n <span className=\"text-xs text-zinc-600 w-4\">{i + 1}</span>\n <span className=\"text-xs font-mono w-6\">{r.id}</span>\n <span className=\"text-xs text-zinc-500 truncate w-24\">{r.name}</span>\n <div className=\"flex-1 h-1.5 bg-zinc-800 rounded-full overflow-hidden\">\n <div className=\"h-full rounded-full\" style={{width: (r.value / maxVal * 100) + '%', backgroundColor: color(r.value), transition: 'all 0.6s ease'}} />\n </div>\n <span className=\"text-xs text-zinc-400 w-10 text-right\">{r.value}%</span>\n </div>\n ))}\n </div>\n </div>\n </div>\n\n <div className=\"px-6 py-3 bg-zinc-900/50 border-t border-zinc-800/50 flex items-center gap-4\">\n <span className=\"text-xs text-zinc-500\">0%</span>\n <div className=\"flex-1 h-2 rounded-full\" style={{background: 'linear-gradient(to right, #d73027, #fc8d59, #fee08b, #d9ef8b, #66bd63, #1a9850)'}} />\n <span className=\"text-xs text-zinc-500\">100%</span>\n <span className=\"text-xs text-zinc-600 ml-2\">Click region to inspect</span>\n </div>\n </Page>\n );\n}",
|
|
61
|
+
"x": 560,
|
|
62
|
+
"y": 160,
|
|
63
|
+
"wires": [
|
|
64
|
+
[
|
|
65
|
+
"fc-d3-debug"
|
|
66
|
+
]
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "fc-d3-debug",
|
|
71
|
+
"type": "debug",
|
|
72
|
+
"z": "fc-d3-flow",
|
|
73
|
+
"name": "Map output",
|
|
74
|
+
"active": true,
|
|
75
|
+
"tosidebar": true,
|
|
76
|
+
"x": 750,
|
|
77
|
+
"y": 160,
|
|
78
|
+
"wires": []
|
|
79
|
+
}
|
|
80
|
+
]
|