轮播折线图

描述:当前是关于Echarts图表中的 折线图 示例。
 
            /* 数据 */
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);
});