dashtaste 0.0.0-stage → 0.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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -2
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +124 -0
  5. package/dist/color.d.ts +4 -0
  6. package/dist/color.js +43 -0
  7. package/dist/engine.d.ts +11 -0
  8. package/dist/engine.js +39 -0
  9. package/dist/extract-in-page.d.ts +3 -0
  10. package/dist/extract-in-page.js +149 -0
  11. package/dist/extract.d.ts +3 -0
  12. package/dist/extract.js +39 -0
  13. package/dist/format.d.ts +18 -0
  14. package/dist/format.js +65 -0
  15. package/dist/index.d.ts +5 -0
  16. package/dist/index.js +5 -0
  17. package/dist/packs/cn.d.ts +2 -0
  18. package/dist/packs/cn.js +56 -0
  19. package/dist/packs/global.d.ts +2 -0
  20. package/dist/packs/global.js +45 -0
  21. package/dist/packs/index.d.ts +53 -0
  22. package/dist/packs/index.js +13 -0
  23. package/dist/rules/dt001-default-palette.d.ts +3 -0
  24. package/dist/rules/dt001-default-palette.js +11 -0
  25. package/dist/rules/dt002-rainbow-palette.d.ts +3 -0
  26. package/dist/rules/dt002-rainbow-palette.js +11 -0
  27. package/dist/rules/dt003-smooth-line.d.ts +3 -0
  28. package/dist/rules/dt003-smooth-line.js +9 -0
  29. package/dist/rules/dt004-symbols-everywhere.d.ts +3 -0
  30. package/dist/rules/dt004-symbols-everywhere.js +21 -0
  31. package/dist/rules/dt005-pie-slices.d.ts +3 -0
  32. package/dist/rules/dt005-pie-slices.js +13 -0
  33. package/dist/rules/dt006-pie-overuse.d.ts +3 -0
  34. package/dist/rules/dt006-pie-overuse.js +14 -0
  35. package/dist/rules/dt007-three-d.d.ts +3 -0
  36. package/dist/rules/dt007-three-d.js +16 -0
  37. package/dist/rules/dt008-dual-axis.d.ts +3 -0
  38. package/dist/rules/dt008-dual-axis.js +10 -0
  39. package/dist/rules/dt009-missing-unit.d.ts +3 -0
  40. package/dist/rules/dt009-missing-unit.js +8 -0
  41. package/dist/rules/dt010-bar-baseline.d.ts +3 -0
  42. package/dist/rules/dt010-bar-baseline.js +11 -0
  43. package/dist/rules/dt011-raw-large-numbers.d.ts +3 -0
  44. package/dist/rules/dt011-raw-large-numbers.js +21 -0
  45. package/dist/rules/dt012-unit-system.d.ts +3 -0
  46. package/dist/rules/dt012-unit-system.js +12 -0
  47. package/dist/rules/dt013-delta-convention.d.ts +3 -0
  48. package/dist/rules/dt013-delta-convention.js +21 -0
  49. package/dist/rules/dt014-delta-colour-only.d.ts +3 -0
  50. package/dist/rules/dt014-delta-colour-only.js +16 -0
  51. package/dist/rules/dt015-low-contrast-text.d.ts +3 -0
  52. package/dist/rules/dt015-low-contrast-text.js +28 -0
  53. package/dist/rules/dt016-thin-line-contrast.d.ts +3 -0
  54. package/dist/rules/dt016-thin-line-contrast.js +12 -0
  55. package/dist/rules/dt017-gradient-decoration.d.ts +3 -0
  56. package/dist/rules/dt017-gradient-decoration.js +15 -0
  57. package/dist/rules/dt018-glow.d.ts +3 -0
  58. package/dist/rules/dt018-glow.js +27 -0
  59. package/dist/rules/dt019-kpi-overload.d.ts +3 -0
  60. package/dist/rules/dt019-kpi-overload.js +7 -0
  61. package/dist/rules/dt020-kpi-rainbow.d.ts +3 -0
  62. package/dist/rules/dt020-kpi-rainbow.js +27 -0
  63. package/dist/rules/dt021-emoji-icons.d.ts +3 -0
  64. package/dist/rules/dt021-emoji-icons.js +10 -0
  65. package/dist/rules/dt022-cjk-min-size.d.ts +3 -0
  66. package/dist/rules/dt022-cjk-min-size.js +9 -0
  67. package/dist/rules/dt023-legend-single-series.d.ts +3 -0
  68. package/dist/rules/dt023-legend-single-series.js +8 -0
  69. package/dist/rules/dt024-bar-width.d.ts +1 -0
  70. package/dist/rules/dt024-bar-width.js +14 -0
  71. package/dist/rules/dt025-legend-not-direct-label.d.ts +1 -0
  72. package/dist/rules/dt025-legend-not-direct-label.js +11 -0
  73. package/dist/rules/dt026-line-weight.d.ts +1 -0
  74. package/dist/rules/dt026-line-weight.js +8 -0
  75. package/dist/rules/dt027-tabular-numerals.d.ts +1 -0
  76. package/dist/rules/dt027-tabular-numerals.js +16 -0
  77. package/dist/rules/dt028-hero-metric.d.ts +1 -0
  78. package/dist/rules/dt028-hero-metric.js +14 -0
  79. package/dist/rules/helpers.d.ts +32 -0
  80. package/dist/rules/helpers.js +161 -0
  81. package/dist/rules/index.d.ts +2 -0
  82. package/dist/rules/index.js +58 -0
  83. package/dist/types.d.ts +122 -0
  84. package/dist/types.js +1 -0
  85. package/docs/rules.md +735 -0
  86. package/docs/usage.md +126 -0
  87. package/package.json +74 -4
  88. package/skills/dashtaste-cn/SKILL.md +51 -0
  89. package/skills/dashtaste-cn/references/avoid.md +135 -0
  90. package/skills/dashtaste-cn/references/charts.md +122 -0
  91. package/skills/dashtaste-cn/references/layout.md +78 -0
  92. package/skills/dashtaste-cn/references/numbers.md +93 -0
  93. package/skills/dashtaste-cn/references/tokens.md +72 -0
  94. package/skills/dashtaste-global/SKILL.md +43 -0
  95. package/skills/dashtaste-global/references/avoid.md +135 -0
  96. package/skills/dashtaste-global/references/charts.md +122 -0
  97. package/skills/dashtaste-global/references/layout.md +78 -0
  98. package/skills/dashtaste-global/references/numbers.md +83 -0
  99. package/skills/dashtaste-global/references/tokens.md +65 -0
package/docs/usage.md ADDED
@@ -0,0 +1,126 @@
1
+ # Usage
2
+
3
+ Build with Node 20.19 or newer and pnpm:
4
+
5
+ ```sh
6
+ pnpm install
7
+ pnpm build
8
+ npx dashtaste --help
9
+ ```
10
+
11
+ ## Check options
12
+
13
+ ```sh
14
+ npx dashtaste check options.json --pack global
15
+ npx dashtaste check first.json second.json --pack cn --format json
16
+ npx dashtaste check options.json --pack cn --mode dark --max-warnings 0
17
+ ```
18
+
19
+ Input may be one ECharts option, an array of options, or a page facts envelope:
20
+
21
+ ```json
22
+ {
23
+ "charts": [{ "id": "orders", "option": { "series": [] } }],
24
+ "page": { "background": "#FFFFFF", "deltaColors": "red-up" }
25
+ }
26
+ ```
27
+
28
+ Page facts may also contain texts, gradients, shadows, kpis, deltas, and emojis.
29
+ An option-only input cannot test computed page typography or CSS decoration.
30
+ See the exported types for each fact shape.
31
+
32
+ Defaults are the global pack, light mode, text output, and unlimited warnings.
33
+ Errors always fail. `--max-warnings 0` also fails on any warning.
34
+ Informational findings lower the score but do not fail a check.
35
+
36
+ ## Check rendered pages
37
+
38
+ ```sh
39
+ CHROME_PATH=/path/to/chromium npx dashtaste check dashboard.html --pack cn
40
+ CHROME_PATH=/path/to/chromium npx dashtaste check http://localhost:3000 --pack global
41
+ ```
42
+
43
+ HTML mode needs Playwright's core package and a Chromium executable.
44
+ It reads mounted ECharts instances through `window.echarts` after network idle
45
+ and a 500ms settling interval. Render charts before that point.
46
+ It collects visible text, composited backgrounds, decoration, KPIs, and deltas.
47
+ Use `data-kpi`, `data-delta`, and `data-direction="up|down|flat"` for explicit facts.
48
+ Set `data-delta-colors="red-up|green-up"` on the document element to override
49
+ one page's comparison convention. Keep every directional delta consistent.
50
+ The extractor inspects visible DOM text; canvas text is checked through options.
51
+
52
+ ## Flags and exit codes
53
+
54
+ | Flag | Commands | Values |
55
+ | ---------------- | ------------- | ------------------------------ |
56
+ | `--pack` | all | `global`, `cn` |
57
+ | `--mode` | check, tokens | `light`, `dark` |
58
+ | `--format` | check, rules | `text`, `json` |
59
+ | `--format` | tokens | `json`, `css` |
60
+ | `--max-warnings` | check | non-negative integer |
61
+ | `--only` | check | comma-separated rule IDs |
62
+ | `--disable` | check | comma-separated rule IDs |
63
+ | `--background` | check | three- or six-digit hex colour |
64
+ | `--help` | all | command-specific usage |
65
+
66
+ `--disable` takes precedence over `--only`. Unknown rule IDs are input errors.
67
+ `--background` overrides chart, page, and pack backgrounds for contrast checks.
68
+ `tokens` requires an explicit `--pack`.
69
+
70
+ Exit 0 means no errors and warnings within the selected limit.
71
+ Exit 1 means errors or too many warnings.
72
+ Exit 2 means invalid arguments, unreadable input, or unavailable extraction.
73
+ Set `NO_COLOR` to suppress ANSI colour in text output.
74
+ JSON output contains version, pack, per-input findings and scores, and summary.
75
+ Each finding contains ruleId, severity, message, path, and fix.
76
+ Score starts at 100: subtract 10 per error, 3 per warning, and 1 per info.
77
+ The minimum score is zero.
78
+
79
+ ## Inspect metadata and tokens
80
+
81
+ ```sh
82
+ npx dashtaste rules --pack cn --format json
83
+ npx dashtaste tokens --pack global --mode light
84
+ npx dashtaste tokens --pack cn --mode dark --format css
85
+ ```
86
+
87
+ The cn pack includes screen composition settings for a 1920×1080 artboard.
88
+ Screen composition uses dark tokens and `--mode dark`; it is not a third CLI mode.
89
+ Pack objects also expose numberSystem, limits, typography, and spacing.
90
+ Token output contains only colours for the selected light or dark mode.
91
+
92
+ ## Library and formatting
93
+
94
+ ```ts
95
+ import { check, summarize } from 'dashtaste';
96
+ import { formatCompact, formatPercent, formatDelta, formatDate } from 'dashtaste/format';
97
+
98
+ const findings = check({ series: [] }, { pack: 'cn', mode: 'light' });
99
+ const summary = summarize(findings);
100
+ const amount = formatCompact(12300, 'cn'); // 1.23万
101
+ const percent = formatPercent(0.125); // 12.5%
102
+ const delta = formatDelta(110, 100, 'cn'); // render text and color together
103
+ const date = formatDate(new Date(2026, 9, 21), 'cn'); // 2026-10-21
104
+ ```
105
+
106
+ The date helper returns local calendar dates in YYYY-MM-DD form for both packs.
107
+ Use an explicit display adapter for global long dates such as Oct 21, 2026.
108
+ See each skill's numbers reference for exact comparison and rounding rules.
109
+
110
+ ## Skills and development
111
+
112
+ Choose skills/dashtaste-global or skills/dashtaste-cn for the intended audience.
113
+ Each skill links tokens, chart examples, numbers, layout, and patterns to avoid.
114
+ Use the matching pack when checking the examples or a generated dashboard.
115
+ Layout and copy still need visual review; the rule checker does not prove usability.
116
+
117
+ ```sh
118
+ pnpm format
119
+ pnpm format:check
120
+ pnpm typecheck
121
+ pnpm build
122
+ pnpm test
123
+ ```
124
+
125
+ The tests cover rule contracts, pack differences, colour contrast and vision,
126
+ CLI behavior, formatting, skill consistency, every chart JSON example, and browser extraction.
package/package.json CHANGED
@@ -1,6 +1,76 @@
1
1
  {
2
2
  "name": "dashtaste",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.0.1",
4
+ "description": "Dashboard taste for coding agents: two style-pack skills (global and cn) plus a dashtaste check linter for ECharts configs and rendered dashboards.",
5
+ "keywords": [
6
+ "dashboard",
7
+ "echarts",
8
+ "chart",
9
+ "lint",
10
+ "linter",
11
+ "data-visualization",
12
+ "dataviz",
13
+ "design",
14
+ "agent-skills",
15
+ "skills",
16
+ "ai-agents",
17
+ "cli"
18
+ ],
19
+ "author": "Felix Fang (https://github.com/FelixFangX)",
20
+ "homepage": "https://github.com/FelixFangX/dashtaste#readme",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/FelixFangX/dashtaste.git"
24
+ },
25
+ "bugs": {
26
+ "url": "https://github.com/FelixFangX/dashtaste/issues"
27
+ },
28
+ "license": "MIT",
29
+ "type": "module",
30
+ "bin": {
31
+ "dashtaste": "dist/cli.js"
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "skills",
36
+ "docs",
37
+ "README.md",
38
+ "LICENSE"
39
+ ],
40
+ "engines": {
41
+ "node": ">=20"
42
+ },
43
+ "exports": {
44
+ ".": {
45
+ "types": "./dist/index.d.ts",
46
+ "import": "./dist/index.js"
47
+ },
48
+ "./format": {
49
+ "types": "./dist/format.d.ts",
50
+ "import": "./dist/format.js"
51
+ }
52
+ },
53
+ "scripts": {
54
+ "build": "tsc",
55
+ "typecheck": "tsc --noEmit",
56
+ "test": "vitest run",
57
+ "lint-skills": "vitest run test/skills.test.ts",
58
+ "format": "prettier --write .",
59
+ "format:check": "prettier --check .",
60
+ "gallery": "pnpm build && node gallery/build.mjs",
61
+ "prepublishOnly": "npm run build"
62
+ },
63
+ "devDependencies": {
64
+ "@fontsource-variable/geist-mono": "^5.3.0",
65
+ "@fontsource-variable/instrument-sans": "^5.3.0",
66
+ "@fontsource-variable/inter": "^5.3.0",
67
+ "@types/node": "^20.19.0",
68
+ "echarts": "^6.1.0",
69
+ "prettier": "^3.9.10",
70
+ "typescript": "~5.9.3",
71
+ "vitest": "~3.2.4"
72
+ },
73
+ "optionalDependencies": {
74
+ "playwright-core": "^1.56.0"
75
+ }
76
+ }
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: dashtaste-cn
3
+ description: Build or review readable Chinese-market dashboards with concrete layout, chart, colour, and number defaults.
4
+ ---
5
+
6
+ # Dashboard workflow
7
+
8
+ Use for dashboard pages, chart options, KPI strips, rankings, and dashboard reviews.
9
+ For a global audience use dashtaste-global.
10
+
11
+ 1. Pick the cn pack and light or dark mode before choosing colours.
12
+ 2. Read [tokens](references/tokens.md) for exact colours and sizes.
13
+ 3. Read [layout](references/layout.md) for page structure and controls.
14
+ 4. Read [charts](references/charts.md) for the chart types you need.
15
+ 5. Read [numbers](references/numbers.md) for units, dates, and comparisons.
16
+ 6. Build the page with real data, explicit units, and clear hierarchy.
17
+ 7. Run `npx dashtaste check options.json --pack cn --max-warnings 0`.
18
+ For a rendered page, check its URL with a browser available through `CHROME_PATH`.
19
+ 8. Fix errors and warnings; inspect informational findings. Recheck after edits.
20
+ Read [avoid](references/avoid.md) when replacing a flagged pattern.
21
+
22
+ ## Ten rules to apply first
23
+
24
+ - DT001: Set explicit series colours from the selected pack.
25
+ - DT002: Keep at most five categorical colours; group the tail as Other.
26
+ - DT003: Draw straight line segments; smoothing invents intermediate values.
27
+ - DT004: Hide line symbols above 12 points.
28
+ - DT005: Use ranked bars for shares; no donuts in KPI boards.
29
+ - DT007: Use flat two-dimensional marks.
30
+ - DT009: Put units in value-axis names.
31
+ - DT010: Start bar value axes at zero and disable scale.
32
+ - DT013: Use red-up and green-down deltas throughout the page.
33
+ - DT015: Meet 4.5:1 text contrast, or 3:1 for large text.
34
+
35
+ ## Layout explains itself
36
+
37
+ Use no helper labels, explanatory captions, or “this chart shows” text.
38
+ Put units in axis names. Titles may state the finding, such as
39
+ “Returns fell for three weeks”. Labels identify data and controls directly.
40
+ Keep definitions in an accessible detail view when needed, outside chart captions.
41
+
42
+ ## Chinese copy
43
+
44
+ Use full-width punctuation in Chinese prose. Add a space between Hanzi and
45
+ Latin text or digits in prose; keep `1.23万` and `12%` intact.
46
+ Use no uppercase or tracked labels and no serif page title.
47
+ Keep CJK text at least 12px, or 16px on screens. Use the numeral face
48
+ and CJK fallback specified in references/numbers.md.
49
+
50
+ Use one hero metric, one sheet, hairlines, and direct labels.
51
+ Use the measured defaults in the references for all KPI boards.
@@ -0,0 +1,135 @@
1
+ # Patterns to avoid
2
+
3
+ Use this list when reviewing a page or replacing a flagged pattern.
4
+ Rule checks cover observable facts; inspect layout and copy manually as well.
5
+
6
+ ## DT001: default-palette
7
+
8
+ Multiple series need explicit colours. Any default palette colour is flagged.
9
+ Replace it: set option.color to the pack palette (dashtaste tokens --pack <pack>).
10
+
11
+ ## DT002: rainbow-palette
12
+
13
+ More than 6 distinct categorical colours or more than 5 saturated 60-degree hue buckets.
14
+ Replace it: use the pack palette and group remaining categories as Other.
15
+
16
+ ## DT003: smooth-line
17
+
18
+ Line smoothing greater than zero draws values that do not exist.
19
+ Replace it: use straight segments: smooth: false.
20
+
21
+ ## DT004: symbols-everywhere
22
+
23
+ Line symbols are noisy above 12 points; ECharts shows symbols by default.
24
+ Replace it: set showSymbol: false.
25
+
26
+ ## DT005: pie-slices
27
+
28
+ Maximum 5 slices; cn rose charts allow 8.
29
+ Replace it: use horizontal bars or combine small parts into Other.
30
+
31
+ ## DT006: pie-overuse
32
+
33
+ More than one pie per page or radius ratio above 0.75 warns. A global pie is informational.
34
+ Replace it: prefer horizontal bars; keep donut radius ratio at most 0.75.
35
+
36
+ ## DT007: three-d
37
+
38
+ 3D series, axes, coordinates, and pseudo-3D pie decoration distort comparisons.
39
+ Replace it: use flat 2D charts.
40
+
41
+ ## DT008: dual-axis
42
+
43
+ Multiple value axes obscure comparisons, including mixed bar and line charts.
44
+ Replace it: use one value axis or aligned small multiples.
45
+
46
+ ## DT009: missing-unit
47
+
48
+ Value axes need a name, formatter, unit metadata, or units in rendered ticks.
49
+ Replace it: put units in axis names, rendered ticks, or formatter metadata.
50
+
51
+ ## DT010: bar-baseline
52
+
53
+ Bar value axes must start at zero; positive min and scale: true distort lengths.
54
+ Replace it: set min: 0 and scale: false.
55
+
56
+ ## DT011: raw-large-numbers
57
+
58
+ At data maximum magnitude 10000 or above, axis, visible data label, and tooltip channels need formatters.
59
+ Replace it: format compact units: cn 万/亿; global K/M.
60
+
61
+ ## DT012: unit-system
62
+
63
+ String formatter templates must use the selected compact unit system.
64
+ Replace it: use cn 万/亿 or global K/M/B consistently.
65
+
66
+ ## DT013: delta-convention
67
+
68
+ Directional deltas must follow one page convention: global green-up; cn red-up by default.
69
+ Replace it: apply one deltaColors convention to the whole page.
70
+
71
+ ## DT014: delta-colour-only
72
+
73
+ Directional colour must be accompanied by an arrow or signed number.
74
+ Replace it: add ▲/▼ or an explicit sign.
75
+
76
+ ## DT015: low-contrast-text
77
+
78
+ Text needs 4.5:1; at least 24px or 18.66px bold needs 3:1. Chart label defaults use 4.5:1.
79
+ Replace it: increase text contrast against its background.
80
+
81
+ ## DT016: thin-line-contrast
82
+
83
+ Line colours need at least 3:1 against the chart background.
84
+ Replace it: darken light-mode lines or lighten dark-mode lines.
85
+
86
+ ## DT017: gradient-decoration
87
+
88
+ Card/page gradients and linear or radial chart fills add decoration.
89
+ Replace it: use solid backgrounds and fills.
90
+
91
+ ## DT018: glow
92
+
93
+ Coloured CSS shadows with blur at least 12px, or chart shadowBlur at least 10, create glow.
94
+ Replace it: remove glow and use hairline borders.
95
+
96
+ ## DT019: kpi-overload
97
+
98
+ More than 6 global or 8 cn KPI tiles weakens priority.
99
+ Replace it: keep only primary KPIs in the first view.
100
+
101
+ ## DT020: kpi-rainbow
102
+
103
+ Three or more distinct accent colours on KPI values or tiles distract. Neutral greys and pack text/background tokens are excluded.
104
+ Replace it: use ink for values and reserve colour for deltas.
105
+
106
+ ## DT021: emoji-icons
107
+
108
+ Emoji in headings, KPI labels, and rankings add inconsistent iconography.
109
+ Replace it: use plain text and plain numerals for rankings.
110
+
111
+ ## DT022: cjk-min-size
112
+
113
+ CJK text must be at least 12px.
114
+ Replace it: set CJK text to at least 12px.
115
+
116
+ ## DT023: legend-single-series
117
+
118
+ An explicitly visible legend on one series repeats context.
119
+ Replace it: hide the legend or label the series directly.
120
+
121
+ ## Manual layout review
122
+
123
+ Helper labels and explanatory captions repeat visible structure; no automatic rule yet.
124
+ Decorative icon tiles distract from values; no automatic rule yet.
125
+ Tracked labels and serif titles impair dense CJK reading; no automatic rule yet.
126
+
127
+ ## Measured anti-patterns
128
+
129
+ DT024: uncapped bars and bars wider than 24px (32px on screens).
130
+ DT025: legends for two to four lines without direct end labels.
131
+ DT026: decorative line strokes above 3px or below 1px.
132
+ DT027: proportional numerals in KPI values.
133
+ DT028: several equally sized KPIs without a clear hero.
134
+ Avoid donuts on KPI boards, dual axes, repeated boxed cards, and empty quadrants.
135
+ Avoid helper sentences, uppercase tracking, and in-flow shadows.
@@ -0,0 +1,122 @@
1
+ # Chart defaults
2
+
3
+ These complete light-mode options use small values so no compact formatter is needed.
4
+ Copy an option into a JSON file and check with `--pack cn`.
5
+ For dark mode replace all foreground and surface colours using tokens.md; check with `--mode dark`.
6
+ For large values, convert data to display units and name the unit in the axis.
7
+ Keep raw values separately for accessible detail views.
8
+
9
+ ## Line
10
+
11
+ Use for change over time. Keep straight segments. Use filled 3–4px dots on series of at most 31 points. A 240px plot is a useful starting height.
12
+
13
+ <!-- prettier-ignore -->
14
+ ```json
15
+ {"color": ["#141414"], "xAxis": {"type": "category", "data": ["Mon", "Tue", "Wed"]}, "yAxis": {"type": "value", "name": "Orders"}, "series": [{"type": "line", "smooth": false, "showSymbol": true, "data": [12, 18, 16], "lineStyle": {"width": 1.5, "color": "#141414"}, "symbol": "circle", "symbolSize": 4, "markPoint": {"symbol": "circle", "symbolSize": 7, "itemStyle": {"color": "#3E6A88"}, "label": {"show": true, "position": "top", "formatter": "{c}"}, "data": [{"coord": [2, 16]}]}}]}
16
+ ```
17
+
18
+ ## Bar
19
+
20
+ Compare amounts. Start at zero. Use horizontal bars for long category labels and at most 12px bar thickness on desktop.
21
+
22
+ <!-- prettier-ignore -->
23
+ ```json
24
+ {"color": ["#141414"], "xAxis": {"type": "value", "name": "Orders", "min": 0, "scale": false}, "yAxis": {"type": "category", "data": ["East", "West", "North"]}, "series": [{"type": "bar", "barMaxWidth": 12, "data": [24, 18, 12]}]}
25
+ ```
26
+
27
+ ## Combo
28
+
29
+ Use aligned panels for different units. Keep comparison series on one shared axis.
30
+
31
+ <!-- prettier-ignore -->
32
+ ```json
33
+ {"color": ["#141414"], "xAxis": {"type": "category", "data": ["Mon", "Tue", "Wed"]}, "yAxis": {"type": "value", "name": "Orders", "min": 0}, "series": [{"name": "Orders", "type": "bar", "data": [24, 18, 12], "barMaxWidth": 12}, {"name": "Prior orders", "type": "line", "showSymbol": true, "smooth": false, "data": [12, 15, 18], "lineStyle": {"width": 1.5, "color": "#141414"}, "symbol": "circle", "symbolSize": 4}]}
34
+ ```
35
+
36
+ ## Share / pie / donut
37
+
38
+ No donuts or pies in KPI boards. Use a ranked bar list or a single 100% stacked bar with direct labels. The option below is for isolated composition analysis.
39
+
40
+ <!-- prettier-ignore -->
41
+ ```json
42
+ {"color": ["#141414"], "series": [{"type": "pie", "radius": ["35%", "60%"], "label": {"show": true, "formatter": "{b}: {d}%"}, "data": [{"name": "New", "value": 60}, {"name": "Repeat", "value": 40}]}]}
43
+ ```
44
+
45
+ ## Funnel
46
+
47
+ Use for ordered process stages with a shared population. Keep one colour, descending values, and visible stage labels.
48
+
49
+ <!-- prettier-ignore -->
50
+ ```json
51
+ {"color": ["#141414"], "series": [{"type": "funnel", "sort": "descending", "label": {"show": true, "formatter": "{b}: {c}"}, "data": [{"name": "Started", "value": 90}, {"name": "Qualified", "value": 60}, {"name": "Completed", "value": 30}]}]}
52
+ ```
53
+
54
+ ## Table
55
+
56
+ Use a semantic HTML table in production: left-align labels, right-align amounts, use 36px rows and hairline separators. This static ECharts graphic is a portable option example.
57
+
58
+ <!-- prettier-ignore -->
59
+ ```json
60
+ {"graphic": [{"type": "text", "left": 16, "top": 16, "style": {"text": "Region Orders", "fill": "#1D2433", "fontSize": 14}}, {"type": "text", "left": 16, "top": 52, "style": {"text": "East 24", "fill": "#1D2433", "fontSize": 14}}]}
61
+ ```
62
+
63
+ ## KPI
64
+
65
+ Use real text with tabular figures. One 52–64px hero, 22–26px secondary values, 11px uppercase tracked mono labels for Latin, 13px CJK labels; weights 400 and 500.
66
+
67
+ <!-- prettier-ignore -->
68
+ ```json
69
+ {"graphic": [{"type": "text", "left": 16, "top": 16, "style": {"text": "Orders", "fill": "#5F6B7E", "fontSize": 14}}, {"type": "text", "left": 16, "top": 44, "style": {"text": "124", "fill": "#1D2433", "fontSize": 32}}]}
70
+ ```
71
+
72
+ ## Ranking / TOP N
73
+
74
+ Sort descending. Default to TOP 5; use TOP 10 only with room. Use muted tabular ranks without medals. Show the cutoff in the title.
75
+
76
+ <!-- prettier-ignore -->
77
+ ```json
78
+ {"title": {"text": "Top 3 regions by orders"}, "color": ["#141414"], "xAxis": {"type": "value", "name": "Orders", "min": 0}, "yAxis": {"type": "category", "inverse": true, "data": ["1 East", "2 West", "3 North"]}, "series": [{"type": "bar", "barMaxWidth": 12, "data": [24, 18, 12]}]}
79
+ ```
80
+
81
+ ## Map
82
+
83
+ Use only for geographic questions, otherwise use ranking bars. Register a matching GeoJSON map as regions before setOption. Keep roam off and use a sequential scale with units.
84
+
85
+ <!-- prettier-ignore -->
86
+ ```json
87
+ {"visualMap": {"min": 0, "max": 100, "text": ["Orders", "0"], "inRange": {"color": ["#141414"]}}, "series": [{"type": "map", "map": "regions", "roam": false, "data": [{"name": "East", "value": 24}, {"name": "West", "value": 18}]}]}
88
+ ```
89
+
90
+ ## Shared interaction defaults
91
+
92
+ Use tooltip trigger axis for time series and item for isolated marks.
93
+ Use one explicit colour for a single series; do not rely on theme defaults.
94
+ Hide the legend for one series. For comparisons, hide legends and use short annotations with thin 1px leader lines.
95
+ Do not use decorative gradients, shadows, 3D marks, or emoji in titles.
96
+ Keep missing observations missing; do not replace them with zero.
97
+ Use stable ordering for categories unless ranking is the question.
98
+ Keep controls outside the plotting rectangle.
99
+ Provide keyboard access and a table or textual data alternative.
100
+ Use a finding title only when the data supports it after filtering.
101
+ A unit belongs in the axis name, not in a helper caption.
102
+
103
+ ## Measured defaults
104
+
105
+ Main lines use 1.5px ink; comparisons use 1px dashed mid-grey.
106
+ Long series hide symbols. Short series use small ink dots; comparisons or incomplete values use hollow dots.
107
+ Use straight segments, horizontal grid lines, and no y-axis line.
108
+ Bars use at most 65% of their category band; keep value labels outside.
109
+ Use one accent mark and neutral context; reserve red and green for deltas.
110
+ Small multiples use 1.5px lines without axes and a shared scale per row.
111
+ No area gradients, glow, or decorative heavy strokes.
112
+
113
+ Exactly one accent mark per chart: a filled 7px latest or peak dot and its value label.
114
+ Never use the accent on another chart element. Bars may highlight one bar instead.
115
+ Only latest and extreme values may have labels.
116
+ Use markLine, markPoint or graphic for leader-line annotations.
117
+ Thin ink bars are at most 12px; negative bars are mid-grey.
118
+ Inline table bars use ink at 20% opacity; the top row uses solid ink.
119
+
120
+ Use story-bearing data in examples. Annotate one event per chart with a leader line, a hollow ink dot, and a short label in empty space. Keep the latest point as the single accent.
121
+
122
+ Use one signature element per board. Place it alongside the main metric so it reinforces the data story.
@@ -0,0 +1,78 @@
1
+ # Layout
2
+
3
+ Use one hero to establish the reading order.
4
+ The hero is 52–64px on desktop and 112–128px on a screen.
5
+ The hero is at least 2.2 times the next KPI.
6
+ Use weight 500 and letter spacing −0.02em for the hero.
7
+ Secondary KPIs use 22–26px, or 32–40px on screens.
8
+ Labels use 12–13px and weight 500.
9
+ Use sentence case without uppercase tracking.
10
+ Titles name the metric or state a supported finding.
11
+ Do not add helper text or explanatory sentences.
12
+
13
+ ## Surface
14
+
15
+ Use one white sheet with a 12px radius on the warm neutral page.
16
+ Separate sections with hairlines and whitespace.
17
+ Avoid repeated boxed cards.
18
+ Inner radii are at most 6px.
19
+ Do not use in-flow shadows, gradients, glow, or glass effects.
20
+ Dark screens use hairlines rather than luminous panel borders.
21
+
22
+ ## Density
23
+
24
+ Fill the viewport with relevant information.
25
+ Size the plot after reserving space for titles and direct labels.
26
+ Keep all content inside the viewport.
27
+ Use a main trend and a compact right rail.
28
+ Place categorical detail beneath the trend.
29
+ Keep date ranges in the header.
30
+ Align section headings and plot edges.
31
+ Align numeric baselines across the rail.
32
+ Reserve room for the longest label.
33
+ Avoid empty quadrants and decorative whitespace.
34
+
35
+ ## Tables
36
+
37
+ Use semantic tables with 13px text and 36px rows.
38
+ Use 11px muted mono column headers for Latin; CJK headers stay at least 12px.
39
+ Right-align numbers with tabular figures.
40
+ Use hairline row separators.
41
+ Do not use zebra stripes or vertical rules.
42
+ Show share with a 4px inline bar.
43
+ The maximum share uses the accent; context uses a tint.
44
+ Use muted tabular ranks without medals.
45
+ Keep row names left aligned.
46
+ Show units consistently within a column.
47
+ Keep decimal precision consistent.
48
+
49
+ ## Screen
50
+
51
+ Use a 1920×1080 viewport.
52
+ The minimum CJK size is 16px.
53
+ Use a 112–128px hero and a secondary KPI strip.
54
+ Use twelve regional small multiples instead of coloured tiles.
55
+ Use the same scale across regional sparklines.
56
+ Keep the current time visible in the header.
57
+ Mark the current hour with a vertical hairline.
58
+ Progress bars are 4px flat fills.
59
+ Use ink for the numerator and muted for the denominator.
60
+
61
+ ## Checks
62
+
63
+ Check overflow at the exact target viewport.
64
+ Inspect every exported image for clipping and overlap.
65
+ Wait for local fonts before rendering.
66
+ Render at a device scale factor of two.
67
+ Keep tooltips out of the captured state.
68
+ Check contrast on every surface.
69
+ Keep at most three font weights, never above 600.
70
+
71
+ Header: a 20px, weight 500 title left and date range right.
72
+ Omit breadcrumbs, identity lines, helper lines and footer captions.
73
+ Use at most one hairline below the header.
74
+ Create breathing room with margins; avoid half-empty panels.
75
+
76
+ Use story-bearing data in examples. Annotate one event per chart with a leader line, a hollow ink dot, and a short label in empty space. Keep the latest point as the single accent.
77
+
78
+ Use one signature element per board. Place it alongside the main metric so it reinforces the data story.