在ECharts中,可以通过series中的markLine和markPoint属性来分别设置图表的标线和标点。在下面的例子中,markLine用于添加一个标记最大值的标线,而markPoint用于添加标记最大值和最小值的标记点。
可以根据需要调整markLine和markPoint的data属性,以设置不同的标记类型和名称。
一、测试数据
以下为此次演示案例的测试数据,代码如下:
[{"name": "负荷曲线","data": [{"name": "1:00","value": 14},{"name": "2:00","value": 10},{"name": "3:00","value": 14},{"name": "4:00","value": 12},{"name": "5:00","value": 1},{"name": "6:00","value": 15},{"name": "7:00","value": 11},{"name": "8:00","value": 12},{"name": "9:00","value": 6},{"name": "10:00","value": 1},{"name": "11:00","value": 15},{"name": "12:00","value": 4},{"name": "13:00","value": 924},{"name": "14:00","value": 178},{"name": "15:00","value": 197},{"name": "16:00","value": 345},{"name": "17:00","value": 646},{"name": "18:00","value": 731},{"name": "19:00","value": 780},{"name": "20:00","value": 193},{"name": "21:00","value": 278},{"name": "22:00","value": 318},{"name": "23:00","value": 179},{"name": "24:00","value": 862}]},{"name": "预测负荷","data": [{"name": "1:00","value": 9},{"name": "2:00","value": 13},{"name": "3:00","value": 13},{"name": "4:00","value": 2},{"name": "5:00","value": 8},{"name": "6:00","value": 18},{"name": "7:00","value": 10},{"name": "8:00","value": 19},{"name": "9:00","value": 6},{"name": "10:00","value": 20},{"name": "11:00","value": 4},{"name": "12:00","value": 2},{"name": "13:00","value": 949},{"name": "14:00","value": 477},{"name": "15:00","value": 144},{"name": "16:00","value": 363},{"name": "17:00","value": 213},{"name": "18:00","value": 660},{"name": "19:00","value": 923},{"name": "20:00","value": 812},{"name": "21:00","value": 720},{"name": "22:00","value": 90},{"name": "23:00","value": 994},{"name": "24:00","value": 597}]}
]
二、绘制图表
这里直接使用EChart的官方实例进行案例演示了,将基础折线图修改为我们需要的效果。测试地址:Examples - Apache ECharts
配置项代码如下:
const data = [{"name": "负荷曲线","data": [{"name": "1:00","value": 14},{"name": "2:00","value": 10},{"name": "3:00","value": 14},{"name": "4:00","value": 12},{"name": "5:00","value": 1},{"name": "6:00","value": 15},// 略...]},{"name": "预测负荷","data": [// 略...]}
]const seriesData = data.map(item => {return {data: item.data.map(item => item.value),type: 'line',smooth: true,name: item.name}
})option = {legend: {},dataZoom: {type: 'inside',show: true,start: 0,end: 60},xAxis: {type: 'category',data: data[0].data.map(item => item.name),splitNumber: 6},yAxis: {type: 'value'},series: seriesData
};
查看图表效果,如下图:
三、最大值标记线
通过MarkLine标记出图例的最大值标记线,通过extraData变量额外追加到图例中,其作用后续再说。配置项代码如下:
// 略...const seriesData = data.map(item => {const extraData = {markLine: {data: [// 最大值标记线{name: 'Max', type: 'max'}]}}return {data: item.data.map(item => item.value),type: 'line',smooth: true,name: item.name,...extraData}
})option = {legend: {},dataZoom: {type: 'inside',show: true,start: 0,end: 60},xAxis: {type: 'category',data: data[0].data.map(item => item.name),splitNumber: 6},yAxis: {type: 'value'},series: seriesData
};
图表效果如下图:
四、标记最大和最小值
通过markPoint属性配置出图例中的最大值和最小值,同样写在extraData变量中。配置项代码如下:
// 略...const seriesData = data.map(item => {const extraData = {markLine: {data: [{name: 'Max', type: 'max'}]},// 最大值和最小值 标记点markPoint: {data: [{name: 'Min', type: 'min'},{name: 'Max', type: 'max'}]}}return {data: item.data.map(item => item.value),type: 'line',smooth: true,name: item.name,...extraData}
})option = {legend: {},dataZoom: {type: 'inside',show: true,start: 0,end: 60},xAxis: {type: 'category',data: data[0].data.map(item => item.name),splitNumber: 6},yAxis: {type: 'value'},series: seriesData
};
图表效果如下图:
如上图,对于有些项目到这一步则已完成了,但是有些可能还希望看到的是,多个图列只显示一个最大值和一个最小值,这个则需要通过函数来查询出最大值或最小值分别 在哪个图例中,并且得到结果后通过索引来判定,哪个图例需要添加markPoint或markLine属性。
五、legend监听事件
在ECharts中,legend图例可能会发生变化(显示/隐藏)。它的变化可以通过监听legendselectchanged事件来捕获,这个事件会在用户切换图例(legend)的选中状态时触发。
监听事件代码如下:
myChart.on('legendselectchanged', (e) => {console.log('legendselectchanged', e)
})
此时,切换图例legend时,控制台输出结果如下图:
从图中可以看出,当图例(legend)显示或隐藏时,是通过true或false来标记的。所以,我们切换图例时,可以通过selected内图例名称对应的true或false来判定显示的图例数据,并且通过它筛选出来的数据,判断最大值和最小值所在图例的索引。
六、最大值和最小值查询
定义getMaxAndMinValue()函数,用于查询每个图例中的最大值和最小值,代码如下:
// 获取最大和最小值
const getMaxAndMinValue = (arr) => {let maxValue = 0let minValue = 0// 循环获取最大和最小值arr.forEach(item => {if (item.value) minValue = item.valueif (item.value > maxValue) maxValue = item.value})return {maxValue,minValue}
}
// 监听图例事件
myChart.on('legendselectchanged', (e) => {const chartData = data.filter(item => e.selected[item.name]) // 筛选数据chartData.forEach(item => {const { maxValue, minValue } = getMaxAndMinValue(item.data)console.log(maxValue, minValue)})console.log('legendselectchanged', chartData)
})
此时,切换图例(legend)查看控制台,如下图:
七、判断最大值和最小值所在图例
上面已经将最大值和最小值查询出来了,现在我们需要将功能函数再修改下,判断出最大值和最小值所在的图例索引。
新增getMaxAndMinIndex()函数,用来获取最大值和最小值所在图例的索引,代码如下:
let maxIndex = 0
let minIndex = 0
// 获取最大和最小值
const getMaxAndMinValue = (arr) => {let maxValue = 0let minValue = 0// 循环获取最大和最小值arr.forEach(item => {if (item.value) minValue = item.valueif (item.value > maxValue) maxValue = item.value})return {maxValue,minValue}
}
// 判断最大值和最小值所在的图例
const getMaxAndMinIndex = (arr) => {let max = 0let min = 0// 获取最大值和最小值索引arr.forEach((item, index) => {const { maxValue, minValue } = getMaxAndMinValue(item.data)if (minValue < min) {min = minValueminIndex = index}if (maxValue > max) {max = maxValuemaxIndex = index}})console.log(maxIndex, minIndex)
}
// 监听图例事件
myChart.on('legendselectchanged', (e) => {const chartData = data.filter(item => e.selected[item.name]) // 筛选数据getMaxAndMinIndex(chartData) // 查询索引myChart.setOption(chartOptions(chartData))
})
查看控制台,可以看到在图例切换后,索引也跟着发生变化。
此时,页面始终显示一个最大值和一个最小值了,如下图:
当预测负荷隐藏后,则会显示负荷曲线的最大值数据,如下图:
八、完成代码
以下为配置项,以及图例监听事件的完整代码。代码如下:
const data = [{"name": "负荷曲线","data": [{"name": "1:00","value": 14},{"name": "2:00","value": 10},{"name": "3:00","value": 14},{"name": "4:00","value": 12},{"name": "5:00","value": 1},{"name": "6:00","value": 15},{"name": "7:00","value": 11},{"name": "8:00","value": 12},{"name": "9:00","value": 6},{"name": "10:00","value": 1},{"name": "11:00","value": 15},{"name": "12:00","value": 4},{"name": "13:00","value": 924},{"name": "14:00","value": 178},{"name": "15:00","value": 197},{"name": "16:00","value": 345},{"name": "17:00","value": 646},{"name": "18:00","value": 731},{"name": "19:00","value": 780},{"name": "20:00","value": 193},{"name": "21:00","value": 278},{"name": "22:00","value": 318},{"name": "23:00","value": 179},{"name": "24:00","value": 862}]},{"name": "预测负荷","data": [{"name": "1:00","value": 9},{"name": "2:00","value": 13},{"name": "3:00","value": 13},{"name": "4:00","value": 2},{"name": "5:00","value": 8},{"name": "6:00","value": 18},{"name": "7:00","value": 10},{"name": "8:00","value": 19},{"name": "9:00","value": 6},{"name": "10:00","value": 20},{"name": "11:00","value": 4},{"name": "12:00","value": 2},{"name": "13:00","value": 949},{"name": "14:00","value": 477},{"name": "15:00","value": 144},{"name": "16:00","value": 363},{"name": "17:00","value": 213},{"name": "18:00","value": 660},{"name": "19:00","value": 923},{"name": "20:00","value": 812},{"name": "21:00","value": 720},{"name": "22:00","value": 90},{"name": "23:00","value": 994},{"name": "24:00","value": 597}]}
]
let maxIndex = 0
let minIndex = 0
// 获取最大和最小值
const getMaxAndMinValue = (arr) => {let maxValue = 0let minValue = 0// 循环获取最大和最小值arr.forEach(item => {if (item.value) minValue = item.valueif (item.value > maxValue) maxValue = item.value})return {maxValue,minValue}
}
// 判断最大值和最小值所在的图例
const getMaxAndMinIndex = (arr) => {let max = 0let min = 0// 获取最大值和最小值索引arr.forEach((item, index) => {const { maxValue, minValue } = getMaxAndMinValue(item.data)if (minValue < min) {min = minValueminIndex = index}if (maxValue > max) {max = maxValuemaxIndex = index}})}
// 获取配置项参数
function chartOptions(chartData) {const seriesData = chartData.map((item, index) => {const extraData = {markLine: {data: []},markPoint: {data: []}}// 通过索引判断该图例中是否有最大值if (maxIndex == index) {extraData.markLine.data.push({name: 'Max', type: 'max'})extraData.markPoint.data.push({name: 'Max', type: 'max'})}if (minIndex == index) {extraData.markPoint.data.push({name: 'Min', type: 'min'})}return {data: item.data.map(item => item.value),type: 'line',smooth: true,name: item.name,...extraData}})return {legend: {},dataZoom: {type: 'inside',show: true,start: 0,end: 60},xAxis: {type: 'category',data: chartData.length > 0 ? chartData[0].data.map(item => item.name) : [],splitNumber: 6},yAxis: {type: 'value'},series: seriesData}
}
getMaxAndMinIndex(data)
// 配置项
option = chartOptions(data);// 监听图例事件
myChart.on('legendselectchanged', (e) => {const chartData = data.filter(item => e.selected[item.name]) // 筛选数据getMaxAndMinIndex(chartData) // 查询索引myChart.setOption(chartOptions(chartData))
})
从完整代码中可见,chartOptions函数中之所以单独定义extraData变量,是方便通过索引来定位哪项数据中存在最大值或最小值,来动态绑定对应的markPoint或marLine属性。
此篇就先讲到这了,希望对大家有所帮助~