diff --git a/content/show/chart/index-en-US.md b/content/show/chart/index-en-US.md
index 26904f7203..2c395e7b69 100644
--- a/content/show/chart/index-en-US.md
+++ b/content/show/chart/index-en-US.md
@@ -5,1073 +5,65 @@ category: Show
title: Data Visualization
icon: doc-vchart
dir: column
-brief: Out-of-the-box multi-terminal charting library.
+brief: Semi DV is a data visualization solution for Semi design systems.
---
-[VisActor](https://visactor.io) is an open-source visualization solution by ByteDance, and we recommend using its core chart component library called [VChart](https://visactor.io/vchart) for data visualization scenarios. It supports various types of charts, making it simple to use while offering powerful functionality.
+Semi DV is a data visualization solution built on top of ByteDance's open-source library [VChart](https://visactor.io/vchart), packaged with styles that match the Semi Design system.
-Based on VChart, we have developed a customized chart library that adheres to the Semi style. The advantages are as follows:
+VChart itself is built using the visualization grammar library VGrammar and the rendering engine VRender. VChart not only supports high-quality data presentation, but also provides animation sequencing for storytelling, rich interactive capabilities, and customizable chart styles. On top of this, Semi DV supports chart theme configuration, helping users maintain a consistent UI while enabling flexible and personalized data visualization.
-- 🧩 Out-of-the-box experience: It provides easy configuration and initialization, allowing you to start using it quickly.
-- 🎨 Consistent style: VChart has been customized to match the Semi design style. It is directly integrated with Semi Design Tokens. The default styles have undergone extensive verification, ensuring high readability and precision. Additionally, it supports user-defined chart styles.
-- 🌗 Responsive: VChart detects changes in the light and dark mode of the page and automatically updates the VChart charts on the page. It also synchronizes with the theme changes.
+Semi DV supports two configuration modes:
+- Simple Mode: Easily customize a chart theme by setting theme colors, choosing a palette, and adjusting corner radius, spacing, and line thickness.
+- Advanced Mode: Fine-tune your chart from the ground up, customizing tokens (color, font, radius, spacing, lines, animations), elements (title, axes, legend, interactive elements), and charts (bar, line, area, pie, funnel, etc.) for full control and precision.
+### Create a Chart Theme
+Go to [Design System Creation](https://semi.design/dsm/design_system_list?type=vcharts) and click the "Create a chart design system" Button. After finishing your configuration, with a single click, you can publish the theme to npm.
-## Installation and Usage
+
-### 1、Installation
+
-To install `@visactor/react-vchart` in a React project, you can use the following command:
+
-```bash
-# npm
-npm i @visactor/react-vchart
+For more detailed documentation on customizing themes, see [Theme Creation Guide](https://semi.design/dsm_vchart/doc/en-US/introduction/start#dsm_Customizethetheme)
-# yarn
-yarn add @visactor/react-vchart
-```
+### Using a Theme
-Additionally, you need to install `@visactor/vchart-semi-theme` to adapt to the default theme of Semi or custom themes published through Semi DSM.
+Install VChart
-```bash
-# npm
-npm i @visactor/vchart-semi-theme
-
-# yarn
-yarn add @visactor/vchart-semi-theme
+```shell
+# Using npm
+npm install @visactor/react-vchart
+# Using yarn
+yarn add @visactor/react-vchart
```
-### 2、Usage
-
-Starting from version v2.47.0, Semi introduced relevant Design Tokens to facilitate the adaptation of VChart to Semi themes or custom themes published through Semi DSM. Therefore, for version v2.47.0 and above, you only need to execute the `initVChartSemiTheme` method once globally for initialization. This statement is typically placed in the entry file of your React project. For example:
-
-```javascript
-//index.jsx
-import React from 'react';
-import { createRoot } from 'react-dom/client';
-import App from './app.jsx';
-import { initVChartSemiTheme } from '@visactor/vchart-semi-theme';
-
-// initialization
-initVChartSemiTheme();
+The theme package will be published by your designer via Semi DV. Please check with the designer for the correct package name. Assuming the package is called `@ies/semi-vchart-theme-test`, you can install it as follows:
-const dom = document.querySelector('#root');
-const root = createRoot(dom);
-root.render();
+```shell
+npm install @ies/semi-vchart-theme-test
+# or
+yarn add @ies/semi-vchart-theme-test
```
-The `initVChartSemiTheme` method supports accepting an object as an option, with the following type declaration:
+Import the Theme
-```typescript
-interface IInitVChartSemiThemeOption {
- /** default mode */
- defaultMode?: 'light' | 'dark';
-}
+```js
+// VChart light theme
+import vchartLight from "@ies/semi-vchart-theme-test/light.json";
+// VChart dark theme
+import vchartDark from "@ies/semi-vchart-theme-test/dark.json";
```
-For versions of Semi below v2.47.0, although there are no corresponding Design Tokens, you can still utilize the default values of the built-in theme styles provided by `@visactor/vchart-semi-theme`. Please note that this usage does not support automatic switching between light and dark modes. Users can manually set the current chart mode as needed. Here's an example:
-
+Register the Theme
```js
-import semiDesignLight from '@visactor/vchart-semi-theme/public/semiDesignLight.json';
-import semiDesignDark from '@visactor/vchart-semi-theme/public/semiDesignDark.json';
import VChart from '@visactor/vchart';
-// register the theme
-VChart.ThemeManager.registerTheme('semiDesignLight', semiDesignLight);
-VChart.ThemeManager.registerTheme('semiDesignDark', semiDesignDark);
-// apply the light theme
-VChart.ThemeManager.setCurrentTheme('semiDesignLight');
-// apply the dark theme
-VChart.ThemeManager.setCurrentTheme('semiDesignDark');
-```
-
->For more information about the theme package, please refer to [@visactor/vchart-semi-theme](https://www.npmjs.com/package/@visactor/vchart-semi-theme)
-For drawing charts and more detailed instructions, please refer to [VChart tutorial](https://visactor.io/vchart/guide/tutorial_docs/Cross-terminal_and_Developer_Ecology/react)
-
-
-## Common Chart Types Examples
-
-VChart is built on the visual grammar library VGrammar and the rendering engine VRender. It provides not only data presentation capabilities but also supports animated storytelling, rich interactivity, and customizable chart styles. The user-friendly configuration greatly reduces the learning curve.
-
-VChart supports various different chart types, allowing users to visualize abstract data through simple configuration, including combination chart, line chart, area chart, bar/column chart, pie/doughnut chart, scatter plot, heat map, histogram, box plot, waterfall chart, progress bar, funnel chart, time series chart, interval column chart, interval area chart, word cloud, dashboard, treemap, Sankey diagram, rose chart, radar chart, map, circle packing, sunburst diagram, etc. For detailed chart examples, please refer to [VChart Examples](https://visactor.io/vchart/example). Below are some showcases of VChart with Semi Design's default theme.
-
-### Bar chart
-
-
Basic bar chart
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-import { initVChartSemiTheme } from '@visactor/vchart-semi-theme';
-
-initVChartSemiTheme();
-
-const commonSpec = {
- type: 'bar',
- data: [
- {
- id: 'barData',
- values: [
- { type:'Date', month: 'Monday', sales: 22 },
- { type:'Date', month: 'Tuesday', sales: 13 },
- { type:'Date', month: 'Wednesday', sales: 25 },
- { type:'Date', month: 'Thursday', sales: 29 },
- { type:'Date', month: 'Friday', sales: 38 }
- ]
- }
- ],
- title: {
- visible: true,
- text: 'Bar chart',
- subtext: 'This is a bar chart',
- },
- legends: {
- visible: true,
- },
- xField: 'month',
- yField: 'sales',
- seriesField: 'type',
-};
-
-function App() {
- const [direction, setDirection] = useState("vertical");
- const onChange = useCallback((e) => setDirection(e.target.value), []);
- const spec = useMemo(() => {
- const isVertical = direction === 'vertical';
- return {
- ...commonSpec,
- xField: isVertical ? 'month' : 'sales',
- yField: isVertical ? 'sales' : 'month',
- direction: direction,
- };
- }, [direction]);
- return (
- <>
-
- vertical
- horizontal
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-Grouped bar chart
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const commonSpec = {
- type: 'bar',
- data: [
- {
- id: 'barData',
- values: [
- { type: 'Autocracies', year: '1930', value: 129 },
- { type: 'Autocracies', year: '1940', value: 133 },
- { type: 'Autocracies', year: '1950', value: 130 },
- { type: 'Autocracies', year: '1960', value: 126 },
- { type: 'Autocracies', year: '1970', value: 117 },
- { type: 'Autocracies', year: '1980', value: 114 },
- { type: 'Autocracies', year: '1990', value: 111 },
- { type: 'Autocracies', year: '2000', value: 89 },
- { type: 'Autocracies', year: '2010', value: 80 },
- { type: 'Autocracies', year: '2018', value: 80 },
- { type: 'Democracies', year: '1930', value: 22 },
- { type: 'Democracies', year: '1940', value: 13 },
- { type: 'Democracies', year: '1950', value: 25 },
- { type: 'Democracies', year: '1960', value: 29 },
- { type: 'Democracies', year: '1970', value: 38 },
- { type: 'Democracies', year: '1980', value: 41 },
- { type: 'Democracies', year: '1990', value: 57 },
- { type: 'Democracies', year: '2000', value: 87 },
- { type: 'Democracies', year: '2010', value: 98 },
- { type: 'Democracies', year: '2018', value: 99 }
- ]
- }
- ],
- seriesField: 'type',
- title: {
- visible: true,
- text: 'Grouped bar chart',
- subtext: 'This is a grouped bar chart',
- },
- legends: {
- visible: true,
- }
-};
-
-function App() {
- const [direction, setDirection] = useState("vertical");
- const onChange = useCallback((e) => setDirection(e.target.value), []);
- const spec = useMemo(() => {
- const isVertical = direction === 'vertical';
- return {
- ...commonSpec,
- xField: isVertical ? ['year', 'type'] : 'value',
- yField: isVertical ? 'value' : ['year', 'type'],
- direction: direction,
- };
- }, [direction]);
- return (
- <>
-
- vertical
- horizontal
-
-
-
-
- >
- )
-}
-render(App);
+VChart.ThemeManager.registerTheme("myLightTheme", vchartLight);
+// Apply a theme
+VChart.ThemeManager.setCurrentTheme('myLightTheme');
```
-Stacked bar chart
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const commonSpec = {
- type: 'bar',
- stack: true,
- data: [
- {
- id: 'barData',
- values: [
- { State: 'WY', Age: 'Under 5 Years', Population: 25635 },
- { State: 'WY', Age: '5 to 13 Years', Population: 1890 },
- { State: 'WY', Age: '14 to 17 Years', Population: 9314 },
- { State: 'DC', Age: 'Under 5 Years', Population: 30352 },
- { State: 'DC', Age: '5 to 13 Years', Population: 20439 },
- { State: 'DC', Age: '14 to 17 Years', Population: 10225 },
- { State: 'VT', Age: 'Under 5 Years', Population: 38253 },
- { State: 'VT', Age: '5 to 13 Years', Population: 42538 },
- { State: 'VT', Age: '14 to 17 Years', Population: 15757 },
- { State: 'ND', Age: 'Under 5 Years', Population: 51896 },
- { State: 'ND', Age: '5 to 13 Years', Population: 67358 },
- { State: 'ND', Age: '14 to 17 Years', Population: 18794 },
- { State: 'AK', Age: 'Under 5 Years', Population: 72083 },
- { State: 'AK', Age: '5 to 13 Years', Population: 85640},
- { State: 'AK', Age: '14 to 17 Years', Population: 22153 }
- ]
- }
- ],
- title: {
- visible: true,
- text: 'Stacked bar chart',
- subtext: 'This is a stacked bar chart',
- },
- seriesField: 'Age',
- legends: {
- visible: true
- },
-};
-
-function App() {
- const [direction, setDirection] = useState("vertical");
- const onChange = useCallback((e) => setDirection(e.target.value), []);
- const spec = useMemo(() => {
- const isVertical = direction === 'vertical';
- return {
- ...commonSpec,
- xField: isVertical ? 'State' : 'Population',
- yField: isVertical ? 'Population' : 'State',
- direction: direction,
- };
- }, [direction]);
- return (
- <>
-
- vertical
- horizontal
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-Percentage stacked bar chart
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const commonSpec = {
- type: 'bar',
- percent: true,
- stack: true,
- data: [
- {
- id: 'barData',
- values: [
- { State: 'WY', Age: 'Under 5 Years', Population: 25635 },
- { State: 'WY', Age: '5 to 13 Years', Population: 1890 },
- { State: 'WY', Age: '14 to 17 Years', Population: 9314 },
- { State: 'DC', Age: 'Under 5 Years', Population: 30352 },
- { State: 'DC', Age: '5 to 13 Years', Population: 20439 },
- { State: 'DC', Age: '14 to 17 Years', Population: 10225 },
- { State: 'VT', Age: 'Under 5 Years', Population: 38253 },
- { State: 'VT', Age: '5 to 13 Years', Population: 42538 },
- { State: 'VT', Age: '14 to 17 Years', Population: 15757 },
- { State: 'ND', Age: 'Under 5 Years', Population: 51896 },
- { State: 'ND', Age: '5 to 13 Years', Population: 67358 },
- { State: 'ND', Age: '14 to 17 Years', Population: 18794 },
- { State: 'AK', Age: 'Under 5 Years', Population: 72083 },
- { State: 'AK', Age: '5 to 13 Years', Population: 85640},
- { State: 'AK', Age: '14 to 17 Years', Population: 22153 }
- ]
- }
- ],
- title: {
- visible: true,
- text: 'Percentage stacked bar chart',
- subtext: 'This is a percentage stacked bar chart',
- },
- seriesField: 'Age',
- legends: { visible: true },
- axes: [
- {
- orient: 'left',
- label: {
- formatMethod: val => {
- return `${(val * 100).toFixed(2)}%`;
- }
- }
- }
- ],
-};
-
-function App() {
- const [direction, setDirection] = useState("vertical");
- const onChange = useCallback((e) => setDirection(e.target.value), []);
- const spec = useMemo(() => {
- const isVertical = direction === 'vertical';
- const spec = {
- ...commonSpec,
- xField: isVertical ? 'State' : 'Population',
- yField: isVertical ? 'Population' : 'State',
- direction: direction,
- };
- spec.axes[0].orient = isVertical ? 'left': 'top';
- return spec;
- }, [direction]);
- return (
- <>
-
- vertical
- horizontal
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-### Line chart
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const commonSpec = {
- type: 'line',
- xField: 'year',
- yField: 'count',
- seriesField: 'medalType',
- legends: { visible: true }
-};
-
-const data = [[40, 32, 34, 36, 45, 33, 34, 83, 36, 37, 44, 37, 35, 36, 46],
- [19, 25, 21, 26, 28, 31, 35, 60, 31, 34, 32, 24, 40, 38, 29],
- [17, 17, 16, 28, 34, 30, 25, 30, 27, 37, 25, 33, 26, 36, 29]].map((arr, outer) => {
- const type = ['Gold', 'Silver', 'Bronze'][outer];
- return arr.map((item, inner) => ({
- year: `${inner * 4 + 1952}`,
- count: item,
- medalType: type,
- }));
-});
-
-function App() {
- const [type, setType] = useState('multiple');
- const onChange = useCallback((e) => setType(e.target.value), []);
- const spec = useMemo(() => {
- return {
- ...commonSpec,
- title: {
- visible: true,
- text: `${type === "multiple" ? "Multi-series" : "Basic"} line chart`,
- subtext: `This is a ${type === "multiple" ? "multi-series" : "basic"} line chart`,
- },
- data: { values: type === 'multiple' ? data[0].concat(data[1]).concat(data[2]) : data[0] }
- };
- }, [type])
-
- return (
- <>
-
- multiple
- single
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-### Area chart
-
-```jsx live=true dir="row" noInline=true half=true
-import React from "react";
-import { VChart } from "@visactor/react-vchart";
-
-const commonSpec = {
- type: 'area',
- stack: true,
- title: {
- visible: true,
- text: 'Stacked area chart',
- subtext: 'This is a stacked area chart',
- },
- xField: 'type',
- yField: 'value',
- seriesField: 'country',
- legends: { visible: true },
- tooltip: {
- dimension: {
- updateContent: data => {
- let sum = 0;
- data.forEach(datum => {
- sum += +datum.value;
- });
- data.push({
- hasShape: 'false',
- key: 'Total',
- value: sum
- });
- return data;
- }
- }
- }
-};
-
-const values = [[4229, 4376, 3054, 12814], [3932, 3987, 5067, 13012],
- [5221, 3574, 7004, 11624], [9256, 4376, 9054, 8814],[3308, 4572, 12043, 12998],
- [5432, 3417, 15067, 12321],[13701, 5231, 10119, 10342],[4008, 4572, 12043, 22998],
- [18712, 6134, 10419, 11261]].reduce((acc, arr, index) => {
- const type = ['Nail polish', 'Eyebrow pencil', 'Rouge', 'Lipstick', 'Eyeshadows',
- 'Eyeliner', 'Foundation', 'Lip gloss', 'Mascara'][index];
- const result = ['Africa', 'EU', 'China', 'USA'].map((item, innerIndex) => ({
- country: item,
- type: type,
- value: arr[innerIndex],
- }));
- return acc.concat(result);
- }, []);
-
-const data = {
- fields: {
- country: {
- domain: ['Africa', 'EU', 'China', 'USA'].reverse(),
- lockStatisticsByDomain: true
- }
- },
- values: values,
-}
-
-function App() {
- return (
-
-
-
- )
-}
-
-render(App);
-```
-
-### Pie Chart
-
-```jsx live=true dir="column" noInline=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const commonSpec = {
- type: 'pie',
- data: [
- {
- id: 'id0',
- values: [{ type: 'oxygen', value: '46.60' }, { type: 'silicon', value: '27.72' },
- { type: 'aluminum', value: '8.13' }, { type: 'iron', value: '5' },
- { type: 'calcium', value: '3.63' }, { type: 'sodium', value: '2.83' },
- { type: 'potassium', value: '2.59' }, { type: 'others', value: '3.5' }]
- }
- ],
- valueField: 'value',
- categoryField: 'type',
- label: {
- visible: true
- },
- tooltip: {
- mark: {
- content: [
- {
- key: datum => datum['type'],
- value: datum => datum['value'] + '%'
- }
- ]
- }
- }
-};
-
-const donutChart = {
- title: {
- visible: true,
- text: 'Pie chart',
- subtext: 'This is a pie chart',
- },
- legends: {
- visible: true,
- orient: 'right'
- },
-}
-
-const donutWithIndicator = {
- title: {
- visible: true,
- text: 'Donut chart with indicator',
- subtext: 'This is a donut chart with indicator',
- },
- legends: {
- visible: true,
- orient: 'right'
- },
- indicator: {
- visible: true,
- trigger: 'select',
- title: {
- visible: true,
- style: {
- fontSize: 12,
- fontWeight: 'normal',
- text: data => {
- if (data) {
- const value = data['type'];
- return value ? value : null;
- }
- return 'Sum';
- }
- }
- },
- content: [
- {
- visible: true,
- fontWeight: 'bold',
- style: {
- fontSize: 20,
- text: data => {
- if (data) {
- const value = data['value'];
- return value ? `${value}%` : null;
- }
- return 1234;
- }
- }
- }
- ]
- }
-}
-
-function App() {
- const [type, setType] = useState('donut');
- const onChange = useCallback((e) => setType(e.target.value), []);
- return (
- <>
-
- 饼图
- 带指标卡饼图
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-
-
-### Radar chart
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const basicSpec = {
- type: 'radar',
- data: [
- {
- id: 'radarData',
- values: [
- { key: 'Strength', value: 5 },
- { key: 'Speed', value: 5 },
- { key: 'Shooting', value: 3 },
- { key: 'Endurance', value: 5 },
- { key: 'Precision', value: 5 },
- { key: 'Growth', value: 5 }
- ]
- }
- ],
- categoryField: 'key',
- valueField: 'value',
- point: { visible: true },
- area: { visible: true },
- axes: [
- {
- orient: 'radius', // radius axis
- zIndex: 100,
- min: 0,
- max: 8,
- domainLine: { visible: false },
- label: {
- visible: true,
- space: 0,
- style: { textAlign: 'center', stroke: '#fff', lineWidth: 4 }
- },
- grid: { smooth: false },
- },
- {
- orient: 'angle', // angle axis
- zIndex: 50,
- tick: { visible: false },
- domainLine: { visible: false },
- label: { space: 20 },
- }
- ]
-};
-
-const groupSpec = {
- type: 'radar',
- data: [{
- values: [[45, 61, 92, 57, 46, 36, 33, 63, 57, 53, 69, 40],
- [31, 39, 81, 39, 64, 21, 58, 72, 47, 37, 80, 74],
- [90, 95, 62, 52, 74, 87, 80, 69, 74, 84, 94, 23]]
- .reduce((acc, cur, index) => {
- const type = ['A', 'B', 'C'];
- const month = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May.', 'Jun.',
- 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.']
- const result = cur.map((item, innerIndex) => ({
- month: month[innerIndex],
- value: item,
- type: type[index]
- }))
- return acc.concat(result);
- }, []),
- }],
- categoryField: 'month',
- valueField: 'value',
- seriesField: 'type',
- stack: true,
- area: { visible: true },
- legends: { visible: true, orient: 'right'}
-}
-
-function App() {
- const [type, setType] = useState('group');
- const onChange = useCallback((e) => setType(e.target.value), []);
- return (
- <>
-
- Basic radar chart
- Grouped radar chart
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-### Scatter chart
-
-```jsx live=true dir="row" noInline=true half=true
-import React from "react";
-import { VChart } from "@visactor/react-vchart";
-
-const data = [
- { continent: 'Americas', Country: 'Argentina', LifeExpectancy: 75.32, GDP: 12779.37964, Population: 40301927 },
- { continent: 'Americas', Country: 'Brazil', LifeExpectancy: 72.39, GDP: 9065.800825, Population: 190010647 },
- { continent: 'Americas', Country: 'Canada', LifeExpectancy: 80.653, GDP: 36319.23501, Population: 33390141 },
- { continent: 'Americas', Country: 'Chile', LifeExpectancy: 78.553, GDP: 13171.63885, Population: 16284741 },
- { continent: 'Americas', Country: 'Colombia', LifeExpectancy: 72.889, GDP: 7006.580419, Population: 44227550 },
- { continent: 'Americas', Country: 'Costa Rica', LifeExpectancy: 78.782, GDP: 9645.06142, Population: 4133884 },
- { continent: 'Americas', Country: 'Cuba', LifeExpectancy: 78.273, GDP: 8948.102923, Population: 11416987 },
- { continent: 'Americas', Country: 'Dominican Republic', LifeExpectancy: 72.235, GDP: 6025.374752, Population: 9319622 },
- { continent: 'Americas', Country: 'Ecuador', LifeExpectancy: 74.994, GDP: 6873.262326, Population: 13755680 },
- { continent: 'Americas', Country: 'El Salvador', LifeExpectancy: 71.878, GDP: 5728.353514, Population: 6939688 },
- { continent: 'Americas', Country: 'Guatemala', LifeExpectancy: 70.259, GDP: 5186.050003, Population: 12572928 },
- { continent: 'Americas', Country: 'Honduras', LifeExpectancy: 70.198, GDP: 3548.330846, Population: 7483763 },
- { continent: 'Americas', Country: 'Jamaica', LifeExpectancy: 72.567, GDP: 7320.880262, Population: 2780132 },
- { continent: 'Americas', Country: 'Mexico', LifeExpectancy: 76.195, GDP: 11977.57496, Population: 108700891 },
- { continent: 'Americas', Country: 'Nicaragua', LifeExpectancy: 72.899, GDP: 2749.320965, Population: 5675356 },
- { continent: 'Americas', Country: 'Panama', LifeExpectancy: 75.537, GDP: 9809.185636, Population: 3242173 },
- { continent: 'Americas', Country: 'Paraguay', LifeExpectancy: 71.752, GDP: 4172.838464, Population: 6667147 },
- { continent: 'Americas', Country: 'Peru', LifeExpectancy: 71.421, GDP: 7408.905561, Population: 28674757 },
- { continent: 'Americas', Country: 'Puerto Rico', LifeExpectancy: 78.746, GDP: 19328.70901, Population: 3942491 },
- { continent: 'Americas', Country: 'Trinidad and Tobago', LifeExpectancy: 69.819, GDP: 18008.50924, Population: 1056608 },
- { continent: 'Americas', Country: 'United States', LifeExpectancy: 78.242, GDP: 42951.65309, Population: 301139947 },
- { continent: 'Americas', Country: 'Uruguay', LifeExpectancy: 76.384, GDP: 10611.46299, Population: 3447496 },
- { continent: 'Americas', Country: 'Venezuela', LifeExpectancy: 73.747, GDP: 11415.80569, Population: 26084662 },
- { continent: 'Asia', Country: 'China', LifeExpectancy: 72.961, GDP: 4959.114854, Population: 1318683096 },
- { continent: 'Asia', Country: 'Hong Kong, China', LifeExpectancy: 82.208, GDP: 39724.97867, Population: 6980412 },
- { continent: 'Asia', Country: 'Japan', LifeExpectancy: 82.603, GDP: 31656.06806, Population: 127467972 },
- { continent: 'Asia', Country: 'Korea, Dem. Rep.', LifeExpectancy: 67.297, GDP: 1593.06548, Population: 23301725 },
- { continent: 'Asia', Country: 'Korea, Rep.', LifeExpectancy: 78.623, GDP: 23348.13973, Population: 49044790 },
- { continent: 'Europe', Country: 'Albania', LifeExpectancy: 76.423, GDP: 5937.029526, Population: 3600523 },
- { continent: 'Europe', Country: 'Austria', LifeExpectancy: 79.829, GDP: 36126.4927, Population: 8199783 },
- { continent: 'Europe', Country: 'Belgium', LifeExpectancy: 79.441, GDP: 33692.60508, Population: 10392226 },
- { continent: 'Europe', Country: 'Bosnia and Herzegovina', LifeExpectancy: 74.852, GDP: 7446.298803, Population: 4552198 },
- { continent: 'Europe', Country: 'Bulgaria', LifeExpectancy: 73.005, GDP: 10680.79282, Population: 7322858 },
- { continent: 'Europe', Country: 'Croatia', LifeExpectancy: 75.748, GDP: 14619.22272, Population: 4493312 },
- { continent: 'Europe', Country: 'Czech Republic', LifeExpectancy: 76.486, GDP: 22833.30851, Population: 10228744 },
- { continent: 'Europe', Country: 'Denmark', LifeExpectancy: 78.332, GDP: 35278.41874, Population: 5468120 },
- { continent: 'Europe', Country: 'Finland', LifeExpectancy: 79.313, GDP: 33207.0844, Population: 5238460 },
- { continent: 'Europe', Country: 'France', LifeExpectancy: 80.657, GDP: 30470.0167, Population: 61083916 },
- { continent: 'Europe', Country: 'Germany', LifeExpectancy: 79.406, GDP: 32170.37442, Population: 82400996 },
- { continent: 'Europe', Country: 'Greece', LifeExpectancy: 79.483, GDP: 27538.41188, Population: 10706290 },
- { continent: 'Europe', Country: 'Hungary', LifeExpectancy: 73.338, GDP: 18008.94444, Population: 9956108 },
- { continent: 'Europe', Country: 'Iceland', LifeExpectancy: 81.757, GDP: 36180.78919, Population: 301931 },
- { continent: 'Europe', Country: 'Ireland', LifeExpectancy: 78.885, GDP: 40675.99635, Population: 4109086 },
- { continent: 'Europe', Country: 'Italy', LifeExpectancy: 80.546, GDP: 28569.7197, Population: 58147733 },
- { continent: 'Europe', Country: 'Montenegro', LifeExpectancy: 74.543, GDP: 9253.896111, Population: 684736 },
- { continent: 'Europe', Country: 'Netherlands', LifeExpectancy: 79.762, GDP: 36797.93332, Population: 16570613 },
- { continent: 'Europe', Country: 'Norway', LifeExpectancy: 80.196, GDP: 49357.19017, Population: 4627926 },
- { continent: 'Europe', Country: 'Poland', LifeExpectancy: 75.563, GDP: 15389.92468, Population: 38518241 },
- { continent: 'Europe', Country: 'Portugal', LifeExpectancy: 78.098, GDP: 20509.64777, Population: 10642836 },
- { continent: 'Europe', Country: 'Romania', LifeExpectancy: 72.476, GDP: 10808.47561, Population: 22276056 },
- { continent: 'Europe', Country: 'Serbia', LifeExpectancy: 74.002, GDP: 9786.534714, Population: 10150265 },
- { continent: 'Europe', Country: 'Slovak Republic', LifeExpectancy: 74.663, GDP: 18678.31435, Population: 5447502 },
- { continent: 'Europe', Country: 'Slovenia', LifeExpectancy: 77.926, GDP: 25768.25759, Population: 2009245 },
- { continent: 'Europe', Country: 'Spain', LifeExpectancy: 80.941, GDP: 28821.0637, Population: 40448191 },
- { continent: 'Europe', Country: 'Sweden', LifeExpectancy: 80.884, GDP: 33859.74835, Population: 9031088 },
- { continent: 'Europe', Country: 'Switzerland', LifeExpectancy: 81.701, GDP: 37506.41907, Population: 7554661 },
- { continent: 'Europe', Country: 'Turkey', LifeExpectancy: 71.777, GDP: 8458.276384, Population: 71158647 },
- { continent: 'Europe', Country: 'United Kingdom', LifeExpectancy: 79.425, GDP: 33203.26128, Population: 60776238 },
- { continent: 'Oceania', Country: 'Australia', LifeExpectancy: 81.235, GDP: 34435.36744, Population: 20434176 },
- { continent: 'Oceania', Country: 'New Zealand', LifeExpectancy: 80.204, GDP: 25185.00911, Population: 4115771 }
-];
-
-function logScale(value, domain, range) {
- // Calculate the logarithm of the domain and range
- const logDomain = domain.map(x => (x !== 0 ? Math.log10(x) : 0));
- const logRange = range.map(x => Math.log10(x));
- // Calculate the position of the value in the domain, map it to the range
- const t = (Math.log10(value) - logDomain[0]) / (logDomain[1] - logDomain[0]);
- const newValue = (logRange[1] - logRange[0]) * t + logRange[0];
- // Return the mapped value and restore the logarithmic scaling
- return Math.pow(10, newValue);
-}
-
-// chart spec
-const spec = {
- type: 'common',
- series: [
- {
- type: 'scatter',
- xField: 'GDP',
- yField: 'LifeExpectancy',
- seriesField: 'continent',
- sizeField: 'Population',
- size: d => logScale(d.Population, [0, Math.max(...data.map(d => d.Population))], [1, 20])
- }
- ],
- crosshair: {
- yField: {
- visible: true,
- line: { visible: true, type: 'line' },
- label: { visible: true }
- },
- xField: {
- visible: true,
- line: { visible: true, type: 'line' },
- label: { visible: true }
- }
- },
- data: [{ id: 'data', values: data }],
- title: {
- visible: true,
- text: 'Basic scatter chart',
- subtext: 'This is a basic scatter chart',
- },
- axes: [
- {
- orient: 'left',
- type: 'linear',
- range: {
- min: Math.min(...data.map(d => d.LifeExpectancy)),
- max: Math.max(...data.map(d => d.LifeExpectancy))
- },
- domainLine: { visible: true }
- },
- {
- orient: 'bottom',
- type: 'linear',
- domainLine: { visible: true }
- }
- ],
- legends: [{ visible: true,}]
-};
-
-function App() {
- return (
-
-
-
- )
-}
-
-render(App);
-```
-
-## Design Guidelines
-
-### Usage Guide
-
-In order to assist designers in selecting charts, we have conducted in-depth analyses of 11 commonly used chart types and summarized chart selection guidelines. Please refer to the [Chart Selection Guidelines](https://bytedance.sg.larkoffice.com/docx/N10zdVn7AovY2kxFj8ulPiFYgUh). for more details.
-
-### Color Specifications
-
-`@visactor/vchart-semi-theme` defines color values for 20 discrete data palettes. The color values are sorted based on the principles of split complementary color schemes and alternating dark and light tones from the existing Semi color palette. For discrete data palettes, Semi Design has declared 20 tokens. If users need to customize the discrete data palettes, they can configure these tokens in the [DSM](https://semi.design/dsm) when customizing the theme. The specific steps for generating color values are as follows:
-
-Step1: Follow the split complementary color, generate the first version of the color palette
-
-We refer to the classic color scheme theory and adopt the principle of split complementary color picking, and color picking is carried out in a group of three.
-
-
-
-Step2: Base line correction, reduce ambiguity and improve contrast
-
-1. Avoid ambiguous colors such as red and green.
-2. To ensure discrimination and enhance color contrast, adjacent colors are adjusted to canary release according to the rhythm of "dark-light-dark-light".
-
-
-
-
-Step3: Sensible adjustment to enhance visual aesthetics
-
-In order to make the color system more harmonious, in addition to scientific theoretical support, aesthetic corrections need to be made in real business scenarios.
-
-
-
-Step4: Expand the color palette to adapt to a wide range of scenarios
-
-Based on the 10-color palette, we have expanded to 20-color palettes to adapt to a wider range of business scenarios.
-
-
-
-In VChart, there are various semantic colors applied to chart components, such as background color, border, slider, overlay, font, and text color. The @visactor/vchart-semi-theme package reads the token values of Semi CSS Variables on the body to automatically generate VChart chart themes. Generally, there is no need to consider this part of the specification separately. If you need to understand the detailed mapping of semantic colors, you can refer to the following two documents:
-
-- [VChart Theme Concept and Design Guidelines](https://visactor.io/vchart/guide/tutorial_docs/Theme/Theme_Concept_and_Design_Rules)
-- [VChart Theme Extension](https://visactor.io/vchart/guide/tutorial_docs/Theme/Theme_Extension)
-
-## Design Token
-
-Semi Design has declared 20 tokens for VChart, as shown in the table below.
-
-
-
-
-Prior to version 1.10.2 of @visactor/vchart-semi-theme, the tokens with names --semi-color-data-n (where n is 0, 2, 4, 6, 8, 10, 12, 14, 16, 18) were used as a 10-color palette.
-Starting from version 1.10.2 of @visactor/vchart-semi-theme, the tokens with names --semi-color-data-n (where n ranges from 0 to 9) are used as a 10-color palette.
-
+### Using Chart Themes in Figma
-For any questions, inquiries, or suggestions, you can join the VChart user group to provide feedback.
-
+Install the [Figma plugin](/en-US/start/design-source) to select a theme and draw themed charts directly within your designs.
diff --git a/content/show/chart/index.md b/content/show/chart/index.md
index 633df94375..c09dab52c4 100644
--- a/content/show/chart/index.md
+++ b/content/show/chart/index.md
@@ -2,1077 +2,71 @@
localeCode: zh-CN
order: 85
category: 展示类
-title: Data Visualization 数据可视化
+title: Semi DV 数据可视化
icon: doc-vchart
dir: column
-brief: 开箱即用的多端图表库。
+brief: Semi DV 是 Semi 设计系统中的数据可视化解决方案
---
-对于数据可视化场景,我们推荐使用 [VChart](https://visactor.io/vchart)。VChart 是字节跳动开源可视化解决方案 [VisActor](https://visactor.io) 的核心图表组件库,支持多种图表,简单易用,功能强大。
-基于 VChart,我们定制了一套符合 Semi 风格的图表库,优势如下:
+[Semi DV](/dsm_vchart) 是基于字节跳动开源可视化解决方案 [VChart](https://visactor.io/vchart) 的底层能力,所封装的一套符合 Semi Design 风格的数据可视化解决方案。
-- 🧩 开箱即用:简单配置及初始化即可使用
-- 🎨 风格统一:基于 VChart 定制了符合 Semi 风格的图表库样式,直接和 Semi Design Token 挂钩;默认样式经过多方验证,可读性和精确性高;支持用户自定义图表样式
-- 🌗 响应式:支持监听页面上的亮暗模式变化,自动对页面上的 VChart 图表进行热更新,同步换肤
+VChart 基于可视化语法库 VGrammar 和渲染引擎 VRender 进行封装,在满足数据呈现的同时,还支持面向叙事场景的动画编排、丰富的交互能力和定制化的图表风格。Semi DV 在此基础上支持图表主题配置,帮助用户在保障页面 UI 整体性的同时,灵活实现个性化视觉表达。
+Semi DV 支持简易模式和高级模式两种配置
+- 简易模式:定制主题色,选择色板,以及圆角、间距、粗细风格即可获取轻松获取一套图表主题
+- 高级模式:支持从基础 Token(颜色、字体、圆角、间距、线段、动画),元素(标题、坐标轴、图列、交互元素),图表(柱状图、折线图、面积图、饼图、漏斗图)等层级进行配置,满足用户精细化配置需求
-## 安装和使用
-### 1、安装
+### 创建图表主题
+访问[创建设计系统](/dsm/design_system_list?type=vcharts), 点击创建图表设计系统按钮。完成配置后,一键发布即可推送到 npm 中。
-在 React 工程中,可以使用以下命令安装 `@visactor/react-vchart`:
+
-```bash
-# npm
-npm i @visactor/react-vchart
+
-# yarn
-yarn add @visactor/react-vchart
-```
+
-此外,还需安装 `@visactor/vchart-semi-theme` 来适配 Semi 默认主题或通过 Semi DSM 发布的自定义主题。
+关于配置主题的更详细使用文档请参考[创建主题](https://semi.design/dsm_vchart/doc/zh-CN/theme/customized-theme-tutorial#dsm_创建主题)
-```bash
-# npm
-npm i @visactor/vchart-semi-theme
-
-# yarn
-yarn add @visactor/vchart-semi-theme
-```
-### 2、使用
+### 接入主题
-Semi 自 v2.47.0 版本增加相关的 Design Token 用于实现 VChart 对 Semi 主题或通过 Semi DSM 发布的自定义主题的适配。因此对于 v2.47.0 及以上版本,只需要在全局执行一次 `initVChartSemiTheme` 方法进行初始化。该语句通常可以放在 React 项目的入口文件中。如:
+安装 VChart
-```javascript
-//index.jsx
-import React from 'react';
-import { createRoot } from 'react-dom/client';
-import App from './app.jsx';
-import { initVChartSemiTheme } from '@visactor/vchart-semi-theme';
-
-// initialization
-initVChartSemiTheme();
-
-const dom = document.querySelector('#root');
-const root = createRoot(dom);
-root.render();
+```shell
+# 使用 npm 安装
+npm install @visactor/react-vchart
+# 使用 yarn 安装
+yarn add @visactor/react-vchart
```
-`initVChartSemiTheme` 方法支持传入一个对象作为 option,其类型声明为:
+主题包由设计师在 Semi DV 上配置完主题后发布,请向设计师询问主题包名称,假设主题包名为`@ies/semi-vchart-theme-test`,安装命令为
-```typescript
-interface IInitVChartSemiThemeOption {
- /** 初始亮暗色模式 */
- defaultMode?: 'light' | 'dark';
-}
+```shell
+npm install @ies/semi-vchart-theme-test
+# 或
+yarn add @ies/semi-vchart-theme-test
```
-对于 v2.47.0 以下版本的 Semi,虽然没有相应的 Design Token,但是可以借助 `@visactor/vchart-semi-theme` 中的内置主题包样式默认值。注意:此使用方式不支持明暗模式自动切换,用户可按需设置当前图表模式,代码示例如下:
+引入主题
```js
-import semiDesignLight from '@visactor/vchart-semi-theme/public/semiDesignLight.json';
-import semiDesignDark from '@visactor/vchart-semi-theme/public/semiDesignDark.json';
-import VChart from '@visactor/vchart';
-// register the theme
-VChart.ThemeManager.registerTheme('semiDesignLight', semiDesignLight);
-VChart.ThemeManager.registerTheme('semiDesignDark', semiDesignDark);
-// apply the light theme
-VChart.ThemeManager.setCurrentTheme('semiDesignLight');
-// apply the dark theme
-VChart.ThemeManager.setCurrentTheme('semiDesignDark');
-```
-
->主题包的更多信息见 [@visactor/vchart-semi-theme](https://www.npmjs.com/package/@visactor/vchart-semi-theme)
-绘制图表以及更详细的指引详见 [VChart 教程文档](https://visactor.io/vchart/guide/tutorial_docs/Cross-terminal_and_Developer_Ecology/react)。
-
-
-## 常用图表类型示例
-
-VChart 基于可视化语法库 [VGrammar](https://visactor.io/vgrammar) 和渲染引擎 [VRender](https://visactor.io/vrender) 进行封装,在满足数据呈现的同时,还支持面向叙事场景的动画编排、丰富的交互能力和定制化的图表风格,简单易用的配置大大降低了用户的学习成本。
-
-VChart 支持多种不同的图表类型,包括组合图、折线图、面积图、柱状图/条形图、饼/环图、散点图、色块图、直方图、箱形图、瀑布图、进度条、漏斗图、时序图、区间柱图、区间面积图、词云、仪表盘、矩形树图、桑基图、玫瑰图、雷达图、地图、Circle Packing、旭日图等,图表示例详情见 [VChart 图表示例](https://visactor.io/vchart/example)。以下是基于 Semi Design 默认主题的 VChart 常用图表使用示例:
-
-### 柱状图
-
-基础柱状图
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-import { initVChartSemiTheme } from '@visactor/vchart-semi-theme';
-
-initVChartSemiTheme();
-
-const commonSpec = {
- type: 'bar',
- data: [
- {
- id: 'barData',
- values: [
- { type:'Date', month: 'Monday', sales: 22 },
- { type:'Date', month: 'Tuesday', sales: 13 },
- { type:'Date', month: 'Wednesday', sales: 25 },
- { type:'Date', month: 'Thursday', sales: 29 },
- { type:'Date', month: 'Friday', sales: 38 }
- ]
- }
- ],
- title: {
- visible: true,
- text: 'Bar chart',
- subtext: 'This is a bar chart',
- },
- legends: {
- visible: true,
- },
- xField: 'month',
- yField: 'sales',
- seriesField: 'type',
-};
-
-function App() {
- const [direction, setDirection] = useState("vertical");
- const onChange = useCallback((e) => setDirection(e.target.value), []);
- const spec = useMemo(() => {
- const isVertical = direction === 'vertical';
- return {
- ...commonSpec,
- xField: isVertical ? 'month' : 'sales',
- yField: isVertical ? 'sales' : 'month',
- direction: direction,
- };
- }, [direction]);
- return (
- <>
-
- vertical
- horizontal
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-分组柱状图
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const commonSpec = {
- type: 'bar',
- data: [
- {
- id: 'barData',
- values: [
- { type: 'Autocracies', year: '1930', value: 129 },
- { type: 'Autocracies', year: '1940', value: 133 },
- { type: 'Autocracies', year: '1950', value: 130 },
- { type: 'Autocracies', year: '1960', value: 126 },
- { type: 'Autocracies', year: '1970', value: 117 },
- { type: 'Autocracies', year: '1980', value: 114 },
- { type: 'Autocracies', year: '1990', value: 111 },
- { type: 'Autocracies', year: '2000', value: 89 },
- { type: 'Autocracies', year: '2010', value: 80 },
- { type: 'Autocracies', year: '2018', value: 80 },
- { type: 'Democracies', year: '1930', value: 22 },
- { type: 'Democracies', year: '1940', value: 13 },
- { type: 'Democracies', year: '1950', value: 25 },
- { type: 'Democracies', year: '1960', value: 29 },
- { type: 'Democracies', year: '1970', value: 38 },
- { type: 'Democracies', year: '1980', value: 41 },
- { type: 'Democracies', year: '1990', value: 57 },
- { type: 'Democracies', year: '2000', value: 87 },
- { type: 'Democracies', year: '2010', value: 98 },
- { type: 'Democracies', year: '2018', value: 99 }
- ]
- }
- ],
- seriesField: 'type',
- title: {
- visible: true,
- text: 'Grouped bar chart',
- subtext: 'This is a grouped bar chart',
- },
- legends: {
- visible: true,
- }
-};
-
-function App() {
- const [direction, setDirection] = useState("vertical");
- const onChange = useCallback((e) => setDirection(e.target.value), []);
- const spec = useMemo(() => {
- const isVertical = direction === 'vertical';
- return {
- ...commonSpec,
- xField: isVertical ? ['year', 'type'] : 'value',
- yField: isVertical ? 'value' : ['year', 'type'],
- direction: direction,
- };
- }, [direction]);
- return (
- <>
-
- vertical
- horizontal
-
-
-
-
- >
- )
-}
-
-render(App);
+// vchart 亮色
+import vchartLight from "@ies/semi-vchart-theme-test/light.json";
+// vchart 暗色
+import vchartDark from "@ies/semi-vchart-theme-test/dark.json";
```
-堆叠柱状图
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const commonSpec = {
- type: 'bar',
- stack: true,
- data: [
- {
- id: 'barData',
- values: [
- { State: 'WY', Age: 'Under 5 Years', Population: 25635 },
- { State: 'WY', Age: '5 to 13 Years', Population: 1890 },
- { State: 'WY', Age: '14 to 17 Years', Population: 9314 },
- { State: 'DC', Age: 'Under 5 Years', Population: 30352 },
- { State: 'DC', Age: '5 to 13 Years', Population: 20439 },
- { State: 'DC', Age: '14 to 17 Years', Population: 10225 },
- { State: 'VT', Age: 'Under 5 Years', Population: 38253 },
- { State: 'VT', Age: '5 to 13 Years', Population: 42538 },
- { State: 'VT', Age: '14 to 17 Years', Population: 15757 },
- { State: 'ND', Age: 'Under 5 Years', Population: 51896 },
- { State: 'ND', Age: '5 to 13 Years', Population: 67358 },
- { State: 'ND', Age: '14 to 17 Years', Population: 18794 },
- { State: 'AK', Age: 'Under 5 Years', Population: 72083 },
- { State: 'AK', Age: '5 to 13 Years', Population: 85640},
- { State: 'AK', Age: '14 to 17 Years', Population: 22153 }
- ]
- }
- ],
- title: {
- visible: true,
- text: 'Stacked bar chart',
- subtext: 'This is a stacked bar chart',
- },
- seriesField: 'Age',
- legends: {
- visible: true
- },
-};
-
-function App() {
- const [direction, setDirection] = useState("vertical");
- const onChange = useCallback((e) => setDirection(e.target.value), []);
- const spec = useMemo(() => {
- const isVertical = direction === 'vertical';
- return {
- ...commonSpec,
- xField: isVertical ? 'State' : 'Population',
- yField: isVertical ? 'Population' : 'State',
- direction: direction,
- };
- }, [direction]);
- return (
- <>
-
- vertical
- horizontal
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-百分比堆叠柱状图
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const commonSpec = {
- type: 'bar',
- percent: true,
- stack: true,
- data: [
- {
- id: 'barData',
- values: [
- { State: 'WY', Age: 'Under 5 Years', Population: 25635 },
- { State: 'WY', Age: '5 to 13 Years', Population: 1890 },
- { State: 'WY', Age: '14 to 17 Years', Population: 9314 },
- { State: 'DC', Age: 'Under 5 Years', Population: 30352 },
- { State: 'DC', Age: '5 to 13 Years', Population: 20439 },
- { State: 'DC', Age: '14 to 17 Years', Population: 10225 },
- { State: 'VT', Age: 'Under 5 Years', Population: 38253 },
- { State: 'VT', Age: '5 to 13 Years', Population: 42538 },
- { State: 'VT', Age: '14 to 17 Years', Population: 15757 },
- { State: 'ND', Age: 'Under 5 Years', Population: 51896 },
- { State: 'ND', Age: '5 to 13 Years', Population: 67358 },
- { State: 'ND', Age: '14 to 17 Years', Population: 18794 },
- { State: 'AK', Age: 'Under 5 Years', Population: 72083 },
- { State: 'AK', Age: '5 to 13 Years', Population: 85640},
- { State: 'AK', Age: '14 to 17 Years', Population: 22153 }
- ]
- }
- ],
- title: {
- visible: true,
- text: 'Percentage stacked bar chart',
- subtext: 'This is a percentage stacked bar chart',
- },
- seriesField: 'Age',
- legends: { visible: true },
- axes: [
- {
- orient: 'left',
- label: {
- formatMethod: val => {
- return `${(val * 100).toFixed(2)}%`;
- }
- }
- }
- ],
-};
-
-function App() {
- const [direction, setDirection] = useState("vertical");
- const onChange = useCallback((e) => setDirection(e.target.value), []);
- const spec = useMemo(() => {
- const isVertical = direction === 'vertical';
- const spec = {
- ...commonSpec,
- xField: isVertical ? 'State' : 'Population',
- yField: isVertical ? 'Population' : 'State',
- direction: direction,
- };
- spec.axes[0].orient = isVertical ? 'left': 'top';
- return spec;
- }, [direction]);
- return (
- <>
-
- vertical
- horizontal
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-### 折线图
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const commonSpec = {
- type: 'line',
- xField: 'year',
- yField: 'count',
- seriesField: 'medalType',
- legends: { visible: true }
-};
-
-const data = [[40, 32, 34, 36, 45, 33, 34, 83, 36, 37, 44, 37, 35, 36, 46],
- [19, 25, 21, 26, 28, 31, 35, 60, 31, 34, 32, 24, 40, 38, 29],
- [17, 17, 16, 28, 34, 30, 25, 30, 27, 37, 25, 33, 26, 36, 29]].map((arr, outer) => {
- const type = ['Gold', 'Silver', 'Bronze'][outer];
- return arr.map((item, inner) => ({
- year: `${inner * 4 + 1952}`,
- count: item,
- medalType: type,
- }));
-});
-
-function App() {
- const [type, setType] = useState('multiple');
- const onChange = useCallback((e) => setType(e.target.value), []);
- const spec = useMemo(() => {
- return {
- ...commonSpec,
- title: {
- visible: true,
- text: `${type === "multiple" ? "Multi-series" : "Basic"} line chart`,
- subtext: `This is a ${type === "multiple" ? "multi-series" : "basic"} line chart`,
- },
- data: { values: type === 'multiple' ? data[0].concat(data[1]).concat(data[2]) : data[0] }
- };
- }, [type])
-
- return (
- <>
-
- multiple
- single
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-### 面积图
-
-```jsx live=true dir="row" noInline=true half=true
-import React from "react";
-import { VChart } from "@visactor/react-vchart";
-
-const commonSpec = {
- type: 'area',
- stack: true,
- title: {
- visible: true,
- text: 'Stacked area chart',
- subtext: 'This is a stacked area chart',
- },
- xField: 'type',
- yField: 'value',
- seriesField: 'country',
- legends: { visible: true },
- tooltip: {
- dimension: {
- updateContent: data => {
- let sum = 0;
- data.forEach(datum => {
- sum += +datum.value;
- });
- data.push({
- hasShape: 'false',
- key: 'Total',
- value: sum
- });
- return data;
- }
- }
- }
-};
-
-const values = [[4229, 4376, 3054, 12814], [3932, 3987, 5067, 13012],
- [5221, 3574, 7004, 11624], [9256, 4376, 9054, 8814],[3308, 4572, 12043, 12998],
- [5432, 3417, 15067, 12321],[13701, 5231, 10119, 10342],[4008, 4572, 12043, 22998],
- [18712, 6134, 10419, 11261]].reduce((acc, arr, index) => {
- const type = ['Nail polish', 'Eyebrow pencil', 'Rouge', 'Lipstick', 'Eyeshadows',
- 'Eyeliner', 'Foundation', 'Lip gloss', 'Mascara'][index];
- const result = ['Africa', 'EU', 'China', 'USA'].map((item, innerIndex) => ({
- country: item,
- type: type,
- value: arr[innerIndex],
- }));
- return acc.concat(result);
- }, []);
-
-const data = {
- fields: {
- country: {
- domain: ['Africa', 'EU', 'China', 'USA'].reverse(),
- lockStatisticsByDomain: true
- }
- },
- values: values,
-}
-
-function App() {
- return (
-
-
-
- )
-}
-
-render(App);
-```
-
-### 饼图
-
-```jsx live=true dir="column" noInline=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const commonSpec = {
- type: 'pie',
- data: [
- {
- id: 'id0',
- values: [{ type: 'oxygen', value: '46.60' }, { type: 'silicon', value: '27.72' },
- { type: 'aluminum', value: '8.13' }, { type: 'iron', value: '5' },
- { type: 'calcium', value: '3.63' }, { type: 'sodium', value: '2.83' },
- { type: 'potassium', value: '2.59' }, { type: 'others', value: '3.5' }]
- }
- ],
- valueField: 'value',
- categoryField: 'type',
- label: {
- visible: true
- },
- tooltip: {
- mark: {
- content: [
- {
- key: datum => datum['type'],
- value: datum => datum['value'] + '%'
- }
- ]
- }
- }
-};
-
-const donutChart = {
- title: {
- visible: true,
- text: 'Pie chart',
- subtext: 'This is a pie chart',
- },
- legends: {
- visible: true,
- orient: 'right'
- },
-}
-
-const donutWithIndicator = {
- title: {
- visible: true,
- text: 'Donut chart with indicator',
- subtext: 'This is a donut chart with indicator',
- },
- legends: {
- visible: true,
- orient: 'right'
- },
- indicator: {
- visible: true,
- trigger: 'select',
- title: {
- visible: true,
- style: {
- fontSize: 12,
- fontWeight: 'normal',
- text: data => {
- if (data) {
- const value = data['type'];
- return value ? value : null;
- }
- return '总和';
- }
- }
- },
- content: [
- {
- visible: true,
- fontWeight: 'bold',
- style: {
- fontSize: 20,
- text: data => {
- if (data) {
- const value = data['value'];
- return value ? `${value}%` : null;
- }
- return 1234;
- }
- }
- }
- ]
- }
-}
-
-function App() {
- const [type, setType] = useState('donut');
- const onChange = useCallback((e) => setType(e.target.value), []);
- return (
- <>
-
- 饼图
- 带指标卡饼图
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-
-
-### 雷达图
-
-```jsx live=true dir="row" noInline=true half=true
-import React, { useState, useCallback } from "react";
-import { VChart } from "@visactor/react-vchart";
-import { Radio, RadioGroup } from '@douyinfe/semi-ui';
-
-const basicSpec = {
- type: 'radar',
- data: [
- {
- id: 'radarData',
- values: [
- { key: 'Strength', value: 5 },
- { key: 'Speed', value: 5 },
- { key: 'Shooting', value: 3 },
- { key: 'Endurance', value: 5 },
- { key: 'Precision', value: 5 },
- { key: 'Growth', value: 5 }
- ]
- }
- ],
- categoryField: 'key',
- valueField: 'value',
- point: { visible: true },
- area: { visible: true },
- axes: [
- {
- orient: 'radius', // radius axis
- zIndex: 100,
- min: 0,
- max: 8,
- domainLine: { visible: false },
- label: {
- visible: true,
- space: 0,
- style: { textAlign: 'center', stroke: '#fff', lineWidth: 4 }
- },
- grid: { smooth: false },
- },
- {
- orient: 'angle', // angle axis
- zIndex: 50,
- tick: { visible: false },
- domainLine: { visible: false },
- label: { space: 20 },
- }
- ]
-};
-
-const groupSpec = {
- type: 'radar',
- data: [{
- values: [[45, 61, 92, 57, 46, 36, 33, 63, 57, 53, 69, 40],
- [31, 39, 81, 39, 64, 21, 58, 72, 47, 37, 80, 74],
- [90, 95, 62, 52, 74, 87, 80, 69, 74, 84, 94, 23]]
- .reduce((acc, cur, index) => {
- const type = ['A', 'B', 'C'];
- const month = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May.', 'Jun.',
- 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.']
- const result = cur.map((item, innerIndex) => ({
- month: month[innerIndex],
- value: item,
- type: type[index]
- }))
- return acc.concat(result);
- }, []),
- }],
- categoryField: 'month',
- valueField: 'value',
- seriesField: 'type',
- stack: true,
- area: { visible: true },
- legends: { visible: true, orient: 'right'}
-}
-
-function App() {
- const [type, setType] = useState('group');
- const onChange = useCallback((e) => setType(e.target.value), []);
- return (
- <>
-
- 基础雷达图
- 分组雷达图
-
-
-
-
- >
- )
-}
-
-render(App);
-```
-
-### 散点图
-
-```jsx live=true dir="row" noInline=true half=true
-import React from "react";
-import { VChart } from "@visactor/react-vchart";
-
-const data = [
- { continent: 'Americas', Country: 'Argentina', LifeExpectancy: 75.32, GDP: 12779.37964, Population: 40301927 },
- { continent: 'Americas', Country: 'Brazil', LifeExpectancy: 72.39, GDP: 9065.800825, Population: 190010647 },
- { continent: 'Americas', Country: 'Canada', LifeExpectancy: 80.653, GDP: 36319.23501, Population: 33390141 },
- { continent: 'Americas', Country: 'Chile', LifeExpectancy: 78.553, GDP: 13171.63885, Population: 16284741 },
- { continent: 'Americas', Country: 'Colombia', LifeExpectancy: 72.889, GDP: 7006.580419, Population: 44227550 },
- { continent: 'Americas', Country: 'Costa Rica', LifeExpectancy: 78.782, GDP: 9645.06142, Population: 4133884 },
- { continent: 'Americas', Country: 'Cuba', LifeExpectancy: 78.273, GDP: 8948.102923, Population: 11416987 },
- { continent: 'Americas', Country: 'Dominican Republic', LifeExpectancy: 72.235, GDP: 6025.374752, Population: 9319622 },
- { continent: 'Americas', Country: 'Ecuador', LifeExpectancy: 74.994, GDP: 6873.262326, Population: 13755680 },
- { continent: 'Americas', Country: 'El Salvador', LifeExpectancy: 71.878, GDP: 5728.353514, Population: 6939688 },
- { continent: 'Americas', Country: 'Guatemala', LifeExpectancy: 70.259, GDP: 5186.050003, Population: 12572928 },
- { continent: 'Americas', Country: 'Honduras', LifeExpectancy: 70.198, GDP: 3548.330846, Population: 7483763 },
- { continent: 'Americas', Country: 'Jamaica', LifeExpectancy: 72.567, GDP: 7320.880262, Population: 2780132 },
- { continent: 'Americas', Country: 'Mexico', LifeExpectancy: 76.195, GDP: 11977.57496, Population: 108700891 },
- { continent: 'Americas', Country: 'Nicaragua', LifeExpectancy: 72.899, GDP: 2749.320965, Population: 5675356 },
- { continent: 'Americas', Country: 'Panama', LifeExpectancy: 75.537, GDP: 9809.185636, Population: 3242173 },
- { continent: 'Americas', Country: 'Paraguay', LifeExpectancy: 71.752, GDP: 4172.838464, Population: 6667147 },
- { continent: 'Americas', Country: 'Peru', LifeExpectancy: 71.421, GDP: 7408.905561, Population: 28674757 },
- { continent: 'Americas', Country: 'Puerto Rico', LifeExpectancy: 78.746, GDP: 19328.70901, Population: 3942491 },
- { continent: 'Americas', Country: 'Trinidad and Tobago', LifeExpectancy: 69.819, GDP: 18008.50924, Population: 1056608 },
- { continent: 'Americas', Country: 'United States', LifeExpectancy: 78.242, GDP: 42951.65309, Population: 301139947 },
- { continent: 'Americas', Country: 'Uruguay', LifeExpectancy: 76.384, GDP: 10611.46299, Population: 3447496 },
- { continent: 'Americas', Country: 'Venezuela', LifeExpectancy: 73.747, GDP: 11415.80569, Population: 26084662 },
- { continent: 'Asia', Country: 'China', LifeExpectancy: 72.961, GDP: 4959.114854, Population: 1318683096 },
- { continent: 'Asia', Country: 'Hong Kong, China', LifeExpectancy: 82.208, GDP: 39724.97867, Population: 6980412 },
- { continent: 'Asia', Country: 'Japan', LifeExpectancy: 82.603, GDP: 31656.06806, Population: 127467972 },
- { continent: 'Asia', Country: 'Korea, Dem. Rep.', LifeExpectancy: 67.297, GDP: 1593.06548, Population: 23301725 },
- { continent: 'Asia', Country: 'Korea, Rep.', LifeExpectancy: 78.623, GDP: 23348.13973, Population: 49044790 },
- { continent: 'Europe', Country: 'Albania', LifeExpectancy: 76.423, GDP: 5937.029526, Population: 3600523 },
- { continent: 'Europe', Country: 'Austria', LifeExpectancy: 79.829, GDP: 36126.4927, Population: 8199783 },
- { continent: 'Europe', Country: 'Belgium', LifeExpectancy: 79.441, GDP: 33692.60508, Population: 10392226 },
- { continent: 'Europe', Country: 'Bosnia and Herzegovina', LifeExpectancy: 74.852, GDP: 7446.298803, Population: 4552198 },
- { continent: 'Europe', Country: 'Bulgaria', LifeExpectancy: 73.005, GDP: 10680.79282, Population: 7322858 },
- { continent: 'Europe', Country: 'Croatia', LifeExpectancy: 75.748, GDP: 14619.22272, Population: 4493312 },
- { continent: 'Europe', Country: 'Czech Republic', LifeExpectancy: 76.486, GDP: 22833.30851, Population: 10228744 },
- { continent: 'Europe', Country: 'Denmark', LifeExpectancy: 78.332, GDP: 35278.41874, Population: 5468120 },
- { continent: 'Europe', Country: 'Finland', LifeExpectancy: 79.313, GDP: 33207.0844, Population: 5238460 },
- { continent: 'Europe', Country: 'France', LifeExpectancy: 80.657, GDP: 30470.0167, Population: 61083916 },
- { continent: 'Europe', Country: 'Germany', LifeExpectancy: 79.406, GDP: 32170.37442, Population: 82400996 },
- { continent: 'Europe', Country: 'Greece', LifeExpectancy: 79.483, GDP: 27538.41188, Population: 10706290 },
- { continent: 'Europe', Country: 'Hungary', LifeExpectancy: 73.338, GDP: 18008.94444, Population: 9956108 },
- { continent: 'Europe', Country: 'Iceland', LifeExpectancy: 81.757, GDP: 36180.78919, Population: 301931 },
- { continent: 'Europe', Country: 'Ireland', LifeExpectancy: 78.885, GDP: 40675.99635, Population: 4109086 },
- { continent: 'Europe', Country: 'Italy', LifeExpectancy: 80.546, GDP: 28569.7197, Population: 58147733 },
- { continent: 'Europe', Country: 'Montenegro', LifeExpectancy: 74.543, GDP: 9253.896111, Population: 684736 },
- { continent: 'Europe', Country: 'Netherlands', LifeExpectancy: 79.762, GDP: 36797.93332, Population: 16570613 },
- { continent: 'Europe', Country: 'Norway', LifeExpectancy: 80.196, GDP: 49357.19017, Population: 4627926 },
- { continent: 'Europe', Country: 'Poland', LifeExpectancy: 75.563, GDP: 15389.92468, Population: 38518241 },
- { continent: 'Europe', Country: 'Portugal', LifeExpectancy: 78.098, GDP: 20509.64777, Population: 10642836 },
- { continent: 'Europe', Country: 'Romania', LifeExpectancy: 72.476, GDP: 10808.47561, Population: 22276056 },
- { continent: 'Europe', Country: 'Serbia', LifeExpectancy: 74.002, GDP: 9786.534714, Population: 10150265 },
- { continent: 'Europe', Country: 'Slovak Republic', LifeExpectancy: 74.663, GDP: 18678.31435, Population: 5447502 },
- { continent: 'Europe', Country: 'Slovenia', LifeExpectancy: 77.926, GDP: 25768.25759, Population: 2009245 },
- { continent: 'Europe', Country: 'Spain', LifeExpectancy: 80.941, GDP: 28821.0637, Population: 40448191 },
- { continent: 'Europe', Country: 'Sweden', LifeExpectancy: 80.884, GDP: 33859.74835, Population: 9031088 },
- { continent: 'Europe', Country: 'Switzerland', LifeExpectancy: 81.701, GDP: 37506.41907, Population: 7554661 },
- { continent: 'Europe', Country: 'Turkey', LifeExpectancy: 71.777, GDP: 8458.276384, Population: 71158647 },
- { continent: 'Europe', Country: 'United Kingdom', LifeExpectancy: 79.425, GDP: 33203.26128, Population: 60776238 },
- { continent: 'Oceania', Country: 'Australia', LifeExpectancy: 81.235, GDP: 34435.36744, Population: 20434176 },
- { continent: 'Oceania', Country: 'New Zealand', LifeExpectancy: 80.204, GDP: 25185.00911, Population: 4115771 }
-];
-
-function logScale(value, domain, range) {
- // Calculate the logarithm of the domain and range
- const logDomain = domain.map(x => (x !== 0 ? Math.log10(x) : 0));
- const logRange = range.map(x => Math.log10(x));
- // Calculate the position of the value in the domain, map it to the range
- const t = (Math.log10(value) - logDomain[0]) / (logDomain[1] - logDomain[0]);
- const newValue = (logRange[1] - logRange[0]) * t + logRange[0];
- // Return the mapped value and restore the logarithmic scaling
- return Math.pow(10, newValue);
-}
-
-// chart spec
-const spec = {
- type: 'common',
- series: [
- {
- type: 'scatter',
- xField: 'GDP',
- yField: 'LifeExpectancy',
- seriesField: 'continent',
- sizeField: 'Population',
- size: d => logScale(d.Population, [0, Math.max(...data.map(d => d.Population))], [1, 20])
- }
- ],
- crosshair: {
- yField: {
- visible: true,
- line: { visible: true, type: 'line' },
- label: { visible: true }
- },
- xField: {
- visible: true,
- line: { visible: true, type: 'line' },
- label: { visible: true }
- }
- },
- data: [{ id: 'data', values: data }],
- title: {
- visible: true,
- text: 'Basic scatter chart',
- subtext: 'This is a basic scatter chart',
- },
- axes: [
- {
- orient: 'left',
- type: 'linear',
- range: {
- min: Math.min(...data.map(d => d.LifeExpectancy)),
- max: Math.max(...data.map(d => d.LifeExpectancy))
- },
- domainLine: { visible: true }
- },
- {
- orient: 'bottom',
- type: 'linear',
- domainLine: { visible: true }
- }
- ],
- legends: [{ visible: true,}]
-};
-
-function App() {
- return (
-
-
-
- )
-}
+注册主题
+```js
+import VChart from '@visactor/vchart';
-render(App);
+VChart.ThemeManager.registerTheme("myLightTheme", vchartLight);
+// apply a theme
+VChart.ThemeManager.setCurrentTheme('myLightTheme');
```
-## 设计规范
-
-### 选用指南
-
-为了帮助设计师进行图表选择,我们对常用的 11 种图表进行了深度解析,并归纳出图表选用方案,见[图表选用规范](https://bytedance.sg.larkoffice.com/docx/N10zdVn7AovY2kxFj8ulPiFYgUh)。
-
-### 颜色规范
-
-`@visactor/vchart-semi-theme` 中定义了 20 个离散数据色板的色值。色值从已有的 Semi 色板中按照分裂互补配色和暗亮交替的原则进行排序。对于离散数据色板,Semi Design 侧已声明了 20 个 Token,如果需要自定义离散数据色板,用户可以在 [DSM](https://semi.design/dsm) 自定义主题时配置这些 Token。色值的具体生成步骤如下:
-
-Step1: 遵从分裂互补取色,生成初版色稿
-
-我们参考了经典配色理论,采用分裂互补取色原则,按照三个一组的方式进行取色。
-
-
-
-Step2: 基线矫正,降低歧义提升对比
-
-1. 规避红绿等易引起歧义的色彩。
-2. 为保证区分度, 增强色彩对比,相邻颜色按照“暗-亮-暗-亮”的节奏进行灰度调整。
-
-
-
-
-Step3: 感性调整,提升视觉美学
-
-为了让色彩体系更加和谐,在科学理论支撑之外,还需在真实业务场景下进行美学修正。
-
-
-
-Step4: 色板延展,适应广泛场景
-
-在 10 色色板的基础上,我们拓展到 20 色色板以适应更为广泛的业务场景。
-
-
-
-在 VChart 中,还有许多应用于图表组件的语义颜色,比如背景色、边框、滑块、弹层、字体、字色等。`@visactor/vchart-semi-theme` 会读取 body 上的 Semi CSS Variables 的 Token 值来自动生成 VChart 图表主题,通常无需额外考虑此部分的规范。如果需要了解详细的语义颜色映射关系可以参阅以下两篇文档:
-
-- [VChart 主题概念和设计规范](https://visactor.io/vchart/guide/tutorial_docs/Theme/Theme_Concept_and_Design_Rules)
-- [VChart 扩展主题包](https://visactor.io/vchart/guide/tutorial_docs/Theme/Theme_Extension)
-
-## Design Token
-
-Semi Design 为 VChart 声明的 20 个 Token 详见下表。
-
-
-
-
- 在 @visactor/vchart-semi-theme 1.10.2 版本前,其中的名称为 --semi-color-data-n(n 为 0, 2, 4, 6, 8, 10, 12, 14, 16, 18)的 Token 值作为 10 色的色板。
- 在 @visactor/vchart-semi-theme 1.10.2 版本后,其中的名称为 --semi-color-data-n(n 从 0 到 9)的 Token 作为 10 色的色板。
-
-
+### 在 Figma 中使用图表主题
-使用问题咨询/建议,可加入 VChart 用户群进行反馈
-
+安装 [Figma 插件](/zh-CN/start/design-source) ,可选择主题,并在设计稿上绘制带有主题的图表