/* 数据 */ const nameList = ['2018', '2019', '2020', '2021', '2022']; // x轴数据 const valueList = [ [60, 70, 78, 70, 60], [45, 60, 65, 60, 78] ]; // 折线总数据 const legend = ['金额', '增长率']; // 图例数据 const yName = '人数(人)'; // y轴名称 const unit = '人'; /* 颜色 */ const colorList = ['rgba(57, 126, 240, 1)', 'rgba(250, 173, 20, 1)']; // 主颜色系 const areaColorList = [ { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: 'rgba(0, 117, 255, 0.3)' // 0% 处的颜色 }, { offset: 1, color: 'rgba(0, 117, 255, 0)' // 100% 处的颜色 } ], global: false // 缺省为 false }, { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: 'rgba(255, 175, 20, 0.3)' // 0% 处的颜色 }, { offset: 1, color: 'rgba(255, 179, 31, 0)' // 100% 处的颜色 } ], global: false // 缺省为 false } ]; // 渐变空间颜色 /* 数据整理 */ // 获取拐点数据 const getLineDataAll = () => { let dataArr = []; // 拐点数据 let arr1 = []; let arr2 = []; nameList.map((item, index) => { // 判断大小显示label // arr1 if (Number(valueList[0][index]) > Number(valueList[1][index])) { arr1.push({ value: valueList[0][index], label: { show: true, z: 3, position: 'top', opacity: 0.6, backgroundColor: '#001435', offset: [0, -8], borderRadius: 2, formatter: (params) => { return `{a|${valueList[0][index]}}\n{b|${valueList[1][index]}}`; }, rich: { a: { fontSize: 12, color: 'rgba(57, 126, 240, 1)', fontFamily: 'Source Han Sans CN-Regular', padding: [4, 2, 2, 2] }, b: { fontSize: 12, color: 'rgba(255, 229, 143, 1)', fontFamily: 'Source Han Sans CN-Regular', padding: [2, 2, 0, 2] } } }, emphasis: { scale: 2, itemStyle: { borderWidth: 3 }, label: { opacity: 1, rich: { a: { fontSize: 14, color: '#ABC6F7', fontFamily: 'Source Han Sans CN-Regular', padding: [4, 2, 2, 2] }, b: { fontSize: 14, color: 'rgba(255, 229, 143, 1)', fontFamily: 'Source Han Sans CN-Regular', padding: [2, 2, 0, 2] } } } } }); } else { arr1.push({ value: valueList[0][index], emphasis: { scale: 2, itemStyle: { borderWidth: 3 } } }); } // arr2 if (Number(valueList[1][index]) > Number(valueList[0][index])) { arr2.push({ value: valueList[1][index], label: { show: true, z: 3, position: 'top', opacity: 0.6, backgroundColor: '#001435', offset: [0, -8], borderRadius: 2, formatter: (params) => { return `{b|${valueList[1][index]}}\n{a|${valueList[0][index]}}`; }, rich: { a: { fontSize: 12, color: 'rgba(57, 126, 240, 1)', fontFamily: 'Source Han Sans CN-Regular', padding: [2, 2, 0, 2] }, b: { fontSize: 12, color: 'rgba(255, 229, 143, 1)', fontFamily: 'Source Han Sans CN-Regular', padding: [4, 2, 0, 2] } } }, emphasis: { scale: 2, itemStyle: { borderWidth: 3 }, label: { opacity: 1, rich: { a: { fontSize: 14, color: '#ABC6F7', fontFamily: 'Source Han Sans CN-Regular', padding: [2, 2, 0, 2] }, b: { fontSize: 14, color: 'rgba(255, 229, 143, 1)', fontFamily: 'Source Han Sans CN-Regular', padding: [4, 2, 0, 2] } } } } }); } else { arr2.push({ value: valueList[1][index], emphasis: { scale: 2, itemStyle: { borderWidth: 3 } } }); } }); dataArr.push(arr1); dataArr.push(arr2); return dataArr; }; // 获取单条 const getLineDataSingle = () => { let dataArr = []; // 拐点数据 let arr1 = []; let arr2 = []; nameList.map((item, index) => { // 判断大小显示label // arr1 arr1.push({ value: valueList[0][index], label: { show: true, z: 3, position: 'top', opacity: 0.6, backgroundColor: '#001435', offset: [0, -8], borderRadius: 2, formatter: (params) => { return `{a|${valueList[0][index]}}`; }, rich: { a: { fontSize: 12, color: 'rgba(57, 126, 240, 1)', fontFamily: 'Source Han Sans CN-Regular', padding: [4, 2, 2, 2] } } }, emphasis: { scale: 2, itemStyle: { borderWidth: 3 }, label: { opacity: 1, rich: { a: { fontSize: 14, color: '#ABC6F7', fontFamily: 'Source Han Sans CN-Regular', padding: [4, 2, 2, 2] } } } } }); // arr2 arr2.push({ value: valueList[1][index], label: { show: true, z: 3, position: 'top', opacity: 0.6, backgroundColor: '#001435', offset: [0, -8], borderRadius: 2, formatter: (params) => { return `{b|${valueList[1][index]}}`; }, rich: { b: { fontSize: 12, color: 'rgba(255, 229, 143, 1)', fontFamily: 'Source Han Sans CN-Regular', padding: [4, 2, 0, 2] } } }, emphasis: { scale: 2, itemStyle: { borderWidth: 3 }, label: { opacity: 1, rich: { b: { fontSize: 14, color: 'rgba(255, 229, 143, 1)', fontFamily: 'Source Han Sans CN-Regular', padding: [4, 2, 0, 2] } } } } }); }); dataArr.push(arr1); dataArr.push(arr2); return dataArr; }; let dataList = getLineDataAll(); let legendData = []; // legend数据 let seriesData = []; // series数据 legend.map((item, index) => { legendData.push({ name: item, icon: 'circle', itemStyle: { color: '#FFFFFF', borderColor: colorList[index], borderWidth: 3 } }); seriesData.push({ name: item, yAxisIndex: 0, type: 'line', silent: true, z: 2, data: dataList[index], symbolSize: 6, //标记的大小 lineStyle: { color: colorList[index], width: 2 }, itemStyle: { //折线拐点标志的样式 color: colorList[index], borderColor: colorList[index], borderWidth: 1 }, areaStyle: { color: areaColorList[index] } }); }); let valueMax = 0; [...valueList[0], ...valueList[1]].map((item) => { if (Number(item) > valueMax) { valueMax = Number(item); } }); seriesData.push({ name: 'bgBar', type: 'bar', // silent: true, yAxisIndex: 1, z: 1, data: nameList.map((item) => { return { value: valueMax + 0.2 * valueMax, itemStyle: { color: 'rgba(57,126,240,0)' } }; }) // barWidth: 33 }); var option = { backgroundColor: 'RGBA(0, 13, 32, 1)', tooltip: { trigger: 'none', axisPointer: { type: 'none', shadowStyle: { color: 'rgba(57, 126, 240, 0.2)' } }, showContent: false, position: function (point, params, dom, rect, size) { // 提示框位置 let x = 0; let y = 0; //提示框定位 if (point[0] + size.contentSize[0] < size.viewSize[0]) { x = point[0]; } else if (point[0] > size.contentSize[0]) { x = point[0] - size.contentSize[0]; } else { x = '30%'; } if (point[1] > size.contentSize[1]) { y = point[1] - size.contentSize[1]; } else if (point[1] + size.contentSize[1] < size.viewSize[1]) { y = point[1]; } else { y = '30%'; } return [x, y]; }, formatter: (params) => { let currenrName = params[0].name; let currenrTypeList = params.filter((item) => item.seriesName); let childDiv = `<div>`; legend.map((item, index) => { params.map((item2, index2) => { if (item2.seriesName === item) { childDiv += ` <div style="margin-top: 4px;position:relative;"> <div style="width: 6px;height: 6px;background: #FFFFFF;border: 3px solid ${colorList[index]};position:absolute;top:50%;transform:translateY(-50%);left:0;border-radius:50%;"></div> <span style="margin:0 0 0 20px;font-size: 12px;font-family: Source Han Sans CN-Regular;font-weight: 400;color: #FFFFFF;">${item}:${params[index2].value}${unit}</span> </div> `; } }); }); childDiv += `</div>`; return ` <div style="font-size: 12px;font-family: Source Han Sans CN-Medium;font-weight: 500;color: #FFFFFF;margin-bottom:4px;">${currenrName}年</div> ${childDiv} `; }, extraCssText: 'background-color:rgba(0,13,35,0.9);padding:8px 12px;box-shadow: 1px 6px 15px 1px rgba(0,0,0,0.13);border-radius: 4px;filter: blur(undefinedpx);border:none;' }, legend: { data: legendData, top: 16, left: 0, itemWidth: 9, itemHeight: 9, itemGap: 16, textStyle: { fontSize: 12, color: '#ABC6F7', fontFamily: 'Source Han Sans CN-Regular', padding: [0, 0, 0, 4] } }, grid: { left: '24', right: '24', top: '80', bottom: '24', containLabel: true }, xAxis: { type: 'category', data: nameList, axisTick: { show: false //隐藏X轴刻度 }, axisLine: { lineStyle: { color: 'rgba(62, 102, 181, 1)' } }, axisLabel: { show: true, margin: 12, textStyle: { fontSize: 12, color: '#ABC6F7', //X轴文字颜色 fontFamily: 'Source Han Sans CN-Regular', fontWeight: 400 } } }, yAxis: [ { boundaryGap: ['0', '20%'], name: yName, nameTextStyle: { fontSize: 12, color: '#ABC6F7', //X轴文字颜色 fontFamily: 'Source Han Sans CN-Regular', align: 'left', verticalAlign: 'center' }, type: 'value', axisTick: { show: false }, splitLine: { lineStyle: { type: 'dashed', width: 1, color: '#3E66B5' } }, axisLine: { show: false }, axisLabel: { show: true, fontSize: 12, color: '#ABC6F7', fontFamily: 'HarmonyOS Sans-Regular' }, splitArea: { show: false } }, { boundaryGap: ['0', '10%'], position: 'right', max: valueMax + 0.2 * valueMax, type: 'value', axisTick: { show: false }, splitLine: { show: false }, axisLine: { show: false }, axisLabel: { show: false }, splitArea: { show: false } } ], series: seriesData }; // 图例legend改变时 console.log(seriesData); myChart.on('legendselectchanged', (params) => { let selectArr = []; // 当前选中数据 let lineData = []; // 折线图数据 legend.map((item) => { if (params.selected[item]) { selectArr.push(item); } }); if (selectArr.length < 2) { lineData = getLineDataSingle(); } else { lineData = getLineDataAll(); } myChart.setOption({ series: [ { name: legend[0], data: lineData[0] }, { name: legend[1], data: lineData[1] } ] }); console.log('图例', lineData, selectArr, seriesData); }); let count = 0; let timer = null; let dataLength = option.series[0].data.length; //timer && clearInterval(timer); timer = setInterval(() => { const currentIndex = count % dataLength; myChart.dispatchAction({ type: 'downplay', seriesIndex: [0, 1] }); myChart.dispatchAction({ type: 'highlight', seriesIndex: [0, 1], dataIndex: currentIndex }); myChart.setOption({ tooltip: { trigger: 'none', showContent: false }, series: [ { name: 'bgBar', data: nameList.map((item, index) => { if (index === currentIndex) { return { value: valueMax + 0.2 * valueMax, itemStyle: { color: 'rgba(57,126,240,0.2)' } }; } else { return { value: valueMax + 0.2 * valueMax, itemStyle: { color: 'rgba(57,126,240,0)' } }; } }) } ] }); count++; }, 3000); // 鼠标移入 myChart.on('mouseover', (params) => { timer && clearInterval(timer); const currentIndex = params.dataIndex; myChart.dispatchAction({ type: 'downplay', seriesName: legend }); myChart.dispatchAction({ type: 'highlight', seriesName: legend, dataIndex: currentIndex }); myChart.setOption({ tooltip: { trigger: 'axis', showContent: true }, series: [ { name: 'bgBar', data: nameList.map((item, index) => { if (index === currentIndex) { return { value: valueMax + 0.2 * valueMax, itemStyle: { color: 'rgba(57,126,240,0.2)' } }; } else { return { value: valueMax + 0.2 * valueMax, itemStyle: { color: 'rgba(57,126,240,0)' } }; } }) } ] }); }); // 鼠标移出 myChart.on('mouseout', (params) => { timer && clearInterval(timer); let currentIndex = params.dataIndex; count = params.dataIndex + 1; myChart.setOption({ tooltip: { trigger: 'none', showContent: false }, series: [ { name: 'bgBar', data: nameList.map((item, index) => { return { value: valueMax + 0.2 * valueMax, itemStyle: { color: 'rgba(57,126,240,0)' } }; }) } ] }); timer = setInterval(() => { const currentIndex = count % dataLength; myChart.dispatchAction({ type: 'downplay', seriesIndex: [0, 1] }); myChart.dispatchAction({ type: 'highlight', seriesIndex: [0, 1], dataIndex: currentIndex }); myChart.setOption({ tooltip: { trigger: 'none', showContent: false }, series: [ { name: 'bgBar', data: nameList.map((item, index) => { if (index === currentIndex) { return { value: valueMax + 0.2 * valueMax, itemStyle: { color: 'rgba(57,126,240,0.2)' } }; } else { return { value: valueMax + 0.2 * valueMax, itemStyle: { color: 'rgba(57,126,240,0)' } }; } }) } ] }); count++; }, 3000); });