Skip to content

Commit 3d484eb

Browse files
committed
echart多折线tooltip示例
1 parent 7566577 commit 3d484eb

File tree

3 files changed

+265
-0
lines changed

3 files changed

+265
-0
lines changed

src/mock/menu.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,13 @@ export default [
229229
path: '/function/dragLayout',
230230
component: 'function/drag/index.vue',
231231
},
232+
{
233+
title: 'echarts',
234+
icon: 'i-ep-trend-charts',
235+
name: 'echarts',
236+
path: '/function/echarts',
237+
component: 'function/echarts/index.vue',
238+
},
232239
],
233240
},
234241
{

src/views/function/echarts/a.ts

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import { sortBy, isNumber } from 'lodash-es'
2+
3+
export const getOption = (data: any, dataFormatEnum: string, selectSeries: any) => {
4+
const { chartType, chartName } = data
5+
const option = Object.assign(data, {
6+
tooltip: {},
7+
title: { text: chartName, triggerEvent: true },
8+
grid: {
9+
top: '20%', //距上边距
10+
left: '10%', //距离左边距
11+
right: '10%', //距离右边距
12+
bottom: '10%', //距离下边距
13+
containLabel: true,
14+
},
15+
legend: {
16+
y: '35',
17+
type: 'scroll',
18+
},
19+
})
20+
21+
// tooltip设置
22+
if (chartType === 'funnel') {
23+
option.tooltip.trigger = 'item'
24+
option.tooltip.formatter = '{a} <br/>{b} : {c}'
25+
} else if (chartType === 'pie') {
26+
option.tooltip.trigger = 'item'
27+
option.tooltip.formatter = '{a} {b} : {c} ({d}%)'
28+
} else {
29+
option.tooltip.trigger = 'axis'
30+
option.tooltip.formatter = function (params: any) {
31+
let res = ''
32+
for (let i = 0; i < params.length; i++) {
33+
const series = params[i]
34+
// 百分比处理
35+
if (dataFormatEnum === 'percentage' && isNumber(series.data)) {
36+
series.data = series.data?.mul(100) + '%'
37+
}
38+
// 移动到具体点的时候展示该坐标点数据,否则展示全部
39+
if (selectSeries.value) {
40+
if (series.seriesName === selectSeries.value) {
41+
res = series.axisValue + '<br/>' + series.marker + series.seriesName + ' : ' + series.data + '<br/>'
42+
break
43+
}
44+
} else {
45+
if (i === 0) {
46+
res += series.axisValue + '<br/>'
47+
}
48+
res += series.marker + series.seriesName + ' : ' + series.data + '<br/>'
49+
}
50+
}
51+
return res
52+
}
53+
}
54+
// 横向滚动条
55+
if (option?.xAxis?.[0]?.data?.length >= 20) {
56+
option.dataZoom = {
57+
start: 0,
58+
end: Math.floor(100 / option?.xAxis?.[0]?.data?.length) * 20,
59+
type: 'slider',
60+
show: true,
61+
borderColor: 'transparent',
62+
borderCap: 'round',
63+
xAxisIndex: [0],
64+
height: 6, //组件高度
65+
left: 20, //左边的距离
66+
right: 20, //右边的距离
67+
bottom: 10, //下边的距离
68+
fillerColor: 'rgba(27,90,169,1)',
69+
handleIcon:
70+
'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5M36.9,35.8h-1.3z M27.8,35.8 h-1.3H27L27.8,35.8L27.8,35.8z', // 画一个圆形
71+
handleSize: '100%',
72+
handleStyle: {
73+
color: 'rgba(27,90,169,1)',
74+
borderWidth: 0,
75+
},
76+
// backgroundColor: 'rgba(37, 46, 100, 0.8)', //两边未选中的滑动条区域的颜色
77+
showDataShadow: false, //是否显示数据阴影 默认auto
78+
showDetail: false, //即拖拽时候是否显示详细数值信息 默认true
79+
filterMode: 'filter',
80+
}
81+
}
82+
option?.yAxis?.forEach((item: any, index: number) => {
83+
// 百分比处理
84+
if (dataFormatEnum === 'percentage' && index === 0) {
85+
item.axisLabel = {
86+
show: true,
87+
interval: 'auto',
88+
formatter: (val: number) => {
89+
return val.mul(100) + '%'
90+
},
91+
}
92+
}
93+
item.nameTextStyle = {
94+
padding: [0, 40, 0, 0],
95+
}
96+
})
97+
option?.xAxis?.forEach((item: any) => {
98+
item.nameLocation = 'middle'
99+
item.nameTextStyle = {
100+
padding: 10,
101+
}
102+
})
103+
option?.series?.forEach((item: any) => {
104+
// 饼图设置
105+
if (item.type === 'pie') {
106+
Object.assign(item, {
107+
radius: ['40%', '70%'],
108+
label: {
109+
show: false,
110+
position: 'center',
111+
},
112+
labelLine: {
113+
show: false,
114+
},
115+
})
116+
}
117+
})
118+
return option
119+
}
120+
/*
121+
**获取最新布局位置
122+
*/
123+
export const getPosition = (layout: any[]) => {
124+
layout = sortBy(layout, ['y', 'x'])
125+
const len = layout.length
126+
if (layout[len - 1]) {
127+
const { x, y, w, h } = layout[len - 1]
128+
let newX = x,
129+
newY = y
130+
if (x + w >= 12) {
131+
newX = 0
132+
newY = y + h
133+
} else {
134+
newX = x + w
135+
}
136+
return { x: newX, y: newY, w, h }
137+
}
138+
return { x: 0, y: 100, w: 4, h: 11 }
139+
}

src/views/function/echarts/index.vue

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<template>
2+
<div h-100>
3+
<v-chart
4+
ref="chartRef"
5+
autoresize
6+
:update-options="{ notMerge: true }"
7+
:option="option"
8+
@mousemove="
9+
(params:any) => {
10+
selectSeries = params.seriesName
11+
}
12+
"
13+
@mouseout="
14+
() => {
15+
selectSeries = ''
16+
}
17+
"
18+
@click="clickChart"
19+
></v-chart>
20+
</div>
21+
</template>
22+
23+
<script lang="ts" setup>
24+
const selectSeries = ref('')
25+
const chartRef = ref()
26+
const option = ref({
27+
title: {
28+
text: 'Stacked Line',
29+
triggerEvent: true,
30+
},
31+
tooltip: {
32+
trigger: 'axis',
33+
formatter: function (params: any[]) {
34+
let res = ''
35+
for (let i = 0; i < params.length; i++) {
36+
const series = params[i]
37+
// 移动到具体点的时候展示该坐标点数据,否则展示全部
38+
if (selectSeries.value) {
39+
if (series.seriesName === selectSeries.value) {
40+
res = series.axisValue + '<br/>' + series.marker + series.seriesName + ' : ' + series.data + '<br/>'
41+
break
42+
}
43+
} else {
44+
if (i === 0) {
45+
res += series.axisValue + '<br/>'
46+
}
47+
res += series.marker + series.seriesName + ' : ' + series.data + '<br/>'
48+
}
49+
}
50+
return res
51+
},
52+
},
53+
legend: {
54+
data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine'],
55+
type: 'scroll',
56+
},
57+
grid: {
58+
top: '20%', //距上边距
59+
left: '10%', //距离左边距
60+
right: '10%', //距离右边距
61+
bottom: '10%', //距离下边距
62+
containLabel: true,
63+
},
64+
xAxis: {
65+
type: 'category',
66+
boundaryGap: false,
67+
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
68+
},
69+
yAxis: {
70+
type: 'value',
71+
},
72+
series: [
73+
{
74+
name: 'Email',
75+
type: 'line',
76+
stack: 'Total',
77+
data: [120, 132, 101, 134, 90, 230, 210],
78+
},
79+
{
80+
name: 'Union Ads',
81+
type: 'line',
82+
stack: 'Total',
83+
data: [220, 182, 191, 234, 290, 330, 310],
84+
},
85+
{
86+
name: 'Video Ads',
87+
type: 'line',
88+
stack: 'Total',
89+
data: [150, 232, 201, 154, 190, 330, 410],
90+
},
91+
{
92+
name: 'Direct',
93+
type: 'line',
94+
stack: 'Total',
95+
data: [320, 332, 301, 334, 390, 330, 320],
96+
},
97+
{
98+
name: 'Search Engine',
99+
type: 'line',
100+
stack: 'Total',
101+
data: [820, 932, 901, 934, 1290, 1330, 1320],
102+
},
103+
],
104+
})
105+
106+
const clickChart = (params: any) => {
107+
const key = Object.keys(params.event.target).find(key => key.includes('ec_inner')) || ''
108+
const res = params.event.target[key]
109+
110+
console.log(`当前点击了第${res.dataIndex}组数据中的第${res.seriesIndex}条数据`)
111+
112+
const pointInPixel = [params.event.event.offsetX, params.event.event.offsetY]
113+
if (chartRef.value.containPixel('grid', pointInPixel)) {
114+
let xIndex = chartRef.value.chart.convertFromPixel({ seriesIndex: 0 }, pointInPixel)[0]
115+
xIndex = parseInt(xIndex)
116+
console.log('x轴索引', xIndex)
117+
}
118+
}
119+
</script>

0 commit comments

Comments
 (0)