React D3:如何在同一个图表中使用react-d3-tooltip和react-d3-zoom?

时间:2016-06-01 05:21:12

标签: javascript d3.js svg reactjs

我正在尝试使用 React-d3 (www.reactd3.org)创建一个包含工具提示和缩放组件的折线图。

但是我无法弄清楚如何将两个组件一起使用。

我能够创建一个简单的LineChart

import {LineChart} from 'react-d3-basic';
import {LineTooltip, SimpleTooltip} from 'react-d3-tooltip';
import {LineZoom} from 'react-d3-zoom';

render() {
  var viewCountData = [
    {
      "date": new Date(2016, 5, 29),
      "Object1":11,
      "Object2":13,
      "Object3":16
    },
    {
      "date": new Date(2016, 5, 30),
      "Object1":23,
      "Object2":17,
      "Object3":15
    }
  ];
  var chartSeries = [
    {field: "Object1"},
    {field: "Object2"},
    {field: "Object3"}
  ];
  var x = function(d) {
    return d.date;
  };

  return (
    <LineChart
      data= {viewCountData}
      chartSeries= {chartSeries}
      x= {x}>
    </LineChart>
  );
}

并将LineChart替换为LineTooltip来添加工具提示:

<LineTooltip
  data= {viewCountData}
  chartSeries= {chartSeries}
  x= {x}>
  <SimpleTooltip />
</LineTooltip>

但我无法弄清楚如何使用LineZoom。我尝试将其嵌套在LineTooltip

<LineTooltip ...>
  <LineZoom ...>
  </LineZoom>
</LineTooltip>

并且同时拥有LineChart

<LineChart ...>
  <LineTooltip ...>
  </LineTooltip>
  <LineZoom ...>
  </LineZoom>
</LineChart>

但都没有奏效。任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:0)

我基本上修改了变焦线示例以包含voroni实用程序。 一些快速粗略的测试虽然表明要做兼容性的工作,但这应该可以帮助你

import React, {PropTypes} from 'react';
// import d3 from 'd3';
// import {LineZoom} from 'react-d3-zoom';
import {
  Chart,
} from 'react-d3-core';
import {
  LineChart,
  series
} from 'react-d3-basic';
import ZoomSet from 'react-d3-zoom/lib/inherit';
import ZoomFocus from 'react-d3-zoom/lib/utils/zoom_focus';
import CommonProps from 'react-d3-zoom/lib/commonProps';


// Tooltip
import Voronoi from 'react-d3-tooltip/lib/utils/voronoi';

export default class Line extends ZoomSet {
  constructor(props) {
    super(props);

    const {
      contentTooltip,
      margins,
      width,
      height
    } = this.props;

    this.zoomed = this.zoomed.bind(this);
    this.mkXDomain();
    this.mkYDomain();

    this.state = {
      xDomainSet: this.setXDomain,
      yDomainSet: this.setYDomain,
      onZoom: this.zoomed,
      d3EventSet: null,
      xRange: this.props.xRange ||
        [0, width - margins.left - margins.right],
      yRange: this.props.yRange ||
        [height - margins.top - margins.bottom, 0],
      xRangeRoundBands: this.props.xRangeRoundBands || {
        interval: [0, width - margins.left - margins.right],
        padding: 1
      },
      zoomType: 'line'
    };

    this.mkXScale(this.setXDomain);
    this.mkYScale(this.setYDomain);

    this.state = Object.assign(this.state, {
      xScaleSet: this.setXScale,
      yScaleSet: this.setYScale
    });
  }

  static defaultProps = CommonProps


  render() {
    const {
      xDomainSet,
      yDomainSet,
      contentTooltip
    } = this.state;

    const voroni = (
      <Voronoi
        {...this.state}
        {...this.props}
        // onMouseOver= {(...args)=>console.log(args)}
        // onMouseOut= {(...args)=>console.log(args)}
        />
    );

    const focus = <ZoomFocus {...this.props} />;
    // console.log('state', this.state, Chart);
    return (
      <div>
        <Chart {...this.props} {...this.state}>
          <LineChart
            {...this.props}
            {...this.state}
            xDomain={xDomainSet} yDomain={yDomainSet}
            showZoom/>
          {focus}
          {voroni}
        </Chart>
      </div>
    );
  }
}