dashtaste 0.0.0-stage → 0.0.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/LICENSE +21 -0
- package/README.md +129 -2
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +124 -0
- package/dist/color.d.ts +4 -0
- package/dist/color.js +43 -0
- package/dist/engine.d.ts +11 -0
- package/dist/engine.js +39 -0
- package/dist/extract-in-page.d.ts +3 -0
- package/dist/extract-in-page.js +149 -0
- package/dist/extract.d.ts +3 -0
- package/dist/extract.js +39 -0
- package/dist/format.d.ts +18 -0
- package/dist/format.js +65 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/packs/cn.d.ts +2 -0
- package/dist/packs/cn.js +56 -0
- package/dist/packs/global.d.ts +2 -0
- package/dist/packs/global.js +45 -0
- package/dist/packs/index.d.ts +53 -0
- package/dist/packs/index.js +13 -0
- package/dist/rules/dt001-default-palette.d.ts +3 -0
- package/dist/rules/dt001-default-palette.js +11 -0
- package/dist/rules/dt002-rainbow-palette.d.ts +3 -0
- package/dist/rules/dt002-rainbow-palette.js +11 -0
- package/dist/rules/dt003-smooth-line.d.ts +3 -0
- package/dist/rules/dt003-smooth-line.js +9 -0
- package/dist/rules/dt004-symbols-everywhere.d.ts +3 -0
- package/dist/rules/dt004-symbols-everywhere.js +21 -0
- package/dist/rules/dt005-pie-slices.d.ts +3 -0
- package/dist/rules/dt005-pie-slices.js +13 -0
- package/dist/rules/dt006-pie-overuse.d.ts +3 -0
- package/dist/rules/dt006-pie-overuse.js +14 -0
- package/dist/rules/dt007-three-d.d.ts +3 -0
- package/dist/rules/dt007-three-d.js +16 -0
- package/dist/rules/dt008-dual-axis.d.ts +3 -0
- package/dist/rules/dt008-dual-axis.js +10 -0
- package/dist/rules/dt009-missing-unit.d.ts +3 -0
- package/dist/rules/dt009-missing-unit.js +8 -0
- package/dist/rules/dt010-bar-baseline.d.ts +3 -0
- package/dist/rules/dt010-bar-baseline.js +11 -0
- package/dist/rules/dt011-raw-large-numbers.d.ts +3 -0
- package/dist/rules/dt011-raw-large-numbers.js +21 -0
- package/dist/rules/dt012-unit-system.d.ts +3 -0
- package/dist/rules/dt012-unit-system.js +12 -0
- package/dist/rules/dt013-delta-convention.d.ts +3 -0
- package/dist/rules/dt013-delta-convention.js +21 -0
- package/dist/rules/dt014-delta-colour-only.d.ts +3 -0
- package/dist/rules/dt014-delta-colour-only.js +16 -0
- package/dist/rules/dt015-low-contrast-text.d.ts +3 -0
- package/dist/rules/dt015-low-contrast-text.js +28 -0
- package/dist/rules/dt016-thin-line-contrast.d.ts +3 -0
- package/dist/rules/dt016-thin-line-contrast.js +12 -0
- package/dist/rules/dt017-gradient-decoration.d.ts +3 -0
- package/dist/rules/dt017-gradient-decoration.js +15 -0
- package/dist/rules/dt018-glow.d.ts +3 -0
- package/dist/rules/dt018-glow.js +27 -0
- package/dist/rules/dt019-kpi-overload.d.ts +3 -0
- package/dist/rules/dt019-kpi-overload.js +7 -0
- package/dist/rules/dt020-kpi-rainbow.d.ts +3 -0
- package/dist/rules/dt020-kpi-rainbow.js +27 -0
- package/dist/rules/dt021-emoji-icons.d.ts +3 -0
- package/dist/rules/dt021-emoji-icons.js +10 -0
- package/dist/rules/dt022-cjk-min-size.d.ts +3 -0
- package/dist/rules/dt022-cjk-min-size.js +9 -0
- package/dist/rules/dt023-legend-single-series.d.ts +3 -0
- package/dist/rules/dt023-legend-single-series.js +8 -0
- package/dist/rules/dt024-bar-width.d.ts +1 -0
- package/dist/rules/dt024-bar-width.js +14 -0
- package/dist/rules/dt025-legend-not-direct-label.d.ts +1 -0
- package/dist/rules/dt025-legend-not-direct-label.js +11 -0
- package/dist/rules/dt026-line-weight.d.ts +1 -0
- package/dist/rules/dt026-line-weight.js +8 -0
- package/dist/rules/dt027-tabular-numerals.d.ts +1 -0
- package/dist/rules/dt027-tabular-numerals.js +16 -0
- package/dist/rules/dt028-hero-metric.d.ts +1 -0
- package/dist/rules/dt028-hero-metric.js +14 -0
- package/dist/rules/helpers.d.ts +32 -0
- package/dist/rules/helpers.js +161 -0
- package/dist/rules/index.d.ts +2 -0
- package/dist/rules/index.js +58 -0
- package/dist/types.d.ts +122 -0
- package/dist/types.js +1 -0
- package/docs/rules.md +735 -0
- package/docs/usage.md +126 -0
- package/package.json +74 -4
- package/skills/dashtaste-cn/SKILL.md +51 -0
- package/skills/dashtaste-cn/references/avoid.md +135 -0
- package/skills/dashtaste-cn/references/charts.md +122 -0
- package/skills/dashtaste-cn/references/layout.md +78 -0
- package/skills/dashtaste-cn/references/numbers.md +93 -0
- package/skills/dashtaste-cn/references/tokens.md +72 -0
- package/skills/dashtaste-global/SKILL.md +43 -0
- package/skills/dashtaste-global/references/avoid.md +135 -0
- package/skills/dashtaste-global/references/charts.md +122 -0
- package/skills/dashtaste-global/references/layout.md +78 -0
- package/skills/dashtaste-global/references/numbers.md +83 -0
- package/skills/dashtaste-global/references/tokens.md +65 -0
package/docs/rules.md
ADDED
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
# Rules
|
|
2
|
+
|
|
3
|
+
Run checks with the intended pack and mode. Page-only rules require extracted page facts.
|
|
4
|
+
Errors reduce score by 10, warnings by 3, and information by 1; the minimum score is zero.
|
|
5
|
+
|
|
6
|
+
## DT001 default-palette
|
|
7
|
+
|
|
8
|
+
Severity: error. Packs: global, cn.
|
|
9
|
+
|
|
10
|
+
Why: Implicit theme colours make series meaning unstable across charts.
|
|
11
|
+
|
|
12
|
+
Triggers: Multiple series need explicit colours. Any default palette colour is flagged.
|
|
13
|
+
|
|
14
|
+
Fix: set option.color to the pack palette (dashtaste tokens --pack <pack>).
|
|
15
|
+
|
|
16
|
+
Minimal failing input:
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"charts": [
|
|
21
|
+
{
|
|
22
|
+
"option": {
|
|
23
|
+
"series": [
|
|
24
|
+
{
|
|
25
|
+
"type": "bar"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"type": "line"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## DT002 rainbow-palette
|
|
38
|
+
|
|
39
|
+
Severity: warn. Packs: global, cn.
|
|
40
|
+
|
|
41
|
+
Why: Too many competing hues make category comparison harder.
|
|
42
|
+
|
|
43
|
+
Triggers: More than 6 distinct categorical colours or more than 5 saturated 60-degree hue buckets.
|
|
44
|
+
|
|
45
|
+
Fix: use the pack palette and group remaining categories as Other.
|
|
46
|
+
|
|
47
|
+
Minimal failing input:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"charts": [
|
|
52
|
+
{
|
|
53
|
+
"option": {
|
|
54
|
+
"color": ["#110000", "#220000", "#330000", "#440000", "#550000", "#660000", "#770000"]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## DT003 smooth-line
|
|
62
|
+
|
|
63
|
+
Severity: warn. Packs: global, cn.
|
|
64
|
+
|
|
65
|
+
Why: Curves can imply observations that were never measured.
|
|
66
|
+
|
|
67
|
+
Triggers: Line smoothing greater than zero draws values that do not exist.
|
|
68
|
+
|
|
69
|
+
Fix: use straight segments: smooth: false.
|
|
70
|
+
|
|
71
|
+
Minimal failing input:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"charts": [
|
|
76
|
+
{
|
|
77
|
+
"option": {
|
|
78
|
+
"series": [
|
|
79
|
+
{
|
|
80
|
+
"type": "line",
|
|
81
|
+
"smooth": true
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## DT004 symbols-everywhere
|
|
91
|
+
|
|
92
|
+
Severity: warn. Packs: global, cn.
|
|
93
|
+
|
|
94
|
+
Why: Repeated symbols obscure the line on longer time series.
|
|
95
|
+
|
|
96
|
+
Triggers: Use small explicit dots only on short series; avoid default symbols everywhere.
|
|
97
|
+
|
|
98
|
+
Fix: use dots at most 5px on at most 31 points, or set showSymbol: false.
|
|
99
|
+
|
|
100
|
+
Minimal failing input:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"charts": [
|
|
105
|
+
{
|
|
106
|
+
"option": {
|
|
107
|
+
"series": [
|
|
108
|
+
{
|
|
109
|
+
"type": "line",
|
|
110
|
+
"data": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## DT005 pie-slices
|
|
120
|
+
|
|
121
|
+
Severity: warn. Packs: global, cn.
|
|
122
|
+
|
|
123
|
+
Why: Small pie slices are hard to compare and label.
|
|
124
|
+
|
|
125
|
+
Triggers: Maximum 5 slices; cn rose charts allow 8.
|
|
126
|
+
|
|
127
|
+
Fix: use horizontal bars or combine small parts into Other.
|
|
128
|
+
|
|
129
|
+
Minimal failing input:
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"charts": [
|
|
134
|
+
{
|
|
135
|
+
"option": {
|
|
136
|
+
"series": [
|
|
137
|
+
{
|
|
138
|
+
"type": "pie",
|
|
139
|
+
"data": [1, 1, 1, 1, 1, 1]
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## DT006 pie-overuse
|
|
149
|
+
|
|
150
|
+
Severity: warn. Packs: global, cn.
|
|
151
|
+
|
|
152
|
+
Why: Repeated pies and narrow rings make part comparison difficult.
|
|
153
|
+
|
|
154
|
+
Triggers: More than one pie per page or radius ratio above 0.75 warns. A global pie is informational.
|
|
155
|
+
|
|
156
|
+
Fix: prefer horizontal bars; keep donut radius ratio at most 0.75.
|
|
157
|
+
|
|
158
|
+
Minimal failing input:
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"charts": [
|
|
163
|
+
{
|
|
164
|
+
"option": {
|
|
165
|
+
"series": [
|
|
166
|
+
{
|
|
167
|
+
"type": "pie",
|
|
168
|
+
"radius": ["90%", "100%"],
|
|
169
|
+
"data": [1, 2]
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## DT007 three-d
|
|
179
|
+
|
|
180
|
+
Severity: error. Packs: global, cn.
|
|
181
|
+
|
|
182
|
+
Why: Depth and perspective distort visible size.
|
|
183
|
+
|
|
184
|
+
Triggers: 3D series, axes, coordinates, and pseudo-3D pie decoration distort comparisons.
|
|
185
|
+
|
|
186
|
+
Fix: use flat 2D charts.
|
|
187
|
+
|
|
188
|
+
Minimal failing input:
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"charts": [
|
|
193
|
+
{
|
|
194
|
+
"option": {
|
|
195
|
+
"series": [
|
|
196
|
+
{
|
|
197
|
+
"type": "bar3D"
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## DT008 dual-axis
|
|
207
|
+
|
|
208
|
+
Severity: warn. Packs: global, cn.
|
|
209
|
+
|
|
210
|
+
Why: Independent scales can imply misleading relationships.
|
|
211
|
+
|
|
212
|
+
Triggers: Multiple value axes obscure comparisons, including mixed bar and line charts.
|
|
213
|
+
|
|
214
|
+
Fix: use one value axis or aligned small multiples.
|
|
215
|
+
|
|
216
|
+
Minimal failing input:
|
|
217
|
+
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"charts": [
|
|
221
|
+
{
|
|
222
|
+
"option": {
|
|
223
|
+
"yAxis": [
|
|
224
|
+
{
|
|
225
|
+
"type": "value",
|
|
226
|
+
"name": "A"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"type": "value",
|
|
230
|
+
"name": "B"
|
|
231
|
+
}
|
|
232
|
+
],
|
|
233
|
+
"series": [
|
|
234
|
+
{
|
|
235
|
+
"type": "line"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"type": "line"
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## DT009 missing-unit
|
|
248
|
+
|
|
249
|
+
Severity: warn. Packs: global, cn.
|
|
250
|
+
|
|
251
|
+
Why: A value without a unit is ambiguous.
|
|
252
|
+
|
|
253
|
+
Triggers: Value axes need a name, formatter, unit metadata, or units in rendered ticks.
|
|
254
|
+
|
|
255
|
+
Fix: put units in axis names, rendered ticks, or formatter metadata.
|
|
256
|
+
|
|
257
|
+
Minimal failing input:
|
|
258
|
+
|
|
259
|
+
```json
|
|
260
|
+
{
|
|
261
|
+
"charts": [
|
|
262
|
+
{
|
|
263
|
+
"option": {
|
|
264
|
+
"yAxis": {
|
|
265
|
+
"type": "value"
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## DT010 bar-baseline
|
|
274
|
+
|
|
275
|
+
Severity: error. Packs: global, cn.
|
|
276
|
+
|
|
277
|
+
Why: Bar length encodes magnitude relative to zero.
|
|
278
|
+
|
|
279
|
+
Triggers: Bar value axes must start at zero; positive min and scale: true distort lengths.
|
|
280
|
+
|
|
281
|
+
Fix: set min: 0 and scale: false.
|
|
282
|
+
|
|
283
|
+
Minimal failing input:
|
|
284
|
+
|
|
285
|
+
```json
|
|
286
|
+
{
|
|
287
|
+
"charts": [
|
|
288
|
+
{
|
|
289
|
+
"option": {
|
|
290
|
+
"series": [
|
|
291
|
+
{
|
|
292
|
+
"type": "bar"
|
|
293
|
+
}
|
|
294
|
+
],
|
|
295
|
+
"yAxis": {
|
|
296
|
+
"min": 10
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
]
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## DT011 raw-large-numbers
|
|
305
|
+
|
|
306
|
+
Severity: warn. Packs: global, cn.
|
|
307
|
+
|
|
308
|
+
Why: Unformatted large values crowd labels and hide useful scale.
|
|
309
|
+
|
|
310
|
+
Triggers: At data maximum magnitude 10000 or above, axis, visible data label, and tooltip channels need formatters.
|
|
311
|
+
|
|
312
|
+
Fix: format compact units: cn 万/亿; global K/M.
|
|
313
|
+
|
|
314
|
+
Minimal failing input:
|
|
315
|
+
|
|
316
|
+
```json
|
|
317
|
+
{
|
|
318
|
+
"charts": [
|
|
319
|
+
{
|
|
320
|
+
"option": {
|
|
321
|
+
"series": [
|
|
322
|
+
{
|
|
323
|
+
"data": [10000]
|
|
324
|
+
}
|
|
325
|
+
],
|
|
326
|
+
"yAxis": {}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
]
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## DT012 unit-system
|
|
334
|
+
|
|
335
|
+
Severity: warn. Packs: global, cn.
|
|
336
|
+
|
|
337
|
+
Why: Mixed unit systems make comparisons harder to read.
|
|
338
|
+
|
|
339
|
+
Triggers: String formatter templates must use the selected compact unit system.
|
|
340
|
+
|
|
341
|
+
Fix: use cn 万/亿 or global K/M/B consistently.
|
|
342
|
+
|
|
343
|
+
Minimal failing input:
|
|
344
|
+
|
|
345
|
+
```json
|
|
346
|
+
{
|
|
347
|
+
"charts": [
|
|
348
|
+
{
|
|
349
|
+
"option": {
|
|
350
|
+
"yAxis": {
|
|
351
|
+
"axisLabel": {
|
|
352
|
+
"formatter": "{value}万"
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
]
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## DT013 delta-convention
|
|
362
|
+
|
|
363
|
+
Severity: error. Packs: global, cn.
|
|
364
|
+
|
|
365
|
+
Why: Changing colour conventions reverses the apparent meaning of a delta.
|
|
366
|
+
|
|
367
|
+
Triggers: Directional deltas must follow the page convention and metric polarity: global by polarity; cn red-up by default.
|
|
368
|
+
|
|
369
|
+
Fix: apply one deltaColors convention to the whole page.
|
|
370
|
+
|
|
371
|
+
Minimal failing input:
|
|
372
|
+
|
|
373
|
+
```json
|
|
374
|
+
{
|
|
375
|
+
"charts": [],
|
|
376
|
+
"deltas": [
|
|
377
|
+
{
|
|
378
|
+
"selector": "#delta",
|
|
379
|
+
"text": "▲ 3%",
|
|
380
|
+
"color": "#B4413A"
|
|
381
|
+
}
|
|
382
|
+
]
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
## DT014 delta-colour-only
|
|
387
|
+
|
|
388
|
+
Severity: warn. Packs: global, cn.
|
|
389
|
+
|
|
390
|
+
Why: Colour alone excludes readers who cannot distinguish the chosen hues.
|
|
391
|
+
|
|
392
|
+
Triggers: Directional colour must be accompanied by an arrow or signed number.
|
|
393
|
+
|
|
394
|
+
Fix: add ▲/▼ or an explicit sign.
|
|
395
|
+
|
|
396
|
+
Minimal failing input:
|
|
397
|
+
|
|
398
|
+
```json
|
|
399
|
+
{
|
|
400
|
+
"charts": [],
|
|
401
|
+
"deltas": [
|
|
402
|
+
{
|
|
403
|
+
"selector": "#delta",
|
|
404
|
+
"text": "3%",
|
|
405
|
+
"color": "#2F7D4F"
|
|
406
|
+
}
|
|
407
|
+
]
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## DT015 low-contrast-text
|
|
412
|
+
|
|
413
|
+
Severity: error. Packs: global, cn.
|
|
414
|
+
|
|
415
|
+
Why: Low contrast makes text difficult to read.
|
|
416
|
+
|
|
417
|
+
Triggers: Text needs 4.5:1; at least 24px or 18.66px bold needs 3:1. Chart label defaults use 4.5:1.
|
|
418
|
+
|
|
419
|
+
Fix: increase text contrast against its background.
|
|
420
|
+
|
|
421
|
+
Minimal failing input:
|
|
422
|
+
|
|
423
|
+
```json
|
|
424
|
+
{
|
|
425
|
+
"charts": [],
|
|
426
|
+
"texts": [
|
|
427
|
+
{
|
|
428
|
+
"selector": "#text",
|
|
429
|
+
"text": "Label",
|
|
430
|
+
"color": "#eeeeee",
|
|
431
|
+
"background": "#ffffff",
|
|
432
|
+
"fontSize": 14,
|
|
433
|
+
"fontWeight": 400
|
|
434
|
+
}
|
|
435
|
+
]
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
## DT016 thin-line-contrast
|
|
440
|
+
|
|
441
|
+
Severity: warn. Packs: global, cn.
|
|
442
|
+
|
|
443
|
+
Why: Thin marks need stronger contrast than large filled regions.
|
|
444
|
+
|
|
445
|
+
Triggers: Line colours need at least 3:1 against the chart background.
|
|
446
|
+
|
|
447
|
+
Fix: darken light-mode lines or lighten dark-mode lines.
|
|
448
|
+
|
|
449
|
+
Minimal failing input:
|
|
450
|
+
|
|
451
|
+
```json
|
|
452
|
+
{
|
|
453
|
+
"charts": [
|
|
454
|
+
{
|
|
455
|
+
"option": {
|
|
456
|
+
"backgroundColor": "#ffffff",
|
|
457
|
+
"color": ["#eeeeee"],
|
|
458
|
+
"series": [
|
|
459
|
+
{
|
|
460
|
+
"type": "line"
|
|
461
|
+
}
|
|
462
|
+
]
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
]
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## DT017 gradient-decoration
|
|
470
|
+
|
|
471
|
+
Severity: warn. Packs: global, cn.
|
|
472
|
+
|
|
473
|
+
Why: Decorative gradients add visual structure unrelated to data.
|
|
474
|
+
|
|
475
|
+
Triggers: Card/page gradients and linear or radial chart fills add decoration.
|
|
476
|
+
|
|
477
|
+
Fix: use solid backgrounds and fills.
|
|
478
|
+
|
|
479
|
+
Minimal failing input:
|
|
480
|
+
|
|
481
|
+
```json
|
|
482
|
+
{
|
|
483
|
+
"charts": [],
|
|
484
|
+
"gradients": [
|
|
485
|
+
{
|
|
486
|
+
"selector": ".card",
|
|
487
|
+
"background": "linear-gradient(red, blue)"
|
|
488
|
+
}
|
|
489
|
+
]
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
## DT018 glow
|
|
494
|
+
|
|
495
|
+
Severity: warn. Packs: global, cn.
|
|
496
|
+
|
|
497
|
+
Why: Glow blurs boundaries and competes with measured values.
|
|
498
|
+
|
|
499
|
+
Triggers: Coloured CSS shadows with blur at least 12px, or chart shadowBlur at least 10, create glow.
|
|
500
|
+
|
|
501
|
+
Fix: remove glow and use hairline borders.
|
|
502
|
+
|
|
503
|
+
Minimal failing input:
|
|
504
|
+
|
|
505
|
+
```json
|
|
506
|
+
{
|
|
507
|
+
"charts": [],
|
|
508
|
+
"shadows": [
|
|
509
|
+
{
|
|
510
|
+
"selector": ".card",
|
|
511
|
+
"boxShadow": "0px 0px 14px rgb(0, 0, 255)",
|
|
512
|
+
"textShadow": "none"
|
|
513
|
+
}
|
|
514
|
+
]
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
## DT019 kpi-overload
|
|
519
|
+
|
|
520
|
+
Severity: warn. Packs: global, cn.
|
|
521
|
+
|
|
522
|
+
Why: Too many primary values weaken priority.
|
|
523
|
+
|
|
524
|
+
Triggers: More than 6 global or 8 cn KPI tiles weakens priority.
|
|
525
|
+
|
|
526
|
+
Fix: keep only primary KPIs in the first view.
|
|
527
|
+
|
|
528
|
+
Minimal failing input:
|
|
529
|
+
|
|
530
|
+
```json
|
|
531
|
+
{
|
|
532
|
+
"charts": [],
|
|
533
|
+
"kpis": [
|
|
534
|
+
{
|
|
535
|
+
"selector": ".kpi",
|
|
536
|
+
"text": "22",
|
|
537
|
+
"color": "#111111"
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
"selector": ".kpi",
|
|
541
|
+
"text": "22",
|
|
542
|
+
"color": "#111111"
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
"selector": ".kpi",
|
|
546
|
+
"text": "22",
|
|
547
|
+
"color": "#111111"
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
"selector": ".kpi",
|
|
551
|
+
"text": "22",
|
|
552
|
+
"color": "#111111"
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
"selector": ".kpi",
|
|
556
|
+
"text": "22",
|
|
557
|
+
"color": "#111111"
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
"selector": ".kpi",
|
|
561
|
+
"text": "22",
|
|
562
|
+
"color": "#111111"
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
"selector": ".kpi",
|
|
566
|
+
"text": "22",
|
|
567
|
+
"color": "#111111"
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
"selector": ".kpi",
|
|
571
|
+
"text": "22",
|
|
572
|
+
"color": "#111111"
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
"selector": ".kpi",
|
|
576
|
+
"text": "22",
|
|
577
|
+
"color": "#111111"
|
|
578
|
+
}
|
|
579
|
+
]
|
|
580
|
+
}
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
## DT020 kpi-rainbow
|
|
584
|
+
|
|
585
|
+
Severity: warn. Packs: global, cn.
|
|
586
|
+
|
|
587
|
+
Why: Competing KPI accents distract from the primary measures.
|
|
588
|
+
|
|
589
|
+
Triggers: Three or more distinct accent colours on KPI values or tiles distract. Neutral greys and pack text/background tokens are excluded.
|
|
590
|
+
|
|
591
|
+
Fix: use ink for values and reserve colour for deltas.
|
|
592
|
+
|
|
593
|
+
Minimal failing input:
|
|
594
|
+
|
|
595
|
+
```json
|
|
596
|
+
{
|
|
597
|
+
"charts": [],
|
|
598
|
+
"kpis": [
|
|
599
|
+
{
|
|
600
|
+
"selector": ".kpi",
|
|
601
|
+
"text": "22",
|
|
602
|
+
"color": "#ff0000"
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
"selector": ".kpi",
|
|
606
|
+
"text": "22",
|
|
607
|
+
"color": "#00ff00"
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
"selector": ".kpi",
|
|
611
|
+
"text": "22",
|
|
612
|
+
"color": "#0000ff"
|
|
613
|
+
}
|
|
614
|
+
]
|
|
615
|
+
}
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
## DT021 emoji-icons
|
|
619
|
+
|
|
620
|
+
Severity: warn. Packs: global, cn.
|
|
621
|
+
|
|
622
|
+
Why: Emoji add inconsistent visual emphasis to functional labels.
|
|
623
|
+
|
|
624
|
+
Triggers: Emoji in headings, KPI labels, and rankings add inconsistent iconography.
|
|
625
|
+
|
|
626
|
+
Fix: use plain text and plain numerals for rankings.
|
|
627
|
+
|
|
628
|
+
Minimal failing input:
|
|
629
|
+
|
|
630
|
+
```json
|
|
631
|
+
{
|
|
632
|
+
"charts": [],
|
|
633
|
+
"emojis": [
|
|
634
|
+
{
|
|
635
|
+
"selector": "h1",
|
|
636
|
+
"text": "\uD83C\uDFC6 Sales"
|
|
637
|
+
}
|
|
638
|
+
]
|
|
639
|
+
}
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
## DT022 cjk-min-size
|
|
643
|
+
|
|
644
|
+
Severity: warn. Packs: cn.
|
|
645
|
+
|
|
646
|
+
Why: Small CJK glyphs lose essential detail.
|
|
647
|
+
|
|
648
|
+
Triggers: CJK text must be at least 12px.
|
|
649
|
+
|
|
650
|
+
Fix: set CJK text to at least 12px.
|
|
651
|
+
|
|
652
|
+
Minimal failing input (cn pack):
|
|
653
|
+
|
|
654
|
+
```json
|
|
655
|
+
{
|
|
656
|
+
"charts": [],
|
|
657
|
+
"texts": [
|
|
658
|
+
{
|
|
659
|
+
"selector": "#text",
|
|
660
|
+
"text": "销量",
|
|
661
|
+
"color": "#111111",
|
|
662
|
+
"background": "#ffffff",
|
|
663
|
+
"fontSize": 11,
|
|
664
|
+
"fontWeight": 400
|
|
665
|
+
}
|
|
666
|
+
]
|
|
667
|
+
}
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
## DT023 legend-single-series
|
|
671
|
+
|
|
672
|
+
Severity: info. Packs: global, cn.
|
|
673
|
+
|
|
674
|
+
Why: A single-series legend repeats context already available in the title.
|
|
675
|
+
|
|
676
|
+
Triggers: An explicitly visible legend on one series repeats context.
|
|
677
|
+
|
|
678
|
+
Fix: hide the legend or label the series directly.
|
|
679
|
+
|
|
680
|
+
Minimal failing input:
|
|
681
|
+
|
|
682
|
+
```json
|
|
683
|
+
{
|
|
684
|
+
"charts": [
|
|
685
|
+
{
|
|
686
|
+
"option": {
|
|
687
|
+
"series": [
|
|
688
|
+
{
|
|
689
|
+
"type": "bar"
|
|
690
|
+
}
|
|
691
|
+
],
|
|
692
|
+
"legend": {}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
]
|
|
696
|
+
}
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
## DT024 bar-width
|
|
700
|
+
|
|
701
|
+
Bars need an explicit width cap of 24px, or 32px on screens.
|
|
702
|
+
|
|
703
|
+
set barMaxWidth to 24 or less; use 32 or less on screens
|
|
704
|
+
|
|
705
|
+
## DT025 legend-not-direct-label
|
|
706
|
+
|
|
707
|
+
Two to four line series need direct labels instead of a legend.
|
|
708
|
+
|
|
709
|
+
hide the legend and label series at their last point
|
|
710
|
+
|
|
711
|
+
## DT026 line-weight
|
|
712
|
+
|
|
713
|
+
Line widths outside 1–3px obscure the data.
|
|
714
|
+
|
|
715
|
+
use 2px main lines and 1.5px comparison lines
|
|
716
|
+
|
|
717
|
+
## DT027 tabular-numerals
|
|
718
|
+
|
|
719
|
+
KPI numbers need tabular numerals.
|
|
720
|
+
|
|
721
|
+
set font-variant-numeric to tabular-nums
|
|
722
|
+
|
|
723
|
+
## DT028 hero-metric
|
|
724
|
+
|
|
725
|
+
Pages with at least three KPIs need a clear hero metric.
|
|
726
|
+
|
|
727
|
+
make the largest KPI at least 1.6 times the median of the others
|
|
728
|
+
|
|
729
|
+
## Pack defaults
|
|
730
|
+
|
|
731
|
+
The cn pack uses a warm neutral page, one white sheet, steel data marks, red-up and green-down deltas. Its dark screen uses an almost black page and sky data marks.
|
|
732
|
+
The global pack uses one white surface, ink, one blue accent, and grey context. Its dark mode uses the same hierarchy with a pale accent. Global deltas follow metric polarity.
|
|
733
|
+
Use the numeral faces and exact colour tables in the skill references. Subtle is decorative; the last two cn light categorical fills need direct labels. Comparison lines use muted when other grey cannot meet 3:1.
|
|
734
|
+
Use 400 for body text and 500 for headings and values, at most 600. Use tabular figures everywhere. One hero is 52–64px on desktop or 112–128px on screens, at least 2.2 times the next KPI. Secondary values are 22–26px, or 32–40px on screens.
|
|
735
|
+
Use one sheet, hairlines, 36px table rows, and 4px share bars. Keep screen CJK at least 16px. No donuts on KPI boards, dual axes, helper sentences, gradients, glow, or in-flow shadows.
|