echarts + react实现基金走势图十字坐标随手指滑动显示

1、目前各大券商的基金股票商城很多都是用的H5实现,而谈到基金就离不开基金股票的走势图,那么首先想到的就是用echarts来实现,走势图内容展示用echarts的折线统计图再合适不过了,数据一套就出来了。
2、但是问题也来了,基金最重要的十字坐标怎么展示,即要根据手指滑动的位置实时显示基金的十字坐标点,而echarts只提供了y轴的也就是竖轴的指示线显示功能,下面图就是用echarts配置实现的y轴指示线功能。
3、下面是具体实现的echarts配置项,其中主要的是axisPointer配置项,里面的label配置用于显示y轴指示线底部的日期,而lineStyle用于配置指示线颜色等基本属性:
yaml 复制代码
const option = {
      animation: false,
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'cross',
          snap: true
        },
        formatter(params) {
          props.handleTooltipClick && props.handleTooltipClick(params); // 点击使用
        }
      },
      color: ['#F3402F', '#4C7CF1'],
      grid: {
        top: gridTop,
        left: '1',
        right: '1',
        bottom: '30px',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        axisTick: {
          show: false
        },
        axisLine: {
          lineStyle: {
            color: 'rgba(153, 153, 153, 0.2)',
            type: 'dashed'
          }
        },
        axisLabel: {
          fontSize,
          color: '#999',
          margin: 16,
          showMaxLabel: true,
          showMinLabel: true,
          interval: index => index === 0 || index === chartData.xData.length - 1 || index === Math.floor(chartData.xData.length / 2),
          formatter(value, index) {
            if (index === 0) {
              return `${space}${dayjs(value).format('YYYY-MM-DD')}`;
            } else if (index === chartData.xData.length - 1) {
              return `${dayjs(value).format('YYYY-MM-DD')}${space}`;
            }
            return dayjs(value).format('YYYY-MM-DD');
          },
          ...axisLabel
        },
        axisPointer: {
          label: {
            formatter(obj) {
              return `${obj.value.substring(4, 6)}-${obj.value.substring(6, 8)}`;
            },
            show: true,
            padding: [2, 4, 2, 4],
            fontSize,
            borderRadius: 0,
            backgroundColor: '#F24957'
          },
          lineStyle: {
            color: '#FF5800', // 指示线颜色
            type: 'dashed',
            height: 0.4
          }
        },
        data: chartData.xData
      },
      yAxis: {
        type: 'value',
        axisLabel: {
          fontSize,
          formatter(value) {
            return parseFloat(value).toFixed(toFixed) + sign;
          },
          color: '#999'
        },
        splitLine: {
          lineStyle: {
            color: 'rgba(153, 153, 153, 0.2)',
            type: 'dashed'
          }
        },
        axisPointer: {
          show: false // 隐藏y轴指示线
        },
        splitNumber: 5,
        axisTick: {
          show: false
        },
        axisLine: {
          show: false
        },
        scale: true
      },
      series: [
        {
          type: 'line',
          lineStyle: {
            normal: {
              width: lineWidth
            }
          },
          symbol: 'none',
          data: chartData.yData,
          areaStyle: {
            color: {
              type: 'linear',
              x: 0,
              y: 1,
              x2: 0,
              y2: 0,
              colorStops: [{ offset: 0, color: '#fff' }, { offset: 1, color: 'rgba(242, 73, 87, 0.1)' }],
              global: false // 缺省为 false
            },
            origin: 'start'
          }
        },
        {
          type: 'line',
          lineStyle: {
            normal: {
              width: lineWidth
            }
          },
          symbol: 'none',
          data: chartData.yData1 || []
        }
      ]
    };
4、那还剩下x轴的指示线怎么显示呢?echarts没有提供可以配置,且能根据手指滑动自动变换坐标的x轴的指示线;唯一显示的只有markLine配置项可以配置x轴的指示线,但是是静态的,并不能实时变动,因此要加上监听事件,而监听事件可以使用echarts的getZr()方法监听鼠标移动'mousemove' ,然后获取坐标实时更新markLine配置项,这样就能实现走势图十字坐标了。

(1)首先是markLine配置静态的x轴的指示线样式,下面是markLine配置代码

javascript 复制代码
markLine: {
            data: [],
            animation: false,
            label: {
              formatter(obj) {
                const plus = parseFloat(obj.value) > 0 ? '+' : '';
                return plus + parseFloat(obj.value).toFixed(toFixed) + sign;
              },
              position: 'start',
              padding: [2, 4, 2, 4],
              fontSize,
              borderRadius: 0,
              backgroundColor: '#F24957',
              color: '#fff'
            },
            lineStyle: {
              color: '#FF5800', // 指示线颜色
              type: 'dashed',
              height: 0.4
            },
            symbol: 'none' // 去掉箭头
          },

(2)在echarts的setOption下方加上getZr()方法监听鼠标(手指)移动'mousemove',最后实时获取x轴坐标并更新markLine配置,下面是具体实现的代码:

ini 复制代码
const myChart = echarts.init(document.getElementById('lineChart'));
const option = setLineOption();
    myChart.setOption(option);
    // 模拟十字轴的横轴
    myChart.getZr().on('mousemove', (params) => {
      // 获取点击位置的坐标
      const pointInPixel = [params.offsetX, params.offsetY];
      // containPixel为true则点击位置在坐标轴内
      if (myChart.containPixel('grid', pointInPixel)) {
        // 传入鼠标位置坐标进行转化
        // convertFromPixel返回[x, y],x对应鼠标点击处数据的下标,y对应鼠标点击处的数值
        const x = myChart.convertFromPixel({ seriesIndex: 0 }, pointInPixel)[0];
        if (!data.yData.length) {
          return;
        }
        const markLineValue = data.yData[x];
        if (markLineValue) {
          const series = option.series;
          // 修改markLine的值
          series[0].markLine.data = [{ yAxis: markLineValue }];
          // 重新setOption
          // console.log(series);
          myChart.setOption({ series }, { lazyUpdate: true });
          // 设置选中的内容
          // props.handleTooltipClick({ axisValue: data.xData[x], value: data.yData[x], compRate: data.yData1 ? data.yData1[x] : '' });
        }
      } else {
        // 不在坐标轴内不展示markLine
        const series = option.series;
        series[0].markLine.data = [];
        myChart.setOption({ series }, { lazyUpdate: true });
      }
    });
    myChart.getZr().on('mouseup', () => {
      myChart.dispatchAction({
        type: 'hideTip'
      });
      myChart.dispatchAction({
        type: 'updateAxisPointer',
        currTrigger: 'leave'
      });
      myChart.setOption({ series: [{ markLine: { data: [] } }] }, { lazyUpdate: true });
      // 设置选中的内容
      // props.handleTooltipClick({ axisValue: data.xData[data.xData.length - 1], value: data.yData[data.yData.length - 1], compRate: data.yData1 ? data.yData1[data.yData1.length - 1] : '' });
    });
相关推荐
疯狂的沙粒9 分钟前
Vue 前端大屏做多端屏幕适配时,如何让其自动适配多种不同尺寸的屏幕?
前端·javascript·vue.js
范小多13 分钟前
24小时学会Python Visual code +Python Playwright通过谷歌浏览器取控件元素(连载、十一)
服务器·前端·python
ooolmf14 分钟前
matlab2024读取温度01
java·前端·javascript
打工人小夏15 分钟前
前端vue3项目使用nprogress动画组件,实现页面加载动画
前端
一颗宁檬不酸17 分钟前
前端农业商城中产品产地溯源功能的实现
前端
李少兄24 分钟前
深入理解前端中的透视(Perspective)
前端·css
江公望34 分钟前
HTML5 History 模式 5分钟讲清楚
前端·html·html5
云和数据.ChenGuang40 分钟前
Zabbix Web 界面安装时**无法自动创建配置文件 `zabbix.conf.php`** 的问题
前端·zabbix·运维技术·数据库运维工程师·运维教程
码界奇点43 分钟前
Java Web学习 第15篇jQuery万字长文详解从入门到实战解锁前端交互新境界
java·前端·学习·jquery
前端老曹1 小时前
vue3 三级路由无法缓存的终极解决方案
前端·javascript·vue.js·vue