2017-01-26 9 views
2

私はReactでd3を使用して散布図を作成しようとしています。利用可能な例はあまりありませんが、thisが便利です。グラフは次のようになりますd3を使用したスキャッタプロット

class Axis extends React.Component { 
    constructor(props) { 
     super(props); 
    } 

    componentDidUpdate() { 
     this.renderAxis(); 
    } 

    componentDidMount() { 
     this.renderAxis(); 
    } 

    renderAxis() { 
     const node = ReactDOM.findDOMNode(this); 
     d3.select(node).call(this.props.axis); 
    } 

    render() { 
     const translate = 'translate(0,'+(this.props.h)+')'; 

     return (
      <g className='axis' transform={this.props.axisType == 'x' ? translate : "" }> 
      </g> 
     ); 
    } 
} 


Axis.propTypes = { 
    h: React.PropTypes.number, 
    axis: React.PropTypes.func, 
    axisType: React.PropTypes.oneOf(['x', 'y']) 
}; 

class Points extends React.Component { 
    constructor(props) { 
     super(props); 
    } 

    render() { 

     const _self = this; 
     const circles = _self.props.data.map((d, i) => { 
      return (
       <circle className="dot" r="3.5" cx={_self.props.x(d)} cy={_self.props.y(d)} key={i} fill="red"/> 
      ); 
     }); 
     return (
      <g>{circles}</g> 
     ); 
    } 
} 

Points.propTypes = { 
    data: React.PropTypes.array, 
    x: React.PropTypes.func, 
    y: React.PropTypes.func 
} 

export default class PlotBlock extends React.Component { 
    constructor(props) { 
     super(props); 
    this.state = { 
     csvData: '' 
    }; 
    } 

componentWillMount() { 
    let inputData; 

    inputData = [{"Name":"A1_P1","Category":"A01","Score 1":"2.3","Score 2":"2.4","Score 3":"4.1","Average score":"2.4"},{"Name":"A2_P1","Category":"A02","Score 1":"1.4","Score 2":"1.5","Score 3":"2.4","Average score":"1.5"},{"Name":"A3_P1","Category":"A03","Score 1":"0.9","Score 2":"0.9","Score 3":"0.9","Average score":"0.9"},{"Name":"A4_P1","Category":"B01","Score 1":"1.5","Score 2":"1.5","Score 3":"1","Average score":"1.5"},{"Name":"A5_P1","Category":"B02","Score 1":"1.2","Score 2":"1.2","Score 3":"1.4","Average score":"1.2"},{"Name":"A6_P1","Category":"B03","Score 1":"1","Score 2":"1","Score 3":"1.1","Average score":"1"},{"Name":"A7_P1","Category":"C01","Score 1":"1.6","Score 2":"1.2","Score 3":"1","Average score":"1.2"},{"Name":"A8_P1","Category":"C02","Score 1":"1.2","Score 2":"1.2","Score 3":"0.9","Average score":"1.2"},{"Name":"A9_P1","Category":"C03","Score 1":"1.1","Score 2":"1.1","Score 3":"1","Average score":"1.1"},{"Name":"A10_P1","Category":"D01","Score 1":"1.5","Score 2":"1.6","Score 3":"1.1","Average score":"1.5"}]; 

    this.setState({ csvData: inputData }); 

} 

    render() { 
    const margin = {top: 20, right: 20, bottom: 30, left: 50}; 
    const width = 720 - margin.left - margin.right; 
    const height = 200 - margin.top - margin.bottom; 

    const svg = d3.select('body').append('svg') 
        .attr('width', width + margin.left + margin.right) 
        .attr('height', height + margin.top + margin.bottom + 200) 
        .append('g') 
        .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); 

    const x = (d) => d['Category']; 
    const xScale = d3.scalePoint() 
        .range([0, width]); 
    const xMap = (d) => { 
     return xScale(x(d)); 
    }; 
    const xAxis = d3.axisBottom(xScale); 

    const y = (d) => d['Score']; 
    const yScale = d3.scaleLinear() 
        .range([height, 0]); 
    const yMap = (d) => {; 
     return yScale(y(d)); 
    }; 
    const yAxis = d3.axisLeft(yScale); 

    const svgContainerWidth = width + margin.left + margin.right; 
    const svgContainerHeight = height + margin.top + margin.bottom + 200; 
    const innerContainer = 'translate(' + margin.left + ',' + margin.top + ')'; 


    if (this.state.csvData) { 
     return (
      <div className='plot-block'> 
       <svg width={svgContainerWidth} height={svgContainerHeight}> 
        <g transform={innerContainer}> 
         <Axis h={height} axis={xAxis} axisType="x" /> 
         <Axis h={height} axis={yAxis} axisType="y" /> 
         <Points data={this.state.csvData} x={xMap} y={yMap} /> 
        </g> 
       </svg> 
      </div> 
     ); 
    } 
    return null; 
    } 
} 

:だから私のコードは以下の通りです

enter image description here

最大の問題は、ドットの「CX」属性がまったく表示されないことですし、 'cy'の値も間違っているようです。私はグラフをd3とd3だけを使ってうまくプロットしたので、私は知っています。特に、xMapyMapを呼び出すと、関数と入力パラメータがd3のみを使用してプロットするときと同じように見えますが、値はすべて間違っています。私は本当に混乱しており、React + d3の統合の本当の良い例はありません。助けてください。

答えて

1

私はReactユーザーではありませんが、コードのD3部分に関しては、両方のスケールのドメインが不足していると思います。

彼らは次のようになります。

const yScale = d3.scaleLinear() 
    .domain([0, d3.max(data, y)]) 
    .range([height, 0]); 

const xScale = d3.scalePoint() 
    .domain(data.map((d) => d["Category"])) 
    .range([0, width]); 
+1

OK、はい、ありがとうございました!それは間違いでした。私は実際にそれを以前書いていましたが、他のいくつかの問題をデバッグしている間に削除しました。私は実際にそれを終日行っています: – user3033194

関連する問題