2
votes

I have created chart using D3js and react. I am using grid system of react semantic ui. I want to place chart inside column but the chart is not getting placed inside the column. On barchart is getting placed on left column but piechart should be in right column but it is showing in left side why so ?

Note: I have not added any CSS for piechart and barchart.Barchart component returns svg of width= 550 height=450. Piechart component returns svg of width=height=100

How can I place Piechart inside column in grid system ?

Code:

dashboard.js

import React, { Component } from 'react';
import { Card, Icon, Image, Grid } from 'semantic-ui-react';
import styles from './dashboard.module.css';
import BarChart from './barchart';
import PieChart from './piechart';

const DashBoard = () => (
    <Grid columns='two' divided className={styles.container}>
    <Grid.Row>
      <Grid.Column>
            <BarChart/>
      </Grid.Column>
      <Grid.Column>
            <PieChart/>
      </Grid.Column>
    </Grid.Row>
  </Grid>
)

export default DashBoard;

dashboard.module.css:

.container {
    margin-left: 100px !important;
    margin-top: 100px !important;
    margin-right: 100px !important;
    height: 400px;
}

Screenshot:

enter image description here

enter image description here

1

1 Answers

2
votes

Disclaimer: This had been solved prior to this post in another chatroom.

Working directly with you in Reactiflux I was able to create the following codesandbox to address your issue. https://codesandbox.io/s/m45q494r2x

It would seem that you were doing the following when creating new d3 elements:

   var svg = d3.select("SVG"),
  width = svg.attr("width"),
  height = svg.attr("height"),
  radius = Math.min(width, height) / 2,
  g = svg
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

You were selecting the first instance of an SVG and adding to it. When you placed either chart together they were using the same and first svg they found.

There were a few solutions you could have used.

Solution One

Use a react ref to get the exact instance of SVG you want to apply too.

class PieChart extends Component {
 constructor(props) {
 this.pieChartRef = React.createRef();
}
createPieChart() {
var data = [2, 4, 8, 10, 1];
var svg = d3.select(this.pieChartRef.current),
  width = svg.attr("width"),
  height = svg.attr("height"),
  radius = Math.min(width, height) / 2,
  g = svg
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
  ....etc code 
   render(){
    return <svg ref={this.pieChartRef} width={100} height={100} />;
   }

Solution 2

Use an id to get the exact instance of the element you want to apply too.

class PieChart extends Component {
 constructor(props) {
}
createPieChart() {
 var data = [2, 4, 8, 10, 1];
 var svg = d3.select(this.documentGetElementById("pie-chart")),
  width = svg.attr("width"),
  height = svg.attr("height"),
  radius = Math.min(width, height) / 2,
  g = svg
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
  ....etc code 
render(){
 return <svg id="pie-chart" width={100} height={100} />;
}

Either bit of code would work for your need. I prefer solution One as it uses React to handle the dom element.