React component that plots d3 graph











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
















bumped to the homepage by Community yesterday


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.















  • 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
















bumped to the homepage by Community yesterday


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.















  • 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"} />






react.js jsx d3.js






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 16 at 2:41









Quill

10.4k53287




10.4k53287










asked Apr 15 at 3:04









Canovice

1163




1163





bumped to the homepage by Community yesterday


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.







bumped to the homepage by Community yesterday


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.














  • 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










1 Answer
1






active

oldest

votes

















up vote
0
down vote













I've thought about the unholy union of D3 and React before, and I would be careful. I'd say that so far, your code looks fine, and if you know with a high degree of certainty you won't need much more than this, then you're fine.



However, I suspect you've only gotten started, and it's all the future improvements that will leave you banging your head (especially input handlers and animations).



I don't think the problem is that D3 doesn't like playing with React (although I know there are quirks), but rather that charts are a complex subject. They have their own abstract language, and most people aren't fluent.



You might consider using the new chart-parts. If you want a better foundation to build on, you might look at wrapping Vega in your own components. Or you might want to just see what else is out there: https://npms.io/search?q=react+charts.



Here's a great video with a deeper explanation of my warnings: The Missing Abstraction of Charting - Chris Trevino - React Conf 2018






share|improve this answer





















    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: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    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















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    I've thought about the unholy union of D3 and React before, and I would be careful. I'd say that so far, your code looks fine, and if you know with a high degree of certainty you won't need much more than this, then you're fine.



    However, I suspect you've only gotten started, and it's all the future improvements that will leave you banging your head (especially input handlers and animations).



    I don't think the problem is that D3 doesn't like playing with React (although I know there are quirks), but rather that charts are a complex subject. They have their own abstract language, and most people aren't fluent.



    You might consider using the new chart-parts. If you want a better foundation to build on, you might look at wrapping Vega in your own components. Or you might want to just see what else is out there: https://npms.io/search?q=react+charts.



    Here's a great video with a deeper explanation of my warnings: The Missing Abstraction of Charting - Chris Trevino - React Conf 2018






    share|improve this answer

























      up vote
      0
      down vote













      I've thought about the unholy union of D3 and React before, and I would be careful. I'd say that so far, your code looks fine, and if you know with a high degree of certainty you won't need much more than this, then you're fine.



      However, I suspect you've only gotten started, and it's all the future improvements that will leave you banging your head (especially input handlers and animations).



      I don't think the problem is that D3 doesn't like playing with React (although I know there are quirks), but rather that charts are a complex subject. They have their own abstract language, and most people aren't fluent.



      You might consider using the new chart-parts. If you want a better foundation to build on, you might look at wrapping Vega in your own components. Or you might want to just see what else is out there: https://npms.io/search?q=react+charts.



      Here's a great video with a deeper explanation of my warnings: The Missing Abstraction of Charting - Chris Trevino - React Conf 2018






      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        I've thought about the unholy union of D3 and React before, and I would be careful. I'd say that so far, your code looks fine, and if you know with a high degree of certainty you won't need much more than this, then you're fine.



        However, I suspect you've only gotten started, and it's all the future improvements that will leave you banging your head (especially input handlers and animations).



        I don't think the problem is that D3 doesn't like playing with React (although I know there are quirks), but rather that charts are a complex subject. They have their own abstract language, and most people aren't fluent.



        You might consider using the new chart-parts. If you want a better foundation to build on, you might look at wrapping Vega in your own components. Or you might want to just see what else is out there: https://npms.io/search?q=react+charts.



        Here's a great video with a deeper explanation of my warnings: The Missing Abstraction of Charting - Chris Trevino - React Conf 2018






        share|improve this answer












        I've thought about the unholy union of D3 and React before, and I would be careful. I'd say that so far, your code looks fine, and if you know with a high degree of certainty you won't need much more than this, then you're fine.



        However, I suspect you've only gotten started, and it's all the future improvements that will leave you banging your head (especially input handlers and animations).



        I don't think the problem is that D3 doesn't like playing with React (although I know there are quirks), but rather that charts are a complex subject. They have their own abstract language, and most people aren't fluent.



        You might consider using the new chart-parts. If you want a better foundation to build on, you might look at wrapping Vega in your own components. Or you might want to just see what else is out there: https://npms.io/search?q=react+charts.



        Here's a great video with a deeper explanation of my warnings: The Missing Abstraction of Charting - Chris Trevino - React Conf 2018







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 5 at 7:53









        Johntron

        1,005625




        1,005625






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            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















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Quarter-circle Tiles

            build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

            Mont Emei