React component that plots d3 graph

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












Edit: if there's a better way to make this reproducible, please let me know. I can create some dummy data and put this in a codepen, but that wouldn't really reflect the interaction with React that's required.



I am going to need to build several React d3 components for a web application that I am building - I'd like to make sure the first one is done correctly before moving onto the next.



It is difficult to get a fully-working reproducable example, however here's the code for the full component (with my thoughts below):



Note: The component may seem long, but a lot of the code is simply getting the axis and grid drawn. In total i think it's a short component..



import React, Component from 'react';
import * as d3 from "d3";

class D3Scatter extends Component

// When component mounts, get
componentDidMount()
const context = this.setContext();
this.drawScatter(context);


componentDidUpdate()
var context = d3.select(`#$this.props.svgID`);
context.remove();

context = this.setContext();
this.drawScatter(context);


// This adds the SVG to the <div ref="scatter"> with some attrs
setContext()
const height, width, svgID = this.props;
return d3.select(this.refs.scatter).append('svg')
.attr('id', svgID)
.attr('width', '100%')
.attr('height', '100%')
.attr('viewBox', "0 0 " + width + " " + height)
.attr('preserveAspectRatio', "xMaxYMax")

.append('g')
.attr('transform', `translate(25, 25)`);


// drawScatter called each time new props are passed
drawScatter(context)
const
// data
playerData,
colorData,

// formatting vals
padding,
margin,
height,
width,

// chart parameters
chartType,
position,
teamName,
playerName,
xColname,
yColname

= this.props;


// Fit The Data to the SVG size and width
var xScale = d3.scaleLinear()
.domain(d3.extent(playerData, d => d[xColname]))
.range([padding, width - padding])

var yScale = d3.scaleLinear()
.domain(d3.extent(playerData, d => d[yColname]))
.range([height - padding, padding])

var xAxis = d3.axisBottom(xScale)
.tickSize(2*padding-height)
.tickSizeOuter(0);

var yAxis = d3.axisLeft(yScale)
.tickSize(-width - 2*padding)
.tickSizeOuter(0);


// Size Scale for the markers
// if a certain playerName or teamName is passed, change marker size
var sizeScale = (player) =>
// console.log("playerName:", playerName)
// console.log("teamName:", teamName)
if(player.playerFullName === playerName)
return "24px";
else if(player.teamName === teamName)
return "12px";
else
return "6px";



// also change color for certain teamName or playerName passed
var colorScale = (player) =>
if(player.playerFullName === playerName)
var playersTeam = playerData
.filter(d => d.playerFullName === playerName)
.map(d => d.teamName)
var thisColor = colorData
.filter(d => d.teamname === playersTeam)
.map(d => d.colorhex1)
return thisColor;

else if(player.teamName === teamName)
var teamColor = colorData
.filter(d => d.teamname === teamName)
.map(d => d.colorhex1);
return teamColor;
else
return '#DDD';



// append the circles onto the page
context
.append('g')
.selectAll("circle")
.data(playerData)
.enter()
.append("circle")
.attr("cx", d => xScale(d[xColname]))
.attr("cy", d => yScale(d[yColname]))
.attr("r", d => sizeScale(d))
.attr("fill", d => colorScale(d))
.attr("stroke", "#FFF")


// Title, Y-Axis Name, X-Axis Name, Y-Axis Lines, X-Axis Lines
context
.append("text")
.attr("x", width/2)
.attr("y", padding)
.attr("dy", "-1.5em")
.style("text-anchor", "middle")
.style("font-size", "2.5em")
.text(`Highlighting $teamName and $playerName!`)

context
.append("text")
.attr("transform", "rotate(-90)")
.attr("x", -height/2) //
.attr("y", padding)
.attr("dy", "-2.5em") // gap from axis numbers
.style("font-size", "1.5em") // axis name size
.style("text-anchor", "middle")
.text(`Player $yColname`)

context
.append("text")
.attr("x", width/2)
.attr("y", height - padding)
.attr("dy", "2.5em")
.style("font-size", "1.5em")
.style("text-anchor", "middle")
.text(`Player $xColname`)

context
.append("g")
.attr("transform", "translate(0," + (height-padding) + ")")
.call(xAxis);

context
.append("g")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);

return context


render()

const gridID = this.props;
return (
<div id=gridID ref="scatter"></div>
)



export default D3Scatter;


There are a number of props passed to this component, which I've grouped into 3 different buckets:




  1. data props




    • playerData: has all of the data that gets plotted


    • colorData: has colors for each team (maps teamName to color)



  2. formatting props




    • padding, margin, height, width all used for the SVG



  3. parent component state props (for filtering playerData)




    • chartType: (not used here yet)


    • position: (not used here yet)

    • `teamName: used for setting colors / sizes


    • playerName: used for setting colors / sizes


    • xColname: changes which key in playerData is used for x axis values


    • yColname: changes which key in playerData is used for y axis values


My container app (the one that calls D3Scatter) has chartType, position, teamName, playerName, xColname and yColname in its state, and passes those down to D3Scatter depending on which buttons / select widgets are selected.



Eventually, I want to add transitions / animations so that when xColname and yColname are updated, the points slide to their new spots. I also plan on adding a tooltip and potentially other onClick effects, but I haven't done those yet. Currently I'm worried about whether I'm updating the chart right (if I'm using lifecycle components correctly), and other general best practices.



Last, an example of how this is called in its parent component:



<D3Scatter
gridID="graph1"
svgID='d3-scatterplot'
playerData=playerSeasonData
colorData=mlbLogos

height=window.innerWidth*0.425
width=window.innerWidth*0.85
padding=50
margins=top: 80, right: 35, bottom: 80, left: 25

chartType=null
xColname=statNameX
yColname=statNameY
position=position
teamName=selectedTeam && selectedTeam.label
playerName="Jay Bruce" />






share|improve this question





















  • I'm pretty much the only D3 user answering questions around here, the tag is quite abandoned. Since this is React.js, which I neither use nor know, I'll pass this question... however, I'm writing this comment just to let you know that the D3 side of it seems to be ok.
    – Gerardo Furtado
    May 7 at 3:51











  • @GerardoFurtado no worries, and I've noticed you respond a lot to d3 and I greatly appreciate it.
    – Canovice
    May 7 at 19:52
















up vote
3
down vote

favorite












Edit: if there's a better way to make this reproducible, please let me know. I can create some dummy data and put this in a codepen, but that wouldn't really reflect the interaction with React that's required.



I am going to need to build several React d3 components for a web application that I am building - I'd like to make sure the first one is done correctly before moving onto the next.



It is difficult to get a fully-working reproducable example, however here's the code for the full component (with my thoughts below):



Note: The component may seem long, but a lot of the code is simply getting the axis and grid drawn. In total i think it's a short component..



import React, Component from 'react';
import * as d3 from "d3";

class D3Scatter extends Component

// When component mounts, get
componentDidMount()
const context = this.setContext();
this.drawScatter(context);


componentDidUpdate()
var context = d3.select(`#$this.props.svgID`);
context.remove();

context = this.setContext();
this.drawScatter(context);


// This adds the SVG to the <div ref="scatter"> with some attrs
setContext()
const height, width, svgID = this.props;
return d3.select(this.refs.scatter).append('svg')
.attr('id', svgID)
.attr('width', '100%')
.attr('height', '100%')
.attr('viewBox', "0 0 " + width + " " + height)
.attr('preserveAspectRatio', "xMaxYMax")

.append('g')
.attr('transform', `translate(25, 25)`);


// drawScatter called each time new props are passed
drawScatter(context)
const
// data
playerData,
colorData,

// formatting vals
padding,
margin,
height,
width,

// chart parameters
chartType,
position,
teamName,
playerName,
xColname,
yColname

= this.props;


// Fit The Data to the SVG size and width
var xScale = d3.scaleLinear()
.domain(d3.extent(playerData, d => d[xColname]))
.range([padding, width - padding])

var yScale = d3.scaleLinear()
.domain(d3.extent(playerData, d => d[yColname]))
.range([height - padding, padding])

var xAxis = d3.axisBottom(xScale)
.tickSize(2*padding-height)
.tickSizeOuter(0);

var yAxis = d3.axisLeft(yScale)
.tickSize(-width - 2*padding)
.tickSizeOuter(0);


// Size Scale for the markers
// if a certain playerName or teamName is passed, change marker size
var sizeScale = (player) =>
// console.log("playerName:", playerName)
// console.log("teamName:", teamName)
if(player.playerFullName === playerName)
return "24px";
else if(player.teamName === teamName)
return "12px";
else
return "6px";



// also change color for certain teamName or playerName passed
var colorScale = (player) =>
if(player.playerFullName === playerName)
var playersTeam = playerData
.filter(d => d.playerFullName === playerName)
.map(d => d.teamName)
var thisColor = colorData
.filter(d => d.teamname === playersTeam)
.map(d => d.colorhex1)
return thisColor;

else if(player.teamName === teamName)
var teamColor = colorData
.filter(d => d.teamname === teamName)
.map(d => d.colorhex1);
return teamColor;
else
return '#DDD';



// append the circles onto the page
context
.append('g')
.selectAll("circle")
.data(playerData)
.enter()
.append("circle")
.attr("cx", d => xScale(d[xColname]))
.attr("cy", d => yScale(d[yColname]))
.attr("r", d => sizeScale(d))
.attr("fill", d => colorScale(d))
.attr("stroke", "#FFF")


// Title, Y-Axis Name, X-Axis Name, Y-Axis Lines, X-Axis Lines
context
.append("text")
.attr("x", width/2)
.attr("y", padding)
.attr("dy", "-1.5em")
.style("text-anchor", "middle")
.style("font-size", "2.5em")
.text(`Highlighting $teamName and $playerName!`)

context
.append("text")
.attr("transform", "rotate(-90)")
.attr("x", -height/2) //
.attr("y", padding)
.attr("dy", "-2.5em") // gap from axis numbers
.style("font-size", "1.5em") // axis name size
.style("text-anchor", "middle")
.text(`Player $yColname`)

context
.append("text")
.attr("x", width/2)
.attr("y", height - padding)
.attr("dy", "2.5em")
.style("font-size", "1.5em")
.style("text-anchor", "middle")
.text(`Player $xColname`)

context
.append("g")
.attr("transform", "translate(0," + (height-padding) + ")")
.call(xAxis);

context
.append("g")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);

return context


render()

const gridID = this.props;
return (
<div id=gridID ref="scatter"></div>
)



export default D3Scatter;


There are a number of props passed to this component, which I've grouped into 3 different buckets:




  1. data props




    • playerData: has all of the data that gets plotted


    • colorData: has colors for each team (maps teamName to color)



  2. formatting props




    • padding, margin, height, width all used for the SVG



  3. parent component state props (for filtering playerData)




    • chartType: (not used here yet)


    • position: (not used here yet)

    • `teamName: used for setting colors / sizes


    • playerName: used for setting colors / sizes


    • xColname: changes which key in playerData is used for x axis values


    • yColname: changes which key in playerData is used for y axis values


My container app (the one that calls D3Scatter) has chartType, position, teamName, playerName, xColname and yColname in its state, and passes those down to D3Scatter depending on which buttons / select widgets are selected.



Eventually, I want to add transitions / animations so that when xColname and yColname are updated, the points slide to their new spots. I also plan on adding a tooltip and potentially other onClick effects, but I haven't done those yet. Currently I'm worried about whether I'm updating the chart right (if I'm using lifecycle components correctly), and other general best practices.



Last, an example of how this is called in its parent component:



<D3Scatter
gridID="graph1"
svgID='d3-scatterplot'
playerData=playerSeasonData
colorData=mlbLogos

height=window.innerWidth*0.425
width=window.innerWidth*0.85
padding=50
margins=top: 80, right: 35, bottom: 80, left: 25

chartType=null
xColname=statNameX
yColname=statNameY
position=position
teamName=selectedTeam && selectedTeam.label
playerName="Jay Bruce" />






share|improve this question





















  • I'm pretty much the only D3 user answering questions around here, the tag is quite abandoned. Since this is React.js, which I neither use nor know, I'll pass this question... however, I'm writing this comment just to let you know that the D3 side of it seems to be ok.
    – Gerardo Furtado
    May 7 at 3:51











  • @GerardoFurtado no worries, and I've noticed you respond a lot to d3 and I greatly appreciate it.
    – Canovice
    May 7 at 19:52












up vote
3
down vote

favorite









up vote
3
down vote

favorite











Edit: if there's a better way to make this reproducible, please let me know. I can create some dummy data and put this in a codepen, but that wouldn't really reflect the interaction with React that's required.



I am going to need to build several React d3 components for a web application that I am building - I'd like to make sure the first one is done correctly before moving onto the next.



It is difficult to get a fully-working reproducable example, however here's the code for the full component (with my thoughts below):



Note: The component may seem long, but a lot of the code is simply getting the axis and grid drawn. In total i think it's a short component..



import React, Component from 'react';
import * as d3 from "d3";

class D3Scatter extends Component

// When component mounts, get
componentDidMount()
const context = this.setContext();
this.drawScatter(context);


componentDidUpdate()
var context = d3.select(`#$this.props.svgID`);
context.remove();

context = this.setContext();
this.drawScatter(context);


// This adds the SVG to the <div ref="scatter"> with some attrs
setContext()
const height, width, svgID = this.props;
return d3.select(this.refs.scatter).append('svg')
.attr('id', svgID)
.attr('width', '100%')
.attr('height', '100%')
.attr('viewBox', "0 0 " + width + " " + height)
.attr('preserveAspectRatio', "xMaxYMax")

.append('g')
.attr('transform', `translate(25, 25)`);


// drawScatter called each time new props are passed
drawScatter(context)
const
// data
playerData,
colorData,

// formatting vals
padding,
margin,
height,
width,

// chart parameters
chartType,
position,
teamName,
playerName,
xColname,
yColname

= this.props;


// Fit The Data to the SVG size and width
var xScale = d3.scaleLinear()
.domain(d3.extent(playerData, d => d[xColname]))
.range([padding, width - padding])

var yScale = d3.scaleLinear()
.domain(d3.extent(playerData, d => d[yColname]))
.range([height - padding, padding])

var xAxis = d3.axisBottom(xScale)
.tickSize(2*padding-height)
.tickSizeOuter(0);

var yAxis = d3.axisLeft(yScale)
.tickSize(-width - 2*padding)
.tickSizeOuter(0);


// Size Scale for the markers
// if a certain playerName or teamName is passed, change marker size
var sizeScale = (player) =>
// console.log("playerName:", playerName)
// console.log("teamName:", teamName)
if(player.playerFullName === playerName)
return "24px";
else if(player.teamName === teamName)
return "12px";
else
return "6px";



// also change color for certain teamName or playerName passed
var colorScale = (player) =>
if(player.playerFullName === playerName)
var playersTeam = playerData
.filter(d => d.playerFullName === playerName)
.map(d => d.teamName)
var thisColor = colorData
.filter(d => d.teamname === playersTeam)
.map(d => d.colorhex1)
return thisColor;

else if(player.teamName === teamName)
var teamColor = colorData
.filter(d => d.teamname === teamName)
.map(d => d.colorhex1);
return teamColor;
else
return '#DDD';



// append the circles onto the page
context
.append('g')
.selectAll("circle")
.data(playerData)
.enter()
.append("circle")
.attr("cx", d => xScale(d[xColname]))
.attr("cy", d => yScale(d[yColname]))
.attr("r", d => sizeScale(d))
.attr("fill", d => colorScale(d))
.attr("stroke", "#FFF")


// Title, Y-Axis Name, X-Axis Name, Y-Axis Lines, X-Axis Lines
context
.append("text")
.attr("x", width/2)
.attr("y", padding)
.attr("dy", "-1.5em")
.style("text-anchor", "middle")
.style("font-size", "2.5em")
.text(`Highlighting $teamName and $playerName!`)

context
.append("text")
.attr("transform", "rotate(-90)")
.attr("x", -height/2) //
.attr("y", padding)
.attr("dy", "-2.5em") // gap from axis numbers
.style("font-size", "1.5em") // axis name size
.style("text-anchor", "middle")
.text(`Player $yColname`)

context
.append("text")
.attr("x", width/2)
.attr("y", height - padding)
.attr("dy", "2.5em")
.style("font-size", "1.5em")
.style("text-anchor", "middle")
.text(`Player $xColname`)

context
.append("g")
.attr("transform", "translate(0," + (height-padding) + ")")
.call(xAxis);

context
.append("g")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);

return context


render()

const gridID = this.props;
return (
<div id=gridID ref="scatter"></div>
)



export default D3Scatter;


There are a number of props passed to this component, which I've grouped into 3 different buckets:




  1. data props




    • playerData: has all of the data that gets plotted


    • colorData: has colors for each team (maps teamName to color)



  2. formatting props




    • padding, margin, height, width all used for the SVG



  3. parent component state props (for filtering playerData)




    • chartType: (not used here yet)


    • position: (not used here yet)

    • `teamName: used for setting colors / sizes


    • playerName: used for setting colors / sizes


    • xColname: changes which key in playerData is used for x axis values


    • yColname: changes which key in playerData is used for y axis values


My container app (the one that calls D3Scatter) has chartType, position, teamName, playerName, xColname and yColname in its state, and passes those down to D3Scatter depending on which buttons / select widgets are selected.



Eventually, I want to add transitions / animations so that when xColname and yColname are updated, the points slide to their new spots. I also plan on adding a tooltip and potentially other onClick effects, but I haven't done those yet. Currently I'm worried about whether I'm updating the chart right (if I'm using lifecycle components correctly), and other general best practices.



Last, an example of how this is called in its parent component:



<D3Scatter
gridID="graph1"
svgID='d3-scatterplot'
playerData=playerSeasonData
colorData=mlbLogos

height=window.innerWidth*0.425
width=window.innerWidth*0.85
padding=50
margins=top: 80, right: 35, bottom: 80, left: 25

chartType=null
xColname=statNameX
yColname=statNameY
position=position
teamName=selectedTeam && selectedTeam.label
playerName="Jay Bruce" />






share|improve this question













Edit: if there's a better way to make this reproducible, please let me know. I can create some dummy data and put this in a codepen, but that wouldn't really reflect the interaction with React that's required.



I am going to need to build several React d3 components for a web application that I am building - I'd like to make sure the first one is done correctly before moving onto the next.



It is difficult to get a fully-working reproducable example, however here's the code for the full component (with my thoughts below):



Note: The component may seem long, but a lot of the code is simply getting the axis and grid drawn. In total i think it's a short component..



import React, Component from 'react';
import * as d3 from "d3";

class D3Scatter extends Component

// When component mounts, get
componentDidMount()
const context = this.setContext();
this.drawScatter(context);


componentDidUpdate()
var context = d3.select(`#$this.props.svgID`);
context.remove();

context = this.setContext();
this.drawScatter(context);


// This adds the SVG to the <div ref="scatter"> with some attrs
setContext()
const height, width, svgID = this.props;
return d3.select(this.refs.scatter).append('svg')
.attr('id', svgID)
.attr('width', '100%')
.attr('height', '100%')
.attr('viewBox', "0 0 " + width + " " + height)
.attr('preserveAspectRatio', "xMaxYMax")

.append('g')
.attr('transform', `translate(25, 25)`);


// drawScatter called each time new props are passed
drawScatter(context)
const
// data
playerData,
colorData,

// formatting vals
padding,
margin,
height,
width,

// chart parameters
chartType,
position,
teamName,
playerName,
xColname,
yColname

= this.props;


// Fit The Data to the SVG size and width
var xScale = d3.scaleLinear()
.domain(d3.extent(playerData, d => d[xColname]))
.range([padding, width - padding])

var yScale = d3.scaleLinear()
.domain(d3.extent(playerData, d => d[yColname]))
.range([height - padding, padding])

var xAxis = d3.axisBottom(xScale)
.tickSize(2*padding-height)
.tickSizeOuter(0);

var yAxis = d3.axisLeft(yScale)
.tickSize(-width - 2*padding)
.tickSizeOuter(0);


// Size Scale for the markers
// if a certain playerName or teamName is passed, change marker size
var sizeScale = (player) =>
// console.log("playerName:", playerName)
// console.log("teamName:", teamName)
if(player.playerFullName === playerName)
return "24px";
else if(player.teamName === teamName)
return "12px";
else
return "6px";



// also change color for certain teamName or playerName passed
var colorScale = (player) =>
if(player.playerFullName === playerName)
var playersTeam = playerData
.filter(d => d.playerFullName === playerName)
.map(d => d.teamName)
var thisColor = colorData
.filter(d => d.teamname === playersTeam)
.map(d => d.colorhex1)
return thisColor;

else if(player.teamName === teamName)
var teamColor = colorData
.filter(d => d.teamname === teamName)
.map(d => d.colorhex1);
return teamColor;
else
return '#DDD';



// append the circles onto the page
context
.append('g')
.selectAll("circle")
.data(playerData)
.enter()
.append("circle")
.attr("cx", d => xScale(d[xColname]))
.attr("cy", d => yScale(d[yColname]))
.attr("r", d => sizeScale(d))
.attr("fill", d => colorScale(d))
.attr("stroke", "#FFF")


// Title, Y-Axis Name, X-Axis Name, Y-Axis Lines, X-Axis Lines
context
.append("text")
.attr("x", width/2)
.attr("y", padding)
.attr("dy", "-1.5em")
.style("text-anchor", "middle")
.style("font-size", "2.5em")
.text(`Highlighting $teamName and $playerName!`)

context
.append("text")
.attr("transform", "rotate(-90)")
.attr("x", -height/2) //
.attr("y", padding)
.attr("dy", "-2.5em") // gap from axis numbers
.style("font-size", "1.5em") // axis name size
.style("text-anchor", "middle")
.text(`Player $yColname`)

context
.append("text")
.attr("x", width/2)
.attr("y", height - padding)
.attr("dy", "2.5em")
.style("font-size", "1.5em")
.style("text-anchor", "middle")
.text(`Player $xColname`)

context
.append("g")
.attr("transform", "translate(0," + (height-padding) + ")")
.call(xAxis);

context
.append("g")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);

return context


render()

const gridID = this.props;
return (
<div id=gridID ref="scatter"></div>
)



export default D3Scatter;


There are a number of props passed to this component, which I've grouped into 3 different buckets:




  1. data props




    • playerData: has all of the data that gets plotted


    • colorData: has colors for each team (maps teamName to color)



  2. formatting props




    • padding, margin, height, width all used for the SVG



  3. parent component state props (for filtering playerData)




    • chartType: (not used here yet)


    • position: (not used here yet)

    • `teamName: used for setting colors / sizes


    • playerName: used for setting colors / sizes


    • xColname: changes which key in playerData is used for x axis values


    • yColname: changes which key in playerData is used for y axis values


My container app (the one that calls D3Scatter) has chartType, position, teamName, playerName, xColname and yColname in its state, and passes those down to D3Scatter depending on which buttons / select widgets are selected.



Eventually, I want to add transitions / animations so that when xColname and yColname are updated, the points slide to their new spots. I also plan on adding a tooltip and potentially other onClick effects, but I haven't done those yet. Currently I'm worried about whether I'm updating the chart right (if I'm using lifecycle components correctly), and other general best practices.



Last, an example of how this is called in its parent component:



<D3Scatter
gridID="graph1"
svgID='d3-scatterplot'
playerData=playerSeasonData
colorData=mlbLogos

height=window.innerWidth*0.425
width=window.innerWidth*0.85
padding=50
margins=top: 80, right: 35, bottom: 80, left: 25

chartType=null
xColname=statNameX
yColname=statNameY
position=position
teamName=selectedTeam && selectedTeam.label
playerName="Jay Bruce" />








share|improve this question












share|improve this question




share|improve this question








edited Apr 16 at 2:41









Quill

10.3k53287




10.3k53287









asked Apr 15 at 3:04









Canovice

1163




1163











  • I'm pretty much the only D3 user answering questions around here, the tag is quite abandoned. Since this is React.js, which I neither use nor know, I'll pass this question... however, I'm writing this comment just to let you know that the D3 side of it seems to be ok.
    – Gerardo Furtado
    May 7 at 3:51











  • @GerardoFurtado no worries, and I've noticed you respond a lot to d3 and I greatly appreciate it.
    – Canovice
    May 7 at 19:52
















  • I'm pretty much the only D3 user answering questions around here, the tag is quite abandoned. Since this is React.js, which I neither use nor know, I'll pass this question... however, I'm writing this comment just to let you know that the D3 side of it seems to be ok.
    – Gerardo Furtado
    May 7 at 3:51











  • @GerardoFurtado no worries, and I've noticed you respond a lot to d3 and I greatly appreciate it.
    – Canovice
    May 7 at 19:52















I'm pretty much the only D3 user answering questions around here, the tag is quite abandoned. Since this is React.js, which I neither use nor know, I'll pass this question... however, I'm writing this comment just to let you know that the D3 side of it seems to be ok.
– Gerardo Furtado
May 7 at 3:51





I'm pretty much the only D3 user answering questions around here, the tag is quite abandoned. Since this is React.js, which I neither use nor know, I'll pass this question... however, I'm writing this comment just to let you know that the D3 side of it seems to be ok.
– Gerardo Furtado
May 7 at 3:51













@GerardoFurtado no worries, and I've noticed you respond a lot to d3 and I greatly appreciate it.
– Canovice
May 7 at 19:52




@GerardoFurtado no worries, and I've noticed you respond a lot to d3 and I greatly appreciate it.
– Canovice
May 7 at 19:52















active

oldest

votes











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f192082%2freact-component-that-plots-d3-graph%23new-answer', 'question_page');

);

Post as a guest



































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes










 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f192082%2freact-component-that-plots-d3-graph%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation