@inglorious/charts 1.0.1

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.
Files changed (49) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +554 -0
  3. package/package.json +64 -0
  4. package/src/base.css +86 -0
  5. package/src/cartesian/area.js +392 -0
  6. package/src/cartesian/area.test.js +366 -0
  7. package/src/cartesian/bar.js +445 -0
  8. package/src/cartesian/bar.test.js +346 -0
  9. package/src/cartesian/line.js +823 -0
  10. package/src/cartesian/line.test.js +177 -0
  11. package/src/chart.test.js +444 -0
  12. package/src/component/brush.js +264 -0
  13. package/src/component/empty-state.js +33 -0
  14. package/src/component/empty-state.test.js +81 -0
  15. package/src/component/grid.js +123 -0
  16. package/src/component/grid.test.js +123 -0
  17. package/src/component/legend.js +76 -0
  18. package/src/component/legend.test.js +103 -0
  19. package/src/component/tooltip.js +65 -0
  20. package/src/component/tooltip.test.js +96 -0
  21. package/src/component/x-axis.js +212 -0
  22. package/src/component/x-axis.test.js +148 -0
  23. package/src/component/y-axis.js +77 -0
  24. package/src/component/y-axis.test.js +107 -0
  25. package/src/handlers.js +150 -0
  26. package/src/index.js +264 -0
  27. package/src/polar/donut.js +181 -0
  28. package/src/polar/donut.test.js +152 -0
  29. package/src/polar/pie.js +758 -0
  30. package/src/polar/pie.test.js +268 -0
  31. package/src/shape/curve.js +55 -0
  32. package/src/shape/dot.js +104 -0
  33. package/src/shape/rectangle.js +46 -0
  34. package/src/shape/sector.js +58 -0
  35. package/src/template.js +25 -0
  36. package/src/theme.css +90 -0
  37. package/src/utils/cartesian-layout.js +164 -0
  38. package/src/utils/chart-utils.js +30 -0
  39. package/src/utils/colors.js +77 -0
  40. package/src/utils/data-utils.js +155 -0
  41. package/src/utils/data-utils.test.js +210 -0
  42. package/src/utils/extract-data-keys.js +22 -0
  43. package/src/utils/padding.js +16 -0
  44. package/src/utils/paths.js +279 -0
  45. package/src/utils/process-declarative-child.js +46 -0
  46. package/src/utils/scales.js +250 -0
  47. package/src/utils/shared-context.js +166 -0
  48. package/src/utils/shared-context.test.js +237 -0
  49. package/src/utils/tooltip-handlers.js +129 -0
package/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2025 Inglorious Coderz Srl.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,554 @@
1
+ # Inglorious Charts
2
+
3
+ A powerful, declarative charting library for Inglorious Web, inspired by Recharts. Built with SVG and `lit-html`, Inglorious Charts provides a flexible and composable way to create beautiful data visualizations.
4
+
5
+ ## Features
6
+
7
+ - 📊 **Multiple Chart Types**: Line, Area, Bar, Pie, and Donut charts
8
+ - 🎨 **Two Rendering Modes**: Config-first (declarative) and Composition (Recharts-style)
9
+ - 🧩 **Pure & Stateless**: Core logic built with pure functions for predictable rendering and easy testing
10
+ - 🎯 **Interactive Tooltips**: Smart tooltip positioning with automatic overflow detection
11
+ - 📈 **Multiple Series Support**: Render multiple data series in a single chart
12
+ - 🎨 **Customizable Styling**: Full control over colors, sizes, and appearance
13
+ - 📱 **Responsive**: Works seamlessly across different screen sizes
14
+ - 🔧 **Type-Safe**: Built with TypeScript definitions
15
+ - 🛡️ **Memory-Safe**: No global caches or Singletons, preventing memory leaks in complex SPAs
16
+ - 🚀 **Deterministic Rendering**: Optimized rendering engine that avoids expensive try/catch operations and ensures visual stability
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @inglorious/charts
22
+ # or
23
+ pnpm add @inglorious/charts
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ### Config-First Mode
29
+
30
+ The simplest way to create charts is using the config-first approach. First, register the chart types in your store:
31
+
32
+ ```javascript
33
+ // In your store/index.js
34
+ import { createStore } from "@inglorious/web"
35
+ import {
36
+ lineChart,
37
+ areaChart,
38
+ barChart,
39
+ pieChart,
40
+ donutChart,
41
+ } from "@inglorious/charts"
42
+
43
+ export const store = createStore({
44
+ types: {
45
+ line: lineChart,
46
+ area: areaChart,
47
+ bar: barChart,
48
+ pie: pieChart,
49
+ donut: donutChart,
50
+ },
51
+ entities,
52
+ middlewares,
53
+ })
54
+ ```
55
+
56
+ Then define your chart entity in the store:
57
+
58
+ ```javascript
59
+ // In your store/entities.js
60
+ export const entities = {
61
+ myLineChart: {
62
+ type: "line",
63
+ data: [
64
+ { name: "Jan", value: 400 },
65
+ { name: "Feb", value: 300 },
66
+ { name: "Mar", value: 500 },
67
+ ],
68
+ width: 800,
69
+ height: 400,
70
+ showGrid: true,
71
+ showTooltip: true,
72
+ showLegend: true,
73
+ },
74
+ }
75
+ ```
76
+
77
+ Finally, render the chart in your component:
78
+
79
+ ```javascript
80
+ // In your app.js
81
+ import { html } from "@inglorious/web"
82
+
83
+ export const app = {
84
+ render(api) {
85
+ return html` ${api.render("myLineChart")} `
86
+ },
87
+ }
88
+ ```
89
+
90
+ ### Composition Mode
91
+
92
+ For more control and flexibility, use the composition approach. First, define your chart entity in the store:
93
+
94
+ ```javascript
95
+ // In your store/entities.js
96
+ export const entities = {
97
+ myLineChart: {
98
+ type: "line",
99
+ data: [
100
+ { name: "Jan", value: 400 },
101
+ { name: "Feb", value: 300 },
102
+ { name: "Mar", value: 500 },
103
+ ],
104
+ },
105
+ }
106
+ ```
107
+
108
+ Then use the `chart` helper in your component:
109
+
110
+ ```javascript
111
+ import { html } from "@inglorious/web"
112
+ import { chart } from "@inglorious/charts"
113
+
114
+ export const app = {
115
+ render(api) {
116
+ return html`
117
+ ${chart(api, "myLineChart", (c) =>
118
+ c.renderLineChart(
119
+ [
120
+ c.renderCartesianGrid({ stroke: "#eee", strokeDasharray: "5 5" }),
121
+ c.renderXAxis({ dataKey: "name" }),
122
+ c.renderYAxis({ width: "auto" }),
123
+ c.renderLine({
124
+ dataKey: "value",
125
+ stroke: "#8884d8",
126
+ showDots: true,
127
+ }),
128
+ c.renderTooltip({}),
129
+ ],
130
+ {
131
+ width: 800,
132
+ height: 400,
133
+ dataKeys: ["value"], // Required to sync Y-axis scale across multiple series
134
+ stacked: false, // Set to true to automatically sum values (Area/Bar)
135
+ },
136
+ ),
137
+ )}
138
+ `
139
+ },
140
+ }
141
+ ```
142
+
143
+ **Note:** The `chart` helper takes the `entityId` (e.g., `"myLineChart"`) and fetches the data from your store. You can also override the data by passing it in the config:
144
+
145
+ ```javascript
146
+ c.renderLineChart(
147
+ [
148
+ /* components */
149
+ ],
150
+ {
151
+ width: 800,
152
+ height: 400,
153
+ dataKeys: ["value"], // Required to sync Y-axis scale across multiple series
154
+ stacked: false, // Set to true to automatically sum values (Area/Bar)
155
+ data: [
156
+ { name: "Jan", value: 400 },
157
+ { name: "Feb", value: 300 },
158
+ ], // Override entity data
159
+ },
160
+ )
161
+ ```
162
+
163
+ 💡 **Smart Layering**: The library uses an internal flag system (`isGrid`, `isAxis`, etc.) to ensure elements are rendered in the correct visual order (Z-index). The Grid will always be at the back and Axes always at the front, regardless of the order you declare them in the array.
164
+
165
+ ## Chart Types
166
+
167
+ ### Line Chart
168
+
169
+ Displays data as a connected line, ideal for showing trends over time.
170
+
171
+ **Config Mode:**
172
+
173
+ ```javascript
174
+ {
175
+ type: "line",
176
+ data: [
177
+ { name: "Jan", value: 100 },
178
+ { name: "Feb", value: 200 },
179
+ { name: "Mar", value: 150 },
180
+ ],
181
+ showPoints: true, // Show dots on data points
182
+ }
183
+ ```
184
+
185
+ **Composition Mode:**
186
+
187
+ ```javascript
188
+ c.renderLineChart([
189
+ c.renderLine({ dataKey: "value", stroke: "#8884d8", showDots: true }),
190
+ // ... other components
191
+ ])
192
+ ```
193
+
194
+ ### Area Chart
195
+
196
+ Similar to line charts but with filled areas under the line.
197
+
198
+ **Config Mode:**
199
+
200
+ ```javascript
201
+ {
202
+ type: "area",
203
+ data: [
204
+ { name: "Jan", value: 100 },
205
+ { name: "Feb", value: 200 },
206
+ { name: "Mar", value: 150 },
207
+ ],
208
+ stacked: false, // Set to true for stacked areas
209
+ }
210
+ ```
211
+
212
+ **Composition Mode:**
213
+
214
+ ```javascript
215
+ c.renderAreaChart([
216
+ c.renderArea({
217
+ dataKey: "value",
218
+ fill: "#8884d8",
219
+ fillOpacity: "0.6",
220
+ stroke: "#8884d8",
221
+ }),
222
+ c.renderDots({ dataKey: "value", fill: "#8884d8" }),
223
+ // ... other components
224
+ ])
225
+ ```
226
+
227
+ ### Bar Chart
228
+
229
+ Displays data as rectangular bars, perfect for comparing categories.
230
+
231
+ **Config Mode:**
232
+
233
+ ```javascript
234
+ {
235
+ type: "bar",
236
+ data: [
237
+ { name: "A", value: 100 },
238
+ { name: "B", value: 200 },
239
+ { name: "C", value: 150 },
240
+ ],
241
+ }
242
+ ```
243
+
244
+ **Composition Mode:**
245
+
246
+ ```javascript
247
+ c.renderBarChart([
248
+ c.renderBar({ dataKey: "value", fill: "#8884d8" }),
249
+ // ... other components
250
+ ])
251
+ ```
252
+
253
+ ### Pie Chart
254
+
255
+ Circular chart showing proportions of a whole.
256
+
257
+ **Config Mode:**
258
+
259
+ ```javascript
260
+ {
261
+ type: "pie",
262
+ data: [
263
+ { label: "A", value: 30 },
264
+ { label: "B", value: 40 },
265
+ { label: "C", value: 30 },
266
+ ],
267
+ cx: "50%", // Center X
268
+ cy: "50%", // Center Y
269
+ showTooltip: true,
270
+ }
271
+ ```
272
+
273
+ ### Donut Chart
274
+
275
+ Similar to pie chart but with a hollow center.
276
+
277
+ **Config Mode:**
278
+
279
+ ```javascript
280
+ {
281
+ type: "donut",
282
+ data: [
283
+ { label: "A", value: 30 },
284
+ { label: "B", value: 40 },
285
+ { label: "C", value: 30 },
286
+ ],
287
+ innerRadius: "60%", // Controls the hole size
288
+ }
289
+ ```
290
+
291
+ ## Composition Components
292
+
293
+ When using composition mode, you can combine these components:
294
+
295
+ **Note on Rendering:** Components like `renderLegend` and `renderTooltip` are rendered as HTML overlays, while `renderLine`, `renderArea`, or `renderBar` are rendered as SVG elements. The library handles this separation automatically to ensure accessibility and styling flexibility.
296
+
297
+ ### `renderCartesianGrid`
298
+
299
+ Renders grid lines for cartesian charts.
300
+
301
+ ```javascript
302
+ c.renderCartesianGrid({
303
+ stroke: "#eee",
304
+ strokeDasharray: "5 5",
305
+ })
306
+ ```
307
+
308
+ ### `renderXAxis`
309
+
310
+ Renders the X-axis with labels.
311
+
312
+ ```javascript
313
+ c.renderXAxis({ dataKey: "name" })
314
+ ```
315
+
316
+ ### `renderYAxis`
317
+
318
+ Renders the Y-axis.
319
+
320
+ ```javascript
321
+ c.renderYAxis({ width: "auto" })
322
+ ```
323
+
324
+ ### `renderLine`
325
+
326
+ Renders a line series.
327
+
328
+ ```javascript
329
+ c.renderLine({
330
+ dataKey: "value",
331
+ stroke: "#8884d8",
332
+ showDots: true, // Automatically render dots
333
+ type: "linear", // Curve type: "linear", "monotone", etc.
334
+ })
335
+ ```
336
+
337
+ ### `renderArea`
338
+
339
+ Renders an area series.
340
+
341
+ ```javascript
342
+ c.renderArea({
343
+ dataKey: "value",
344
+ fill: "#8884d8",
345
+ fillOpacity: "0.6",
346
+ stroke: "#8884d8",
347
+ type: "linear",
348
+ })
349
+ ```
350
+
351
+ ### `renderBar`
352
+
353
+ Renders a bar series.
354
+
355
+ ```javascript
356
+ c.renderBar({
357
+ dataKey: "value",
358
+ fill: "#8884d8",
359
+ })
360
+ ```
361
+
362
+ ### `renderDots`
363
+
364
+ Renders dots on data points (alternative to `showDots` in `renderLine`).
365
+
366
+ ```javascript
367
+ c.renderDots({
368
+ dataKey: "value",
369
+ fill: "#8884d8",
370
+ r: "0.25em",
371
+ stroke: "white",
372
+ strokeWidth: "0.125em",
373
+ })
374
+ ```
375
+
376
+ ### `renderLegend`
377
+
378
+ Renders a legend for multiple series.
379
+
380
+ ```javascript
381
+ c.renderLegend({
382
+ dataKeys: ["productA", "productB"],
383
+ labels: ["Product A", "Product B"],
384
+ colors: ["#8884d8", "#82ca9d"],
385
+ })
386
+ ```
387
+
388
+ ### `renderTooltip`
389
+
390
+ Renders the tooltip overlay.
391
+
392
+ ```javascript
393
+ c.renderTooltip({})
394
+ ```
395
+
396
+ ## Data Formats
397
+
398
+ Inglorious Charts supports two data formats:
399
+
400
+ **Wide Format (Recharts Style)**: Useful for composition. A single object contains multiple keys.
401
+
402
+ ```javascript
403
+ {
404
+ name: "Jan",
405
+ productA: 100,
406
+ productB: 200,
407
+ productC: 150,
408
+ }
409
+ ```
410
+
411
+ **Long Format (Config Style)**: Ideal for dynamic APIs. Separate series with their own arrays.
412
+
413
+ ```javascript
414
+ {
415
+ name: "Product A",
416
+ values: [
417
+ { x: 0, y: 100 },
418
+ { x: 1, y: 200 },
419
+ ],
420
+ }
421
+ ```
422
+
423
+ ## Multiple Series
424
+
425
+ ### Config Mode
426
+
427
+ For multiple series, use nested data structure:
428
+
429
+ ```javascript
430
+ {
431
+ type: "line",
432
+ data: [
433
+ {
434
+ name: "Product A",
435
+ values: [
436
+ { x: 0, y: 10 },
437
+ { x: 1, y: 250 },
438
+ ],
439
+ },
440
+ {
441
+ name: "Product B",
442
+ values: [
443
+ { x: 0, y: 280 },
444
+ { x: 1, y: 120 },
445
+ ],
446
+ },
447
+ ],
448
+ showLegend: true,
449
+ }
450
+ ```
451
+
452
+ ### Composition Mode
453
+
454
+ Render multiple series by adding multiple components:
455
+
456
+ ```javascript
457
+ import { html } from "@inglorious/web"
458
+ import { chart } from "@inglorious/charts"
459
+
460
+ // In your component
461
+ ${chart(api, "multiSeriesChart", (c) =>
462
+ c.renderLineChart([
463
+ c.renderLegend({
464
+ dataKeys: ["productA", "productB"],
465
+ labels: ["Product A", "Product B"],
466
+ colors: ["#8884d8", "#82ca9d"],
467
+ }),
468
+ c.renderLine({ dataKey: "productA", stroke: "#8884d8", showDots: true }),
469
+ c.renderLine({ dataKey: "productB", stroke: "#82ca9d", showDots: true }),
470
+ c.renderTooltip({}),
471
+ ], {
472
+ width: 800,
473
+ height: 400,
474
+ dataKeys: ["productA", "productB"], // Required to sync Y-axis scale across multiple series
475
+ stacked: false, // Set to true to automatically sum values (Area/Bar)
476
+ })
477
+ )}
478
+ ```
479
+
480
+ ## Styling
481
+
482
+ Import the base styles and theme:
483
+
484
+ ```javascript
485
+ import "@inglorious/charts/base.css"
486
+ import "@inglorious/charts/theme.css"
487
+ ```
488
+
489
+ Or customize using CSS variables and classes:
490
+
491
+ - `.iw-chart` - Main chart container
492
+ - `.iw-chart-svg` - SVG element
493
+ - `.iw-chart-line` - Line elements
494
+ - `.iw-chart-area` - Area elements
495
+ - `.iw-chart-bar` - Bar elements
496
+ - `.iw-chart-dot` - Dot elements
497
+ - `.iw-chart-modal` - Tooltip element. Rendered as absolute HTML outside the SVG, giving you full freedom to use shadows, border-radius, and CSS transitions without SVG limitations.
498
+ - `.iw-chart-legend` - Legend element
499
+
500
+ ## API Reference
501
+
502
+ ### `chart(api, entityId, renderFn)`
503
+
504
+ Helper function for composition mode that provides bound chart methods.
505
+
506
+ **Parameters:**
507
+
508
+ - `api`: Inglorious Web API instance
509
+ - `entityId`: Entity ID from the store
510
+ - `renderFn`: Function that receives chart methods and returns chart configuration
511
+
512
+ **Returns:** `TemplateResult`
513
+
514
+ ### `charts.render(entity, api)`
515
+
516
+ Renders a chart from an entity (config mode).
517
+
518
+ **Parameters:**
519
+
520
+ - `entity`: Chart entity object
521
+ - `api`: Inglorious Web API instance
522
+
523
+ **Returns:** `TemplateResult`
524
+
525
+ ### Internal Render Method Signature
526
+
527
+ All render methods follow the standard signature pattern: `render<Sub>(entity, props, api)`
528
+
529
+ - `entity`: The chart entity object
530
+ - `props`: Configuration object with method-specific options
531
+ - `api`: Inglorious Web API instance
532
+
533
+ This pattern ensures consistency across all chart components and makes the API predictable for developers extending the library.
534
+
535
+ ### Chart Entity Properties
536
+
537
+ Common properties for all chart entities:
538
+
539
+ - `type`: Chart type (`"line"`, `"area"`, `"bar"`, `"pie"`, `"donut"`)
540
+ - `data`: Array of data points
541
+ - `width`: Chart width in pixels (default: 800)
542
+ - `height`: Chart height in pixels (default: 400)
543
+ - `showGrid`: Show grid lines (default: true)
544
+ - `showTooltip`: Enable tooltips (default: true)
545
+ - `showLegend`: Show legend for multi-series (default: true)
546
+ - `colors`: Array of colors for series (optional)
547
+
548
+ ## Examples
549
+
550
+ See the [examples directory](../../examples/apps/web-charts) for complete working examples of all chart types and rendering modes.
551
+
552
+ ## License
553
+
554
+ MIT
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@inglorious/charts",
3
+ "version": "1.0.1",
4
+ "description": "Chart components for Inglorious Web, inspired by Recharts",
5
+ "author": "IceOnFire <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/IngloriousCoderz/inglorious-forge.git",
10
+ "directory": "packages/charts"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/IngloriousCoderz/inglorious-forge/issues"
14
+ },
15
+ "keywords": [
16
+ "charts",
17
+ "visualization",
18
+ "svg",
19
+ "recharts",
20
+ "inglorious"
21
+ ],
22
+ "type": "module",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./types/index.d.ts",
26
+ "import": "./src/index.js"
27
+ },
28
+ "./base.css": "./src/base.css",
29
+ "./theme.css": "./src/theme.css"
30
+ },
31
+ "files": [
32
+ "src",
33
+ "types"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "dependencies": {
39
+ "d3-array": "^3.2.4",
40
+ "d3-format": "^3.1.0",
41
+ "d3-scale": "^4.0.2",
42
+ "d3-shape": "^3.2.0",
43
+ "d3-time-format": "^4.1.0",
44
+ "@inglorious/web": "4.2.4"
45
+ },
46
+ "peerDependencies": {
47
+ "@inglorious/web": "4.2.4"
48
+ },
49
+ "devDependencies": {
50
+ "prettier": "^3.6.2",
51
+ "vite": "^7.1.3",
52
+ "vitest": "^4.0.15",
53
+ "@inglorious/eslint-config": "1.1.2"
54
+ },
55
+ "engines": {
56
+ "node": ">= 22"
57
+ },
58
+ "scripts": {
59
+ "format": "prettier --write '**/*.{js,jsx}'",
60
+ "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
61
+ "test:watch": "vitest",
62
+ "test": "vitest run"
63
+ }
64
+ }
package/src/base.css ADDED
@@ -0,0 +1,86 @@
1
+ .iw-chart {
2
+ position: relative;
3
+ display: inline-block;
4
+ overflow: visible;
5
+
6
+ .iw-chart-svg {
7
+ display: block;
8
+ overflow: visible;
9
+ }
10
+
11
+ .iw-chart-line {
12
+ transition: stroke-width 0.2s ease;
13
+ cursor: pointer;
14
+ }
15
+
16
+ .iw-chart-point {
17
+ cursor: pointer;
18
+ transition:
19
+ r 0.2s ease,
20
+ fill 0.2s ease;
21
+ }
22
+
23
+ .iw-chart-dot {
24
+ cursor: pointer;
25
+ transition:
26
+ r 0.2s ease,
27
+ fill 0.2s ease;
28
+ }
29
+
30
+ .iw-chart-bar,
31
+ .iw-chart-bar-rectangle {
32
+ cursor: pointer;
33
+ transition:
34
+ opacity 0.2s ease,
35
+ filter 0.2s ease;
36
+ }
37
+
38
+ .iw-chart-area {
39
+ cursor: pointer;
40
+ transition:
41
+ opacity 0.2s ease,
42
+ filter 0.2s ease;
43
+ }
44
+
45
+ .iw-chart-pie-slice,
46
+ .iw-chart-donut-slice {
47
+ cursor: pointer;
48
+ transition:
49
+ opacity 0.2s ease,
50
+ filter 0.2s ease;
51
+ }
52
+
53
+ .iw-chart-tooltip {
54
+ pointer-events: none;
55
+ }
56
+
57
+ .iw-chart-modal {
58
+ position: absolute;
59
+ pointer-events: none;
60
+ z-index: 1000;
61
+ display: flex;
62
+ flex-direction: column;
63
+
64
+ .iw-chart-modal-header {
65
+ display: flex;
66
+ align-items: center;
67
+ }
68
+
69
+ .iw-chart-modal-color {
70
+ flex-shrink: 0;
71
+ }
72
+
73
+ .iw-chart-modal-body {
74
+ display: flex;
75
+ flex-direction: column;
76
+ }
77
+ }
78
+
79
+ .iw-chart-legend {
80
+ pointer-events: none;
81
+ }
82
+
83
+ .iw-chart-legend-item {
84
+ cursor: default;
85
+ }
86
+ }