使用d3.selectAll与反应组件

时间:2017-06-13 17:21:11

标签: javascript reactjs d3.js svg

我希望能够复制此演示:https://bl.ocks.org/danasilver/cc5f33a5ba9f90be77d96897768802ca但我想使用React组件而不是标准的svg圈子。从我所做的所有研究中,标准票价通常是将d3代码包装在React组件中而不是相反。我希望能够,而不是编写这段代码:

var circles = svg.selectAll('circle')
    .data(points)
  .enter().append('circle')
    .attr('cx', function(d) { return d.x; })
    .attr('cy', function(d) { return d.y; })
    .attr('r', r)
    .call(drag);

我想写这样的代码:

var circles = svg.selectAll({{insert react component here}})
    .data({{pass in the props here (or elsewhere)}})
  .enter().append('circle')
    .attr('cx', function(d) { return d.x; })
    .attr('cy', function(d) { return d.y; })
    .attr('r', r)
    .call(drag);

基本上我想使用react组件而不是标准的svg元素。如果可以,或者如果存在更好的解决方案,请告诉我。

我确实尝试过这样的事情(它顺便滚动):

import React, { Component } from 'react'
import './App.css'
import { scaleLinear } from 'd3-scale’
import { max } from 'd3-array'
import { select } from 'd3-selection'

const testcomponent = ({children, ...props}) => {
    <span> hello </span>
}

class DragArea extends Component {
   constructor(props){
      super(props)
      this.createDragArea = this.createDragArea.bind(this)
   }
   componentDidMount() {
      this.createDragArea()
   }
   componentDidUpdate() {
      this.createDragArea()
   }
   createDragArea() {
      const node = this.node
      var width = 960,
      height = 500,
      resolution = 20,
      r = 15;

      var points = d3.range(10).map(function() {
          return {
              x: round(Math.random() * width, resolution),
              y: round(Math.random() * height, resolution)
          };
      });

      var drag = d3.behavior.drag()
          .origin(function(d) { return d; })
          .on('drag', dragged);

      var svg = d3.select('body').append('svg')
          .attr('width', width)
          .attr('height', height);

      svg.selectAll('.vertical')
          .data(d3.range(1, width / resolution))
      .enter().append('line')
          .attr('class', 'vertical')
          .attr('x1', function(d) { return d * resolution; })
          .attr('y1', 0)
          .attr('x2', function(d) { return d * resolution; })
          .attr('y2', height);

      svg.selectAll('.horizontal')
          .data(d3.range(1, height / resolution))
      .enter().append('line')
          .attr('class', 'horizontal')
          .attr('x1', 0)
          .attr('y1', function(d) { return d * resolution; })
          .attr('x2', width)
          .attr('y2', function(d) { return d * resolution; });

       var circles = svg.selectAll('testcomponent')
           .data(points)
       .enter().append('circle')
           .attr('cx', function(d) { return d.x; })
           .attr('cy', function(d) { return d.y; })
           .attr('r', r)
           .call(drag);

    function dragged(d) {
        var x = d3.event.x,
            y = d3.event.y,
            gridX = round(Math.max(r, Math.min(width - r, resolution),
            gridY = round(Math.max(r, Math.min(height - r, resolution);

        d3.select(this).attr('cx', d.x = gridX).attr('cy', d.gridY);
    }

    function round(p, n) {
        return p % n < n / 2 ? p - (p % n) : p + n - (p % n);
    }
}
render() {
      return <svg ref={node => this.node = node}
      width={500} height={500}>
          <testcomponent></testcomponent>
      </svg>
   }
}
export default DragArea

但它肯定不起作用。我认为它不会识别选择器或类似的东西。

0 个答案:

没有答案