mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-05-01 12:38:12 +08:00
2152 lines
46 KiB
Markdown
2152 lines
46 KiB
Markdown
---
|
||
url: /guide/chart/echarts/index.md
|
||
---
|
||
## 概述
|
||
|
||
主题支持在文章中嵌入 [ECharts](https://echarts.apache.org/zh/index.html) 图表。
|
||
|
||
该功能由 [@vuepress/plugin-markdown-chart](https://ecosystem.vuejs.press/plugins/markdown/markdown-chart/) 提供支持。
|
||
|
||
## 配置
|
||
|
||
主题默认不启用该功能。
|
||
|
||
你需要在你的项目中安装 [ECharts](https://echarts.apache.org/zh/index.html) 库。
|
||
|
||
::: npm-to
|
||
|
||
```sh
|
||
npm install echarts
|
||
```
|
||
|
||
:::
|
||
|
||
然后在 `.vuepress/config.ts` 配置文件中,启用该功能:
|
||
|
||
```ts title=".vuepress/config.ts"
|
||
export default defineUserConfig({
|
||
theme: plumeTheme({
|
||
markdown: {
|
||
echarts: true, // [!code ++]
|
||
},
|
||
})
|
||
})
|
||
```
|
||
|
||
::: note
|
||
以下文档 Fork 自 [@vuepress/plugin-markdown-chart](https://ecosystem.vuejs.press/plugins/markdown/markdown-chart/echarts.html),
|
||
遵循 [MIT](https://github.com/vuepress/ecosystem/blob/main/LICENSE) 许可证。
|
||
:::
|
||
|
||
## 语法
|
||
|
||
### JSON 配置
|
||
|
||
如果你可以很轻松的生成数据,你可以直接通过一个 JSON 代码块来提供 Echarts 配置:
|
||
|
||
````md
|
||
::: echarts 标题
|
||
|
||
```json
|
||
{
|
||
// 此处为 ECharts 图表配置
|
||
}
|
||
```
|
||
|
||
:::
|
||
````
|
||
|
||
### JavaScript 配置
|
||
|
||
如果你需要通过脚本来获取数据,你可以使用 js 和 javascript 的代码块。
|
||
|
||
我们将通过 `echarts` 变量暴露 Echarts 实例,并且你应该将 Echart 配置赋值给 `option` 变量。
|
||
同时,你也可以赋值 `width` 和 `height` 来设置图表大小。
|
||
|
||
````md
|
||
::: echarts Title
|
||
```js
|
||
const option = {
|
||
// 此处为 ECharts 图表配置
|
||
}
|
||
```
|
||
:::
|
||
````
|
||
|
||
:::tip
|
||
你可以使用顶级 `await` 和 `fetch` 来从网络请求中获取数据。
|
||
:::
|
||
|
||
相关配置,详见 [ECharts 文档](https://echarts.apache.org/handbook/zh/get-started/)
|
||
|
||
## 高级
|
||
|
||
你可以在 [客户端配置文件](https://vuejs.press/zh/guide/configuration.html##使用脚本) 中导入并使用 `defineEchartsConfig` 来自定义 Echarts:
|
||
|
||
```ts
|
||
import { defineEchartsConfig } from '@vuepress/plugin-markdown-chart/client'
|
||
import { defineClientConfig } from 'vuepress/client'
|
||
|
||
defineEchartsConfig({
|
||
options: {
|
||
// 全局 Echarts 配置
|
||
},
|
||
setup: async () => {
|
||
// Echarts 设置
|
||
// 例如: await import("echarts-wordcloud")
|
||
},
|
||
})
|
||
|
||
export default defineClientConfig({
|
||
// ...
|
||
})
|
||
```
|
||
|
||
## 示例
|
||
|
||
### 线图
|
||
|
||
**输入:**
|
||
|
||
:::: details 查看代码
|
||
|
||
````md
|
||
::: echarts Dynamic Data & Time Axis
|
||
```js
|
||
const oneDay = 86400000
|
||
const data = []
|
||
let now = new Date(1997, 9, 3)
|
||
let value = Math.random() * 1000
|
||
|
||
function randomData() {
|
||
now = new Date(+now + oneDay)
|
||
value = value + Math.random() * 21 - 10
|
||
return {
|
||
name: now.toString(),
|
||
value: [
|
||
[now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'),
|
||
Math.round(value),
|
||
],
|
||
}
|
||
}
|
||
|
||
for (let i = 0; i < 1000; i++) data.push(randomData())
|
||
|
||
const option = {
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
formatter(params) {
|
||
params = params[0]
|
||
const date = new Date(params.name)
|
||
return (
|
||
`${date.getDate()
|
||
}/${
|
||
date.getMonth() + 1
|
||
}/${
|
||
date.getFullYear()
|
||
} : ${
|
||
params.value[1]}`
|
||
)
|
||
},
|
||
axisPointer: {
|
||
animation: false,
|
||
},
|
||
},
|
||
xAxis: {
|
||
type: 'time',
|
||
splitLine: {
|
||
show: false,
|
||
},
|
||
},
|
||
yAxis: {
|
||
type: 'value',
|
||
boundaryGap: [0, '100%'],
|
||
splitLine: {
|
||
show: false,
|
||
},
|
||
},
|
||
toolbox: {
|
||
show: true,
|
||
feature: {
|
||
mark: {
|
||
show: true,
|
||
},
|
||
dataView: {
|
||
show: true,
|
||
readOnly: false,
|
||
},
|
||
restore: {
|
||
show: true,
|
||
},
|
||
saveAsImage: {
|
||
show: true,
|
||
},
|
||
},
|
||
},
|
||
series: [
|
||
{
|
||
name: 'Fake Data',
|
||
type: 'line',
|
||
showSymbol: false,
|
||
data,
|
||
},
|
||
],
|
||
}
|
||
const timeId = setInterval(() => {
|
||
if (echarts._disposed)
|
||
return clearInterval(timeId)
|
||
|
||
for (let i = 0; i < 5; i++) {
|
||
data.shift()
|
||
data.push(randomData())
|
||
}
|
||
echarts.setOption({
|
||
series: [
|
||
{
|
||
data,
|
||
},
|
||
],
|
||
})
|
||
}, 1000)
|
||
```
|
||
:::
|
||
````
|
||
|
||
::::
|
||
|
||
**输出:**
|
||
|
||
::: echarts Dynamic Data & Time Axis
|
||
|
||
```js
|
||
const oneDay = 86400000
|
||
const data = []
|
||
let now = new Date(1997, 9, 3)
|
||
let value = Math.random() * 1000
|
||
|
||
function randomData() {
|
||
now = new Date(+now + oneDay)
|
||
value = value + Math.random() * 21 - 10
|
||
return {
|
||
name: now.toString(),
|
||
value: [
|
||
[now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'),
|
||
Math.round(value),
|
||
],
|
||
}
|
||
}
|
||
|
||
for (let i = 0; i < 1000; i++) data.push(randomData())
|
||
|
||
const option = {
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
formatter(params) {
|
||
params = params[0]
|
||
const date = new Date(params.name)
|
||
return (
|
||
`${date.getDate()
|
||
}/${
|
||
date.getMonth() + 1
|
||
}/${
|
||
date.getFullYear()
|
||
} : ${
|
||
params.value[1]}`
|
||
)
|
||
},
|
||
axisPointer: {
|
||
animation: false,
|
||
},
|
||
},
|
||
xAxis: {
|
||
type: 'time',
|
||
splitLine: {
|
||
show: false,
|
||
},
|
||
},
|
||
yAxis: {
|
||
type: 'value',
|
||
boundaryGap: [0, '100%'],
|
||
splitLine: {
|
||
show: false,
|
||
},
|
||
},
|
||
toolbox: {
|
||
show: true,
|
||
feature: {
|
||
mark: {
|
||
show: true,
|
||
},
|
||
dataView: {
|
||
show: true,
|
||
readOnly: false,
|
||
},
|
||
restore: {
|
||
show: true,
|
||
},
|
||
saveAsImage: {
|
||
show: true,
|
||
},
|
||
},
|
||
},
|
||
series: [
|
||
{
|
||
name: 'Fake Data',
|
||
type: 'line',
|
||
showSymbol: false,
|
||
data,
|
||
},
|
||
],
|
||
}
|
||
const timeId = setInterval(() => {
|
||
if (echarts._disposed)
|
||
return clearInterval(timeId)
|
||
|
||
for (let i = 0; i < 5; i++) {
|
||
data.shift()
|
||
data.push(randomData())
|
||
}
|
||
echarts.setOption({
|
||
series: [
|
||
{
|
||
data,
|
||
},
|
||
],
|
||
})
|
||
}, 1000)
|
||
```
|
||
|
||
:::
|
||
|
||
### 柱状图
|
||
|
||
**输入:**
|
||
|
||
:::: details 查看代码
|
||
|
||
````md
|
||
::: echarts A bar chart
|
||
```js
|
||
const data = []
|
||
|
||
for (let i = 0; i < 5; i++) data.push(Math.round(Math.random() * 200))
|
||
|
||
const option = {
|
||
xAxis: {
|
||
max: 'dataMax',
|
||
},
|
||
yAxis: {
|
||
type: 'category',
|
||
data: ['A', 'B', 'C', 'D', 'E'],
|
||
inverse: true,
|
||
animationDuration: 300,
|
||
animationDurationUpdate: 300,
|
||
max: 2, // only the largest 3 bars will be displayed
|
||
},
|
||
series: [
|
||
{
|
||
realtimeSort: true,
|
||
name: 'X',
|
||
type: 'bar',
|
||
data,
|
||
label: {
|
||
show: true,
|
||
position: 'right',
|
||
valueAnimation: true,
|
||
},
|
||
},
|
||
],
|
||
legend: {
|
||
show: true,
|
||
},
|
||
toolbox: {
|
||
show: true,
|
||
feature: {
|
||
mark: {
|
||
show: true,
|
||
},
|
||
dataView: {
|
||
show: true,
|
||
readOnly: false,
|
||
},
|
||
restore: {
|
||
show: true,
|
||
},
|
||
saveAsImage: {
|
||
show: true,
|
||
},
|
||
},
|
||
},
|
||
animationDuration: 0,
|
||
animationDurationUpdate: 3000,
|
||
animationEasing: 'linear',
|
||
animationEasingUpdate: 'linear',
|
||
}
|
||
function run() {
|
||
for (let i = 0; i < data.length; i++)
|
||
data[i] += Math.round(Math.random() * Math.random() > 0.9 ? 2000 : 200)
|
||
|
||
echarts.setOption({
|
||
series: [{ type: 'bar', data }],
|
||
})
|
||
}
|
||
|
||
const timeId = setInterval(() => {
|
||
if (echarts._disposed)
|
||
return clearInterval(timeId)
|
||
|
||
run()
|
||
}, 3000)
|
||
```
|
||
:::
|
||
````
|
||
|
||
::::
|
||
|
||
**输出:**
|
||
|
||
::: echarts A bar chart
|
||
|
||
```js
|
||
const data = []
|
||
|
||
for (let i = 0; i < 5; i++) data.push(Math.round(Math.random() * 200))
|
||
|
||
const option = {
|
||
xAxis: {
|
||
max: 'dataMax',
|
||
},
|
||
yAxis: {
|
||
type: 'category',
|
||
data: ['A', 'B', 'C', 'D', 'E'],
|
||
inverse: true,
|
||
animationDuration: 300,
|
||
animationDurationUpdate: 300,
|
||
max: 2, // only the largest 3 bars will be displayed
|
||
},
|
||
series: [
|
||
{
|
||
realtimeSort: true,
|
||
name: 'X',
|
||
type: 'bar',
|
||
data,
|
||
label: {
|
||
show: true,
|
||
position: 'right',
|
||
valueAnimation: true,
|
||
},
|
||
},
|
||
],
|
||
legend: {
|
||
show: true,
|
||
},
|
||
toolbox: {
|
||
show: true,
|
||
feature: {
|
||
mark: {
|
||
show: true,
|
||
},
|
||
dataView: {
|
||
show: true,
|
||
readOnly: false,
|
||
},
|
||
restore: {
|
||
show: true,
|
||
},
|
||
saveAsImage: {
|
||
show: true,
|
||
},
|
||
},
|
||
},
|
||
animationDuration: 0,
|
||
animationDurationUpdate: 3000,
|
||
animationEasing: 'linear',
|
||
animationEasingUpdate: 'linear',
|
||
}
|
||
function run() {
|
||
for (let i = 0; i < data.length; i++)
|
||
data[i] += Math.round(Math.random() * Math.random() > 0.9 ? 2000 : 200)
|
||
|
||
echarts.setOption({
|
||
series: [{ type: 'bar', data }],
|
||
})
|
||
}
|
||
|
||
const timeId = setInterval(() => {
|
||
if (echarts._disposed)
|
||
return clearInterval(timeId)
|
||
|
||
run()
|
||
}, 3000)
|
||
```
|
||
|
||
:::
|
||
|
||
### 饼图
|
||
|
||
**输入:**
|
||
|
||
:::: details 查看代码
|
||
|
||
````md
|
||
::: echarts A nightingale chart
|
||
```json
|
||
{
|
||
"legend": {
|
||
"top": "bottom"
|
||
},
|
||
"toolbox": {
|
||
"show": true,
|
||
"feature": {
|
||
"mark": {
|
||
"show": true
|
||
},
|
||
"dataView": {
|
||
"show": true,
|
||
"readOnly": false
|
||
},
|
||
"restore": {
|
||
"show": true
|
||
},
|
||
"saveAsImage": {
|
||
"show": true
|
||
}
|
||
}
|
||
},
|
||
"series": [
|
||
{
|
||
"name": "Nightingale Chart",
|
||
"type": "pie",
|
||
"radius": [20, 100],
|
||
"center": ["50%", "50%"],
|
||
"roseType": "area",
|
||
"itemStyle": {
|
||
"borderRadius": 8
|
||
},
|
||
"data": [
|
||
{
|
||
"value": 40,
|
||
"name": "rose 1"
|
||
},
|
||
{
|
||
"value": 38,
|
||
"name": "rose 2"
|
||
},
|
||
{
|
||
"value": 32,
|
||
"name": "rose 3"
|
||
},
|
||
{
|
||
"value": 30,
|
||
"name": "rose 4"
|
||
},
|
||
{
|
||
"value": 28,
|
||
"name": "rose 5"
|
||
},
|
||
{
|
||
"value": 26,
|
||
"name": "rose 6"
|
||
},
|
||
{
|
||
"value": 22,
|
||
"name": "rose 7"
|
||
},
|
||
{
|
||
"value": 18,
|
||
"name": "rose 8"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
:::
|
||
````
|
||
|
||
::::
|
||
|
||
**输出:**
|
||
|
||
::: echarts A nightingale chart
|
||
|
||
```json
|
||
{
|
||
"legend": {
|
||
"top": "bottom"
|
||
},
|
||
"toolbox": {
|
||
"show": true,
|
||
"feature": {
|
||
"mark": {
|
||
"show": true
|
||
},
|
||
"dataView": {
|
||
"show": true,
|
||
"readOnly": false
|
||
},
|
||
"restore": {
|
||
"show": true
|
||
},
|
||
"saveAsImage": {
|
||
"show": true
|
||
}
|
||
}
|
||
},
|
||
"series": [
|
||
{
|
||
"name": "Nightingale Chart",
|
||
"type": "pie",
|
||
"radius": [20, 100],
|
||
"center": ["50%", "50%"],
|
||
"roseType": "area",
|
||
"itemStyle": {
|
||
"borderRadius": 8
|
||
},
|
||
"data": [
|
||
{
|
||
"value": 40,
|
||
"name": "rose 1"
|
||
},
|
||
{
|
||
"value": 38,
|
||
"name": "rose 2"
|
||
},
|
||
{
|
||
"value": 32,
|
||
"name": "rose 3"
|
||
},
|
||
{
|
||
"value": 30,
|
||
"name": "rose 4"
|
||
},
|
||
{
|
||
"value": 28,
|
||
"name": "rose 5"
|
||
},
|
||
{
|
||
"value": 26,
|
||
"name": "rose 6"
|
||
},
|
||
{
|
||
"value": 22,
|
||
"name": "rose 7"
|
||
},
|
||
{
|
||
"value": 18,
|
||
"name": "rose 8"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
:::
|
||
|
||
### 散点图
|
||
|
||
**输入:**
|
||
|
||
:::: details 查看代码
|
||
|
||
````md
|
||
::: echarts A scatter chart
|
||
```json
|
||
{
|
||
"xAxis": {},
|
||
"yAxis": {},
|
||
"series": [
|
||
{
|
||
"symbolSize": 20,
|
||
"data": [
|
||
[10.0, 8.04],
|
||
[8.07, 6.95],
|
||
[13.0, 7.58],
|
||
[9.05, 8.81],
|
||
[11.0, 8.33],
|
||
[14.0, 7.66],
|
||
[13.4, 6.81],
|
||
[10.0, 6.33],
|
||
[14.0, 8.96],
|
||
[12.5, 6.82],
|
||
[9.15, 7.2],
|
||
[11.5, 7.2],
|
||
[3.03, 4.23],
|
||
[12.2, 7.83],
|
||
[2.02, 4.47],
|
||
[1.05, 3.33],
|
||
[4.05, 4.96],
|
||
[6.03, 7.24],
|
||
[12.0, 6.26],
|
||
[12.0, 8.84],
|
||
[7.08, 5.82],
|
||
[5.02, 5.68]
|
||
],
|
||
"type": "scatter"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
:::
|
||
````
|
||
|
||
::::
|
||
|
||
**输出:**
|
||
|
||
::: echarts A scatter chart
|
||
|
||
```json
|
||
{
|
||
"xAxis": {},
|
||
"yAxis": {},
|
||
"series": [
|
||
{
|
||
"symbolSize": 20,
|
||
"data": [
|
||
[10.0, 8.04],
|
||
[8.07, 6.95],
|
||
[13.0, 7.58],
|
||
[9.05, 8.81],
|
||
[11.0, 8.33],
|
||
[14.0, 7.66],
|
||
[13.4, 6.81],
|
||
[10.0, 6.33],
|
||
[14.0, 8.96],
|
||
[12.5, 6.82],
|
||
[9.15, 7.2],
|
||
[11.5, 7.2],
|
||
[3.03, 4.23],
|
||
[12.2, 7.83],
|
||
[2.02, 4.47],
|
||
[1.05, 3.33],
|
||
[4.05, 4.96],
|
||
[6.03, 7.24],
|
||
[12.0, 6.26],
|
||
[12.0, 8.84],
|
||
[7.08, 5.82],
|
||
[5.02, 5.68]
|
||
],
|
||
"type": "scatter"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
:::
|
||
|
||
### 极坐标图
|
||
|
||
**输入:**
|
||
|
||
:::: details 查看代码
|
||
|
||
````md
|
||
::: echarts Two Value-Axes in Polar
|
||
```js
|
||
const data = []
|
||
|
||
for (let i = 0; i <= 100; i++) {
|
||
const theta = (i / 100) * 360
|
||
const r = 5 * (1 + Math.sin((theta / 180) * Math.PI))
|
||
data.push([r, theta])
|
||
}
|
||
|
||
const height = 450
|
||
|
||
const option = {
|
||
legend: {
|
||
data: ['line'],
|
||
},
|
||
polar: {},
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
axisPointer: {
|
||
type: 'cross',
|
||
},
|
||
},
|
||
angleAxis: {
|
||
type: 'value',
|
||
startAngle: 0,
|
||
},
|
||
radiusAxis: {},
|
||
series: [
|
||
{
|
||
coordinateSystem: 'polar',
|
||
name: 'line',
|
||
type: 'line',
|
||
data,
|
||
},
|
||
],
|
||
}
|
||
```
|
||
:::
|
||
````
|
||
|
||
::::
|
||
|
||
**输出:**
|
||
|
||
::: echarts Two Value-Axes in Polar
|
||
|
||
```js
|
||
const data = []
|
||
|
||
for (let i = 0; i <= 100; i++) {
|
||
const theta = (i / 100) * 360
|
||
const r = 5 * (1 + Math.sin((theta / 180) * Math.PI))
|
||
data.push([r, theta])
|
||
}
|
||
|
||
const height = 450
|
||
|
||
const option = {
|
||
legend: {
|
||
data: ['line'],
|
||
},
|
||
polar: {},
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
axisPointer: {
|
||
type: 'cross',
|
||
},
|
||
},
|
||
angleAxis: {
|
||
type: 'value',
|
||
startAngle: 0,
|
||
},
|
||
radiusAxis: {},
|
||
series: [
|
||
{
|
||
coordinateSystem: 'polar',
|
||
name: 'line',
|
||
type: 'line',
|
||
data,
|
||
},
|
||
],
|
||
}
|
||
```
|
||
|
||
:::
|
||
|
||
### 烛台图
|
||
|
||
**输入:**
|
||
|
||
:::: details 查看代码
|
||
|
||
````md
|
||
::: echarts Stocks
|
||
```js
|
||
const upColor = '#ec0000'
|
||
const upBorderColor = '#8A0000'
|
||
const downColor = '#00da3c'
|
||
const downBorderColor = '#008F28'
|
||
|
||
function splitData(rawData) {
|
||
const categoryData = []
|
||
const values = []
|
||
|
||
for (let i = 0; i < rawData.length; i++) {
|
||
categoryData.push(rawData[i].splice(0, 1)[0])
|
||
values.push(rawData[i])
|
||
}
|
||
|
||
return {
|
||
categoryData,
|
||
values,
|
||
}
|
||
}
|
||
|
||
// Each item: open,close,lowest,highest
|
||
const data0 = splitData([
|
||
['2013/1/24', 2320.26, 2320.26, 2287.3, 2362.94],
|
||
['2013/1/25', 2300, 2291.3, 2288.26, 2308.38],
|
||
['2013/1/28', 2295.35, 2346.5, 2295.35, 2346.92],
|
||
['2013/1/29', 2347.22, 2358.98, 2337.35, 2363.8],
|
||
['2013/1/30', 2360.75, 2382.48, 2347.89, 2383.76],
|
||
['2013/1/31', 2383.43, 2385.42, 2371.23, 2391.82],
|
||
['2013/2/1', 2377.41, 2419.02, 2369.57, 2421.15],
|
||
['2013/2/4', 2425.92, 2428.15, 2417.58, 2440.38],
|
||
['2013/2/5', 2411, 2433.13, 2403.3, 2437.42],
|
||
['2013/2/6', 2432.68, 2434.48, 2427.7, 2441.73],
|
||
['2013/2/7', 2430.69, 2418.53, 2394.22, 2433.89],
|
||
['2013/2/8', 2416.62, 2432.4, 2414.4, 2443.03],
|
||
['2013/2/18', 2441.91, 2421.56, 2415.43, 2444.8],
|
||
['2013/2/19', 2420.26, 2382.91, 2373.53, 2427.07],
|
||
['2013/2/20', 2383.49, 2397.18, 2370.61, 2397.94],
|
||
['2013/2/21', 2378.82, 2325.95, 2309.17, 2378.82],
|
||
['2013/2/22', 2322.94, 2314.16, 2308.76, 2330.88],
|
||
['2013/2/25', 2320.62, 2325.82, 2315.01, 2338.78],
|
||
['2013/2/26', 2313.74, 2293.34, 2289.89, 2340.71],
|
||
['2013/2/27', 2297.77, 2313.22, 2292.03, 2324.63],
|
||
['2013/2/28', 2322.32, 2365.59, 2308.92, 2366.16],
|
||
['2013/3/1', 2364.54, 2359.51, 2330.86, 2369.65],
|
||
['2013/3/4', 2332.08, 2273.4, 2259.25, 2333.54],
|
||
['2013/3/5', 2274.81, 2326.31, 2270.1, 2328.14],
|
||
['2013/3/6', 2333.61, 2347.18, 2321.6, 2351.44],
|
||
['2013/3/7', 2340.44, 2324.29, 2304.27, 2352.02],
|
||
['2013/3/8', 2326.42, 2318.61, 2314.59, 2333.67],
|
||
['2013/3/11', 2314.68, 2310.59, 2296.58, 2320.96],
|
||
['2013/3/12', 2309.16, 2286.6, 2264.83, 2333.29],
|
||
['2013/3/13', 2282.17, 2263.97, 2253.25, 2286.33],
|
||
['2013/3/14', 2255.77, 2270.28, 2253.31, 2276.22],
|
||
['2013/3/15', 2269.31, 2278.4, 2250, 2312.08],
|
||
['2013/3/18', 2267.29, 2240.02, 2239.21, 2276.05],
|
||
['2013/3/19', 2244.26, 2257.43, 2232.02, 2261.31],
|
||
['2013/3/20', 2257.74, 2317.37, 2257.42, 2317.86],
|
||
['2013/3/21', 2318.21, 2324.24, 2311.6, 2330.81],
|
||
['2013/3/22', 2321.4, 2328.28, 2314.97, 2332],
|
||
['2013/3/25', 2334.74, 2326.72, 2319.91, 2344.89],
|
||
['2013/3/26', 2318.58, 2297.67, 2281.12, 2319.99],
|
||
['2013/3/27', 2299.38, 2301.26, 2289, 2323.48],
|
||
['2013/3/28', 2273.55, 2236.3, 2232.91, 2273.55],
|
||
['2013/3/29', 2238.49, 2236.62, 2228.81, 2246.87],
|
||
['2013/4/1', 2229.46, 2234.4, 2227.31, 2243.95],
|
||
['2013/4/2', 2234.9, 2227.74, 2220.44, 2253.42],
|
||
['2013/4/3', 2232.69, 2225.29, 2217.25, 2241.34],
|
||
['2013/4/8', 2196.24, 2211.59, 2180.67, 2212.59],
|
||
['2013/4/9', 2215.47, 2225.77, 2215.47, 2234.73],
|
||
['2013/4/10', 2224.93, 2226.13, 2212.56, 2233.04],
|
||
['2013/4/11', 2236.98, 2219.55, 2217.26, 2242.48],
|
||
['2013/4/12', 2218.09, 2206.78, 2204.44, 2226.26],
|
||
['2013/4/15', 2199.91, 2181.94, 2177.39, 2204.99],
|
||
['2013/4/16', 2169.63, 2194.85, 2165.78, 2196.43],
|
||
['2013/4/17', 2195.03, 2193.8, 2178.47, 2197.51],
|
||
['2013/4/18', 2181.82, 2197.6, 2175.44, 2206.03],
|
||
['2013/4/19', 2201.12, 2244.64, 2200.58, 2250.11],
|
||
['2013/4/22', 2236.4, 2242.17, 2232.26, 2245.12],
|
||
['2013/4/23', 2242.62, 2184.54, 2182.81, 2242.62],
|
||
['2013/4/24', 2187.35, 2218.32, 2184.11, 2226.12],
|
||
['2013/4/25', 2213.19, 2199.31, 2191.85, 2224.63],
|
||
['2013/4/26', 2203.89, 2177.91, 2173.86, 2210.58],
|
||
['2013/5/2', 2170.78, 2174.12, 2161.14, 2179.65],
|
||
['2013/5/3', 2179.05, 2205.5, 2179.05, 2222.81],
|
||
['2013/5/6', 2212.5, 2231.17, 2212.5, 2236.07],
|
||
['2013/5/7', 2227.86, 2235.57, 2219.44, 2240.26],
|
||
['2013/5/8', 2242.39, 2246.3, 2235.42, 2255.21],
|
||
['2013/5/9', 2246.96, 2232.97, 2221.38, 2247.86],
|
||
['2013/5/10', 2228.82, 2246.83, 2225.81, 2247.67],
|
||
['2013/5/13', 2247.68, 2241.92, 2231.36, 2250.85],
|
||
['2013/5/14', 2238.9, 2217.01, 2205.87, 2239.93],
|
||
['2013/5/15', 2217.09, 2224.8, 2213.58, 2225.19],
|
||
['2013/5/16', 2221.34, 2251.81, 2210.77, 2252.87],
|
||
['2013/5/17', 2249.81, 2282.87, 2248.41, 2288.09],
|
||
['2013/5/20', 2286.33, 2299.99, 2281.9, 2309.39],
|
||
['2013/5/21', 2297.11, 2305.11, 2290.12, 2305.3],
|
||
['2013/5/22', 2303.75, 2302.4, 2292.43, 2314.18],
|
||
['2013/5/23', 2293.81, 2275.67, 2274.1, 2304.95],
|
||
['2013/5/24', 2281.45, 2288.53, 2270.25, 2292.59],
|
||
['2013/5/27', 2286.66, 2293.08, 2283.94, 2301.7],
|
||
['2013/5/28', 2293.4, 2321.32, 2281.47, 2322.1],
|
||
['2013/5/29', 2323.54, 2324.02, 2321.17, 2334.33],
|
||
['2013/5/30', 2316.25, 2317.75, 2310.49, 2325.72],
|
||
['2013/5/31', 2320.74, 2300.59, 2299.37, 2325.53],
|
||
['2013/6/3', 2300.21, 2299.25, 2294.11, 2313.43],
|
||
['2013/6/4', 2297.1, 2272.42, 2264.76, 2297.1],
|
||
['2013/6/5', 2270.71, 2270.93, 2260.87, 2276.86],
|
||
['2013/6/6', 2264.43, 2242.11, 2240.07, 2266.69],
|
||
['2013/6/7', 2242.26, 2210.9, 2205.07, 2250.63],
|
||
['2013/6/13', 2190.1, 2148.35, 2126.22, 2190.1],
|
||
])
|
||
|
||
function calculateMA(dayCount) {
|
||
const result = []
|
||
|
||
for (let i = 0; i < data0.values.length; i++) {
|
||
if (i < dayCount) {
|
||
result.push('-')
|
||
continue
|
||
}
|
||
let sum = 0
|
||
|
||
for (let j = 0; j < dayCount; j++) sum += +data0.values[i - j][1]
|
||
|
||
result.push(sum / dayCount)
|
||
}
|
||
|
||
return result
|
||
}
|
||
const option = {
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
axisPointer: {
|
||
type: 'cross',
|
||
},
|
||
},
|
||
legend: {
|
||
data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30'],
|
||
},
|
||
grid: {
|
||
left: '10%',
|
||
right: '10%',
|
||
bottom: '15%',
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: data0.categoryData,
|
||
boundaryGap: false,
|
||
axisLine: { onZero: false },
|
||
splitLine: { show: false },
|
||
min: 'dataMin',
|
||
max: 'dataMax',
|
||
},
|
||
yAxis: {
|
||
scale: true,
|
||
splitArea: {
|
||
show: true,
|
||
},
|
||
},
|
||
dataZoom: [
|
||
{
|
||
type: 'inside',
|
||
start: 50,
|
||
end: 100,
|
||
},
|
||
{
|
||
show: true,
|
||
type: 'slider',
|
||
top: '90%',
|
||
start: 50,
|
||
end: 100,
|
||
},
|
||
],
|
||
series: [
|
||
{
|
||
name: '日K',
|
||
type: 'candlestick',
|
||
data: data0.values,
|
||
itemStyle: {
|
||
color: upColor,
|
||
color0: downColor,
|
||
borderColor: upBorderColor,
|
||
borderColor0: downBorderColor,
|
||
},
|
||
markPoint: {
|
||
label: {
|
||
formatter: param =>
|
||
param == null ? '' : Math.round(param.value).toString(),
|
||
},
|
||
data: [
|
||
{
|
||
name: 'Mark',
|
||
coord: ['2013/5/31', 2300],
|
||
value: 2300,
|
||
itemStyle: {
|
||
color: 'rgb(41,60,85)',
|
||
},
|
||
},
|
||
{
|
||
name: 'highest value',
|
||
type: 'max',
|
||
valueDim: 'highest',
|
||
},
|
||
{
|
||
name: 'lowest value',
|
||
type: 'min',
|
||
valueDim: 'lowest',
|
||
},
|
||
{
|
||
name: 'average value on close',
|
||
type: 'average',
|
||
valueDim: 'close',
|
||
},
|
||
],
|
||
tooltip: {
|
||
formatter: param => `${param.name}<br>${param.data.coord || ''}`,
|
||
},
|
||
},
|
||
markLine: {
|
||
symbol: ['none', 'none'],
|
||
data: [
|
||
[
|
||
{
|
||
name: 'from lowest to highest',
|
||
type: 'min',
|
||
valueDim: 'lowest',
|
||
symbol: 'circle',
|
||
symbolSize: 10,
|
||
label: {
|
||
show: false,
|
||
},
|
||
emphasis: {
|
||
label: {
|
||
show: false,
|
||
},
|
||
},
|
||
},
|
||
{
|
||
type: 'max',
|
||
valueDim: 'highest',
|
||
symbol: 'circle',
|
||
symbolSize: 10,
|
||
label: {
|
||
show: false,
|
||
},
|
||
emphasis: {
|
||
label: {
|
||
show: false,
|
||
},
|
||
},
|
||
},
|
||
],
|
||
{
|
||
name: 'min line on close',
|
||
type: 'min',
|
||
valueDim: 'close',
|
||
},
|
||
{
|
||
name: 'max line on close',
|
||
type: 'max',
|
||
valueDim: 'close',
|
||
},
|
||
],
|
||
},
|
||
},
|
||
{
|
||
name: 'MA5',
|
||
type: 'line',
|
||
data: calculateMA(5),
|
||
smooth: true,
|
||
lineStyle: {
|
||
opacity: 0.5,
|
||
},
|
||
},
|
||
{
|
||
name: 'MA10',
|
||
type: 'line',
|
||
data: calculateMA(10),
|
||
smooth: true,
|
||
lineStyle: {
|
||
opacity: 0.5,
|
||
},
|
||
},
|
||
{
|
||
name: 'MA20',
|
||
type: 'line',
|
||
data: calculateMA(20),
|
||
smooth: true,
|
||
lineStyle: {
|
||
opacity: 0.5,
|
||
},
|
||
},
|
||
{
|
||
name: 'MA30',
|
||
type: 'line',
|
||
data: calculateMA(30),
|
||
smooth: true,
|
||
lineStyle: {
|
||
opacity: 0.5,
|
||
},
|
||
},
|
||
],
|
||
}
|
||
```
|
||
:::
|
||
````
|
||
|
||
::::
|
||
|
||
**输出:**
|
||
|
||
::: echarts Stocks
|
||
|
||
```js
|
||
const upColor = '#ec0000'
|
||
const upBorderColor = '#8A0000'
|
||
const downColor = '#00da3c'
|
||
const downBorderColor = '#008F28'
|
||
|
||
function splitData(rawData) {
|
||
const categoryData = []
|
||
const values = []
|
||
|
||
for (let i = 0; i < rawData.length; i++) {
|
||
categoryData.push(rawData[i].splice(0, 1)[0])
|
||
values.push(rawData[i])
|
||
}
|
||
|
||
return {
|
||
categoryData,
|
||
values,
|
||
}
|
||
}
|
||
|
||
// Each item: open,close,lowest,highest
|
||
const data0 = splitData([
|
||
['2013/1/24', 2320.26, 2320.26, 2287.3, 2362.94],
|
||
['2013/1/25', 2300, 2291.3, 2288.26, 2308.38],
|
||
['2013/1/28', 2295.35, 2346.5, 2295.35, 2346.92],
|
||
['2013/1/29', 2347.22, 2358.98, 2337.35, 2363.8],
|
||
['2013/1/30', 2360.75, 2382.48, 2347.89, 2383.76],
|
||
['2013/1/31', 2383.43, 2385.42, 2371.23, 2391.82],
|
||
['2013/2/1', 2377.41, 2419.02, 2369.57, 2421.15],
|
||
['2013/2/4', 2425.92, 2428.15, 2417.58, 2440.38],
|
||
['2013/2/5', 2411, 2433.13, 2403.3, 2437.42],
|
||
['2013/2/6', 2432.68, 2434.48, 2427.7, 2441.73],
|
||
['2013/2/7', 2430.69, 2418.53, 2394.22, 2433.89],
|
||
['2013/2/8', 2416.62, 2432.4, 2414.4, 2443.03],
|
||
['2013/2/18', 2441.91, 2421.56, 2415.43, 2444.8],
|
||
['2013/2/19', 2420.26, 2382.91, 2373.53, 2427.07],
|
||
['2013/2/20', 2383.49, 2397.18, 2370.61, 2397.94],
|
||
['2013/2/21', 2378.82, 2325.95, 2309.17, 2378.82],
|
||
['2013/2/22', 2322.94, 2314.16, 2308.76, 2330.88],
|
||
['2013/2/25', 2320.62, 2325.82, 2315.01, 2338.78],
|
||
['2013/2/26', 2313.74, 2293.34, 2289.89, 2340.71],
|
||
['2013/2/27', 2297.77, 2313.22, 2292.03, 2324.63],
|
||
['2013/2/28', 2322.32, 2365.59, 2308.92, 2366.16],
|
||
['2013/3/1', 2364.54, 2359.51, 2330.86, 2369.65],
|
||
['2013/3/4', 2332.08, 2273.4, 2259.25, 2333.54],
|
||
['2013/3/5', 2274.81, 2326.31, 2270.1, 2328.14],
|
||
['2013/3/6', 2333.61, 2347.18, 2321.6, 2351.44],
|
||
['2013/3/7', 2340.44, 2324.29, 2304.27, 2352.02],
|
||
['2013/3/8', 2326.42, 2318.61, 2314.59, 2333.67],
|
||
['2013/3/11', 2314.68, 2310.59, 2296.58, 2320.96],
|
||
['2013/3/12', 2309.16, 2286.6, 2264.83, 2333.29],
|
||
['2013/3/13', 2282.17, 2263.97, 2253.25, 2286.33],
|
||
['2013/3/14', 2255.77, 2270.28, 2253.31, 2276.22],
|
||
['2013/3/15', 2269.31, 2278.4, 2250, 2312.08],
|
||
['2013/3/18', 2267.29, 2240.02, 2239.21, 2276.05],
|
||
['2013/3/19', 2244.26, 2257.43, 2232.02, 2261.31],
|
||
['2013/3/20', 2257.74, 2317.37, 2257.42, 2317.86],
|
||
['2013/3/21', 2318.21, 2324.24, 2311.6, 2330.81],
|
||
['2013/3/22', 2321.4, 2328.28, 2314.97, 2332],
|
||
['2013/3/25', 2334.74, 2326.72, 2319.91, 2344.89],
|
||
['2013/3/26', 2318.58, 2297.67, 2281.12, 2319.99],
|
||
['2013/3/27', 2299.38, 2301.26, 2289, 2323.48],
|
||
['2013/3/28', 2273.55, 2236.3, 2232.91, 2273.55],
|
||
['2013/3/29', 2238.49, 2236.62, 2228.81, 2246.87],
|
||
['2013/4/1', 2229.46, 2234.4, 2227.31, 2243.95],
|
||
['2013/4/2', 2234.9, 2227.74, 2220.44, 2253.42],
|
||
['2013/4/3', 2232.69, 2225.29, 2217.25, 2241.34],
|
||
['2013/4/8', 2196.24, 2211.59, 2180.67, 2212.59],
|
||
['2013/4/9', 2215.47, 2225.77, 2215.47, 2234.73],
|
||
['2013/4/10', 2224.93, 2226.13, 2212.56, 2233.04],
|
||
['2013/4/11', 2236.98, 2219.55, 2217.26, 2242.48],
|
||
['2013/4/12', 2218.09, 2206.78, 2204.44, 2226.26],
|
||
['2013/4/15', 2199.91, 2181.94, 2177.39, 2204.99],
|
||
['2013/4/16', 2169.63, 2194.85, 2165.78, 2196.43],
|
||
['2013/4/17', 2195.03, 2193.8, 2178.47, 2197.51],
|
||
['2013/4/18', 2181.82, 2197.6, 2175.44, 2206.03],
|
||
['2013/4/19', 2201.12, 2244.64, 2200.58, 2250.11],
|
||
['2013/4/22', 2236.4, 2242.17, 2232.26, 2245.12],
|
||
['2013/4/23', 2242.62, 2184.54, 2182.81, 2242.62],
|
||
['2013/4/24', 2187.35, 2218.32, 2184.11, 2226.12],
|
||
['2013/4/25', 2213.19, 2199.31, 2191.85, 2224.63],
|
||
['2013/4/26', 2203.89, 2177.91, 2173.86, 2210.58],
|
||
['2013/5/2', 2170.78, 2174.12, 2161.14, 2179.65],
|
||
['2013/5/3', 2179.05, 2205.5, 2179.05, 2222.81],
|
||
['2013/5/6', 2212.5, 2231.17, 2212.5, 2236.07],
|
||
['2013/5/7', 2227.86, 2235.57, 2219.44, 2240.26],
|
||
['2013/5/8', 2242.39, 2246.3, 2235.42, 2255.21],
|
||
['2013/5/9', 2246.96, 2232.97, 2221.38, 2247.86],
|
||
['2013/5/10', 2228.82, 2246.83, 2225.81, 2247.67],
|
||
['2013/5/13', 2247.68, 2241.92, 2231.36, 2250.85],
|
||
['2013/5/14', 2238.9, 2217.01, 2205.87, 2239.93],
|
||
['2013/5/15', 2217.09, 2224.8, 2213.58, 2225.19],
|
||
['2013/5/16', 2221.34, 2251.81, 2210.77, 2252.87],
|
||
['2013/5/17', 2249.81, 2282.87, 2248.41, 2288.09],
|
||
['2013/5/20', 2286.33, 2299.99, 2281.9, 2309.39],
|
||
['2013/5/21', 2297.11, 2305.11, 2290.12, 2305.3],
|
||
['2013/5/22', 2303.75, 2302.4, 2292.43, 2314.18],
|
||
['2013/5/23', 2293.81, 2275.67, 2274.1, 2304.95],
|
||
['2013/5/24', 2281.45, 2288.53, 2270.25, 2292.59],
|
||
['2013/5/27', 2286.66, 2293.08, 2283.94, 2301.7],
|
||
['2013/5/28', 2293.4, 2321.32, 2281.47, 2322.1],
|
||
['2013/5/29', 2323.54, 2324.02, 2321.17, 2334.33],
|
||
['2013/5/30', 2316.25, 2317.75, 2310.49, 2325.72],
|
||
['2013/5/31', 2320.74, 2300.59, 2299.37, 2325.53],
|
||
['2013/6/3', 2300.21, 2299.25, 2294.11, 2313.43],
|
||
['2013/6/4', 2297.1, 2272.42, 2264.76, 2297.1],
|
||
['2013/6/5', 2270.71, 2270.93, 2260.87, 2276.86],
|
||
['2013/6/6', 2264.43, 2242.11, 2240.07, 2266.69],
|
||
['2013/6/7', 2242.26, 2210.9, 2205.07, 2250.63],
|
||
['2013/6/13', 2190.1, 2148.35, 2126.22, 2190.1],
|
||
])
|
||
|
||
function calculateMA(dayCount) {
|
||
const result = []
|
||
|
||
for (let i = 0; i < data0.values.length; i++) {
|
||
if (i < dayCount) {
|
||
result.push('-')
|
||
continue
|
||
}
|
||
let sum = 0
|
||
|
||
for (let j = 0; j < dayCount; j++) sum += +data0.values[i - j][1]
|
||
|
||
result.push(sum / dayCount)
|
||
}
|
||
|
||
return result
|
||
}
|
||
const option = {
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
axisPointer: {
|
||
type: 'cross',
|
||
},
|
||
},
|
||
legend: {
|
||
data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30'],
|
||
},
|
||
grid: {
|
||
left: '10%',
|
||
right: '10%',
|
||
bottom: '15%',
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: data0.categoryData,
|
||
boundaryGap: false,
|
||
axisLine: { onZero: false },
|
||
splitLine: { show: false },
|
||
min: 'dataMin',
|
||
max: 'dataMax',
|
||
},
|
||
yAxis: {
|
||
scale: true,
|
||
splitArea: {
|
||
show: true,
|
||
},
|
||
},
|
||
dataZoom: [
|
||
{
|
||
type: 'inside',
|
||
start: 50,
|
||
end: 100,
|
||
},
|
||
{
|
||
show: true,
|
||
type: 'slider',
|
||
top: '90%',
|
||
start: 50,
|
||
end: 100,
|
||
},
|
||
],
|
||
series: [
|
||
{
|
||
name: '日K',
|
||
type: 'candlestick',
|
||
data: data0.values,
|
||
itemStyle: {
|
||
color: upColor,
|
||
color0: downColor,
|
||
borderColor: upBorderColor,
|
||
borderColor0: downBorderColor,
|
||
},
|
||
markPoint: {
|
||
label: {
|
||
formatter: param =>
|
||
param == null ? '' : Math.round(param.value).toString(),
|
||
},
|
||
data: [
|
||
{
|
||
name: 'Mark',
|
||
coord: ['2013/5/31', 2300],
|
||
value: 2300,
|
||
itemStyle: {
|
||
color: 'rgb(41,60,85)',
|
||
},
|
||
},
|
||
{
|
||
name: 'highest value',
|
||
type: 'max',
|
||
valueDim: 'highest',
|
||
},
|
||
{
|
||
name: 'lowest value',
|
||
type: 'min',
|
||
valueDim: 'lowest',
|
||
},
|
||
{
|
||
name: 'average value on close',
|
||
type: 'average',
|
||
valueDim: 'close',
|
||
},
|
||
],
|
||
tooltip: {
|
||
formatter: param => `${param.name}<br>${param.data.coord || ''}`,
|
||
},
|
||
},
|
||
markLine: {
|
||
symbol: ['none', 'none'],
|
||
data: [
|
||
[
|
||
{
|
||
name: 'from lowest to highest',
|
||
type: 'min',
|
||
valueDim: 'lowest',
|
||
symbol: 'circle',
|
||
symbolSize: 10,
|
||
label: {
|
||
show: false,
|
||
},
|
||
emphasis: {
|
||
label: {
|
||
show: false,
|
||
},
|
||
},
|
||
},
|
||
{
|
||
type: 'max',
|
||
valueDim: 'highest',
|
||
symbol: 'circle',
|
||
symbolSize: 10,
|
||
label: {
|
||
show: false,
|
||
},
|
||
emphasis: {
|
||
label: {
|
||
show: false,
|
||
},
|
||
},
|
||
},
|
||
],
|
||
{
|
||
name: 'min line on close',
|
||
type: 'min',
|
||
valueDim: 'close',
|
||
},
|
||
{
|
||
name: 'max line on close',
|
||
type: 'max',
|
||
valueDim: 'close',
|
||
},
|
||
],
|
||
},
|
||
},
|
||
{
|
||
name: 'MA5',
|
||
type: 'line',
|
||
data: calculateMA(5),
|
||
smooth: true,
|
||
lineStyle: {
|
||
opacity: 0.5,
|
||
},
|
||
},
|
||
{
|
||
name: 'MA10',
|
||
type: 'line',
|
||
data: calculateMA(10),
|
||
smooth: true,
|
||
lineStyle: {
|
||
opacity: 0.5,
|
||
},
|
||
},
|
||
{
|
||
name: 'MA20',
|
||
type: 'line',
|
||
data: calculateMA(20),
|
||
smooth: true,
|
||
lineStyle: {
|
||
opacity: 0.5,
|
||
},
|
||
},
|
||
{
|
||
name: 'MA30',
|
||
type: 'line',
|
||
data: calculateMA(30),
|
||
smooth: true,
|
||
lineStyle: {
|
||
opacity: 0.5,
|
||
},
|
||
},
|
||
],
|
||
}
|
||
```
|
||
|
||
:::
|
||
|
||
### 雷达图
|
||
|
||
**输入:**
|
||
|
||
:::: details 查看代码
|
||
|
||
````md
|
||
::: echarts A Radar Chart
|
||
```json
|
||
{
|
||
"legend": {
|
||
"data": ["Allocated Budget", "Actual Spending"]
|
||
},
|
||
"radar": {
|
||
"indicator": [
|
||
{ "name": "Sales", "max": 6500 },
|
||
{ "name": "Administration", "max": 16000 },
|
||
{ "name": "Information Technology", "max": 30000 },
|
||
{ "name": "Customer Support", "max": 38000 },
|
||
{ "name": "Development", "max": 52000 },
|
||
{ "name": "Marketing", "max": 25000 }
|
||
]
|
||
},
|
||
"series": [
|
||
{
|
||
"name": "Budget vs spending",
|
||
"type": "radar",
|
||
"data": [
|
||
{
|
||
"value": [4200, 3000, 20000, 35000, 50000, 18000],
|
||
"name": "Allocated Budget"
|
||
},
|
||
{
|
||
"value": [5000, 14000, 28000, 26000, 42000, 21000],
|
||
"name": "Actual Spending"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
:::
|
||
````
|
||
|
||
::::
|
||
|
||
**输出:**
|
||
|
||
::: echarts A Radar Chart
|
||
|
||
```json
|
||
{
|
||
"legend": {
|
||
"data": ["Allocated Budget", "Actual Spending"]
|
||
},
|
||
"radar": {
|
||
"indicator": [
|
||
{ "name": "Sales", "max": 6500 },
|
||
{ "name": "Administration", "max": 16000 },
|
||
{ "name": "Information Technology", "max": 30000 },
|
||
{ "name": "Customer Support", "max": 38000 },
|
||
{ "name": "Development", "max": 52000 },
|
||
{ "name": "Marketing", "max": 25000 }
|
||
]
|
||
},
|
||
"series": [
|
||
{
|
||
"name": "Budget vs spending",
|
||
"type": "radar",
|
||
"data": [
|
||
{
|
||
"value": [4200, 3000, 20000, 35000, 50000, 18000],
|
||
"name": "Allocated Budget"
|
||
},
|
||
{
|
||
"value": [5000, 14000, 28000, 26000, 42000, 21000],
|
||
"name": "Actual Spending"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
:::
|
||
|
||
### 热力图
|
||
|
||
**输入:**
|
||
|
||
:::: details 查看代码
|
||
|
||
````md
|
||
::: echarts
|
||
```js
|
||
/* eslint-disable */
|
||
|
||
function getNoiseHelper() {
|
||
class Grad {
|
||
constructor(x, y, z) {
|
||
this.x = x
|
||
this.y = y
|
||
this.z = z
|
||
}
|
||
|
||
dot2(x, y) {
|
||
return this.x * x + this.y * y
|
||
}
|
||
|
||
dot3(x, y, z) {
|
||
return this.x * x + this.y * y + this.z * z
|
||
}
|
||
}
|
||
const grad3 = [
|
||
new Grad(1, 1, 0),
|
||
new Grad(-1, 1, 0),
|
||
new Grad(1, -1, 0),
|
||
new Grad(-1, -1, 0),
|
||
new Grad(1, 0, 1),
|
||
new Grad(-1, 0, 1),
|
||
new Grad(1, 0, -1),
|
||
new Grad(-1, 0, -1),
|
||
new Grad(0, 1, 1),
|
||
new Grad(0, -1, 1),
|
||
new Grad(0, 1, -1),
|
||
new Grad(0, -1, -1),
|
||
]
|
||
const p = [
|
||
151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140,
|
||
36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120,
|
||
234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
|
||
88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71,
|
||
134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133,
|
||
230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161,
|
||
1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130,
|
||
116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250,
|
||
124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227,
|
||
47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44,
|
||
154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98,
|
||
108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34,
|
||
242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14,
|
||
239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121,
|
||
50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243,
|
||
141, 128, 195, 78, 66, 215, 61, 156, 180,
|
||
]
|
||
// To remove the need for index wrapping, double the permutation table length
|
||
const perm = Array.from({ length: 512 })
|
||
const gradP = Array.from({ length: 512 })
|
||
// This isn't a very good seeding function, but it works ok. It supports 2^16
|
||
// different seed values. Write something better if you need more seeds.
|
||
function seed(seed) {
|
||
if (seed > 0 && seed < 1) {
|
||
// Scale the seed out
|
||
seed *= 65536
|
||
}
|
||
seed = Math.floor(seed)
|
||
if (seed < 256)
|
||
seed |= seed << 8
|
||
|
||
for (let i = 0; i < 256; i++) {
|
||
let v
|
||
if (i & 1)
|
||
v = p[i] ^ (seed & 255)
|
||
else
|
||
v = p[i] ^ ((seed >> 8) & 255)
|
||
|
||
perm[i] = perm[i + 256] = v
|
||
gradP[i] = gradP[i + 256] = grad3[v % 12]
|
||
}
|
||
}
|
||
seed(0)
|
||
// ##### Perlin noise stuff
|
||
function fade(t) {
|
||
return t * t * t * (t * (t * 6 - 15) + 10)
|
||
}
|
||
function lerp(a, b, t) {
|
||
return (1 - t) * a + t * b
|
||
}
|
||
// 2D Perlin Noise
|
||
function perlin2(x, y) {
|
||
// Find unit grid cell containing point
|
||
let X = Math.floor(x)
|
||
let Y = Math.floor(y)
|
||
// Get relative xy coordinates of point within that cell
|
||
x = x - X
|
||
y = y - Y
|
||
// Wrap the integer cells at 255 (smaller integer period can be introduced here)
|
||
X = X & 255
|
||
Y = Y & 255
|
||
// Calculate noise contributions from each of the four corners
|
||
const n00 = gradP[X + perm[Y]].dot2(x, y)
|
||
const n01 = gradP[X + perm[Y + 1]].dot2(x, y - 1)
|
||
const n10 = gradP[X + 1 + perm[Y]].dot2(x - 1, y)
|
||
const n11 = gradP[X + 1 + perm[Y + 1]].dot2(x - 1, y - 1)
|
||
// Compute the fade curve value for x
|
||
const u = fade(x)
|
||
// Interpolate the four results
|
||
return lerp(lerp(n00, n10, u), lerp(n01, n11, u), fade(y))
|
||
}
|
||
return {
|
||
seed,
|
||
perlin2,
|
||
}
|
||
}
|
||
|
||
const noise = getNoiseHelper()
|
||
const xData = []
|
||
const yData = []
|
||
noise.seed(Math.random())
|
||
|
||
const data = []
|
||
for (let i = 0; i <= 200; i++) {
|
||
for (let j = 0; j <= 100; j++)
|
||
data.push([i, j, noise.perlin2(i / 40, j / 20) + 0.5])
|
||
|
||
xData.push(i)
|
||
}
|
||
for (let j = 0; j < 100; j++)
|
||
yData.push(j)
|
||
|
||
option = {
|
||
tooltip: {},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: xData,
|
||
},
|
||
yAxis: {
|
||
type: 'category',
|
||
data: yData,
|
||
},
|
||
visualMap: {
|
||
min: 0,
|
||
max: 1,
|
||
calculable: true,
|
||
realtime: false,
|
||
inRange: {
|
||
color: [
|
||
'#313695',
|
||
'#4575b4',
|
||
'#74add1',
|
||
'#abd9e9',
|
||
'#e0f3f8',
|
||
'#ffffbf',
|
||
'#fee090',
|
||
'#fdae61',
|
||
'#f46d43',
|
||
'#d73027',
|
||
'#a50026',
|
||
],
|
||
},
|
||
},
|
||
series: [
|
||
{
|
||
name: 'Gaussian',
|
||
type: 'heatmap',
|
||
data,
|
||
emphasis: {
|
||
itemStyle: {
|
||
borderColor: '#333',
|
||
borderWidth: 1,
|
||
},
|
||
},
|
||
progressive: 1000,
|
||
animation: false,
|
||
},
|
||
],
|
||
}
|
||
|
||
const height = 500
|
||
```
|
||
:::
|
||
````
|
||
|
||
::::
|
||
|
||
**输出:**
|
||
|
||
::: echarts
|
||
|
||
```js
|
||
/* eslint-disable */
|
||
|
||
function getNoiseHelper() {
|
||
class Grad {
|
||
constructor(x, y, z) {
|
||
this.x = x
|
||
this.y = y
|
||
this.z = z
|
||
}
|
||
|
||
dot2(x, y) {
|
||
return this.x * x + this.y * y
|
||
}
|
||
|
||
dot3(x, y, z) {
|
||
return this.x * x + this.y * y + this.z * z
|
||
}
|
||
}
|
||
const grad3 = [
|
||
new Grad(1, 1, 0),
|
||
new Grad(-1, 1, 0),
|
||
new Grad(1, -1, 0),
|
||
new Grad(-1, -1, 0),
|
||
new Grad(1, 0, 1),
|
||
new Grad(-1, 0, 1),
|
||
new Grad(1, 0, -1),
|
||
new Grad(-1, 0, -1),
|
||
new Grad(0, 1, 1),
|
||
new Grad(0, -1, 1),
|
||
new Grad(0, 1, -1),
|
||
new Grad(0, -1, -1),
|
||
]
|
||
const p = [
|
||
151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140,
|
||
36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120,
|
||
234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
|
||
88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71,
|
||
134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133,
|
||
230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161,
|
||
1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130,
|
||
116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250,
|
||
124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227,
|
||
47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44,
|
||
154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98,
|
||
108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34,
|
||
242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14,
|
||
239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121,
|
||
50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243,
|
||
141, 128, 195, 78, 66, 215, 61, 156, 180,
|
||
]
|
||
// To remove the need for index wrapping, double the permutation table length
|
||
const perm = Array.from({ length: 512 })
|
||
const gradP = Array.from({ length: 512 })
|
||
// This isn't a very good seeding function, but it works ok. It supports 2^16
|
||
// different seed values. Write something better if you need more seeds.
|
||
function seed(seed) {
|
||
if (seed > 0 && seed < 1) {
|
||
// Scale the seed out
|
||
seed *= 65536
|
||
}
|
||
seed = Math.floor(seed)
|
||
if (seed < 256)
|
||
seed |= seed << 8
|
||
|
||
for (let i = 0; i < 256; i++) {
|
||
let v
|
||
if (i & 1)
|
||
v = p[i] ^ (seed & 255)
|
||
else
|
||
v = p[i] ^ ((seed >> 8) & 255)
|
||
|
||
perm[i] = perm[i + 256] = v
|
||
gradP[i] = gradP[i + 256] = grad3[v % 12]
|
||
}
|
||
}
|
||
seed(0)
|
||
// ##### Perlin noise stuff
|
||
function fade(t) {
|
||
return t * t * t * (t * (t * 6 - 15) + 10)
|
||
}
|
||
function lerp(a, b, t) {
|
||
return (1 - t) * a + t * b
|
||
}
|
||
// 2D Perlin Noise
|
||
function perlin2(x, y) {
|
||
// Find unit grid cell containing point
|
||
let X = Math.floor(x)
|
||
let Y = Math.floor(y)
|
||
// Get relative xy coordinates of point within that cell
|
||
x = x - X
|
||
y = y - Y
|
||
// Wrap the integer cells at 255 (smaller integer period can be introduced here)
|
||
X = X & 255
|
||
Y = Y & 255
|
||
// Calculate noise contributions from each of the four corners
|
||
const n00 = gradP[X + perm[Y]].dot2(x, y)
|
||
const n01 = gradP[X + perm[Y + 1]].dot2(x, y - 1)
|
||
const n10 = gradP[X + 1 + perm[Y]].dot2(x - 1, y)
|
||
const n11 = gradP[X + 1 + perm[Y + 1]].dot2(x - 1, y - 1)
|
||
// Compute the fade curve value for x
|
||
const u = fade(x)
|
||
// Interpolate the four results
|
||
return lerp(lerp(n00, n10, u), lerp(n01, n11, u), fade(y))
|
||
}
|
||
return {
|
||
seed,
|
||
perlin2,
|
||
}
|
||
}
|
||
|
||
const noise = getNoiseHelper()
|
||
const xData = []
|
||
const yData = []
|
||
noise.seed(Math.random())
|
||
|
||
const data = []
|
||
for (let i = 0; i <= 200; i++) {
|
||
for (let j = 0; j <= 100; j++)
|
||
data.push([i, j, noise.perlin2(i / 40, j / 20) + 0.5])
|
||
|
||
xData.push(i)
|
||
}
|
||
for (let j = 0; j < 100; j++)
|
||
yData.push(j)
|
||
|
||
option = {
|
||
tooltip: {},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: xData,
|
||
},
|
||
yAxis: {
|
||
type: 'category',
|
||
data: yData,
|
||
},
|
||
visualMap: {
|
||
min: 0,
|
||
max: 1,
|
||
calculable: true,
|
||
realtime: false,
|
||
inRange: {
|
||
color: [
|
||
'#313695',
|
||
'#4575b4',
|
||
'#74add1',
|
||
'#abd9e9',
|
||
'#e0f3f8',
|
||
'#ffffbf',
|
||
'#fee090',
|
||
'#fdae61',
|
||
'#f46d43',
|
||
'#d73027',
|
||
'#a50026',
|
||
],
|
||
},
|
||
},
|
||
series: [
|
||
{
|
||
name: 'Gaussian',
|
||
type: 'heatmap',
|
||
data,
|
||
emphasis: {
|
||
itemStyle: {
|
||
borderColor: '#333',
|
||
borderWidth: 1,
|
||
},
|
||
},
|
||
progressive: 1000,
|
||
animation: false,
|
||
},
|
||
],
|
||
}
|
||
|
||
const height = 500
|
||
```
|
||
|
||
:::
|
||
|
||
### 树图
|
||
|
||
**输入:**
|
||
|
||
:::: details 查看代码
|
||
|
||
````md
|
||
::: echarts Tree
|
||
```js
|
||
const data = await fetch(
|
||
'/data/flare.json',
|
||
).then(res => res.json())
|
||
|
||
const option = {
|
||
tooltip: {
|
||
trigger: 'item',
|
||
triggerOn: 'mousemove',
|
||
},
|
||
series: [
|
||
{
|
||
type: 'tree',
|
||
data: [data],
|
||
top: '18%',
|
||
bottom: '14%',
|
||
layout: 'radial',
|
||
symbol: 'emptyCircle',
|
||
symbolSize: 7,
|
||
initialTreeDepth: 3,
|
||
animationDurationUpdate: 750,
|
||
emphasis: {
|
||
focus: 'descendant',
|
||
},
|
||
},
|
||
],
|
||
}
|
||
|
||
const height = 600
|
||
```
|
||
:::
|
||
````
|
||
|
||
::::
|
||
|
||
**输出:**
|
||
|
||
::: echarts Tree
|
||
|
||
```js
|
||
const data = await fetch(
|
||
'/data/flare.json',
|
||
).then(res => res.json())
|
||
|
||
const option = {
|
||
tooltip: {
|
||
trigger: 'item',
|
||
triggerOn: 'mousemove',
|
||
},
|
||
series: [
|
||
{
|
||
type: 'tree',
|
||
data: [data],
|
||
top: '18%',
|
||
bottom: '14%',
|
||
layout: 'radial',
|
||
symbol: 'emptyCircle',
|
||
symbolSize: 7,
|
||
initialTreeDepth: 3,
|
||
animationDurationUpdate: 750,
|
||
emphasis: {
|
||
focus: 'descendant',
|
||
},
|
||
},
|
||
],
|
||
}
|
||
|
||
const height = 600
|
||
```
|
||
|
||
:::
|
||
|
||
### 多图
|
||
|
||
**输入:**
|
||
|
||
:::: details 查看代码
|
||
|
||
````md
|
||
::: echarts
|
||
```js
|
||
const option = {
|
||
legend: {},
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
showContent: false,
|
||
},
|
||
dataset: {
|
||
source: [
|
||
['product', '2012', '2013', '2014', '2015', '2016', '2017'],
|
||
['Milk Tea', 56.5, 82.1, 88.7, 70.1, 53.4, 85.1],
|
||
['Matcha Latte', 51.1, 51.4, 55.1, 53.3, 73.8, 68.7],
|
||
['Cheese Cocoa', 40.1, 62.2, 69.5, 36.4, 45.2, 32.5],
|
||
['Walnut Brownie', 25.2, 37.1, 41.2, 18, 33.9, 49.1],
|
||
],
|
||
},
|
||
xAxis: { type: 'category' },
|
||
yAxis: { gridIndex: 0 },
|
||
grid: { top: '55%' },
|
||
series: [
|
||
{
|
||
type: 'line',
|
||
smooth: true,
|
||
seriesLayoutBy: 'row',
|
||
emphasis: { focus: 'series' },
|
||
},
|
||
{
|
||
type: 'line',
|
||
smooth: true,
|
||
seriesLayoutBy: 'row',
|
||
emphasis: { focus: 'series' },
|
||
},
|
||
{
|
||
type: 'line',
|
||
smooth: true,
|
||
seriesLayoutBy: 'row',
|
||
emphasis: { focus: 'series' },
|
||
},
|
||
{
|
||
type: 'line',
|
||
smooth: true,
|
||
seriesLayoutBy: 'row',
|
||
emphasis: { focus: 'series' },
|
||
},
|
||
{
|
||
type: 'pie',
|
||
id: 'pie',
|
||
radius: '30%',
|
||
center: ['50%', '25%'],
|
||
emphasis: {
|
||
focus: 'self',
|
||
},
|
||
label: {
|
||
formatter: '{b}: {@2012} ({d}%)',
|
||
},
|
||
encode: {
|
||
itemName: 'product',
|
||
value: '2012',
|
||
tooltip: '2012',
|
||
},
|
||
},
|
||
],
|
||
}
|
||
|
||
const height = 800
|
||
```
|
||
:::
|
||
````
|
||
|
||
::::
|
||
|
||
**输出:**
|
||
|
||
::: echarts
|
||
|
||
```js
|
||
const option = {
|
||
legend: {},
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
showContent: false,
|
||
},
|
||
dataset: {
|
||
source: [
|
||
['product', '2012', '2013', '2014', '2015', '2016', '2017'],
|
||
['Milk Tea', 56.5, 82.1, 88.7, 70.1, 53.4, 85.1],
|
||
['Matcha Latte', 51.1, 51.4, 55.1, 53.3, 73.8, 68.7],
|
||
['Cheese Cocoa', 40.1, 62.2, 69.5, 36.4, 45.2, 32.5],
|
||
['Walnut Brownie', 25.2, 37.1, 41.2, 18, 33.9, 49.1],
|
||
],
|
||
},
|
||
xAxis: { type: 'category' },
|
||
yAxis: { gridIndex: 0 },
|
||
grid: { top: '55%' },
|
||
series: [
|
||
{
|
||
type: 'line',
|
||
smooth: true,
|
||
seriesLayoutBy: 'row',
|
||
emphasis: { focus: 'series' },
|
||
},
|
||
{
|
||
type: 'line',
|
||
smooth: true,
|
||
seriesLayoutBy: 'row',
|
||
emphasis: { focus: 'series' },
|
||
},
|
||
{
|
||
type: 'line',
|
||
smooth: true,
|
||
seriesLayoutBy: 'row',
|
||
emphasis: { focus: 'series' },
|
||
},
|
||
{
|
||
type: 'line',
|
||
smooth: true,
|
||
seriesLayoutBy: 'row',
|
||
emphasis: { focus: 'series' },
|
||
},
|
||
{
|
||
type: 'pie',
|
||
id: 'pie',
|
||
radius: '30%',
|
||
center: ['50%', '25%'],
|
||
emphasis: {
|
||
focus: 'self',
|
||
},
|
||
label: {
|
||
formatter: '{b}: {@2012} ({d}%)',
|
||
},
|
||
encode: {
|
||
itemName: 'product',
|
||
value: '2012',
|
||
tooltip: '2012',
|
||
},
|
||
},
|
||
],
|
||
}
|
||
|
||
const height = 800
|
||
```
|
||
|
||
:::
|