Nikita Vlasenko
Nikita Vlasenko

Reputation: 4352

Can't draw barchart using d3.js in React

I am trying to draw barchart with each bar next to its corresponding checkbox. I have several <div className="geneCountBar">s and I try to select all of them, append the data and then draw bars using the following function:

createBarChart = () => {
 let datum = this.props.datum.map((geneObj) => {
   return geneObj["values"].length;
 });
 d3.selectAll("div.geneCountBar")
   .data(datum)
   .enter()
   .append("div")
   .attr("class", "bar")
   .attr('transform', 'rotate(-90)')
   .style("height", function(d) {
      var barHeight = d * 5;
      return barHeight + "px";
  });
}

I just took it from the most basic tutorial on barchart creation with d3:

http://alignedleft.com/tutorials/d3/making-a-bar-chart

Somehow after the function runs - I trigger it with the button when the DOM has already been rendered - no DOM manipulation happens at all. I checked datum and it is correct: just an array of several values. The number of elements in the datum corresponds to the number of the selected divs. I checked whether d3.selectAll(div.geneCountBar) actually selects the right elements and it is. The DOM looks like that:

enter image description here

To further clarify what I actually want to achieve. Here you can see checkboxes:

enter image description here

Next to each one of them I want to draw a bar which would represent the amount of each item present in the dataset.

What am I doing wrong here? Any suggestions will be greatly appreciated.

Upvotes: 0

Views: 144

Answers (2)

Nikita Vlasenko
Nikita Vlasenko

Reputation: 4352

I ended up drawing bars without the use of d3s entering the data. I put the following divs on the page:

       <div className="geneCountBar"
         style={{width: this.getHeightForGeneBar(idx, innerIdx), height:"10px",
           backgroundColor: getColorForGene(this.getGeneIdx(idx, innerIdx)),
           borderRadius: "2px"}}>&nbsp;</div>

And set up individual bars height and color in code with the two functions: getHeightForGeneBar(idx, innerIdx) and getColorForGene(this.getGeneIdx(idx, innerIdx)).

Upvotes: 0

Klaujesi
Klaujesi

Reputation: 1836

On this case you are not using svg. Need to Style your divs. Try this:

  • Remove Transform, style width intead heigh
  • Style background-color for div,
  • add & nbsp; to prevent colapse empty div

change

createBarChart = () => {
 let datum = this.props.datum.map((geneObj) => {
   return geneObj["values"].length;
 });
 d3.selectAll("div.geneCountBar")
   .data(datum)
   .enter()
   .append("div")
   .attr("class", "geneCountBar") // <----CHANGE class
   .style("background-color","red")
   .style("width", function(d) { return (d*5)+"px";})
   .html("&nbsp;")
}

Every bar must look like this:

<div class="geneCountBar" style="backgroud-color:red;width:50px;">&nbsp;</div>

Or, on CSS define .geneCountBar{background-color:red;}

<div class="geneCountBar" style="width:50px;">&nbsp;</div>

I've not access to your rig. Here a working code.

var myData=[15, 30, 20, 10]

var graph = d3.select("#graph")

graph.selectAll("div#graph")
   .data(myData)             // maybe this's data(myData), not data(datum)
   .enter()
   .append("div")
   .attr("class", "geneCountBar") // <----CHANGE class
   .style("width", function(d) {return (d*5)+"px";})
   .html("&nbsp;")
.geneCountBar {
  background-color: red;
  margin:3px}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<div id="graph">

</div>

Hope this help

Upvotes: 1

Related Questions