Birish
Birish

Reputation: 5832

Failed to render a d3js object in Reactjs: Objects are not valid as a React child (found: object with keys {_groups, _parents})

I'm trying to use d3js with ReactJs. I'm not sure how to write the render function :/ can someone help please? I tried to render {circleAttributes} but it returns an error: Objects are not valid as a React child (found: object with keys {_groups, _parents}).

import React, { Component } from 'react'
import './App.css'
import * as d3 from "d3";
import { select } from 'd3-selection'

class StartAgain extends Component {
  constructor(props){
    super(props)
    this.svgExample = this.svgExample.bind(this)
  }

  svgExample(){
    var jsonCircles = [
      { "x_axis": 30, "y_axis": 30, "radius": 20, "color" : "green" },
      { "x_axis": 70, "y_axis": 70, "radius": 20, "color" : "purple"},
      { "x_axis": 110, "y_axis": 100, "radius": 20, "color" : "red"}];

    var svgContainer = d3.select("body").append("svg")
                        .attr("width", 200)
                        .attr("height", 200);

    var circles = svgContainer.selectAll("circle")
                        .data(jsonCircles)
                        .enter()
                        .append("circle");

    var circleAttributes = circles
                         .attr("cx", function (d) { return d.x_axis; })
                         .attr("cy", function (d) { return d.y_axis; })
                         .attr("r", function (d) { return d.radius; })
                         .style("fill", function(d) { return d.color; });
  }

  render() {
        return (<svg width="500" height="500">
                  {?????}
                </svg>)
    }
}

export default StartAgain

Upvotes: 1

Views: 543

Answers (1)

Mario Nikolaus
Mario Nikolaus

Reputation: 2406

First of all, your d3 selector is selecting body, instead it should be within scope of component. I suggest you to do something like this.

Secondly you have to make sure that your component is rendered before you call d3 functions on dom.

Thirdly you are not calling function for svgExample anywhere.

Try this code

import React, { Component } from 'react'
import './App.css'
import * as d3 from "d3";
import { select } from 'd3-selection'

class StartAgain extends Component {
  constructor(){
    super();
    this.svgExample = this.svgExample.bind(this);
  }

  componentDidMount() {
    this.svgExample();
  }

  svgExample(){
    var jsonCircles = [
      { "x_axis": 30, "y_axis": 30, "radius": 20, "color" : "green" },
      { "x_axis": 70, "y_axis": 70, "radius": 20, "color" : "purple"},
      { "x_axis": 110, "y_axis": 100, "radius": 20, "color" : "red"}];

    var svgContainer = d3.select(this.container).append("svg")
                        .attr("width", 200)
                        .attr("height", 200);

    var circles = svgContainer.selectAll("circle")
                        .data(jsonCircles)
                        .enter()
                        .append("circle");

    var circleAttributes = circles
                         .attr("cx", function (d) { return d.x_axis; })
                         .attr("cy", function (d) { return d.y_axis; })
                         .attr("r", function (d) { return d.radius; })
                         .style("fill", function(d) { return d.color; });
  }

  render() {
        return <div ref={cont => this.container = cont} style={{ height: '200px', width: '200px' }} />
    }
}

export default StartAgain

Hope that helps!

Upvotes: 3

Related Questions