Vue中使用ECharts图表中的阈值标记(附源码)

发布于:2024-12-06 ⋅ 阅读:(35) ⋅ 点赞:(0)

在数据处理和可视化领域,我们经常需要对一系列数据点进行分析。本文将介绍如何在给定的数据点中找到对应于特定Y值的X值,并设置标线起始点标记在ECharts图表中,效果图如下:

实现步骤

1、数据准备

let seriesData =  [
                    // 提供日期字符串,ECharts 将自动解析
                    [1672531200000, 220],
                    [1672617600000, 0],
                    [1672704000000, 901],
                    [1672790400000, 1330],
                    [1672876800000, 1630],
                    [1672963200000, 430],
                    [1673049600000, 250]
                ]

2、计算阈值Y值

假设Y值为最大值的90%:

let maxDataValue = seriesData.reduce((max, item) => Math.max(max, item[1]), 0);
let thresholdValue = maxDataValue * 0.9;

3、查找对应的X值

function findXByY(dataPoints, givenY) {
    // 遍历数据点数组
    for (let i = 0; i < dataPoints.length - 1; i++) {
        // 获取当前点和下一个点的坐标
        const [x1, y1] = dataPoints[i];
        const [x2, y2] = dataPoints[i + 1];

        // 判断给定Y值是否在当前点和下一个点之间
        if (y1 <= givenY && givenY <= y2) {
            // 计算并返回对应的X值
            return x1 + (givenY - y1) * (x2 - x1) / (y2 - y1);
        }
    }

    // 如果给定Y值不在任何两个点之间,返回undefined
    return undefined;
}



const xValue = findXByY(seriesData, thresholdValue);

4、在ECharts图表中标记

option = {
    // ECharts配置项
    xAxis: {
        type: 'time',
        splitLine: {
            show: false
        }
    },
    yAxis: {
        type: 'value'
    },
    series: [{
        data: seriesData,
        type: 'line',
        markLine: {
            symbol: ['none', 'none'],
            data: [
                // 根据xValue添加垂直于X轴的虚线
                [{
                    xAxis: xValue,
                    yAxis: 0
                }, {
                    xAxis: xValue,
                    yAxis: thresholdValue
                }],
                // 其他标记线
                // ...
            ]
        }
    }]
}

完整代码:

<template>
  <div>
    <div id="myEcharts" class="charts"></div>
  </div>
</template>

<script>
import * as echarts from "echarts";
export default {
  data() {
    return {};
  },
  mounted() {
    this.seriesData = [
      [0, 1733286720001],
      [30, 1733286721001],
      [40, 1733286722001],
      [60, 1733286723001],
      [100, 1733286724001],
      [100, 1733286725001],
      [200, 1733286726001],
      [200, 1733286727001],
      [300, 1733286728001],
      [0, 1733286729001],
    ];
    this.seriesData = this.seriesData.map((pair) => [pair[1], pair[0]]);
    let firstYZero = this.seriesData.find((pair) => pair[1] === 0);

    let maxDataValue = this.seriesData.reduce(
      (max, item) => Math.max(max, item[1]),
      0
    );
    let thresholdValue = maxDataValue * 0.9;

    const xValue = this.findXByY(this.seriesData, thresholdValue);
    let option = {
      xAxis: {
        type: "time", // 使用时间轴
        name:'日期',
        splitLine: {
          show: false,
        },
        axisLabel: {
          interval: 0, 
        },
      },
      yAxis: {
        type: "value",
      },
      series: [
        {
          data: this.seriesData,
          type: "line",
        //   smooth: true,
          markLine: {
            symbol: ["none", "none"], // 线两端无箭头
            data: [
              // 垂直于X轴的虚线
              [
                {
                  xAxis: xValue, // 使用日期字符串
                  yAxis: 0,
                  lineStyle: {
                    color: "#000",
                  }
                },
                {
                  xAxis: xValue,
                  yAxis: thresholdValue,
                },
              ],
              [
                {
                  xAxis: firstYZero[0], // 使用日期字符串
                  yAxis: 0,
                  lineStyle: {
                    color: "#000",
                  }
                },
                {
                  xAxis: firstYZero[0],
                  yAxis: thresholdValue,
                },
              ],
              // 垂直于Y轴的虚线
              [
                {
                  xAxis: xValue, // 使用日期字符串
                  yAxis: thresholdValue,
                  label: {
                    formatter: "响应时间",
                    position: "middle", // 标签位置
                  },
                  lineStyle: {
                    color: "#000",
                  }
                },
                {
                  xAxis: firstYZero[0],
                  yAxis: thresholdValue,
                },
              ],
              [
                {
                  type: "max",
                  lineStyle: {
                    color: "red",
                  },
                },
                {
                  xAxis: "min",
                  yAxis: "max",
                },
              ],
              {
                yAxis: 250,
                label: {
                  formatter: "标准线",
                  position: "end",
                },
                lineStyle: {
                  color: "#00B79D",
                },
              },
            ],
          },
        },
      ],
    };
    let chartDom = document.getElementById("myEcharts");
    let myChart = echarts.init(chartDom);
    myChart.setOption(option);
  },
  methods: {
    findXByY(dataPoints, givenY) {
      for (let i = 0; i < dataPoints.length - 1; i++) {
        const [x1, y1] = dataPoints[i];
        const [x2, y2] = dataPoints[i + 1];

        // 检查给定的 y 值是否在当前点和下一个点之间
        if (y1 <= givenY && givenY <= y2) {
          // 计算并返回对应的 x 值
          return x1 + ((givenY - y1) * (x2 - x1)) / (y2 - y1);
        }
      }

      // 如果给定的 y 值不在任何两个点之间,则返回 undefined 或抛出错误
      return undefined;
    },
  },
};
</script>

<style scoped>
.charts {
  width: 100%;
  height: 600px;
}
</style>

 

 

 

 

 

 

 


网站公告

今日签到

点亮在社区的每一天
去签到

热门文章