agentcss 0.0.0-stage → 0.11.3
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/01-tokens/README.md +236 -0
- package/01-tokens/behavior/dismissable.js +132 -0
- package/01-tokens/behavior/emit.js +76 -0
- package/01-tokens/behavior/focus-return.js +81 -0
- package/01-tokens/behavior/roving.js +152 -0
- package/01-tokens/behavior/typeahead.js +124 -0
- package/01-tokens/focus-ring-demo.html +133 -0
- package/01-tokens/focus-ring.css +102 -0
- package/01-tokens/page.css +244 -0
- package/01-tokens/polyfill.js +116 -0
- package/01-tokens/responsive-demo.html +171 -0
- package/01-tokens/scrollbar-demo.html +194 -0
- package/01-tokens/scrollbar.css +179 -0
- package/01-tokens/theme-toggle.js +103 -0
- package/01-tokens/tokens.css +972 -0
- package/01-tokens/typography.css +156 -0
- package/02-primitives/badge/README.md +71 -0
- package/02-primitives/badge/badge.css +141 -0
- package/02-primitives/badge/demo.html +101 -0
- package/02-primitives/button/README.md +99 -0
- package/02-primitives/button/button.css +353 -0
- package/02-primitives/button/demo.html +200 -0
- package/02-primitives/card/README.md +145 -0
- package/02-primitives/card/card.css +246 -0
- package/02-primitives/card/demo.html +170 -0
- package/02-primitives/choice/README.md +161 -0
- package/02-primitives/choice/choice.css +395 -0
- package/02-primitives/choice/demo.html +277 -0
- package/02-primitives/combobox/README.md +79 -0
- package/02-primitives/combobox/combobox.css +223 -0
- package/02-primitives/combobox/combobox.js +485 -0
- package/02-primitives/combobox/demo.html +109 -0
- package/02-primitives/date-range/README.md +100 -0
- package/02-primitives/date-range/date-range.css +206 -0
- package/02-primitives/date-range/date-range.js +301 -0
- package/02-primitives/date-range/demo.html +104 -0
- package/02-primitives/input/README.md +170 -0
- package/02-primitives/input/demo.html +246 -0
- package/02-primitives/input/input.css +239 -0
- package/02-primitives/popover/README.md +80 -0
- package/02-primitives/popover/demo.html +150 -0
- package/02-primitives/popover/popover.css +187 -0
- package/02-primitives/popover/popover.js +331 -0
- package/02-primitives/progress/README.md +82 -0
- package/02-primitives/progress/demo.html +154 -0
- package/02-primitives/progress/progress.css +172 -0
- package/02-primitives/select/README.md +95 -0
- package/02-primitives/select/demo.html +121 -0
- package/02-primitives/select/select.css +151 -0
- package/02-primitives/select/select.js +549 -0
- package/02-primitives/separator/README.md +63 -0
- package/02-primitives/separator/demo.html +84 -0
- package/02-primitives/separator/separator.css +73 -0
- package/02-primitives/skeleton/README.md +69 -0
- package/02-primitives/skeleton/demo.html +110 -0
- package/02-primitives/skeleton/skeleton.css +96 -0
- package/02-primitives/switch/README.md +65 -0
- package/02-primitives/switch/demo.html +115 -0
- package/02-primitives/switch/switch.css +370 -0
- package/03-patterns/accordion/README.md +121 -0
- package/03-patterns/accordion/accordion.css +453 -0
- package/03-patterns/accordion/accordion.js +369 -0
- package/03-patterns/accordion/demo.html +223 -0
- package/03-patterns/content/README.md +103 -0
- package/03-patterns/content/content.css +286 -0
- package/03-patterns/content/demo.html +88 -0
- package/03-patterns/drawer/README.md +79 -0
- package/03-patterns/drawer/demo.html +101 -0
- package/03-patterns/drawer/drawer.css +129 -0
- package/03-patterns/drawer/drawer.js +258 -0
- package/03-patterns/dropdown/README.md +78 -0
- package/03-patterns/dropdown/demo.html +101 -0
- package/03-patterns/dropdown/dropdown.css +135 -0
- package/03-patterns/dropdown/dropdown.js +451 -0
- package/03-patterns/form-validation/README.md +147 -0
- package/03-patterns/form-validation/demo.html +280 -0
- package/03-patterns/form-validation/form-validation.css +263 -0
- package/03-patterns/list/README.md +150 -0
- package/03-patterns/list/demo.html +225 -0
- package/03-patterns/list/flip.js +201 -0
- package/03-patterns/list/list.css +162 -0
- package/03-patterns/nav/README.md +225 -0
- package/03-patterns/nav/demo.html +131 -0
- package/03-patterns/nav/nav.css +314 -0
- package/03-patterns/nav/nav.js +430 -0
- package/03-patterns/nav/toc.js +111 -0
- package/03-patterns/overlay/README.md +196 -0
- package/03-patterns/overlay/demo.html +241 -0
- package/03-patterns/overlay/overlay.css +319 -0
- package/03-patterns/overlay/overlay.js +563 -0
- package/03-patterns/pagination/README.md +114 -0
- package/03-patterns/pagination/demo.html +165 -0
- package/03-patterns/pagination/pagination.css +195 -0
- package/03-patterns/pagination/pagination.js +395 -0
- package/03-patterns/reveal/README.md +91 -0
- package/03-patterns/reveal/demo.html +106 -0
- package/03-patterns/reveal/reveal.css +93 -0
- package/03-patterns/reveal/reveal.js +172 -0
- package/03-patterns/states/README.md +141 -0
- package/03-patterns/states/demo.html +240 -0
- package/03-patterns/states/states.css +252 -0
- package/03-patterns/tabs/README.md +84 -0
- package/03-patterns/tabs/demo.html +139 -0
- package/03-patterns/tabs/tabs.css +172 -0
- package/03-patterns/tabs/tabs.js +307 -0
- package/03-patterns/tooltip/README.md +96 -0
- package/03-patterns/tooltip/demo.html +78 -0
- package/03-patterns/tooltip/tooltip.css +89 -0
- package/03-patterns/tooltip/tooltip.js +288 -0
- package/03-patterns/tree/README.md +94 -0
- package/03-patterns/tree/demo.html +138 -0
- package/03-patterns/tree/tree.css +113 -0
- package/03-patterns/tree/tree.js +456 -0
- package/04-recipes/analysis-report/README.md +80 -0
- package/04-recipes/analysis-report/analysis-report.css +187 -0
- package/04-recipes/analysis-report/demo.html +274 -0
- package/04-recipes/data-showcase/README.md +45 -0
- package/04-recipes/data-showcase/demo.html +247 -0
- package/04-recipes/detail-page/README.md +93 -0
- package/04-recipes/detail-page/demo.html +55 -0
- package/04-recipes/detail-page/detail-page.css +190 -0
- package/04-recipes/detail-page/full.html +60 -0
- package/04-recipes/detail-page/null.html +60 -0
- package/04-recipes/detail-page/partial.html +60 -0
- package/04-recipes/detail-page/verify-skeleton.py +19 -0
- package/04-recipes/longform/README.md +93 -0
- package/04-recipes/longform/agc-memory.svg +4 -0
- package/04-recipes/longform/content.html +610 -0
- package/04-recipes/longform/content.md +51 -0
- package/04-recipes/longform/longform.html +627 -0
- package/04-recipes/report/README.md +176 -0
- package/04-recipes/report/demo.html +355 -0
- package/04-recipes/report/report.css +364 -0
- package/04-recipes/table/README.md +103 -0
- package/04-recipes/table/demo.html +455 -0
- package/04-recipes/table/table.css +372 -0
- package/04-recipes/tierA-tokens.css +189 -0
- package/09-assets/README.md +74 -0
- package/09-assets/bar/README.md +94 -0
- package/09-assets/bar/bar.css +166 -0
- package/09-assets/bar/bar.js +320 -0
- package/09-assets/bar/demo.html +176 -0
- package/09-assets/echarts-adapter/demo.html +192 -0
- package/09-assets/echarts-adapter/echarts-adapter.js +277 -0
- package/09-assets/model-viewer/README.md +155 -0
- package/09-assets/model-viewer/demo.html +105 -0
- package/09-assets/model-viewer/model-viewer.css +143 -0
- package/09-assets/model-viewer/model-viewer.js +423 -0
- package/09-assets/scientific-plot/README.md +94 -0
- package/09-assets/scientific-plot/demo.html +252 -0
- package/09-assets/scientific-plot/scientific-plot.css +141 -0
- package/09-assets/scientific-plot/scientific-plot.js +610 -0
- package/09-assets/sparkline/README.md +153 -0
- package/09-assets/sparkline/demo.html +163 -0
- package/09-assets/sparkline/sparkline.css +158 -0
- package/09-assets/sparkline/sparkline.js +508 -0
- package/API.md +332 -0
- package/CHANGELOG.md +3138 -0
- package/CODE_OF_CONDUCT.md +64 -0
- package/CONTRIBUTING.md +89 -0
- package/ERRORS.md +1658 -0
- package/LICENSE +21 -0
- package/README.md +497 -2
- package/SECURITY.md +72 -0
- package/START-HERE.md +164 -0
- package/SUPPORT.md +109 -0
- package/adapters/presentation/README.md +113 -0
- package/adapters/presentation/check.js +101 -0
- package/adapters/presentation/deck.schema.json +74 -0
- package/adapters/presentation/to-doc.js +138 -0
- package/ai/START-HERE.md +104 -0
- package/ai/behaviors.json +380 -0
- package/ai/behaviors.schema.json +61 -0
- package/ai/capabilities.json +56 -0
- package/ai/cli.js +387 -0
- package/ai/components.json +1944 -0
- package/ai/components.meta.json +168 -0
- package/ai/components.schema.json +220 -0
- package/ai/contract.schema.json +147 -0
- package/ai/deprecations.json +55 -0
- package/ai/deprecations.schema.json +85 -0
- package/ai/motion-policy.json +22 -0
- package/ai/patch.js +323 -0
- package/ai/patch.schema.json +63 -0
- package/ai/profiles.json +92 -0
- package/ai/tokens.audience.json +55 -0
- package/ai/tokens.audience.schema.json +73 -0
- package/ai/tokens.json +762 -0
- package/ai/tokens.schema.json +58 -0
- package/ai/tokens.tree.json +752 -0
- package/ai/tokens.tree.schema.json +56 -0
- package/ai/validate.js +383 -0
- package/dist/01-tokens/behavior/dismissable.js +60 -0
- package/dist/01-tokens/behavior/emit.js +21 -0
- package/dist/01-tokens/behavior/focus-return.js +31 -0
- package/dist/01-tokens/behavior/roving.js +77 -0
- package/dist/01-tokens/behavior/typeahead.js +61 -0
- package/dist/01-tokens/focus-ring.css +1 -0
- package/dist/01-tokens/page.css +1 -0
- package/dist/01-tokens/polyfill.js +78 -0
- package/dist/01-tokens/scrollbar.css +1 -0
- package/dist/01-tokens/theme-toggle.js +61 -0
- package/dist/01-tokens/tokens.css +1 -0
- package/dist/01-tokens/typography.css +1 -0
- package/dist/02-primitives/badge/badge.css +1 -0
- package/dist/02-primitives/button/button.css +1 -0
- package/dist/02-primitives/card/card.css +1 -0
- package/dist/02-primitives/choice/choice.css +1 -0
- package/dist/02-primitives/combobox/combobox.css +1 -0
- package/dist/02-primitives/combobox/combobox.js +439 -0
- package/dist/02-primitives/date-range/date-range.css +1 -0
- package/dist/02-primitives/date-range/date-range.js +267 -0
- package/dist/02-primitives/input/input.css +1 -0
- package/dist/02-primitives/popover/popover.css +1 -0
- package/dist/02-primitives/popover/popover.js +257 -0
- package/dist/02-primitives/progress/progress.css +1 -0
- package/dist/02-primitives/select/select.css +1 -0
- package/dist/02-primitives/select/select.js +449 -0
- package/dist/02-primitives/separator/separator.css +1 -0
- package/dist/02-primitives/skeleton/skeleton.css +1 -0
- package/dist/02-primitives/switch/switch.css +1 -0
- package/dist/03-patterns/accordion/accordion.css +1 -0
- package/dist/03-patterns/accordion/accordion.js +219 -0
- package/dist/03-patterns/content/content.css +1 -0
- package/dist/03-patterns/drawer/drawer.css +1 -0
- package/dist/03-patterns/drawer/drawer.js +229 -0
- package/dist/03-patterns/dropdown/dropdown.css +1 -0
- package/dist/03-patterns/dropdown/dropdown.js +365 -0
- package/dist/03-patterns/form-validation/form-validation.css +1 -0
- package/dist/03-patterns/list/flip.js +117 -0
- package/dist/03-patterns/list/list.css +1 -0
- package/dist/03-patterns/nav/nav.css +1 -0
- package/dist/03-patterns/nav/nav.js +322 -0
- package/dist/03-patterns/nav/toc.js +76 -0
- package/dist/03-patterns/overlay/overlay.css +1 -0
- package/dist/03-patterns/overlay/overlay.js +398 -0
- package/dist/03-patterns/pagination/pagination.css +1 -0
- package/dist/03-patterns/pagination/pagination.js +273 -0
- package/dist/03-patterns/reveal/reveal.css +1 -0
- package/dist/03-patterns/reveal/reveal.js +138 -0
- package/dist/03-patterns/states/states.css +1 -0
- package/dist/03-patterns/tabs/tabs.css +1 -0
- package/dist/03-patterns/tabs/tabs.js +242 -0
- package/dist/03-patterns/tooltip/tooltip.css +1 -0
- package/dist/03-patterns/tooltip/tooltip.js +213 -0
- package/dist/03-patterns/tree/tree.css +1 -0
- package/dist/03-patterns/tree/tree.js +383 -0
- package/dist/04-recipes/analysis-report/analysis-report.css +1 -0
- package/dist/04-recipes/detail-page/detail-page.css +1 -0
- package/dist/04-recipes/report/report.css +1 -0
- package/dist/04-recipes/table/table.css +1 -0
- package/dist/04-recipes/tierA-tokens.css +1 -0
- package/dist/09-assets/bar/bar.css +1 -0
- package/dist/09-assets/bar/bar.js +222 -0
- package/dist/09-assets/echarts-adapter/echarts-adapter.js +185 -0
- package/dist/09-assets/model-viewer/model-viewer.css +1 -0
- package/dist/09-assets/model-viewer/model-viewer.js +320 -0
- package/dist/09-assets/scientific-plot/scientific-plot.css +1 -0
- package/dist/09-assets/scientific-plot/scientific-plot.js +568 -0
- package/dist/09-assets/sparkline/sparkline.css +1 -0
- package/dist/09-assets/sparkline/sparkline.js +265 -0
- package/dist/COSTS.md +56 -0
- package/docs/AI-CONTRACT.md +197 -0
- package/docs/BACKLOG.md +127 -0
- package/docs/BENCHMARK.md +252 -0
- package/docs/GUIDANCE.md +154 -0
- package/docs/INVARIANT.md +372 -0
- package/docs/LAYER-BASELINE.md +158 -0
- package/docs/RELEASING.md +311 -0
- package/docs/RFC-THEME-SCOPE.md +141 -0
- package/docs/ROADMAP.md +182 -0
- package/index.html +82 -0
- package/package.json +107 -4
- package/types/index.d.ts +310 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<link rel="icon" href="data:,">
|
|
7
|
+
<title>scientific-plot · 二维科学绘图 · frontend-lib</title>
|
|
8
|
+
<link rel="stylesheet" href="../../01-tokens/tokens.css">
|
|
9
|
+
<link rel="stylesheet" href="../../01-tokens/typography.css">
|
|
10
|
+
<link rel="stylesheet" href="../../01-tokens/page.css">
|
|
11
|
+
<link rel="stylesheet" href="scientific-plot.css">
|
|
12
|
+
<style>
|
|
13
|
+
/* 示例页自己的排布;不属于组件样式 */
|
|
14
|
+
.fig { margin: 0 0 var(--sp-6); }
|
|
15
|
+
.fig__cap { font-size: var(--fs-sm); color: var(--text-secondary); margin: var(--sp-2) 0 0; }
|
|
16
|
+
.fig__box { border: 1px solid var(--border-decor); border-radius: var(--r-md);
|
|
17
|
+
padding: var(--sp-3); background: var(--surface); overflow-x: auto; }
|
|
18
|
+
.data-sum { font-size: var(--fs-xs); color: var(--text-tertiary); margin: var(--sp-2) 0 0; }
|
|
19
|
+
.data-sum table { border-collapse: collapse; }
|
|
20
|
+
.data-sum th, .data-sum td { padding: 2px var(--sp-3) 2px 0; text-align: start; }
|
|
21
|
+
.data-sum td.num { font-variant-numeric: tabular-nums; }
|
|
22
|
+
</style>
|
|
23
|
+
</head>
|
|
24
|
+
<body class="page">
|
|
25
|
+
<main class="wrap">
|
|
26
|
+
|
|
27
|
+
<h1>scientific-plot · 二维科学绘图</h1>
|
|
28
|
+
<p class="lede">
|
|
29
|
+
坐标轴、单位、刻度、误差棒、置信区间带 —— 用原生 SVG 画,
|
|
30
|
+
零第三方运行时依赖。<strong>本模块不计算任何统计量</strong>,
|
|
31
|
+
它只把调用方给的数画在正确的位置上。
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
<!-- ==================================================================== -->
|
|
35
|
+
<h2 class="rule-top">1 · 函数曲线与坐标轴</h2>
|
|
36
|
+
<p class="note">
|
|
37
|
+
阻尼振荡 <code>y(t) = A·e^(−λt)·cos(2πft)</code>。
|
|
38
|
+
曲线是<strong>采样</strong>出来的数据点 —— 调用方传的是函数,不是字符串表达式,
|
|
39
|
+
本模块<strong>不做表达式求值</strong>。
|
|
40
|
+
</p>
|
|
41
|
+
<figure class="fig">
|
|
42
|
+
<div class="fig__box" id="fig1"></div>
|
|
43
|
+
<figcaption class="fig__cap">
|
|
44
|
+
图 1 · 阻尼振荡位移随时间的变化。A = 1.00 m,λ = 0.35 s⁻¹,f = 1.20 Hz。
|
|
45
|
+
</figcaption>
|
|
46
|
+
</figure>
|
|
47
|
+
|
|
48
|
+
<!-- ==================================================================== -->
|
|
49
|
+
<h2 class="rule-top">2 · 离散测量 + 误差棒</h2>
|
|
50
|
+
<p class="note">
|
|
51
|
+
误差棒画的是<strong>调用方给的</strong>误差边界。本模块不判断它表示标准差还是标准误,
|
|
52
|
+
也不据此推断显著性 —— 这两件事必须由测量者说清楚。
|
|
53
|
+
</p>
|
|
54
|
+
<figure class="fig">
|
|
55
|
+
<div class="fig__box" id="fig2"></div>
|
|
56
|
+
<figcaption class="fig__cap">
|
|
57
|
+
图 2 · 五种催化剂在不同温度下的转化率(示例数据,误差棒为 ±1 个测量标准差)。
|
|
58
|
+
</figcaption>
|
|
59
|
+
</figure>
|
|
60
|
+
|
|
61
|
+
<!-- ==================================================================== -->
|
|
62
|
+
<h2 class="rule-top">3 · 折线 + 置信区间带 + 参考线</h2>
|
|
63
|
+
<p class="note">
|
|
64
|
+
区间带是<strong>调用方算好的上下边界</strong>。图上的水平虚线是工艺控制下限。
|
|
65
|
+
</p>
|
|
66
|
+
<figure class="fig">
|
|
67
|
+
<div class="fig__box" id="fig3"></div>
|
|
68
|
+
<figcaption class="fig__cap">
|
|
69
|
+
图 3 · 反应收率随生产批号的走势与 95% 置信区间(示例数据)。
|
|
70
|
+
</figcaption>
|
|
71
|
+
</figure>
|
|
72
|
+
|
|
73
|
+
<!-- ==================================================================== -->
|
|
74
|
+
<h2 class="rule-top">4 · 对数坐标</h2>
|
|
75
|
+
<p class="note">
|
|
76
|
+
对数轴<strong>必须显式声明</strong>。跨度跨 6 个数量级时自动只保留 10 的幂做刻度,
|
|
77
|
+
避免标签挤成一团。若给对数轴一个 ≤ 0 的边界,模块会<strong>直接报错</strong>而不是悄悄修正。
|
|
78
|
+
</p>
|
|
79
|
+
<figure class="fig">
|
|
80
|
+
<div class="fig__box" id="fig4"></div>
|
|
81
|
+
<figcaption class="fig__cap">
|
|
82
|
+
图 4 · 细菌培养液浓度随时间变化(对数纵轴,示例数据)。
|
|
83
|
+
</figcaption>
|
|
84
|
+
</figure>
|
|
85
|
+
|
|
86
|
+
<h2 class="rule-top">4b · 对数轴上的无效数据(≤ 0)必须明说</h2>
|
|
87
|
+
<p class="note">
|
|
88
|
+
对数轴上 <code>0</code> 和负数<strong>没有位置</strong>。这里的做法不是"悄悄当成一个很小的正数"
|
|
89
|
+
(那会画出一条看起来正常、实际是假的线),也不是"静默丢掉"(读者会以为那里本来就没测):
|
|
90
|
+
曲线<strong>断在这两个点两侧</strong>,并且图上明写"有几个点未绘制"。
|
|
91
|
+
</p>
|
|
92
|
+
<figure class="fig">
|
|
93
|
+
<div class="fig__box" id="figLogBad"></div>
|
|
94
|
+
<figcaption class="fig__cap">
|
|
95
|
+
图 4b · 测值含 0 与负值的情形(示例数据)。第 4 点为 0、第 7 点为负,两者都不在 log 轴上。
|
|
96
|
+
</figcaption>
|
|
97
|
+
</figure>
|
|
98
|
+
|
|
99
|
+
<!-- ==================================================================== -->
|
|
100
|
+
<h2 class="rule-top">5 · 缺失值 ≠ 零(这一节是反例自证)</h2>
|
|
101
|
+
<p class="note">
|
|
102
|
+
两个序列的<strong>非缺失数据完全相同</strong>,只有缺失的处理方式不同:
|
|
103
|
+
左边把 <code>null</code> 当缺失 ⇒ 曲线<strong>断开</strong>;
|
|
104
|
+
右边把缺失当 <code>0</code> ⇒ 曲线<strong>掉到零再爬回来</strong>。
|
|
105
|
+
后者画出的是一段<strong>不存在的趋势</strong>。
|
|
106
|
+
</p>
|
|
107
|
+
<figure class="fig">
|
|
108
|
+
<div class="fig__box" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:var(--sp-3)">
|
|
109
|
+
<div id="figGap"></div>
|
|
110
|
+
<div id="figZero"></div>
|
|
111
|
+
</div>
|
|
112
|
+
<figcaption class="fig__cap">
|
|
113
|
+
图 5 · 同一组数据,两种缺失处理。左:缺失断开(正确)。右:缺失当 0(错误,仅用于对照)。
|
|
114
|
+
</figcaption>
|
|
115
|
+
</figure>
|
|
116
|
+
|
|
117
|
+
<div class="data-sum" id="textEquiv"></div>
|
|
118
|
+
|
|
119
|
+
</main>
|
|
120
|
+
|
|
121
|
+
<script src="scientific-plot.js"></script>
|
|
122
|
+
<script>
|
|
123
|
+
(function () {
|
|
124
|
+
'use strict';
|
|
125
|
+
var P = window.ScientificPlot;
|
|
126
|
+
|
|
127
|
+
/* ---------------------------------------------------- 图 1:阻尼振荡 */
|
|
128
|
+
function damped(t) {
|
|
129
|
+
return 1.00 * Math.exp(-0.35 * t) * Math.cos(2 * Math.PI * 1.20 * t);
|
|
130
|
+
}
|
|
131
|
+
P.render(document.getElementById('fig1'), {
|
|
132
|
+
width: 680, height: 340,
|
|
133
|
+
title: '阻尼振荡位移',
|
|
134
|
+
desc: '采样 400 点',
|
|
135
|
+
x: { label: '时间', unit: 's', scale: 'linear', domain: [0, 4] },
|
|
136
|
+
y: { label: '位移', unit: 'm', scale: 'linear', domain: [-1.1, 1.1] },
|
|
137
|
+
series: [{ type: 'function', fn: damped, domain: [0, 4], samples: 400 }],
|
|
138
|
+
refs: [{ axis: 'y', value: 0 }]
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
/* --------------------------------------- 图 2:离散测量 + 误差棒 */
|
|
142
|
+
var T = [300, 320, 340, 360, 380, 400];
|
|
143
|
+
var catA = [[300, 12, 3], [320, 21, 4], [340, 33, 5], [360, 41, 4], [380, 47, 6], [400, 52, 5]];
|
|
144
|
+
var catB = [[300, 8, 2], [320, 15, 3], [340, 24, 3], [360, 35, 4], [380, 44, 5], [400, 50, 6]];
|
|
145
|
+
void T;
|
|
146
|
+
P.render(document.getElementById('fig2'), {
|
|
147
|
+
width: 680, height: 340,
|
|
148
|
+
title: '催化剂转化率',
|
|
149
|
+
desc: '误差棒为 ±1 标准差',
|
|
150
|
+
x: { label: '温度', unit: 'K', scale: 'linear', domain: [290, 410] },
|
|
151
|
+
y: { label: '转化率', unit: '%', scale: 'linear', domain: [0, 60] },
|
|
152
|
+
/* 🔴 errorbar 与 line 是**同一个系列**(同一种催化剂的测量值 + 走势)
|
|
153
|
+
⇒ 名字必须一样,它们才会共用一个色号 */
|
|
154
|
+
series: [
|
|
155
|
+
{ type: 'errorbar', data: catA, name: '催化剂 A' },
|
|
156
|
+
{ type: 'line', data: catA, name: '催化剂 A' },
|
|
157
|
+
{ type: 'errorbar', data: catB, name: '催化剂 B' },
|
|
158
|
+
{ type: 'line', data: catB, name: '催化剂 B' }
|
|
159
|
+
]
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
/* ------------------------- 图 3:折线 + 置信区间带 + 参考线 */
|
|
163
|
+
var batches = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
|
164
|
+
var yieldMid = [71.2, 73.5, 72.8, 75.1, 76.4, 74.9, 77.2, 78.1, 77.6, 79.3, 80.1, 79.8];
|
|
165
|
+
var yieldBand = yieldMid.map(function (v, i) {
|
|
166
|
+
var hw = 2.6 - i * 0.09; /* 样本越多、估计越稳 —— 这是**调用方**给的半宽 */
|
|
167
|
+
return [batches[i], v - hw, v + hw];
|
|
168
|
+
});
|
|
169
|
+
P.render(document.getElementById('fig3'), {
|
|
170
|
+
width: 680, height: 340,
|
|
171
|
+
title: '反应收率走势',
|
|
172
|
+
desc: '阴影为 95% 置信区间',
|
|
173
|
+
x: { label: '批号', scale: 'linear', domain: [1, 12] },
|
|
174
|
+
y: { label: '收率', unit: '%', scale: 'linear', domain: [66, 84] },
|
|
175
|
+
/* 带 / 线 / 点属于**同一个**系列 ⇒ 同一份名字 ⇒ 同一支色 */
|
|
176
|
+
series: [
|
|
177
|
+
{ type: 'band', data: yieldBand, name: '批次收率' },
|
|
178
|
+
{ type: 'line', data: batches.map(function (b, i) { return [b, yieldMid[i]]; }),
|
|
179
|
+
name: '批次收率' },
|
|
180
|
+
{ type: 'scatter', data: batches.map(function (b, i) { return [b, yieldMid[i]]; }),
|
|
181
|
+
name: '批次收率' }
|
|
182
|
+
],
|
|
183
|
+
refs: [{ axis: 'y', value: 72, label: '控制下限 72%' }]
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
/* ------------------------------------------------------ 图 4:对数坐标 */
|
|
187
|
+
var hours = [0, 2, 4, 6, 8, 10, 12, 14, 16];
|
|
188
|
+
var cfu = [1.2e2, 3.4e2, 9.8e2, 2.9e3, 8.6e3, 2.5e4, 7.4e4, 2.1e5, 6.0e5];
|
|
189
|
+
P.render(document.getElementById('fig4'), {
|
|
190
|
+
width: 680, height: 340,
|
|
191
|
+
title: '菌液浓度增长',
|
|
192
|
+
desc: '对数纵轴,跨度跨 4 个数量级',
|
|
193
|
+
x: { label: '培养时间', unit: 'h', scale: 'linear', domain: [0, 16] },
|
|
194
|
+
y: { label: '浓度', unit: 'CFU/mL', scale: 'log', domain: [1e2, 1e6] },
|
|
195
|
+
series: [{ type: 'line', data: hours.map(function (h, i) { return [h, cfu[i]]; }),
|
|
196
|
+
name: '实测值' },
|
|
197
|
+
{ type: 'scatter', data: hours.map(function (h, i) { return [h, cfu[i]]; }),
|
|
198
|
+
name: '实测值' }]
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
/* --------------------- 图 4b:对数轴上的无效数据必须**明说**
|
|
202
|
+
------------------------------------------------------------------
|
|
203
|
+
对数轴上 ≤0 的值**没有位置**(log(0) 没有定义)。三种做法的差别:
|
|
204
|
+
· 悄悄把它当成一个很小的正数 ⇒ 画出一条看起来正常、**实际是假**的线
|
|
205
|
+
· 直接扔掉 ⇒ 读者以为"这里本来就没有点"
|
|
206
|
+
· 【本图采用】断在这两点两侧,并在图上写出"有几个点未绘制"
|
|
207
|
+
⇒ 这也是"异常数据不变成误导图形"的验收点。 */
|
|
208
|
+
var badY = [[1, 3.2e2], [2, 5.6e2], [3, 9.1e2],
|
|
209
|
+
[4, 0], /* ← 0:对数轴上没有位置 */
|
|
210
|
+
[5, 2.7e3], [6, 4.4e3],
|
|
211
|
+
[7, -5], /* ← 负数:同样没有位置 */
|
|
212
|
+
[8, 1.9e4], [9, 5.8e4]];
|
|
213
|
+
P.render(document.getElementById('figLogBad'), {
|
|
214
|
+
width: 680, height: 300,
|
|
215
|
+
title: '对数轴遇到 ≤0:断开 + 明确提示',
|
|
216
|
+
desc: '第 4 点测值为 0、第 7 点为负,均无法在 log 轴上定位',
|
|
217
|
+
x: { label: '培养时间', unit: 'h', scale: 'linear', domain: [0, 10] },
|
|
218
|
+
y: { label: '计数', unit: 'CFU/mL', scale: 'log', domain: [1e2, 1e5] },
|
|
219
|
+
series: [{ type: 'line', data: badY, name: '实测值' },
|
|
220
|
+
{ type: 'scatter', data: badY, name: '实测值' }]
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
/* --------------------------------- 图 5:缺失值断开 vs 当零(反例对照) */
|
|
224
|
+
var signal = [[0, 12], [1, 14], [2, null], [3, null], [4, 21], [5, 24], [6, 22]];
|
|
225
|
+
var asZero = signal.map(function (p) { return [p[0], p[1] === null ? 0 : p[1]]; });
|
|
226
|
+
|
|
227
|
+
P.render(document.getElementById('figGap'), {
|
|
228
|
+
width: 460, height: 300,
|
|
229
|
+
title: '缺失断开(正确)',
|
|
230
|
+
x: { label: '采样点', scale: 'linear', domain: [0, 6] },
|
|
231
|
+
y: { label: '读数', scale: 'linear', domain: [0, 30] },
|
|
232
|
+
series: [{ type: 'line', data: signal }, { type: 'scatter', data: signal }]
|
|
233
|
+
});
|
|
234
|
+
P.render(document.getElementById('figZero'), {
|
|
235
|
+
width: 460, height: 300,
|
|
236
|
+
title: '缺失当 0(错误,仅对照)',
|
|
237
|
+
x: { label: '采样点', scale: 'linear', domain: [0, 6] },
|
|
238
|
+
y: { label: '读数', scale: 'linear', domain: [0, 30] },
|
|
239
|
+
series: [{ type: 'line', data: asZero }, { type: 'scatter', data: asZero }]
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
/* --------------------------- 文本等价信息(原则⑤:结论不能只在图里) */
|
|
243
|
+
document.getElementById('textEquiv').innerHTML =
|
|
244
|
+
'<strong>图 5 的文本等价说明:</strong>' +
|
|
245
|
+
'采样点 2、3 处没有读数(缺失)。左图把这两点之间<strong>断开</strong>,' +
|
|
246
|
+
'读者看到的是"中间没有数据";右图把它们画成 0,' +
|
|
247
|
+
'读者看到的是"信号掉到零又回升"—— 后者是一个<strong>不存在的事件</strong>。' +
|
|
248
|
+
'两张图用的是同一组非缺失数据。';
|
|
249
|
+
})();
|
|
250
|
+
</script>
|
|
251
|
+
</body>
|
|
252
|
+
</html>
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/* ============================================================================
|
|
2
|
+
scientific-plot.css — 二维科学绘图样式(零依赖 · 纯令牌驱动)
|
|
3
|
+
============================================================================
|
|
4
|
+
依赖:01-tokens/tokens.css
|
|
5
|
+
🔴 全部颜色走令牌:
|
|
6
|
+
- 换主题(明/暗)时图表跟着变,不需要重画
|
|
7
|
+
- 本文件的色值一处都不写死(hardcode-gate 会拦)
|
|
8
|
+
|
|
9
|
+
🔴 分类色只有 5 个(--splot-s0..s4),超出的曲线靠**线型**区分,
|
|
10
|
+
不循环用色 —— 第 6 条和第 1 条同色,读者分不清谁是谁。
|
|
11
|
+
这与 09-assets/echarts-adapter 的 seriesColors 是同一条规则。
|
|
12
|
+
============================================================================ */
|
|
13
|
+
|
|
14
|
+
.splot {
|
|
15
|
+
display: block;
|
|
16
|
+
max-width: 100%;
|
|
17
|
+
height: auto; /* 窄屏时按比例缩,不横向溢出 */
|
|
18
|
+
font-family: var(--sans);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* ---------- 分类色:一个系列一个变量,各元素消费它 ---------- */
|
|
22
|
+
.splot__s0 { --splot-c: var(--accent); }
|
|
23
|
+
.splot__s1 { --splot-c: var(--danger); }
|
|
24
|
+
.splot__s2 { --splot-c: var(--success); }
|
|
25
|
+
.splot__s3 { --splot-c: var(--warning); }
|
|
26
|
+
.splot__s4 { --splot-c: var(--info); }
|
|
27
|
+
|
|
28
|
+
/* ---------- 网格与轴 ---------- */
|
|
29
|
+
.splot__grid {
|
|
30
|
+
stroke: var(--border-decor);
|
|
31
|
+
stroke-width: 1;
|
|
32
|
+
}
|
|
33
|
+
.splot__axis {
|
|
34
|
+
stroke: var(--border-decor-str);
|
|
35
|
+
stroke-width: 1;
|
|
36
|
+
}
|
|
37
|
+
.splot__tick {
|
|
38
|
+
stroke: var(--border-decor-str);
|
|
39
|
+
stroke-width: 1;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ---------- 文字:刻度 / 轴名 ---------- */
|
|
43
|
+
.splot__tick-label {
|
|
44
|
+
fill: var(--text-tertiary);
|
|
45
|
+
font-size: var(--fs-xs);
|
|
46
|
+
font-variant-numeric: tabular-nums;
|
|
47
|
+
}
|
|
48
|
+
.splot__axis-label {
|
|
49
|
+
fill: var(--text-secondary);
|
|
50
|
+
font-size: var(--fs-xs);
|
|
51
|
+
font-weight: 500;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* ---------- 数据:线 / 点 / 误差棒 / 区间带 ---------- */
|
|
55
|
+
.splot__line {
|
|
56
|
+
fill: none;
|
|
57
|
+
stroke: var(--splot-c, var(--accent));
|
|
58
|
+
stroke-width: 2;
|
|
59
|
+
stroke-linejoin: round;
|
|
60
|
+
stroke-linecap: round;
|
|
61
|
+
}
|
|
62
|
+
.splot__pt {
|
|
63
|
+
fill: var(--splot-c, var(--accent));
|
|
64
|
+
stroke: var(--surface); /* 点压在线上时留一圈底,避免和线糊在一起 */
|
|
65
|
+
stroke-width: 1;
|
|
66
|
+
}
|
|
67
|
+
.splot__err {
|
|
68
|
+
stroke: var(--splot-c, var(--accent));
|
|
69
|
+
stroke-width: 1.5;
|
|
70
|
+
stroke-linecap: round;
|
|
71
|
+
}
|
|
72
|
+
.splot__band {
|
|
73
|
+
fill: var(--splot-c, var(--accent));
|
|
74
|
+
fill-opacity: .14; /* 区间带要能被下面的网格透出来 */
|
|
75
|
+
stroke: none;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* ---------- 图例 ---------- *
|
|
79
|
+
🔴 为什么要有:颜色**不是**自解释的。三条不同颜色的曲线但没有名字,
|
|
80
|
+
这张图就答不出"哪条是哪个"。色号由系列类提供 ⇒ 不可能与图上的线不一致。 */
|
|
81
|
+
.splot__legend {
|
|
82
|
+
display: flex;
|
|
83
|
+
flex-wrap: wrap;
|
|
84
|
+
gap: var(--sp-2) var(--sp-4, 1rem);
|
|
85
|
+
margin: var(--sp-2) 0 0;
|
|
86
|
+
padding: 0;
|
|
87
|
+
list-style: none;
|
|
88
|
+
font-size: var(--fs-xs);
|
|
89
|
+
color: var(--text-secondary);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.splot__legend-item {
|
|
93
|
+
display: inline-flex;
|
|
94
|
+
align-items: center;
|
|
95
|
+
gap: var(--sp-1);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.splot__legend-mark {
|
|
99
|
+
flex: 0 0 auto;
|
|
100
|
+
overflow: visible;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.splot__legend-mark line {
|
|
104
|
+
stroke: var(--splot-c, var(--accent));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* ---------- 参考线 / 标注 / 备注 ---------- */
|
|
108
|
+
.splot__ref {
|
|
109
|
+
stroke: var(--text-tertiary);
|
|
110
|
+
stroke-width: 1;
|
|
111
|
+
stroke-dasharray: 4 4;
|
|
112
|
+
}
|
|
113
|
+
.splot__ref-label {
|
|
114
|
+
fill: var(--text-tertiary);
|
|
115
|
+
font-size: var(--fs-xs);
|
|
116
|
+
}
|
|
117
|
+
.splot__anno-dot {
|
|
118
|
+
fill: var(--text-primary);
|
|
119
|
+
}
|
|
120
|
+
.splot__anno {
|
|
121
|
+
fill: var(--text-primary);
|
|
122
|
+
font-size: var(--fs-xs);
|
|
123
|
+
font-weight: 600;
|
|
124
|
+
}
|
|
125
|
+
.splot__note {
|
|
126
|
+
fill: var(--warning);
|
|
127
|
+
font-size: var(--fs-xs);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* ---------- 高对比度模式:加粗轴与线,避免糊在一起 ---------- */
|
|
131
|
+
@media (prefers-contrast: more) {
|
|
132
|
+
.splot__axis,
|
|
133
|
+
.splot__tick { stroke: var(--text-primary); }
|
|
134
|
+
.splot__line { stroke-width: 3; }
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* ---------- 打印:网格退到更浅,线保持清晰 ---------- */
|
|
138
|
+
@media print {
|
|
139
|
+
.splot__grid { stroke: var(--border-decor); }
|
|
140
|
+
.splot__band { fill-opacity: .22; }
|
|
141
|
+
}
|