欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在react中使用antv g2绘制带有sider滑块的chart图表

程序员文章站 2022-04-21 23:48:17
...

在slider中会遇到的问题,slider两边要求展示的为文字,但过滤的时候过滤条件为下标,实现思路如下:

  • 过滤的时候判断条件是数值类型即下标,但为了在滑块两端展示文字,需要将’start’,'end’那边改成对应的起始终止文字,但又会出现新的问题,就是在onChange里面打印的startText和endText也为相应的文字而不是下标,考虑着在变化的时候需要将变化的下标赋值给ds里面的from和to,不然chart图表不再展示,就需要进行遍历判断一下,找到文字下对应的下标,然后赋值给from和to
import React from 'react';
import G2 from '@antv/g2';
import Slider from '@antv/g2-plugin-slider';
import DataSet from '@antv/data-set';

class Silder extends React.Component {
  constructor(props) {
    super(props)
    this.state = {}
  }
  componentDidMount() {
    this.fun()
  }

  fun() {
    const data = [
      { index: 0, type: 'a', type1: 'b', country: '巴西', value: 18203, value1: 1820 },
      { index: 1, type: 'a', type1: 'b', country: '印尼', value: 23489, value1: 2349 },
      { index: 2, type: 'a', type1: 'b', country: '美国', value: 29034, value1: 2934 },
      { index: 3, type: 'a', type1: 'b', country: '印度', value: 104970, value1: 14970 },
      { index: 4, type: 'a', type1: 'b', country: '中国', value: 131744, value1: 31744 },
    ];

    const ds = new DataSet({
      state: {
        from: data[0].index,
        to: data[data.length - 1].index
      }
    })

    const dv = ds.createView();
    dv.source(data)
      .transform({
        type: 'filter',//过滤条件,与滑块联动进行chart展示
        callback: obj => {
          // console.log(obj);
          return obj.index >= ds.state.from && obj.index <= ds.state.to
        }
      });

    const chart = new G2.Chart({
      container: 'container',
      forceFit: true,
      height: 320,
      padding: [40, 60, 70, 90]
    })

    const view1 = chart.view()
    view1.source(dv)
    view1.interval().position('country*value').color('type').tooltip('country*value*value1', function (country, value, value1) {
      console.log(country, value, value1, 'ccc');
      return {
        value: !value ? '--' : value,
        value1: !value1 ? '--' : value1
      }
    })

    const view2 = chart.view()
    view2.source(dv)
    //triangle 三角形
    view2.point().position('country*value1').color('type1', 'orange').shape('triangle').size(7).style({
      lineWidth: 0
    })
    view2.axis('value1', {
      position: 'right',
      grid: null
    })
    view2.tooltip(false)


    //使用辅助文本来设置坐标上方的单位
    chart.guide().text({
      top: true,
      position: ['start', 'end'],
      content: '(万m²)',
      style: {
        fill: '#000',
        fontSize: '12'
      },
      offsetX: -40,
      offsetY: -20
    })

    chart.guide().text({
      top: true,
      position: ['end', 'end'],
      content: '(月)',
      style: {
        fill: '#000',
        fontSize: '12'
      },
      offsetX: 15,
      offsetY: -20
    })

    //设置tooltip
    chart.tooltip({
      // title: 'year',
      containerTpl: '<div class="g2-tooltip">' + '<p class="g2-tooltip-title" ></p>' + '<ul class="g2-tooltip-list"></ul>' + '</div>', // tooltip的外层模板
      itemTpl:
        `<li class="g2-tooltip-list-item" data-index={index} >
  <span style="width:5px;height:5px;background:#2762d3;float:left;margin-right:5px;margin-top:8px; border-radius: 50%;"></span><p>a(万m²)<span class="g2-tooltip-value">{value}</span></p>
  <span style="width:5px;height:5px;background:#ffa900;float:left;margin-right:5px;margin-top:8px; border-radius: 50%;"></span><p>b(月)<span class="g2-tooltip-value" style="display: inline-block; float: right; margin-left: 30px;"
  >{value1}</span></p>
  </li> `,
      offset: 50,
      'g2-tooltip': {
        position: 'absolute',
        width: '160px',
        backgroundColor: '#fff',
        color: '#000',
        padding: '5px 15px',
        fontSize: '12px',
        'transition': 'top 200ms,left 200ms'
      }
    });

    chart.render()

    //滑块
    const slider = new Slider({
      container: 'silder',
      padding: [60],
      height: 15,
      start: data[0].country,//声明滑动条起始滑块的位置对应的数据值
      end: data[data.length - 1].country,//声明滑动条结束滑块的位置对应的数据值
      data,//原始数据data不是转换后的数据dv
      xAxis: 'country',//x轴对应的字段
      yAxis: 'value1',//y轴对应的字段
      fillerStyle: {//选中区域的样式配置,默认配置如下:
        fill: 'red',
        fillOpacity: 0.4
      },
      backgroundChart: {//slider 整体背景样式。
        type: 'line',
        color: 'rgba(0, 0, 0, 0.3)',
        fill: 'yellow'
      },
      textStyle: {//slider 辅助文本字体样式配置。
        fill: 'orange'
      },
      backgroundStyle: {
        fill: 'blue'
      },
      onChange: ({ startText, endText }) => {//当滑动条滑块发生变化时,触发该回调函数,主要用于更新 ds 的状态量。该回调函数会提供一个参数,该参数是一个对象,包含如下属性:const { startValue, endValue, startText, endText } = obj;
        // console.log(startText, endText);

        //dv.rows的数据是实时变化的,所以不能拿dv.rows数据做判断条件,拿原始的数据dv.origin或者data做判断

        let startRows = dv.origin.filter(item => item.country == startText)
        let endRows = dv.origin.filter(item => item.country == endText)

        let startIndex = startRows[0].index
        let endIndex = endRows[0].index

        // !!! 更新状态量
        ds.setState('from', startIndex);
        ds.setState('to', endIndex);
      }
    });

    slider.render();
  }

  render() {
    return (
      <div>
        <div id='container'></div>
        <div id='silder'></div>
      </div >
    )
  }
}
export default Silder

相关标签: chart react g2