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

在slider中会遇到的问题

1.slider两边要求展示的为文字,但过滤的时候过滤条件为下标,实现思路如下:
  • 过滤的时候判断条件是数值类型即下标,但为了在滑块两端展示文字,需要将’start’,'end’那边改成对应的起始终止文字,但又会出现新的问题,就是在onChange里面打印的startText和endText也为相应的文字而不是下标,考虑着在变化的时候需要将变化的下标赋值给ds里面的from和to,不然chart图表不再展示,就需要进行遍历判断一下,找到文字下对应的下标,然后赋值给from和to。
2. 视野中默认展示5条数据,鼠标移入柱图的时候,label变颜色,但当移动slider后,再移入柱图时会报错
  • 原因:移动完slider之后,重新获取的视野中的五个label又是新的0-4的label,labelAll = document.querySelectorAll('.g2-label-customize'),但移入的当前的柱图的下标是所有数据中的某一个,这样就会有冲突(比如:移入的当前的柱图,下标是3,但在当前label下可能是0)
  • 解决:截取当前视野下的数据,放在一个数组里面,其顺序就会与所有的label的顺序一致

在react中使用antv g2绘制带有sider滑块的chart图表_第1张图片

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() {
     
    let mIndex;//当前移入的下标
    let startIndex = 0;//起始下标
    let endIndex = 4;//终止下标
    const data = [
      {
      index: 0, type: 'a', type1: 'b', type2: 'c', country: '巴西', value: 18203, value1: 1820 },
      {
      index: 1, type: 'a', type1: 'b', type2: 'c', country: '印尼', value: 23489, value1: 2349 },
      {
      index: 2, type: 'a', type1: 'b', type2: 'c', country: '美国', value: 29034, value1: 2934 },
      {
      index: 3, type: 'a', type1: 'b', type2: 'c', country: '印度', value: 104970, value1: 14970 },
      {
      index: 4, type: 'a', type1: 'b', type2: 'c', country: '中国', value: 131744, value1: 31744 },
      {
      index: 5, type: 'a', type1: 'b', type2: 'c', country: '加拿大', value: 11203, value1: 1320 },
      {
      index: 6, type: 'a', type1: 'b', type2: 'c', country: '塞尔维亚', value: 143489, value1: 12349 },
      {
      index: 7, type: 'a', type1: 'b', type2: 'c', country: '伦敦', value: 20034, value1: 21934 },
      {
      index: 8, type: 'a', type1: 'b', type2: 'c', country: '泰国', value: 14970, value1: 1470 },
      {
      index: 9, type: 'a', type1: 'b', type2: 'c', country: '巴基斯坦', value: 0, value1: 21744 },
    ];

    let nums = []//value的所有值
    data.forEach(item => {
     
      nums.push(item.value)
    })

    let maxNum = 0;//最大值
    maxNum = Math.max(...nums) + 1

    data.forEach(item => {
     
      item.value2 = maxNum
    })

    const ds = new DataSet({
     
      state: {
     
        from: data[0].index,
        to: data[4].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.scale('value', {
     
      min: Math.min(...nums),
      max: Math.max(...nums) + 1
    })
    view1.interval().position('country*value').color('type').tooltip('country*value*value1*value2', function (country, value, value1, value2) {
     
      // console.log(country, value, value1, 'ccc');
      return {
     
        value: !value ? '--' : value,
        value1: !value1 ? '--' : value1,
        value2: !value2 ? '--' : value2
      }
    }).label('country*value', function (country, value) {
     
      return {
     
        useHtml: true,
        htmlTemplate: function htmlTemplate(text, item) {
     
          return (
            `` +
            value +
            " "
          );
        },
        // offset: 10,
      }
    })

    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)

    const view3 = chart.view()
    view3.source(dv)
    view3.scale('value2', {
     
      min: Math.min(...nums),
      max: Math.max(...nums) + 1
    })
    view3.interval().position('country*value2').color('transparent')
    view3.axis('value2', false)
    view3.tooltip(false)

    chart.on('interval:mouseenter', ev => {
     
      mIndex = dv.origin.slice(startIndex, endIndex + 1).findIndex(item => item.country === ev.data._origin.country
      )
      let labelAll = document.querySelectorAll('.g2-label-customize');
      labelAll[mIndex].style.color = 'red';
    })

    chart.on('interval:mouseleave', ev => {
     
      let labelAll = document.querySelectorAll('.g2-label-customize');
      labelAll[mIndex].style.color = '#b3f';
    })

    //使用辅助文本来设置坐标上方的单位
    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: '
' + '

'
+ '
    '
    + '
    '
    , // tooltip的外层模板 itemTpl: `
  • a(万m²){value}

    b(月){value1}

  • `
    , 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[4].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); //过滤的时候判断条件是数值类型即下标,但为了在滑块两端展示文字,需要将'start','end'那边改成对应的起始终止文字,但又会出现新的问题,就是在onChange里面打印的startText和endText也为相应的文字而不是下标,考虑着在变化的时候需要将变化的下标赋值给ds里面的from和to,不然chart图表不再展示,就需要进行遍历判断一下,找到文字下对应的下标,然后赋值给from和to //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) startIndex = startRows[0].index 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)