@qkix/strapi-plugin-chartkit 0.1.0 → 0.1.2
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 +149 -72
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,31 +1,107 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Charts for Strapi v5, as
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
<h1 align="center">Chartkit for Strapi</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">Charts for Strapi v5, rendered as server-side SVG. Your pages ship <strong>zero client-side JavaScript</strong> to draw them.</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@qkix/strapi-plugin-chartkit">
|
|
7
|
+
<img alt="npm version" src="https://img.shields.io/npm/v/@qkix/strapi-plugin-chartkit.svg" />
|
|
8
|
+
</a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/@qkix/strapi-plugin-chartkit">
|
|
10
|
+
<img alt="npm downloads" src="https://img.shields.io/npm/dm/@qkix/strapi-plugin-chartkit.svg" />
|
|
11
|
+
</a>
|
|
12
|
+
<a href="https://github.com/qkix/strapi-plugins/blob/main/LICENSE">
|
|
13
|
+
<img alt="license" src="https://img.shields.io/npm/l/@qkix/strapi-plugin-chartkit.svg" />
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://buymeacoffee.com/qkix">
|
|
16
|
+
<img alt="Buy Me a Coffee" src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-support-FFDD00?logo=buymeacoffee&logoColor=black" />
|
|
17
|
+
</a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
<p align="center">
|
|
21
|
+
<img src="https://raw.githubusercontent.com/qkix/strapi-plugins/main/packages/strapi-plugin-chartkit/docs/field.png" alt="A chart in the Strapi edit view" width="720" />
|
|
22
|
+
</p>
|
|
6
23
|
|
|
7
24
|
```sh
|
|
8
25
|
npm install @qkix/strapi-plugin-chartkit
|
|
9
26
|
```
|
|
10
27
|
|
|
11
|
-
Add a **Chart** field to a content type
|
|
12
|
-
|
|
28
|
+
Add a **Chart** field to a content type. That's it — no config file, no provider.
|
|
29
|
+
|
|
30
|
+
## Why server-side SVG
|
|
31
|
+
|
|
32
|
+
Most chart plugins hand the browser a charting library and some JSON, and let it
|
|
33
|
+
draw. That means shipping and executing a charting runtime on every page that
|
|
34
|
+
has a chart, and leaving a hole in the layout until it runs.
|
|
35
|
+
|
|
36
|
+
Chartkit renders the SVG **when the page is built or requested**. The browser
|
|
37
|
+
receives finished markup:
|
|
38
|
+
|
|
39
|
+
- **No runtime.** Nothing to download, parse, or execute.
|
|
40
|
+
- **Nothing to hydrate**, so no layout shift and no flash of empty box.
|
|
41
|
+
- **It scales and prints** — it is vector, not a canvas bitmap.
|
|
42
|
+
- **Screen readers get a real description**: `role="img"` with a `<title>` and
|
|
43
|
+
the description you wrote.
|
|
44
|
+
|
|
45
|
+
## Every chart type
|
|
46
|
+
|
|
47
|
+
<img src="https://raw.githubusercontent.com/qkix/strapi-plugins/main/packages/strapi-plugin-chartkit/docs/chart-types.png" alt="Bar, grouped, stacked, line, area, pie, donut, gaps and negative values" width="900" />
|
|
48
|
+
|
|
49
|
+
Bar, grouped and stacked bars, line, area and stacked area, pie and donut.
|
|
50
|
+
|
|
51
|
+
Two of those tiles are the details that usually go wrong. A missing reading
|
|
52
|
+
stays a **gap** — never a zero pretending to be a measurement. And negative
|
|
53
|
+
values get a real baseline instead of being flipped or clipped.
|
|
54
|
+
|
|
55
|
+
## Editing
|
|
56
|
+
|
|
57
|
+
<img src="https://raw.githubusercontent.com/qkix/strapi-plugins/main/packages/strapi-plugin-chartkit/docs/editor.png" alt="The chart editor: live preview, chart settings and a data grid" width="700" />
|
|
58
|
+
|
|
59
|
+
A live preview above a spreadsheet-style grid. **The preview is the real
|
|
60
|
+
renderer** — the same function that draws the published page — so a chart cannot
|
|
61
|
+
look right here and wrong there.
|
|
62
|
+
|
|
63
|
+
The editor opens in a dialog. Cancel genuinely cancels: it edits a draft and
|
|
64
|
+
only writes on save.
|
|
65
|
+
|
|
66
|
+
## Three ways to get the numbers in
|
|
67
|
+
|
|
68
|
+
Most charts already exist as numbers somewhere, and retyping them is the worst
|
|
69
|
+
part of every charting tool.
|
|
70
|
+
|
|
71
|
+
<img src="https://raw.githubusercontent.com/qkix/strapi-plugins/main/packages/strapi-plugin-chartkit/docs/paste.png" alt="Pasting a semicolon-separated spreadsheet, with the parse summary shown before anything is replaced" width="700" />
|
|
72
|
+
|
|
73
|
+
**Paste from a spreadsheet.** Copy a range out of Sheets or Excel and paste it.
|
|
74
|
+
|
|
75
|
+
| Input | Read as |
|
|
76
|
+
| ------------------------- | ------------------------------------- |
|
|
77
|
+
| tab, comma or semicolon | detected per paste |
|
|
78
|
+
| `1.234,50` and `1,234.50` | 1234.5 either way |
|
|
79
|
+
| `€1 234,50` | 1234.5 — currency and spaces stripped |
|
|
80
|
+
| `"North, inland"` | one cell; a quoted delimiter survives |
|
|
81
|
+
| `n/a`, `—`, empty | a **gap**, never a zero |
|
|
82
|
+
|
|
83
|
+
It shows **what it parsed before replacing anything** — above, four categories,
|
|
84
|
+
two series, and one unreadable cell called out. The parser has to guess whether
|
|
85
|
+
the first row is a header, and a wrong guess that silently overwrites your data
|
|
86
|
+
is far worse than one you can cancel.
|
|
13
87
|
|
|
14
|
-
|
|
88
|
+
**From the Media Library.** Pick a `.csv`, `.tsv` or `.txt` you already
|
|
89
|
+
uploaded. Anything else is refused before it is fetched — handing a PDF to a CSV
|
|
90
|
+
parser produces a confident table of nonsense.
|
|
15
91
|
|
|
16
|
-
|
|
17
|
-
|
|
92
|
+
**By hand**, in the grid.
|
|
93
|
+
|
|
94
|
+
## Rendering it
|
|
95
|
+
|
|
96
|
+
The field stores a `ChartSpec` — the same object the renderers take. Nothing
|
|
97
|
+
sits in between:
|
|
18
98
|
|
|
19
99
|
```tsx
|
|
20
100
|
import { Chart } from '@qkix/chartkit-react-renderer';
|
|
21
101
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<Chart spec={article.data.chart} locale="en-US" />;
|
|
102
|
+
<Chart spec={article.chart} locale="en-US" />;
|
|
25
103
|
```
|
|
26
104
|
|
|
27
|
-
Astro is the same shape:
|
|
28
|
-
|
|
29
105
|
```astro
|
|
30
106
|
---
|
|
31
107
|
import { Chart } from '@qkix/chartkit-astro-renderer';
|
|
@@ -34,92 +110,93 @@ import { Chart } from '@qkix/chartkit-astro-renderer';
|
|
|
34
110
|
<Chart spec={article.chart} locale="en-US" />
|
|
35
111
|
```
|
|
36
112
|
|
|
37
|
-
Both
|
|
113
|
+
Both produce markup at build or request time. Neither ships a runtime.
|
|
38
114
|
|
|
39
|
-
##
|
|
115
|
+
## It takes your theme, including dark mode
|
|
40
116
|
|
|
41
117
|
The chart carries no colors of its own. Series are drawn as
|
|
42
|
-
`fill="var(--chart-series-N, currentColor)"` and text inherits the page
|
|
43
|
-
|
|
44
|
-
mode, which is the reason for hand-written SVG rather than an off-the-shelf SSR
|
|
45
|
-
renderer that bakes hex values into the markup.
|
|
118
|
+
`fill="var(--chart-series-N, currentColor)"` and text inherits the page font, so
|
|
119
|
+
a chart looks like it belongs wherever it lands:
|
|
46
120
|
|
|
47
121
|
```css
|
|
48
122
|
:root {
|
|
49
123
|
--chart-series-1: #4945ff;
|
|
50
|
-
--chart-series-2: #
|
|
124
|
+
--chart-series-2: #f0a500;
|
|
51
125
|
--chart-axis: #8e8ea9;
|
|
52
126
|
--chart-text: #32324a;
|
|
53
127
|
--chart-grid: #eaeaef;
|
|
54
128
|
}
|
|
129
|
+
|
|
130
|
+
[data-theme='dark'] {
|
|
131
|
+
--chart-text: #ffffff;
|
|
132
|
+
--chart-grid: #32324a;
|
|
133
|
+
}
|
|
55
134
|
```
|
|
56
135
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
136
|
+
This is the reason the SVG is hand-written rather than produced by an existing
|
|
137
|
+
SSR chart renderer. The obvious candidate, ECharts in SSR mode, writes its
|
|
138
|
+
palette into the markup as literal hex values — which makes class-based dark
|
|
139
|
+
mode impossible without post-processing the output.
|
|
60
140
|
|
|
61
|
-
##
|
|
141
|
+
## Also a block, if you use Better Blocks
|
|
62
142
|
|
|
63
|
-
|
|
64
|
-
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
65
|
-
| **Number formatting locale** | How axis numbers are formatted **in the admin preview** — a BCP 47 tag such as `de-DE`. The front end passes its own at render. |
|
|
66
|
-
| **Required** | Standard Strapi validation. |
|
|
143
|
+
<img src="https://raw.githubusercontent.com/qkix/strapi-plugins/main/packages/strapi-plugin-chartkit/docs/block.png" alt="A chart block inside a Better Blocks rich-text document" width="700" />
|
|
67
144
|
|
|
68
|
-
|
|
145
|
+
Charts can live inside a rich-text document instead of, or as well as, in a
|
|
146
|
+
field of their own. With
|
|
147
|
+
[Better Blocks](https://www.npmjs.com/package/@qkix/strapi-plugin-better-blocks)
|
|
148
|
+
installed, that is one line in `src/admin/app.tsx`:
|
|
69
149
|
|
|
70
|
-
|
|
71
|
-
|
|
150
|
+
```ts
|
|
151
|
+
import { registerBlock } from '@qkix/strapi-plugin-better-blocks/strapi-admin';
|
|
152
|
+
import { chartBlockDefinition } from '@qkix/chartkit-editor/block';
|
|
72
153
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
154
|
+
export default {
|
|
155
|
+
register() {
|
|
156
|
+
registerBlock(chartBlockDefinition({ locale: 'en-US' }));
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
```
|
|
78
160
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
161
|
+
The front end needs its own half — `chartBlockPlugin` from whichever renderer
|
|
162
|
+
you use — or a chart authored in a document is stored correctly and drawn as
|
|
163
|
+
nothing.
|
|
82
164
|
|
|
83
|
-
##
|
|
165
|
+
## Field options
|
|
84
166
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
draft and only writes on save.
|
|
167
|
+
| Option | Effect |
|
|
168
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
169
|
+
| **Number formatting locale** | How axis numbers are formatted **in the admin preview** — a BCP 47 tag such as `de-DE`. The front end passes its own at render. |
|
|
170
|
+
| **Required** | Standard Strapi validation. |
|
|
90
171
|
|
|
91
|
-
|
|
92
|
-
chart into the document. Opening an entry must not be enough to mark it dirty.
|
|
172
|
+
## Old charts stay working
|
|
93
173
|
|
|
94
|
-
|
|
174
|
+
The spec is versioned, and the field **migrates on read**, so opening a chart
|
|
175
|
+
saved against an older schema edits and saves the current shape. Nothing has to
|
|
176
|
+
be resaved for a site to keep working: `renderChart` migrates in memory too.
|
|
95
177
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
to be resaved for a site to keep working.
|
|
178
|
+
If a field holds something that is not a readable chart — a value from an import
|
|
179
|
+
script, or a field that used to be a different type — it says so and goes
|
|
180
|
+
**read-only** rather than offering to overwrite it.
|
|
100
181
|
|
|
101
|
-
|
|
102
|
-
import script, or a field that used to be a different type — it says so and goes
|
|
103
|
-
**read-only**. Showing the usual "create a chart" prompt over data that exists
|
|
104
|
-
would be an offer to overwrite it.
|
|
182
|
+
## Packages
|
|
105
183
|
|
|
106
|
-
|
|
184
|
+
| Package | For |
|
|
185
|
+
| ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
|
|
186
|
+
| [`@qkix/strapi-plugin-chartkit`](https://www.npmjs.com/package/@qkix/strapi-plugin-chartkit) | this plugin — the field in the Strapi admin |
|
|
187
|
+
| [`@qkix/chartkit-core`](https://www.npmjs.com/package/@qkix/chartkit-core) | the spec, the validator and the SVG renderer. No dependencies. |
|
|
188
|
+
| [`@qkix/chartkit-react-renderer`](https://www.npmjs.com/package/@qkix/chartkit-react-renderer) | rendering a stored chart in React / Next.js |
|
|
189
|
+
| [`@qkix/chartkit-astro-renderer`](https://www.npmjs.com/package/@qkix/chartkit-astro-renderer) | rendering a stored chart in Astro |
|
|
190
|
+
| [`@qkix/chartkit-editor`](https://www.npmjs.com/package/@qkix/chartkit-editor) | the editing surface, and the ready-made block |
|
|
107
191
|
|
|
108
|
-
|
|
109
|
-
[Better Blocks](https://www.npmjs.com/package/@qkix/strapi-plugin-better-blocks),
|
|
110
|
-
charts can live inside a rich-text document as a block instead of, or as well
|
|
111
|
-
as, in a field of their own — see `@qkix/chartkit-core`'s `chartBlock` and the
|
|
112
|
-
`registerBlock` API.
|
|
192
|
+
## Not there yet
|
|
113
193
|
|
|
114
|
-
|
|
194
|
+
Being honest about the edges: no time axes, no tooltips or other
|
|
195
|
+
interactivity, and no per-chart color overrides — palettes are set in your site's
|
|
196
|
+
CSS. Data is stored with the chart rather than queried from a collection.
|
|
115
197
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
| [`@qkix/strapi-plugin-chartkit`](https://www.npmjs.com/package/@qkix/strapi-plugin-chartkit) | this plugin — the field in the Strapi admin |
|
|
119
|
-
| [`@qkix/chartkit-core`](https://www.npmjs.com/package/@qkix/chartkit-core) | the spec, the validator and the SVG renderer |
|
|
120
|
-
| [`@qkix/chartkit-react-renderer`](https://www.npmjs.com/package/@qkix/chartkit-react-renderer) | rendering a stored chart in React / Next.js |
|
|
121
|
-
| [`@qkix/chartkit-astro-renderer`](https://www.npmjs.com/package/@qkix/chartkit-astro-renderer) | rendering a stored chart in Astro |
|
|
122
|
-
| [`@qkix/chartkit-editor`](https://www.npmjs.com/package/@qkix/chartkit-editor) | the editing surface, if you are embedding it |
|
|
198
|
+
Issues and ideas welcome at
|
|
199
|
+
[qkix/strapi-plugins](https://github.com/qkix/strapi-plugins/issues).
|
|
123
200
|
|
|
124
201
|
## License
|
|
125
202
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qkix/strapi-plugin-chartkit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Charts for Strapi v5, rendered as server-side SVG with no client-side JavaScript",
|
|
5
5
|
"strapi": {
|
|
6
6
|
"kind": "plugin",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@qkix/chartkit-core": "^0.2.0",
|
|
47
|
-
"@qkix/chartkit-editor": "^0.1.
|
|
47
|
+
"@qkix/chartkit-editor": "^0.1.2"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@strapi/sdk-plugin": "^5.3.2",
|