@hsu-react/ui 2.3.0 → 2.4.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.
- package/es/build/webpack.d.ts +40 -0
- package/es/build/webpack.js +43 -0
- package/es/components/Chart/Bar/index.js +12 -5
- package/es/components/Chart/Heatmap/index.js +12 -4
- package/es/components/Chart/Line/index.js +12 -4
- package/es/components/Chart/_utils/cartesian.d.ts +3 -2
- package/es/components/Chart/_utils/cartesian.js +9 -10
- package/es/components/Chart/_utils/chartTheme.d.ts +22 -0
- package/es/components/Chart/_utils/chartTheme.js +23 -0
- package/es/components/Chart/_utils/heatmap.d.ts +3 -2
- package/es/components/Chart/_utils/heatmap.js +7 -10
- package/es/components/Panel/ListPanel/ListModalPanel/index.module.scss +10 -0
- package/lib/build/webpack.d.ts +40 -0
- package/lib/build/webpack.js +48 -0
- package/lib/components/Chart/Bar/index.js +10 -5
- package/lib/components/Chart/Heatmap/index.js +10 -4
- package/lib/components/Chart/Line/index.js +10 -4
- package/lib/components/Chart/_utils/cartesian.d.ts +3 -2
- package/lib/components/Chart/_utils/cartesian.js +9 -11
- package/lib/components/Chart/_utils/chartTheme.d.ts +22 -0
- package/lib/components/Chart/_utils/chartTheme.js +29 -0
- package/lib/components/Chart/_utils/heatmap.d.ts +3 -2
- package/lib/components/Chart/_utils/heatmap.js +7 -10
- package/lib/components/Panel/ListPanel/ListModalPanel/index.module.scss +10 -0
- package/lib/package.json +3 -0
- package/package.json +3 -3
- package/src/build/webpack.ts +44 -0
- package/src/components/Chart/Bar/index.tsx +10 -4
- package/src/components/Chart/Heatmap/index.tsx +10 -3
- package/src/components/Chart/Line/index.tsx +10 -3
- package/src/components/Chart/_utils/cartesian.ts +11 -10
- package/src/components/Chart/_utils/chartTheme.ts +34 -0
- package/src/components/Chart/_utils/heatmap.ts +10 -10
- package/src/components/Panel/ListPanel/ListModalPanel/index.module.scss +10 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 给消费方 webpack 配置用的工具。**构建期模块,不要从应用代码里引**
|
|
3
|
+
* —— 它不依赖 React,也不该进运行时产物。
|
|
4
|
+
*
|
|
5
|
+
* ```js
|
|
6
|
+
* // webpack.config.js(CJS)
|
|
7
|
+
* const { excludeNodeModulesExceptHsuUi } = require("@hsu-react/ui/lib/build/webpack");
|
|
8
|
+
*
|
|
9
|
+
* { test: /\.scss$/, exclude: excludeNodeModulesExceptHsuUi, use: [...] }
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* 判断一个模块路径「是否该被 loader 排除」:node_modules 一律排除,但放行本库。
|
|
14
|
+
*
|
|
15
|
+
* ## 为什么需要它
|
|
16
|
+
*
|
|
17
|
+
* 本库的 es / lib 产物里带着**未编译的 `.module.scss`** 和图片资源,要由消费方自己的
|
|
18
|
+
* loader 处理(这样 CSS Module 的类名哈希、`getLocalIdent` 等策略才由消费方说了算)。
|
|
19
|
+
* 于是每个 webpack 项目都得在 scss / 图片规则上开一个「排除 node_modules,但放行
|
|
20
|
+
* @hsu-react/ui」的例外。
|
|
21
|
+
*
|
|
22
|
+
* ## 为什么不能用正则
|
|
23
|
+
*
|
|
24
|
+
* 手写的版本几乎都是 `/node_modules\/(?!@hsu-react\/ui\/)/`。它只看**第一个**
|
|
25
|
+
* node_modules 后面跟着什么——扁平安装(yarn / npm)下确实是 `@hsu-react/ui/`,
|
|
26
|
+
* 但 pnpm 的真实路径是
|
|
27
|
+
*
|
|
28
|
+
* ```
|
|
29
|
+
* node_modules/.pnpm/@hsu-react+ui@<版本>/node_modules/@hsu-react/ui/es/...
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* 跟着的是 `.pnpm/`,否定前瞻立刻失败,本库的 scss 与图片会被**全部排除**,
|
|
33
|
+
* 报「no loaders are configured to process this file」。这个坑在四个下游项目里
|
|
34
|
+
* 各踩过一次,所以把判定收进库里导出,消费方引用而不是各抄一份。
|
|
35
|
+
*
|
|
36
|
+
* 改按「整条路径里有没有 @hsu-react/ui」判断,扁平与嵌套两种布局都成立;
|
|
37
|
+
* 路径分隔符同时接受 `/` 与 `\`,Windows 下同样有效。
|
|
38
|
+
*/
|
|
39
|
+
export declare const excludeNodeModulesExceptHsuUi: (modulePath: string) => boolean;
|
|
40
|
+
export default excludeNodeModulesExceptHsuUi;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 给消费方 webpack 配置用的工具。**构建期模块,不要从应用代码里引**
|
|
3
|
+
* —— 它不依赖 React,也不该进运行时产物。
|
|
4
|
+
*
|
|
5
|
+
* ```js
|
|
6
|
+
* // webpack.config.js(CJS)
|
|
7
|
+
* const { excludeNodeModulesExceptHsuUi } = require("@hsu-react/ui/lib/build/webpack");
|
|
8
|
+
*
|
|
9
|
+
* { test: /\.scss$/, exclude: excludeNodeModulesExceptHsuUi, use: [...] }
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 判断一个模块路径「是否该被 loader 排除」:node_modules 一律排除,但放行本库。
|
|
15
|
+
*
|
|
16
|
+
* ## 为什么需要它
|
|
17
|
+
*
|
|
18
|
+
* 本库的 es / lib 产物里带着**未编译的 `.module.scss`** 和图片资源,要由消费方自己的
|
|
19
|
+
* loader 处理(这样 CSS Module 的类名哈希、`getLocalIdent` 等策略才由消费方说了算)。
|
|
20
|
+
* 于是每个 webpack 项目都得在 scss / 图片规则上开一个「排除 node_modules,但放行
|
|
21
|
+
* @hsu-react/ui」的例外。
|
|
22
|
+
*
|
|
23
|
+
* ## 为什么不能用正则
|
|
24
|
+
*
|
|
25
|
+
* 手写的版本几乎都是 `/node_modules\/(?!@hsu-react\/ui\/)/`。它只看**第一个**
|
|
26
|
+
* node_modules 后面跟着什么——扁平安装(yarn / npm)下确实是 `@hsu-react/ui/`,
|
|
27
|
+
* 但 pnpm 的真实路径是
|
|
28
|
+
*
|
|
29
|
+
* ```
|
|
30
|
+
* node_modules/.pnpm/@hsu-react+ui@<版本>/node_modules/@hsu-react/ui/es/...
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* 跟着的是 `.pnpm/`,否定前瞻立刻失败,本库的 scss 与图片会被**全部排除**,
|
|
34
|
+
* 报「no loaders are configured to process this file」。这个坑在四个下游项目里
|
|
35
|
+
* 各踩过一次,所以把判定收进库里导出,消费方引用而不是各抄一份。
|
|
36
|
+
*
|
|
37
|
+
* 改按「整条路径里有没有 @hsu-react/ui」判断,扁平与嵌套两种布局都成立;
|
|
38
|
+
* 路径分隔符同时接受 `/` 与 `\`,Windows 下同样有效。
|
|
39
|
+
*/
|
|
40
|
+
export var excludeNodeModulesExceptHsuUi = function excludeNodeModulesExceptHsuUi(modulePath) {
|
|
41
|
+
return /node_modules/.test(modulePath) && !/@hsu-react[\\/]ui[\\/]/.test(modulePath);
|
|
42
|
+
};
|
|
43
|
+
export default excludeNodeModulesExceptHsuUi;
|
|
@@ -13,6 +13,8 @@ import styles from "../index.module.scss";
|
|
|
13
13
|
import { autoScrollLegend } from "../_utils/autoScrollLegend";
|
|
14
14
|
import { autoScrollByItem } from "../_utils/autoSmooth";
|
|
15
15
|
import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, percentWindowToIndexWindow, resolveScrollConfig } from "../_utils/cartesian";
|
|
16
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
17
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
16
18
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
19
|
var ChartBar = function ChartBar(props) {
|
|
18
20
|
var className = props.className,
|
|
@@ -50,12 +52,18 @@ var ChartBar = function ChartBar(props) {
|
|
|
50
52
|
var normalizedScroll = useMemo(function () {
|
|
51
53
|
return resolveScrollConfig(scrollConfig);
|
|
52
54
|
}, [scrollConfig]);
|
|
55
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
56
|
+
// legend colours have to be resolved against the active appearance here
|
|
57
|
+
var isDark = useIsDark();
|
|
58
|
+
var chrome = useMemo(function () {
|
|
59
|
+
return resolveChartChrome(isDark);
|
|
60
|
+
}, [isDark]);
|
|
53
61
|
|
|
54
62
|
// Cache the chart option with useMemo
|
|
55
63
|
var chartOption = useMemo(function () {
|
|
56
64
|
var _xAxisData$length, _ref, _ref2;
|
|
57
|
-
var def_xAxis = createDefaultCategoryXAxis(xAxisData);
|
|
58
|
-
var def_yAxis = createDefaultValueYAxis("bar");
|
|
65
|
+
var def_xAxis = createDefaultCategoryXAxis(xAxisData, chrome);
|
|
66
|
+
var def_yAxis = createDefaultValueYAxis("bar", chrome);
|
|
59
67
|
|
|
60
68
|
// Process xAxis config
|
|
61
69
|
var processedXAxis = Array.isArray(xAxis) ? xAxis === null || xAxis === void 0 ? void 0 : xAxis.map(function (item) {
|
|
@@ -150,8 +158,7 @@ var ChartBar = function ChartBar(props) {
|
|
|
150
158
|
data: legendData,
|
|
151
159
|
icon: "circle",
|
|
152
160
|
textStyle: {
|
|
153
|
-
color:
|
|
154
|
-
fontSize: 16
|
|
161
|
+
color: chrome.text
|
|
155
162
|
},
|
|
156
163
|
itemWidth: 8,
|
|
157
164
|
itemHeight: 8
|
|
@@ -175,7 +182,7 @@ var ChartBar = function ChartBar(props) {
|
|
|
175
182
|
series: buildCartesianSeriesOptions("bar", seriesData, series)
|
|
176
183
|
}, coreOption);
|
|
177
184
|
return option;
|
|
178
|
-
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, tooltip, legendData, legend, seriesData, series, enableLegendAutoScroll, coreOption]);
|
|
185
|
+
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, tooltip, legendData, legend, seriesData, series, enableLegendAutoScroll, coreOption, chrome]);
|
|
179
186
|
|
|
180
187
|
// Callback for handling chart resize
|
|
181
188
|
var handleResize = useCallback(function () {
|
|
@@ -17,6 +17,8 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
|
|
17
17
|
import styles from "../index.module.scss";
|
|
18
18
|
import * as echarts from "echarts";
|
|
19
19
|
import { createDefaultHeatmapXAxis, createDefaultHeatmapYAxis } from "../_utils/heatmap";
|
|
20
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
21
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
20
22
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
21
23
|
var Heatmap = function Heatmap(props) {
|
|
22
24
|
var className = props.className,
|
|
@@ -41,6 +43,12 @@ var Heatmap = function Heatmap(props) {
|
|
|
41
43
|
var chartRef = useRef(null);
|
|
42
44
|
var chartInstanceRef = useRef(null);
|
|
43
45
|
var resizeObserverRef = useRef(null);
|
|
46
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and legend
|
|
47
|
+
// colours have to be resolved against the active appearance here
|
|
48
|
+
var isDark = useIsDark();
|
|
49
|
+
var chrome = useMemo(function () {
|
|
50
|
+
return resolveChartChrome(isDark);
|
|
51
|
+
}, [isDark]);
|
|
44
52
|
|
|
45
53
|
// Process the data and generate the chart option
|
|
46
54
|
var chartOption = useMemo(function () {
|
|
@@ -85,7 +93,7 @@ var Heatmap = function Heatmap(props) {
|
|
|
85
93
|
left: "right",
|
|
86
94
|
top: "center",
|
|
87
95
|
textStyle: {
|
|
88
|
-
color:
|
|
96
|
+
color: chrome.text
|
|
89
97
|
},
|
|
90
98
|
inRange: {
|
|
91
99
|
color: inRangeColor
|
|
@@ -93,7 +101,7 @@ var Heatmap = function Heatmap(props) {
|
|
|
93
101
|
};
|
|
94
102
|
|
|
95
103
|
// Process xAxis config
|
|
96
|
-
var def_xAxis = createDefaultHeatmapXAxis(xAxisData);
|
|
104
|
+
var def_xAxis = createDefaultHeatmapXAxis(xAxisData, chrome);
|
|
97
105
|
var processedXAxis = Array.isArray(xAxis) ? xAxis === null || xAxis === void 0 ? void 0 : xAxis.map(function (item) {
|
|
98
106
|
return _objectSpread(_objectSpread({}, def_xAxis), {}, {
|
|
99
107
|
data: (item === null || item === void 0 ? void 0 : item.type) === "value" ? undefined : xAxisData
|
|
@@ -103,7 +111,7 @@ var Heatmap = function Heatmap(props) {
|
|
|
103
111
|
}, xAxis);
|
|
104
112
|
|
|
105
113
|
// Process yAxis config
|
|
106
|
-
var def_yAxis = createDefaultHeatmapYAxis(yAxisData);
|
|
114
|
+
var def_yAxis = createDefaultHeatmapYAxis(yAxisData, chrome);
|
|
107
115
|
var processedYAxis = Array.isArray(yAxis) ? yAxis === null || yAxis === void 0 ? void 0 : yAxis.map(function (item) {
|
|
108
116
|
return _objectSpread(_objectSpread({}, def_yAxis), {}, {
|
|
109
117
|
data: (item === null || item === void 0 ? void 0 : item.type) === "value" ? undefined : yAxisData
|
|
@@ -170,7 +178,7 @@ var Heatmap = function Heatmap(props) {
|
|
|
170
178
|
}, series)]
|
|
171
179
|
}, coreOption);
|
|
172
180
|
return option;
|
|
173
|
-
}, [data, inRangeColor, xAxisData, xAxis, yAxisData, yAxis, propVisualMap, grid, chartTitle, title, tooltip, series, coreOption, zeroColor]);
|
|
181
|
+
}, [data, inRangeColor, xAxisData, xAxis, yAxisData, yAxis, propVisualMap, grid, chartTitle, title, tooltip, series, coreOption, zeroColor, chrome]);
|
|
174
182
|
|
|
175
183
|
// Callback for handling chart resize
|
|
176
184
|
var handleResize = useCallback(function () {
|
|
@@ -13,6 +13,8 @@ import styles from "../index.module.scss";
|
|
|
13
13
|
import { autoScrollLegend } from "../_utils/autoScrollLegend";
|
|
14
14
|
import { autoScrollByItem } from "../_utils/autoSmooth";
|
|
15
15
|
import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, percentWindowToIndexWindow, resolveScrollConfig } from "../_utils/cartesian";
|
|
16
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
17
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
16
18
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
19
|
var ChartLine = function ChartLine(props) {
|
|
18
20
|
var className = props.className,
|
|
@@ -50,12 +52,18 @@ var ChartLine = function ChartLine(props) {
|
|
|
50
52
|
var normalizedScroll = useMemo(function () {
|
|
51
53
|
return resolveScrollConfig(scrollConfig);
|
|
52
54
|
}, [scrollConfig]);
|
|
55
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
56
|
+
// legend colours have to be resolved against the active appearance here
|
|
57
|
+
var isDark = useIsDark();
|
|
58
|
+
var chrome = useMemo(function () {
|
|
59
|
+
return resolveChartChrome(isDark);
|
|
60
|
+
}, [isDark]);
|
|
53
61
|
|
|
54
62
|
// Cache the chart option with useMemo
|
|
55
63
|
var chartOption = useMemo(function () {
|
|
56
64
|
var _xAxisData$length, _ref, _ref2;
|
|
57
|
-
var def_xAxis = createDefaultCategoryXAxis(xAxisData);
|
|
58
|
-
var def_yAxis = createDefaultValueYAxis("line");
|
|
65
|
+
var def_xAxis = createDefaultCategoryXAxis(xAxisData, chrome);
|
|
66
|
+
var def_yAxis = createDefaultValueYAxis("line", chrome);
|
|
59
67
|
|
|
60
68
|
// Process xAxis config
|
|
61
69
|
var processedXAxis = Array.isArray(xAxis) ? xAxis === null || xAxis === void 0 ? void 0 : xAxis.map(function (item) {
|
|
@@ -144,7 +152,7 @@ var ChartLine = function ChartLine(props) {
|
|
|
144
152
|
top: "5%",
|
|
145
153
|
icon: "circle",
|
|
146
154
|
textStyle: {
|
|
147
|
-
color:
|
|
155
|
+
color: chrome.text
|
|
148
156
|
},
|
|
149
157
|
itemWidth: 8,
|
|
150
158
|
itemHeight: 8
|
|
@@ -171,7 +179,7 @@ var ChartLine = function ChartLine(props) {
|
|
|
171
179
|
series: buildCartesianSeriesOptions("line", seriesData, series)
|
|
172
180
|
}, coreOption);
|
|
173
181
|
return option;
|
|
174
|
-
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, legendData, legend, tooltip, seriesData, series, enableLegendAutoScroll, coreOption]);
|
|
182
|
+
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, legendData, legend, tooltip, seriesData, series, enableLegendAutoScroll, coreOption, chrome]);
|
|
175
183
|
|
|
176
184
|
// Callback for handling chart resize
|
|
177
185
|
var handleResize = useCallback(function () {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as echarts from "echarts";
|
|
2
2
|
import { ChartOptionType, SeriesDataType } from "..";
|
|
3
|
+
import { ChartChrome } from "./chartTheme";
|
|
3
4
|
export interface ChartScrollConfig {
|
|
4
5
|
enabled?: boolean;
|
|
5
6
|
autoScroll?: boolean;
|
|
@@ -29,8 +30,8 @@ export interface DataZoomIndexWindow {
|
|
|
29
30
|
* percentages produced by native echarts interactions are rounded outward, so each boundary may include at most one extra item, without affecting the axis magnitude.
|
|
30
31
|
*/
|
|
31
32
|
export declare const percentWindowToIndexWindow: (startPercent: number, endPercent: number, total: number) => DataZoomIndexWindow;
|
|
32
|
-
export declare const createDefaultCategoryXAxis: (xAxisData
|
|
33
|
-
export declare const createDefaultValueYAxis: (mode
|
|
33
|
+
export declare const createDefaultCategoryXAxis: (xAxisData: Array<string> | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
34
|
+
export declare const createDefaultValueYAxis: (mode: "bar" | "line" | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
34
35
|
export declare const buildCartesianSeriesOptions: (mode: "bar" | "line", seriesData?: SeriesDataType, series?: echarts.SeriesOption | echarts.SeriesOption[]) => echarts.SeriesOption[];
|
|
35
36
|
export declare const getSliderShow: (zoom?: echarts.DataZoomComponentOption | Record<string, unknown>) => boolean | undefined;
|
|
36
37
|
export declare const resolveScrollConfig: (scrollConfig?: ChartScrollConfig) => NormalizedScrollConfig;
|
|
@@ -23,7 +23,7 @@ export var percentWindowToIndexWindow = function percentWindowToIndexWindow(star
|
|
|
23
23
|
endIndex: endIndex
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
|
-
export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxisData) {
|
|
26
|
+
export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxisData, chrome) {
|
|
27
27
|
return {
|
|
28
28
|
type: "category",
|
|
29
29
|
boundaryGap: true,
|
|
@@ -31,10 +31,10 @@ export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxi
|
|
|
31
31
|
axisLabel: {
|
|
32
32
|
interval: 0,
|
|
33
33
|
hideOverlap: true,
|
|
34
|
-
textStyle:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
// echarts removed the `textStyle` nesting under `axisLabel` in v4: keeping it means both
|
|
35
|
+
// properties are silently dropped *and* a deprecation warning is logged on every render.
|
|
36
|
+
fontSize: chrome.fontSize,
|
|
37
|
+
color: chrome.axis
|
|
38
38
|
},
|
|
39
39
|
axisTick: {
|
|
40
40
|
show: false
|
|
@@ -43,17 +43,16 @@ export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxi
|
|
|
43
43
|
};
|
|
44
44
|
export var createDefaultValueYAxis = function createDefaultValueYAxis() {
|
|
45
45
|
var mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "bar";
|
|
46
|
+
var chrome = arguments.length > 1 ? arguments[1] : undefined;
|
|
46
47
|
return {
|
|
47
48
|
type: "value",
|
|
48
49
|
axisLabel: {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
color: "#373D48"
|
|
52
|
-
}
|
|
50
|
+
fontSize: chrome.fontSize,
|
|
51
|
+
color: chrome.axis
|
|
53
52
|
},
|
|
54
53
|
splitLine: mode === "line" ? {
|
|
55
54
|
lineStyle: {
|
|
56
|
-
color:
|
|
55
|
+
color: chrome.splitLine,
|
|
57
56
|
type: "dashed"
|
|
58
57
|
}
|
|
59
58
|
} : {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colours for the chart *chrome* — axis ticks, split lines, legend labels.
|
|
3
|
+
*
|
|
4
|
+
* echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
|
|
5
|
+
* library styles itself with; the literal values have to be resolved here instead. These used to
|
|
6
|
+
* be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
|
|
7
|
+
* nearly invisible once the page switched to the dark palette.
|
|
8
|
+
*
|
|
9
|
+
* The plotted data is deliberately *not* covered here: series colours come from echarts' own
|
|
10
|
+
* palette or from whatever the caller passes as `color`, and both read fine on either background.
|
|
11
|
+
*/
|
|
12
|
+
export interface ChartChrome {
|
|
13
|
+
/** Legend labels — a real label, so it sits on the foreground ramp */
|
|
14
|
+
text: string;
|
|
15
|
+
/** Axis tick labels — secondary information, one step down */
|
|
16
|
+
axis: string;
|
|
17
|
+
/** Split lines behind the plot area */
|
|
18
|
+
splitLine: string;
|
|
19
|
+
/** Base font size, same scale the rest of the library uses */
|
|
20
|
+
fontSize: number;
|
|
21
|
+
}
|
|
22
|
+
export declare const resolveChartChrome: (dark: boolean) => ChartChrome;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { darkTokens, fontTokens, lightTokens } from "../../../styles/tokens";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Colours for the chart *chrome* — axis ticks, split lines, legend labels.
|
|
5
|
+
*
|
|
6
|
+
* echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
|
|
7
|
+
* library styles itself with; the literal values have to be resolved here instead. These used to
|
|
8
|
+
* be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
|
|
9
|
+
* nearly invisible once the page switched to the dark palette.
|
|
10
|
+
*
|
|
11
|
+
* The plotted data is deliberately *not* covered here: series colours come from echarts' own
|
|
12
|
+
* palette or from whatever the caller passes as `color`, and both read fine on either background.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export var resolveChartChrome = function resolveChartChrome(dark) {
|
|
16
|
+
var t = dark ? darkTokens : lightTokens;
|
|
17
|
+
return {
|
|
18
|
+
text: t.foreground,
|
|
19
|
+
axis: t.mutedForeground,
|
|
20
|
+
splitLine: t.border,
|
|
21
|
+
fontSize: fontTokens.size
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { ChartOptionType } from "..";
|
|
2
|
-
|
|
3
|
-
export declare const
|
|
2
|
+
import { ChartChrome } from "./chartTheme";
|
|
3
|
+
export declare const createDefaultHeatmapXAxis: (xAxisData: string[] | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
4
|
+
export declare const createDefaultHeatmapYAxis: (yAxisData: string[] | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export var createDefaultHeatmapXAxis = function createDefaultHeatmapXAxis(xAxisData) {
|
|
1
|
+
export var createDefaultHeatmapXAxis = function createDefaultHeatmapXAxis(xAxisData, chrome) {
|
|
2
2
|
return {
|
|
3
3
|
type: "category",
|
|
4
4
|
data: xAxisData,
|
|
@@ -8,17 +8,16 @@ export var createDefaultHeatmapXAxis = function createDefaultHeatmapXAxis(xAxisD
|
|
|
8
8
|
axisLabel: {
|
|
9
9
|
interval: 0,
|
|
10
10
|
hideOverlap: true,
|
|
11
|
-
textStyle
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
11
|
+
// See the note in `cartesian.ts`: `axisLabel.textStyle` has been deprecated since echarts 4
|
|
12
|
+
fontSize: chrome.fontSize,
|
|
13
|
+
color: chrome.axis
|
|
15
14
|
},
|
|
16
15
|
axisTick: {
|
|
17
16
|
show: false
|
|
18
17
|
}
|
|
19
18
|
};
|
|
20
19
|
};
|
|
21
|
-
export var createDefaultHeatmapYAxis = function createDefaultHeatmapYAxis(yAxisData) {
|
|
20
|
+
export var createDefaultHeatmapYAxis = function createDefaultHeatmapYAxis(yAxisData, chrome) {
|
|
22
21
|
return {
|
|
23
22
|
type: "category",
|
|
24
23
|
data: yAxisData,
|
|
@@ -26,10 +25,8 @@ export var createDefaultHeatmapYAxis = function createDefaultHeatmapYAxis(yAxisD
|
|
|
26
25
|
show: true
|
|
27
26
|
},
|
|
28
27
|
axisLabel: {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
color: "#373D48"
|
|
32
|
-
}
|
|
28
|
+
fontSize: chrome.fontSize,
|
|
29
|
+
color: chrome.axis
|
|
33
30
|
},
|
|
34
31
|
axisTick: {
|
|
35
32
|
show: false
|
|
@@ -21,8 +21,18 @@
|
|
|
21
21
|
|
|
22
22
|
height: 100%;
|
|
23
23
|
|
|
24
|
+
// Inside a modal the Search must not keep its card chrome. On a page it is an outlined white
|
|
25
|
+
// card standing on the grey page background; in a modal the body is already `--vita-surface`,
|
|
26
|
+
// so the same treatment paints a white card on white and only the border survives — a stray
|
|
27
|
+
// outline around the search row. The padding was already being cleared here; the background and
|
|
28
|
+
// border are the other half of the same intent, and `.tableContainer` below is flush for
|
|
29
|
+
// exactly this reason.
|
|
24
30
|
.search {
|
|
25
31
|
padding: 0px;
|
|
32
|
+
|
|
33
|
+
background: transparent;
|
|
34
|
+
|
|
35
|
+
border: none;
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
.tableContainer {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 给消费方 webpack 配置用的工具。**构建期模块,不要从应用代码里引**
|
|
3
|
+
* —— 它不依赖 React,也不该进运行时产物。
|
|
4
|
+
*
|
|
5
|
+
* ```js
|
|
6
|
+
* // webpack.config.js(CJS)
|
|
7
|
+
* const { excludeNodeModulesExceptHsuUi } = require("@hsu-react/ui/lib/build/webpack");
|
|
8
|
+
*
|
|
9
|
+
* { test: /\.scss$/, exclude: excludeNodeModulesExceptHsuUi, use: [...] }
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* 判断一个模块路径「是否该被 loader 排除」:node_modules 一律排除,但放行本库。
|
|
14
|
+
*
|
|
15
|
+
* ## 为什么需要它
|
|
16
|
+
*
|
|
17
|
+
* 本库的 es / lib 产物里带着**未编译的 `.module.scss`** 和图片资源,要由消费方自己的
|
|
18
|
+
* loader 处理(这样 CSS Module 的类名哈希、`getLocalIdent` 等策略才由消费方说了算)。
|
|
19
|
+
* 于是每个 webpack 项目都得在 scss / 图片规则上开一个「排除 node_modules,但放行
|
|
20
|
+
* @hsu-react/ui」的例外。
|
|
21
|
+
*
|
|
22
|
+
* ## 为什么不能用正则
|
|
23
|
+
*
|
|
24
|
+
* 手写的版本几乎都是 `/node_modules\/(?!@hsu-react\/ui\/)/`。它只看**第一个**
|
|
25
|
+
* node_modules 后面跟着什么——扁平安装(yarn / npm)下确实是 `@hsu-react/ui/`,
|
|
26
|
+
* 但 pnpm 的真实路径是
|
|
27
|
+
*
|
|
28
|
+
* ```
|
|
29
|
+
* node_modules/.pnpm/@hsu-react+ui@<版本>/node_modules/@hsu-react/ui/es/...
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* 跟着的是 `.pnpm/`,否定前瞻立刻失败,本库的 scss 与图片会被**全部排除**,
|
|
33
|
+
* 报「no loaders are configured to process this file」。这个坑在四个下游项目里
|
|
34
|
+
* 各踩过一次,所以把判定收进库里导出,消费方引用而不是各抄一份。
|
|
35
|
+
*
|
|
36
|
+
* 改按「整条路径里有没有 @hsu-react/ui」判断,扁平与嵌套两种布局都成立;
|
|
37
|
+
* 路径分隔符同时接受 `/` 与 `\`,Windows 下同样有效。
|
|
38
|
+
*/
|
|
39
|
+
export declare const excludeNodeModulesExceptHsuUi: (modulePath: string) => boolean;
|
|
40
|
+
export default excludeNodeModulesExceptHsuUi;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.excludeNodeModulesExceptHsuUi = exports.default = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* 给消费方 webpack 配置用的工具。**构建期模块,不要从应用代码里引**
|
|
9
|
+
* —— 它不依赖 React,也不该进运行时产物。
|
|
10
|
+
*
|
|
11
|
+
* ```js
|
|
12
|
+
* // webpack.config.js(CJS)
|
|
13
|
+
* const { excludeNodeModulesExceptHsuUi } = require("@hsu-react/ui/lib/build/webpack");
|
|
14
|
+
*
|
|
15
|
+
* { test: /\.scss$/, exclude: excludeNodeModulesExceptHsuUi, use: [...] }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 判断一个模块路径「是否该被 loader 排除」:node_modules 一律排除,但放行本库。
|
|
21
|
+
*
|
|
22
|
+
* ## 为什么需要它
|
|
23
|
+
*
|
|
24
|
+
* 本库的 es / lib 产物里带着**未编译的 `.module.scss`** 和图片资源,要由消费方自己的
|
|
25
|
+
* loader 处理(这样 CSS Module 的类名哈希、`getLocalIdent` 等策略才由消费方说了算)。
|
|
26
|
+
* 于是每个 webpack 项目都得在 scss / 图片规则上开一个「排除 node_modules,但放行
|
|
27
|
+
* @hsu-react/ui」的例外。
|
|
28
|
+
*
|
|
29
|
+
* ## 为什么不能用正则
|
|
30
|
+
*
|
|
31
|
+
* 手写的版本几乎都是 `/node_modules\/(?!@hsu-react\/ui\/)/`。它只看**第一个**
|
|
32
|
+
* node_modules 后面跟着什么——扁平安装(yarn / npm)下确实是 `@hsu-react/ui/`,
|
|
33
|
+
* 但 pnpm 的真实路径是
|
|
34
|
+
*
|
|
35
|
+
* ```
|
|
36
|
+
* node_modules/.pnpm/@hsu-react+ui@<版本>/node_modules/@hsu-react/ui/es/...
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* 跟着的是 `.pnpm/`,否定前瞻立刻失败,本库的 scss 与图片会被**全部排除**,
|
|
40
|
+
* 报「no loaders are configured to process this file」。这个坑在四个下游项目里
|
|
41
|
+
* 各踩过一次,所以把判定收进库里导出,消费方引用而不是各抄一份。
|
|
42
|
+
*
|
|
43
|
+
* 改按「整条路径里有没有 @hsu-react/ui」判断,扁平与嵌套两种布局都成立;
|
|
44
|
+
* 路径分隔符同时接受 `/` 与 `\`,Windows 下同样有效。
|
|
45
|
+
*/
|
|
46
|
+
const excludeNodeModulesExceptHsuUi = modulePath => /node_modules/.test(modulePath) && !/@hsu-react[\\/]ui[\\/]/.test(modulePath);
|
|
47
|
+
exports.excludeNodeModulesExceptHsuUi = excludeNodeModulesExceptHsuUi;
|
|
48
|
+
var _default = exports.default = excludeNodeModulesExceptHsuUi;
|
|
@@ -10,6 +10,8 @@ var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
|
10
10
|
var _autoScrollLegend = require("../_utils/autoScrollLegend");
|
|
11
11
|
var _autoSmooth = require("../_utils/autoSmooth");
|
|
12
12
|
var _cartesian = require("../_utils/cartesian");
|
|
13
|
+
var _chartTheme = require("../_utils/chartTheme");
|
|
14
|
+
var _useIsDark = _interopRequireDefault(require("../../../hooks/useIsDark"));
|
|
13
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
17
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
@@ -47,11 +49,15 @@ const ChartBar = props => {
|
|
|
47
49
|
const prevXAxisKeyRef = (0, _react.useRef)(null);
|
|
48
50
|
const legendScrollRef = (0, _react.useRef)(null);
|
|
49
51
|
const normalizedScroll = (0, _react.useMemo)(() => (0, _cartesian.resolveScrollConfig)(scrollConfig), [scrollConfig]);
|
|
52
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
53
|
+
// legend colours have to be resolved against the active appearance here
|
|
54
|
+
const isDark = (0, _useIsDark.default)();
|
|
55
|
+
const chrome = (0, _react.useMemo)(() => (0, _chartTheme.resolveChartChrome)(isDark), [isDark]);
|
|
50
56
|
|
|
51
57
|
// Cache the chart option with useMemo
|
|
52
58
|
const chartOption = (0, _react.useMemo)(() => {
|
|
53
|
-
const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData);
|
|
54
|
-
const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("bar");
|
|
59
|
+
const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData, chrome);
|
|
60
|
+
const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("bar", chrome);
|
|
55
61
|
|
|
56
62
|
// Process xAxis config
|
|
57
63
|
const processedXAxis = Array.isArray(xAxis) ? xAxis?.map(item => ({
|
|
@@ -155,8 +161,7 @@ const ChartBar = props => {
|
|
|
155
161
|
data: legendData,
|
|
156
162
|
icon: "circle",
|
|
157
163
|
textStyle: {
|
|
158
|
-
color:
|
|
159
|
-
fontSize: 16
|
|
164
|
+
color: chrome.text
|
|
160
165
|
},
|
|
161
166
|
itemWidth: 8,
|
|
162
167
|
itemHeight: 8,
|
|
@@ -183,7 +188,7 @@ const ChartBar = props => {
|
|
|
183
188
|
...coreOption
|
|
184
189
|
};
|
|
185
190
|
return option;
|
|
186
|
-
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, tooltip, legendData, legend, seriesData, series, enableLegendAutoScroll, coreOption]);
|
|
191
|
+
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, tooltip, legendData, legend, seriesData, series, enableLegendAutoScroll, coreOption, chrome]);
|
|
187
192
|
|
|
188
193
|
// Callback for handling chart resize
|
|
189
194
|
const handleResize = (0, _react.useCallback)(() => {
|
|
@@ -8,6 +8,8 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
8
8
|
var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
9
9
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
10
10
|
var _heatmap = require("../_utils/heatmap");
|
|
11
|
+
var _chartTheme = require("../_utils/chartTheme");
|
|
12
|
+
var _useIsDark = _interopRequireDefault(require("../../../hooks/useIsDark"));
|
|
11
13
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
15
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
@@ -36,6 +38,10 @@ const Heatmap = props => {
|
|
|
36
38
|
const chartRef = (0, _react.useRef)(null);
|
|
37
39
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
38
40
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
41
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and legend
|
|
42
|
+
// colours have to be resolved against the active appearance here
|
|
43
|
+
const isDark = (0, _useIsDark.default)();
|
|
44
|
+
const chrome = (0, _react.useMemo)(() => (0, _chartTheme.resolveChartChrome)(isDark), [isDark]);
|
|
39
45
|
|
|
40
46
|
// Process the data and generate the chart option
|
|
41
47
|
const chartOption = (0, _react.useMemo)(() => {
|
|
@@ -76,7 +82,7 @@ const Heatmap = props => {
|
|
|
76
82
|
left: "right",
|
|
77
83
|
top: "center",
|
|
78
84
|
textStyle: {
|
|
79
|
-
color:
|
|
85
|
+
color: chrome.text
|
|
80
86
|
},
|
|
81
87
|
inRange: {
|
|
82
88
|
color: inRangeColor
|
|
@@ -84,7 +90,7 @@ const Heatmap = props => {
|
|
|
84
90
|
};
|
|
85
91
|
|
|
86
92
|
// Process xAxis config
|
|
87
|
-
const def_xAxis = (0, _heatmap.createDefaultHeatmapXAxis)(xAxisData);
|
|
93
|
+
const def_xAxis = (0, _heatmap.createDefaultHeatmapXAxis)(xAxisData, chrome);
|
|
88
94
|
const processedXAxis = Array.isArray(xAxis) ? xAxis?.map(item => ({
|
|
89
95
|
...def_xAxis,
|
|
90
96
|
data: item?.type === "value" ? undefined : xAxisData,
|
|
@@ -96,7 +102,7 @@ const Heatmap = props => {
|
|
|
96
102
|
};
|
|
97
103
|
|
|
98
104
|
// Process yAxis config
|
|
99
|
-
const def_yAxis = (0, _heatmap.createDefaultHeatmapYAxis)(yAxisData);
|
|
105
|
+
const def_yAxis = (0, _heatmap.createDefaultHeatmapYAxis)(yAxisData, chrome);
|
|
100
106
|
const processedYAxis = Array.isArray(yAxis) ? yAxis?.map(item => ({
|
|
101
107
|
...def_yAxis,
|
|
102
108
|
data: item?.type === "value" ? undefined : yAxisData,
|
|
@@ -172,7 +178,7 @@ const Heatmap = props => {
|
|
|
172
178
|
...coreOption
|
|
173
179
|
};
|
|
174
180
|
return option;
|
|
175
|
-
}, [data, inRangeColor, xAxisData, xAxis, yAxisData, yAxis, propVisualMap, grid, chartTitle, title, tooltip, series, coreOption, zeroColor]);
|
|
181
|
+
}, [data, inRangeColor, xAxisData, xAxis, yAxisData, yAxis, propVisualMap, grid, chartTitle, title, tooltip, series, coreOption, zeroColor, chrome]);
|
|
176
182
|
|
|
177
183
|
// Callback for handling chart resize
|
|
178
184
|
const handleResize = (0, _react.useCallback)(() => {
|
|
@@ -10,6 +10,8 @@ var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
|
10
10
|
var _autoScrollLegend = require("../_utils/autoScrollLegend");
|
|
11
11
|
var _autoSmooth = require("../_utils/autoSmooth");
|
|
12
12
|
var _cartesian = require("../_utils/cartesian");
|
|
13
|
+
var _chartTheme = require("../_utils/chartTheme");
|
|
14
|
+
var _useIsDark = _interopRequireDefault(require("../../../hooks/useIsDark"));
|
|
13
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
17
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
@@ -47,11 +49,15 @@ const ChartLine = props => {
|
|
|
47
49
|
const prevXAxisKeyRef = (0, _react.useRef)(null);
|
|
48
50
|
const legendScrollRef = (0, _react.useRef)(null);
|
|
49
51
|
const normalizedScroll = (0, _react.useMemo)(() => (0, _cartesian.resolveScrollConfig)(scrollConfig), [scrollConfig]);
|
|
52
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
53
|
+
// legend colours have to be resolved against the active appearance here
|
|
54
|
+
const isDark = (0, _useIsDark.default)();
|
|
55
|
+
const chrome = (0, _react.useMemo)(() => (0, _chartTheme.resolveChartChrome)(isDark), [isDark]);
|
|
50
56
|
|
|
51
57
|
// Cache the chart option with useMemo
|
|
52
58
|
const chartOption = (0, _react.useMemo)(() => {
|
|
53
|
-
const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData);
|
|
54
|
-
const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("line");
|
|
59
|
+
const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData, chrome);
|
|
60
|
+
const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("line", chrome);
|
|
55
61
|
|
|
56
62
|
// Process xAxis config
|
|
57
63
|
const processedXAxis = Array.isArray(xAxis) ? xAxis?.map(item => ({
|
|
@@ -148,7 +154,7 @@ const ChartLine = props => {
|
|
|
148
154
|
top: "5%",
|
|
149
155
|
icon: "circle",
|
|
150
156
|
textStyle: {
|
|
151
|
-
color:
|
|
157
|
+
color: chrome.text
|
|
152
158
|
},
|
|
153
159
|
itemWidth: 8,
|
|
154
160
|
itemHeight: 8,
|
|
@@ -179,7 +185,7 @@ const ChartLine = props => {
|
|
|
179
185
|
...coreOption
|
|
180
186
|
};
|
|
181
187
|
return option;
|
|
182
|
-
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, legendData, legend, tooltip, seriesData, series, enableLegendAutoScroll, coreOption]);
|
|
188
|
+
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, legendData, legend, tooltip, seriesData, series, enableLegendAutoScroll, coreOption, chrome]);
|
|
183
189
|
|
|
184
190
|
// Callback for handling chart resize
|
|
185
191
|
const handleResize = (0, _react.useCallback)(() => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as echarts from "echarts";
|
|
2
2
|
import { ChartOptionType, SeriesDataType } from "..";
|
|
3
|
+
import { ChartChrome } from "./chartTheme";
|
|
3
4
|
export interface ChartScrollConfig {
|
|
4
5
|
enabled?: boolean;
|
|
5
6
|
autoScroll?: boolean;
|
|
@@ -29,8 +30,8 @@ export interface DataZoomIndexWindow {
|
|
|
29
30
|
* percentages produced by native echarts interactions are rounded outward, so each boundary may include at most one extra item, without affecting the axis magnitude.
|
|
30
31
|
*/
|
|
31
32
|
export declare const percentWindowToIndexWindow: (startPercent: number, endPercent: number, total: number) => DataZoomIndexWindow;
|
|
32
|
-
export declare const createDefaultCategoryXAxis: (xAxisData
|
|
33
|
-
export declare const createDefaultValueYAxis: (mode
|
|
33
|
+
export declare const createDefaultCategoryXAxis: (xAxisData: Array<string> | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
34
|
+
export declare const createDefaultValueYAxis: (mode: "bar" | "line" | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
34
35
|
export declare const buildCartesianSeriesOptions: (mode: "bar" | "line", seriesData?: SeriesDataType, series?: echarts.SeriesOption | echarts.SeriesOption[]) => echarts.SeriesOption[];
|
|
35
36
|
export declare const getSliderShow: (zoom?: echarts.DataZoomComponentOption | Record<string, unknown>) => boolean | undefined;
|
|
36
37
|
export declare const resolveScrollConfig: (scrollConfig?: ChartScrollConfig) => NormalizedScrollConfig;
|
|
@@ -24,34 +24,32 @@ const percentWindowToIndexWindow = (startPercent, endPercent, total) => {
|
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
26
|
exports.percentWindowToIndexWindow = percentWindowToIndexWindow;
|
|
27
|
-
const createDefaultCategoryXAxis = xAxisData => ({
|
|
27
|
+
const createDefaultCategoryXAxis = (xAxisData, chrome) => ({
|
|
28
28
|
type: "category",
|
|
29
29
|
boundaryGap: true,
|
|
30
30
|
data: xAxisData,
|
|
31
31
|
axisLabel: {
|
|
32
32
|
interval: 0,
|
|
33
33
|
hideOverlap: true,
|
|
34
|
-
textStyle:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
// echarts removed the `textStyle` nesting under `axisLabel` in v4: keeping it means both
|
|
35
|
+
// properties are silently dropped *and* a deprecation warning is logged on every render.
|
|
36
|
+
fontSize: chrome.fontSize,
|
|
37
|
+
color: chrome.axis
|
|
38
38
|
},
|
|
39
39
|
axisTick: {
|
|
40
40
|
show: false
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
exports.createDefaultCategoryXAxis = createDefaultCategoryXAxis;
|
|
44
|
-
const createDefaultValueYAxis = (mode = "bar") => ({
|
|
44
|
+
const createDefaultValueYAxis = (mode = "bar", chrome) => ({
|
|
45
45
|
type: "value",
|
|
46
46
|
axisLabel: {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
color: "#373D48"
|
|
50
|
-
}
|
|
47
|
+
fontSize: chrome.fontSize,
|
|
48
|
+
color: chrome.axis
|
|
51
49
|
},
|
|
52
50
|
splitLine: mode === "line" ? {
|
|
53
51
|
lineStyle: {
|
|
54
|
-
color:
|
|
52
|
+
color: chrome.splitLine,
|
|
55
53
|
type: "dashed"
|
|
56
54
|
}
|
|
57
55
|
} : {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colours for the chart *chrome* — axis ticks, split lines, legend labels.
|
|
3
|
+
*
|
|
4
|
+
* echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
|
|
5
|
+
* library styles itself with; the literal values have to be resolved here instead. These used to
|
|
6
|
+
* be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
|
|
7
|
+
* nearly invisible once the page switched to the dark palette.
|
|
8
|
+
*
|
|
9
|
+
* The plotted data is deliberately *not* covered here: series colours come from echarts' own
|
|
10
|
+
* palette or from whatever the caller passes as `color`, and both read fine on either background.
|
|
11
|
+
*/
|
|
12
|
+
export interface ChartChrome {
|
|
13
|
+
/** Legend labels — a real label, so it sits on the foreground ramp */
|
|
14
|
+
text: string;
|
|
15
|
+
/** Axis tick labels — secondary information, one step down */
|
|
16
|
+
axis: string;
|
|
17
|
+
/** Split lines behind the plot area */
|
|
18
|
+
splitLine: string;
|
|
19
|
+
/** Base font size, same scale the rest of the library uses */
|
|
20
|
+
fontSize: number;
|
|
21
|
+
}
|
|
22
|
+
export declare const resolveChartChrome: (dark: boolean) => ChartChrome;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.resolveChartChrome = void 0;
|
|
7
|
+
var _tokens = require("../../../styles/tokens");
|
|
8
|
+
/**
|
|
9
|
+
* Colours for the chart *chrome* — axis ticks, split lines, legend labels.
|
|
10
|
+
*
|
|
11
|
+
* echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
|
|
12
|
+
* library styles itself with; the literal values have to be resolved here instead. These used to
|
|
13
|
+
* be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
|
|
14
|
+
* nearly invisible once the page switched to the dark palette.
|
|
15
|
+
*
|
|
16
|
+
* The plotted data is deliberately *not* covered here: series colours come from echarts' own
|
|
17
|
+
* palette or from whatever the caller passes as `color`, and both read fine on either background.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const resolveChartChrome = dark => {
|
|
21
|
+
const t = dark ? _tokens.darkTokens : _tokens.lightTokens;
|
|
22
|
+
return {
|
|
23
|
+
text: t.foreground,
|
|
24
|
+
axis: t.mutedForeground,
|
|
25
|
+
splitLine: t.border,
|
|
26
|
+
fontSize: _tokens.fontTokens.size
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
exports.resolveChartChrome = resolveChartChrome;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { ChartOptionType } from "..";
|
|
2
|
-
|
|
3
|
-
export declare const
|
|
2
|
+
import { ChartChrome } from "./chartTheme";
|
|
3
|
+
export declare const createDefaultHeatmapXAxis: (xAxisData: string[] | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
4
|
+
export declare const createDefaultHeatmapYAxis: (yAxisData: string[] | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.createDefaultHeatmapYAxis = exports.createDefaultHeatmapXAxis = void 0;
|
|
7
|
-
const createDefaultHeatmapXAxis = xAxisData => ({
|
|
7
|
+
const createDefaultHeatmapXAxis = (xAxisData, chrome) => ({
|
|
8
8
|
type: "category",
|
|
9
9
|
data: xAxisData,
|
|
10
10
|
splitArea: {
|
|
@@ -13,27 +13,24 @@ const createDefaultHeatmapXAxis = xAxisData => ({
|
|
|
13
13
|
axisLabel: {
|
|
14
14
|
interval: 0,
|
|
15
15
|
hideOverlap: true,
|
|
16
|
-
textStyle
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
16
|
+
// See the note in `cartesian.ts`: `axisLabel.textStyle` has been deprecated since echarts 4
|
|
17
|
+
fontSize: chrome.fontSize,
|
|
18
|
+
color: chrome.axis
|
|
20
19
|
},
|
|
21
20
|
axisTick: {
|
|
22
21
|
show: false
|
|
23
22
|
}
|
|
24
23
|
});
|
|
25
24
|
exports.createDefaultHeatmapXAxis = createDefaultHeatmapXAxis;
|
|
26
|
-
const createDefaultHeatmapYAxis = yAxisData => ({
|
|
25
|
+
const createDefaultHeatmapYAxis = (yAxisData, chrome) => ({
|
|
27
26
|
type: "category",
|
|
28
27
|
data: yAxisData,
|
|
29
28
|
splitArea: {
|
|
30
29
|
show: true
|
|
31
30
|
},
|
|
32
31
|
axisLabel: {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
color: "#373D48"
|
|
36
|
-
}
|
|
32
|
+
fontSize: chrome.fontSize,
|
|
33
|
+
color: chrome.axis
|
|
37
34
|
},
|
|
38
35
|
axisTick: {
|
|
39
36
|
show: false
|
|
@@ -21,8 +21,18 @@
|
|
|
21
21
|
|
|
22
22
|
height: 100%;
|
|
23
23
|
|
|
24
|
+
// Inside a modal the Search must not keep its card chrome. On a page it is an outlined white
|
|
25
|
+
// card standing on the grey page background; in a modal the body is already `--vita-surface`,
|
|
26
|
+
// so the same treatment paints a white card on white and only the border survives — a stray
|
|
27
|
+
// outline around the search row. The padding was already being cleared here; the background and
|
|
28
|
+
// border are the other half of the same intent, and `.tableContainer` below is flush for
|
|
29
|
+
// exactly this reason.
|
|
24
30
|
.search {
|
|
25
31
|
padding: 0px;
|
|
32
|
+
|
|
33
|
+
background: transparent;
|
|
34
|
+
|
|
35
|
+
border: none;
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
.tableContainer {
|
package/lib/package.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hsu-react/ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "一套基于 React + Ant Design 的中后台业务组件库",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"dev": "dumi dev",
|
|
42
42
|
"docs:build": "dumi build",
|
|
43
43
|
"docs:preview": "dumi preview",
|
|
44
|
-
"build": "node scripts/clean-dist.cjs && node scripts/gen-tokens-scss.cjs && father build && node scripts/check-heavy-deps.cjs",
|
|
45
|
-
"prepublishOnly": "node scripts/clean-dist.cjs && node scripts/gen-tokens-scss.cjs --check && father build && node scripts/check-heavy-deps.cjs",
|
|
44
|
+
"build": "node scripts/clean-dist.cjs && node scripts/gen-tokens-scss.cjs && father build && node scripts/mark-cjs.cjs && node scripts/check-heavy-deps.cjs",
|
|
45
|
+
"prepublishOnly": "node scripts/clean-dist.cjs && node scripts/gen-tokens-scss.cjs --check && father build && node scripts/mark-cjs.cjs && node scripts/check-heavy-deps.cjs",
|
|
46
46
|
"check:deps": "node scripts/check-heavy-deps.cjs",
|
|
47
47
|
"tokens": "node scripts/gen-tokens-scss.cjs",
|
|
48
48
|
"check:tokens": "node scripts/gen-tokens-scss.cjs --check"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 给消费方 webpack 配置用的工具。**构建期模块,不要从应用代码里引**
|
|
3
|
+
* —— 它不依赖 React,也不该进运行时产物。
|
|
4
|
+
*
|
|
5
|
+
* ```js
|
|
6
|
+
* // webpack.config.js(CJS)
|
|
7
|
+
* const { excludeNodeModulesExceptHsuUi } = require("@hsu-react/ui/lib/build/webpack");
|
|
8
|
+
*
|
|
9
|
+
* { test: /\.scss$/, exclude: excludeNodeModulesExceptHsuUi, use: [...] }
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 判断一个模块路径「是否该被 loader 排除」:node_modules 一律排除,但放行本库。
|
|
15
|
+
*
|
|
16
|
+
* ## 为什么需要它
|
|
17
|
+
*
|
|
18
|
+
* 本库的 es / lib 产物里带着**未编译的 `.module.scss`** 和图片资源,要由消费方自己的
|
|
19
|
+
* loader 处理(这样 CSS Module 的类名哈希、`getLocalIdent` 等策略才由消费方说了算)。
|
|
20
|
+
* 于是每个 webpack 项目都得在 scss / 图片规则上开一个「排除 node_modules,但放行
|
|
21
|
+
* @hsu-react/ui」的例外。
|
|
22
|
+
*
|
|
23
|
+
* ## 为什么不能用正则
|
|
24
|
+
*
|
|
25
|
+
* 手写的版本几乎都是 `/node_modules\/(?!@hsu-react\/ui\/)/`。它只看**第一个**
|
|
26
|
+
* node_modules 后面跟着什么——扁平安装(yarn / npm)下确实是 `@hsu-react/ui/`,
|
|
27
|
+
* 但 pnpm 的真实路径是
|
|
28
|
+
*
|
|
29
|
+
* ```
|
|
30
|
+
* node_modules/.pnpm/@hsu-react+ui@<版本>/node_modules/@hsu-react/ui/es/...
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* 跟着的是 `.pnpm/`,否定前瞻立刻失败,本库的 scss 与图片会被**全部排除**,
|
|
34
|
+
* 报「no loaders are configured to process this file」。这个坑在四个下游项目里
|
|
35
|
+
* 各踩过一次,所以把判定收进库里导出,消费方引用而不是各抄一份。
|
|
36
|
+
*
|
|
37
|
+
* 改按「整条路径里有没有 @hsu-react/ui」判断,扁平与嵌套两种布局都成立;
|
|
38
|
+
* 路径分隔符同时接受 `/` 与 `\`,Windows 下同样有效。
|
|
39
|
+
*/
|
|
40
|
+
export const excludeNodeModulesExceptHsuUi = (modulePath: string): boolean =>
|
|
41
|
+
/node_modules/.test(modulePath) &&
|
|
42
|
+
!/@hsu-react[\\/]ui[\\/]/.test(modulePath);
|
|
43
|
+
|
|
44
|
+
export default excludeNodeModulesExceptHsuUi;
|
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
percentWindowToIndexWindow,
|
|
22
22
|
resolveScrollConfig,
|
|
23
23
|
} from "../_utils/cartesian";
|
|
24
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
25
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
24
26
|
|
|
25
27
|
export interface ChartBarProps extends ChartCommonProps {
|
|
26
28
|
chartTitle?: string;
|
|
@@ -79,11 +81,15 @@ const ChartBar: React.FC<ChartBarProps> = (props) => {
|
|
|
79
81
|
() => resolveScrollConfig(scrollConfig),
|
|
80
82
|
[scrollConfig],
|
|
81
83
|
);
|
|
84
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
85
|
+
// legend colours have to be resolved against the active appearance here
|
|
86
|
+
const isDark = useIsDark();
|
|
87
|
+
const chrome = useMemo(() => resolveChartChrome(isDark), [isDark]);
|
|
82
88
|
|
|
83
89
|
// Cache the chart option with useMemo
|
|
84
90
|
const chartOption = useMemo(() => {
|
|
85
|
-
const def_xAxis = createDefaultCategoryXAxis(xAxisData);
|
|
86
|
-
const def_yAxis = createDefaultValueYAxis("bar");
|
|
91
|
+
const def_xAxis = createDefaultCategoryXAxis(xAxisData, chrome);
|
|
92
|
+
const def_yAxis = createDefaultValueYAxis("bar", chrome);
|
|
87
93
|
|
|
88
94
|
// Process xAxis config
|
|
89
95
|
const processedXAxis = Array.isArray(xAxis)
|
|
@@ -212,8 +218,7 @@ const ChartBar: React.FC<ChartBarProps> = (props) => {
|
|
|
212
218
|
data: legendData,
|
|
213
219
|
icon: "circle",
|
|
214
220
|
textStyle: {
|
|
215
|
-
color:
|
|
216
|
-
fontSize: 16,
|
|
221
|
+
color: chrome.text,
|
|
217
222
|
},
|
|
218
223
|
itemWidth: 8,
|
|
219
224
|
itemHeight: 8,
|
|
@@ -259,6 +264,7 @@ const ChartBar: React.FC<ChartBarProps> = (props) => {
|
|
|
259
264
|
series,
|
|
260
265
|
enableLegendAutoScroll,
|
|
261
266
|
coreOption,
|
|
267
|
+
chrome,
|
|
262
268
|
]);
|
|
263
269
|
|
|
264
270
|
// Callback for handling chart resize
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
createDefaultHeatmapXAxis,
|
|
7
7
|
createDefaultHeatmapYAxis,
|
|
8
8
|
} from "../_utils/heatmap";
|
|
9
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
10
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
9
11
|
|
|
10
12
|
export interface HeatmapDataItem {
|
|
11
13
|
/** X-axis index or name */
|
|
@@ -73,6 +75,10 @@ const Heatmap: React.FC<ChartHeatmapProps> = (props) => {
|
|
|
73
75
|
const chartRef = useRef<HTMLDivElement>(null);
|
|
74
76
|
const chartInstanceRef = useRef<echarts.ECharts | null>(null);
|
|
75
77
|
const resizeObserverRef = useRef<ResizeObserver | null>(null);
|
|
78
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and legend
|
|
79
|
+
// colours have to be resolved against the active appearance here
|
|
80
|
+
const isDark = useIsDark();
|
|
81
|
+
const chrome = useMemo(() => resolveChartChrome(isDark), [isDark]);
|
|
76
82
|
|
|
77
83
|
// Process the data and generate the chart option
|
|
78
84
|
const chartOption = useMemo(() => {
|
|
@@ -120,7 +126,7 @@ const Heatmap: React.FC<ChartHeatmapProps> = (props) => {
|
|
|
120
126
|
left: "right",
|
|
121
127
|
top: "center",
|
|
122
128
|
textStyle: {
|
|
123
|
-
color:
|
|
129
|
+
color: chrome.text,
|
|
124
130
|
},
|
|
125
131
|
inRange: {
|
|
126
132
|
color: inRangeColor,
|
|
@@ -128,7 +134,7 @@ const Heatmap: React.FC<ChartHeatmapProps> = (props) => {
|
|
|
128
134
|
};
|
|
129
135
|
|
|
130
136
|
// Process xAxis config
|
|
131
|
-
const def_xAxis = createDefaultHeatmapXAxis(xAxisData);
|
|
137
|
+
const def_xAxis = createDefaultHeatmapXAxis(xAxisData, chrome);
|
|
132
138
|
const processedXAxis = Array.isArray(xAxis)
|
|
133
139
|
? xAxis?.map((item) => ({
|
|
134
140
|
...def_xAxis,
|
|
@@ -142,7 +148,7 @@ const Heatmap: React.FC<ChartHeatmapProps> = (props) => {
|
|
|
142
148
|
};
|
|
143
149
|
|
|
144
150
|
// Process yAxis config
|
|
145
|
-
const def_yAxis = createDefaultHeatmapYAxis(yAxisData);
|
|
151
|
+
const def_yAxis = createDefaultHeatmapYAxis(yAxisData, chrome);
|
|
146
152
|
const processedYAxis = Array.isArray(yAxis)
|
|
147
153
|
? yAxis?.map((item) => ({
|
|
148
154
|
...def_yAxis,
|
|
@@ -244,6 +250,7 @@ const Heatmap: React.FC<ChartHeatmapProps> = (props) => {
|
|
|
244
250
|
series,
|
|
245
251
|
coreOption,
|
|
246
252
|
zeroColor,
|
|
253
|
+
chrome,
|
|
247
254
|
]);
|
|
248
255
|
|
|
249
256
|
// Callback for handling chart resize
|
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
percentWindowToIndexWindow,
|
|
22
22
|
resolveScrollConfig,
|
|
23
23
|
} from "../_utils/cartesian";
|
|
24
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
25
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
24
26
|
|
|
25
27
|
export interface ChartLineProps extends ChartCommonProps {
|
|
26
28
|
chartTitle?: string;
|
|
@@ -80,11 +82,15 @@ const ChartLine: React.FC<ChartLineProps> = (props) => {
|
|
|
80
82
|
() => resolveScrollConfig(scrollConfig),
|
|
81
83
|
[scrollConfig],
|
|
82
84
|
);
|
|
85
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
86
|
+
// legend colours have to be resolved against the active appearance here
|
|
87
|
+
const isDark = useIsDark();
|
|
88
|
+
const chrome = useMemo(() => resolveChartChrome(isDark), [isDark]);
|
|
83
89
|
|
|
84
90
|
// Cache the chart option with useMemo
|
|
85
91
|
const chartOption = useMemo(() => {
|
|
86
|
-
const def_xAxis = createDefaultCategoryXAxis(xAxisData);
|
|
87
|
-
const def_yAxis = createDefaultValueYAxis("line");
|
|
92
|
+
const def_xAxis = createDefaultCategoryXAxis(xAxisData, chrome);
|
|
93
|
+
const def_yAxis = createDefaultValueYAxis("line", chrome);
|
|
88
94
|
|
|
89
95
|
// Process xAxis config
|
|
90
96
|
const processedXAxis = Array.isArray(xAxis)
|
|
@@ -206,7 +212,7 @@ const ChartLine: React.FC<ChartLineProps> = (props) => {
|
|
|
206
212
|
top: "5%",
|
|
207
213
|
icon: "circle",
|
|
208
214
|
textStyle: {
|
|
209
|
-
color:
|
|
215
|
+
color: chrome.text,
|
|
210
216
|
},
|
|
211
217
|
itemWidth: 8,
|
|
212
218
|
itemHeight: 8,
|
|
@@ -256,6 +262,7 @@ const ChartLine: React.FC<ChartLineProps> = (props) => {
|
|
|
256
262
|
series,
|
|
257
263
|
enableLegendAutoScroll,
|
|
258
264
|
coreOption,
|
|
265
|
+
chrome,
|
|
259
266
|
]);
|
|
260
267
|
|
|
261
268
|
// Callback for handling chart resize
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as echarts from "echarts";
|
|
2
2
|
import { ChartOptionType, SeriesData, SeriesDataType } from "..";
|
|
3
|
+
import { ChartChrome } from "./chartTheme";
|
|
3
4
|
|
|
4
5
|
export interface ChartScrollConfig {
|
|
5
6
|
enabled?: boolean;
|
|
@@ -50,7 +51,8 @@ export const percentWindowToIndexWindow = (
|
|
|
50
51
|
};
|
|
51
52
|
|
|
52
53
|
export const createDefaultCategoryXAxis = (
|
|
53
|
-
xAxisData
|
|
54
|
+
xAxisData: Array<string> | undefined,
|
|
55
|
+
chrome: ChartChrome,
|
|
54
56
|
): ChartOptionType => ({
|
|
55
57
|
type: "category",
|
|
56
58
|
boundaryGap: true,
|
|
@@ -58,10 +60,10 @@ export const createDefaultCategoryXAxis = (
|
|
|
58
60
|
axisLabel: {
|
|
59
61
|
interval: 0,
|
|
60
62
|
hideOverlap: true,
|
|
61
|
-
textStyle:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
// echarts removed the `textStyle` nesting under `axisLabel` in v4: keeping it means both
|
|
64
|
+
// properties are silently dropped *and* a deprecation warning is logged on every render.
|
|
65
|
+
fontSize: chrome.fontSize,
|
|
66
|
+
color: chrome.axis,
|
|
65
67
|
},
|
|
66
68
|
axisTick: {
|
|
67
69
|
show: false,
|
|
@@ -70,19 +72,18 @@ export const createDefaultCategoryXAxis = (
|
|
|
70
72
|
|
|
71
73
|
export const createDefaultValueYAxis = (
|
|
72
74
|
mode: "bar" | "line" = "bar",
|
|
75
|
+
chrome: ChartChrome,
|
|
73
76
|
): ChartOptionType => ({
|
|
74
77
|
type: "value",
|
|
75
78
|
axisLabel: {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
color: "#373D48",
|
|
79
|
-
},
|
|
79
|
+
fontSize: chrome.fontSize,
|
|
80
|
+
color: chrome.axis,
|
|
80
81
|
},
|
|
81
82
|
splitLine:
|
|
82
83
|
mode === "line"
|
|
83
84
|
? {
|
|
84
85
|
lineStyle: {
|
|
85
|
-
color:
|
|
86
|
+
color: chrome.splitLine,
|
|
86
87
|
type: "dashed",
|
|
87
88
|
},
|
|
88
89
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { darkTokens, fontTokens, lightTokens } from "../../../styles/tokens";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Colours for the chart *chrome* — axis ticks, split lines, legend labels.
|
|
5
|
+
*
|
|
6
|
+
* echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
|
|
7
|
+
* library styles itself with; the literal values have to be resolved here instead. These used to
|
|
8
|
+
* be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
|
|
9
|
+
* nearly invisible once the page switched to the dark palette.
|
|
10
|
+
*
|
|
11
|
+
* The plotted data is deliberately *not* covered here: series colours come from echarts' own
|
|
12
|
+
* palette or from whatever the caller passes as `color`, and both read fine on either background.
|
|
13
|
+
*/
|
|
14
|
+
export interface ChartChrome {
|
|
15
|
+
/** Legend labels — a real label, so it sits on the foreground ramp */
|
|
16
|
+
text: string;
|
|
17
|
+
/** Axis tick labels — secondary information, one step down */
|
|
18
|
+
axis: string;
|
|
19
|
+
/** Split lines behind the plot area */
|
|
20
|
+
splitLine: string;
|
|
21
|
+
/** Base font size, same scale the rest of the library uses */
|
|
22
|
+
fontSize: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const resolveChartChrome = (dark: boolean): ChartChrome => {
|
|
26
|
+
const t = dark ? darkTokens : lightTokens;
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
text: t.foreground,
|
|
30
|
+
axis: t.mutedForeground,
|
|
31
|
+
splitLine: t.border,
|
|
32
|
+
fontSize: fontTokens.size,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { ChartOptionType } from "..";
|
|
2
|
+
import { ChartChrome } from "./chartTheme";
|
|
2
3
|
|
|
3
4
|
export const createDefaultHeatmapXAxis = (
|
|
4
|
-
xAxisData
|
|
5
|
+
xAxisData: string[] | undefined,
|
|
6
|
+
chrome: ChartChrome,
|
|
5
7
|
): ChartOptionType => ({
|
|
6
8
|
type: "category",
|
|
7
9
|
data: xAxisData,
|
|
@@ -11,10 +13,9 @@ export const createDefaultHeatmapXAxis = (
|
|
|
11
13
|
axisLabel: {
|
|
12
14
|
interval: 0,
|
|
13
15
|
hideOverlap: true,
|
|
14
|
-
textStyle
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
},
|
|
16
|
+
// See the note in `cartesian.ts`: `axisLabel.textStyle` has been deprecated since echarts 4
|
|
17
|
+
fontSize: chrome.fontSize,
|
|
18
|
+
color: chrome.axis,
|
|
18
19
|
},
|
|
19
20
|
axisTick: {
|
|
20
21
|
show: false,
|
|
@@ -22,7 +23,8 @@ export const createDefaultHeatmapXAxis = (
|
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
export const createDefaultHeatmapYAxis = (
|
|
25
|
-
yAxisData
|
|
26
|
+
yAxisData: string[] | undefined,
|
|
27
|
+
chrome: ChartChrome,
|
|
26
28
|
): ChartOptionType => ({
|
|
27
29
|
type: "category",
|
|
28
30
|
data: yAxisData,
|
|
@@ -30,10 +32,8 @@ export const createDefaultHeatmapYAxis = (
|
|
|
30
32
|
show: true,
|
|
31
33
|
},
|
|
32
34
|
axisLabel: {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
color: "#373D48",
|
|
36
|
-
},
|
|
35
|
+
fontSize: chrome.fontSize,
|
|
36
|
+
color: chrome.axis,
|
|
37
37
|
},
|
|
38
38
|
axisTick: {
|
|
39
39
|
show: false,
|
|
@@ -21,8 +21,18 @@
|
|
|
21
21
|
|
|
22
22
|
height: 100%;
|
|
23
23
|
|
|
24
|
+
// Inside a modal the Search must not keep its card chrome. On a page it is an outlined white
|
|
25
|
+
// card standing on the grey page background; in a modal the body is already `--vita-surface`,
|
|
26
|
+
// so the same treatment paints a white card on white and only the border survives — a stray
|
|
27
|
+
// outline around the search row. The padding was already being cleared here; the background and
|
|
28
|
+
// border are the other half of the same intent, and `.tableContainer` below is flush for
|
|
29
|
+
// exactly this reason.
|
|
24
30
|
.search {
|
|
25
31
|
padding: 0px;
|
|
32
|
+
|
|
33
|
+
background: transparent;
|
|
34
|
+
|
|
35
|
+
border: none;
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
.tableContainer {
|