javascript - Apache echarts 中拖动垂直标记线

标签 javascript css echarts apache-echarts

我想在折线图中添加几条垂直标记线,并允许用户进行水平拖动,类似于this Highcharts example.

设置xAxis.axisPointer在这个意义上很有用。但是,如何才能允许在水平线上拖动整条垂直线,而不是使用如下所示的底部按钮?

Here's my attempt :

Edit echart-line-vanilla (forked)

enter image description here

import "./styles.css";
import echarts from "echarts";

const myChart = echarts.init(document.getElementById("app"));

const option = {
  xAxis: {
    type: "time",
    nameLocation: "center",
    nameGap: 20,
    interval: 420000,
    min: 1625741884000,
    max: 1625749084000,
    axisLabel: {
      rotate: 0
    },
    boundaryGap: ["0%", "0%"],
    axisPointer: {
      value: 1625742000000,
      snap: true,
      lineStyle: {
        color: "#ff0000",
        width: 4
      },
      handle: {
        show: true,
        color: "#ff0000"
      }
    }
  },
  yAxis: [
    {
      type: "value",
      nameLocation: "center",
      nameGap: 8,
      interval: 0.33,
      min: 1,
      max: 5.33,
      axisLabel: {
        margin: 24,
        rotate: 0
      }
    }
  ],
  series: [
    {
      id: "test",
      name: "Average Time",
      yAxisIndex: 0,
      data: [
        {
          value: [1625741884000, 1]
        },
        {
          value: [1625741885000, 1]
        },
        {
          value: [1625741890000, 1]
        },
         ...

      ],
      subSeries: [],
      invert: false,
      type: "line",
      showSymbol: false,
      symbolSize: 5,
      smooth: false,
      color: "#4da6e8",
      lineStyle: {}
    }
  ]
};

myChart.setOption(option);

最佳答案

据我所知,不可能在同一个图表上有 2 个 axisPointer 。我一直在寻找这个功能一段时间,但仍然找不到完美的解决方案。使用graphics的解决方法可以用来实现与您想要的类似的效果,但它远非完美。我还是分享一下,希望对你有帮助。

var myChart = echarts.init(document.getElementById('main'));

let base = +new Date(1988, 9, 3);
let oneDay = 24 * 3600 * 1000;
let data = [[base, Math.random() * 300]];

for (let i = 1; i < 20000; i++) {
    let now = new Date((base += oneDay));
    data.push([+now, Math.round((Math.random() - 0.5) * 20 + data[i - 1][1])]);
}

option = {
  grid: {
    top: '40px',
    bottom: '60px',
    left: '50px',
    right: '30px'
  },
  xAxis: {
    type: 'time',
    boundaryGap: false,
    axisLine: {onZero: false},
    axisPointer:
    {
      show: true,
      type: 'line',
    },
  },
  yAxis: {
    type: 'value',
    boundaryGap: [0, '100%']
  },
  series: [
    {
    name: 'Fake Data',
    type: 'line',
    smooth: true,
    symbol: 'none',
    areaStyle: {},
    data: data
    }
  ],
  graphic: {
    elements: [
    {
    type: 'group',
    left: 'center',
    draggable: 'horizontal',
    ondrag: function (params) {    
      var pointInPixel = [params.offsetX, params.offsetY];
      var pointInGrid = myChart.convertFromPixel('grid', pointInPixel);

      var xTime = new Date(pointInGrid[0])

      //get closest value from cursor
      var point = data.reduce((prev, curr) => Math.abs(new Date(curr[0]).valueOf() - xTime.valueOf()) < Math.abs(new Date(prev[0]).valueOf() - xTime.valueOf()) ? curr : prev)

      //console.log('poi', new Date(pointInGrid[0]), new Date(point[0]), point[1])

      var d = document.getElementById('value2');
      d.style.left = params.offsetX+'px';
      d.innerHTML = point[1]
    },
    children: [
    {
      id: 'bar1',
      type: 'rect',
      top: '30px',
      shape: {
          width: 2,
          height: 685
      },
      style: {
          fill: "#ff0000"
      },
      cursor: 'ew-resize'
    },
    {
      type: 'circle',
      top: '740px',
      shape: {
          r:10
      },
      style: {
          fill: "#ff0000"
      },
    }
    ]
    },
    {
      type: 'group',
      left: '150px',
      draggable: 'horizontal',
      ondrag: function (params) {    
        var pointInPixel = [params.offsetX, params.offsetY];
        var pointInGrid = myChart.convertFromPixel('grid', pointInPixel);

        var xTime = new Date(pointInGrid[0])

        //get closest value from cursor
        var point = data.reduce((prev, curr) => Math.abs(new Date(curr[0]).valueOf() - xTime.valueOf()) < Math.abs(new Date(prev[0]).valueOf() - xTime.valueOf()) ? curr : prev)

        //console.log('poi', new Date(pointInGrid[0]), new Date(point[0]), point[1])

        var d = document.getElementById('value1');
        d.style.left = params.offsetX+'px';
        d.innerHTML = point[1]
      },
      children: [
        {
            type: 'rect',
            top: '30px',
            shape: {
                width: 2,
                height: 685
            },
            style: {
                fill: "#0000ff"
            },
            cursor: 'ew-resize'
        },
      ]
    },
  ]}
};

myChart .setOption(option)
<html>
  <body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.3.2/echarts.min.js"></script>
    <div id="main" style="width: 1200px; height:775px;"></div>
    <div id="value1" style="background-color: blue; color: white; position: absolute; top: 280px; left: 185px">0</div>
    <div id="value2" style="background-color: red; position: absolute; top: 280px; left: 605px">0</div>
  </body>
</html>

graphic.elements.ondrag 函数非常有趣,因为它允许获取沿光标的系列值。在示例中,该值显示在“光标”上方的 div 中,但它可以在其他地方以更漂亮的方式显示。

关于javascript - Apache echarts 中拖动垂直标记线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72686838/

相关文章:

javascript - 多个悬停实例 jQuery

javascript - Angular ngrepeat 不显示对象数组中的任何数据

javascript - 插入自定义的滚动文本

css - 框阴影不覆盖div

json - Echarts - 基于Json数据的动态多折线图

echarts - 如何动态更新echarts plot主题

javascript - 如何从异步调用返回响应?

javascript - Google reCAPTCHA v2 忽略 CSS 对齐

bar-chart - 如何在 Apache Echarts 上的 xAxis 线本身和条形下边缘之间添加空间

html - CSS - 在边距中包含滚动条大小