HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Basic Transitioning D3 Bar Chart

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
chartbarbasictransitioning

Problem

I have the following data in a csv file called BarData.csv:

Fruit,dt,amount
Apple,12/28/2016,4566
Apple,12/29/2016,5898
Apple,12/30/2016,3694
Apple,12/31/2016,5586
Apple,1/1/2017,4558
Apple,1/2/2017,6696
Apple,1/3/2017,7757
Apple,1/4/2017,8528
Apple,1/5/2017,5543
Apple,1/6/2017,3363
Apple,1/7/2017,5464
Pear,12/25/2017,250
Pear,12/26/2017,669
Pear,12/27/2017,441
Pear,12/28/2017,159
Pear,12/29/2017,357
Pear,12/30/2017,775
Pear,12/31/2017,669


The following html, css, and javascript is in one .html file:

```


BAR SINGLE FUNCTION


#radioDiv {
top: 45px;
font-family: verdana;
font-size: 8px;
width: 455px;
}

#TOPbarChart {
position: absolute;
top: 50px;
left: 30px;
width: 750px;
height: 195px;
}

.axis--y path,
.axis--x path {
display: none;
}

.axis--x line,
.axis--y line {
stroke: black;
fill: none;
stroke-width: 2px
}

.yAxis text,
.xAxis text {
font: 7pt Verdana;
stroke: none;
fill: black;
}

.title,
.titleX {
font-family: Verdana;
font-size: 10px;
}




APPLE


PEAR




var currentFruit = "Apple";
var currentColr = "#00a5b6";

var barDataCSV_Dly = "BarData.csv";

//
//
// radio button
document.getElementById("radioFrt").checked = true;
d3.selectAll('input[name="frt"]').on("change", function change() {
currentFruit = this.value;
TOPbarChart(currentFruit, currentColr);
});

//FORMATS
var parseDate = d3.time.format("%m/%d/%Y").parse;

//
// BASIC SIZING
//
function barChartBasics() {
var margin = {
top: 25,
right: 35,
bottom: 25,
left: 70
},
width = 550 - margin.left - margin.r

Solution

There is something wrong regarding the use of D3 requests.

You asked:


Should I move the call to the csv d3.csv to another part of the script so that the data is not being read everytime another option is selected?

Definitely. The way your code is right now, with d3.csv inside TOPbarChart function (which is called clicking the radio button) makes very little sense to any seasoned D3 programmer, for two reasons:

  • d3.csv is asynchronous, meaning that the browser has to get the data (sometimes not even in the same server), parse it and then resume the chart creation. You should avoid the best you can putting d3.csv (or d3.json, d3.tsv etc...) inside an event listener for a button, a radio button, a dropdown menu or any other input like those, because the user experience will be very poor.



  • There is no difference in the CSV file being loaded and parsed. Thus, you are doing a new request again and again to get the same data, just wasting time and resources.



Therefore, you should load and parse the CSV just once. Then, inside the TOPbarChart function, you just need to manipulate the already loaded data the way you want (but take care here: some methods change the original array).

The good news is that the changes you need to do are minimal.

This is a general idea of how your code should look like:

d3.csv("foo.csv", function(data) {

    //data is available here

    d3.select("input").on("change", function() {
        //call TOPbarChart function
        TOPbarChart();
    })

    functionTOPbarChart() {
        //manipulate data here and draw your chart
    }

});


And here is a working Plunker showing your code with those changes: https://plnkr.co/edit/Zbw5begLu0stbOUmtu5e?p=preview

As you can see, the code loads and parses the CSV file only once, manipulating the data according to the inputs.

Code Snippets

d3.csv("foo.csv", function(data) {

    //data is available here

    d3.select("input").on("change", function() {
        //call TOPbarChart function
        TOPbarChart();
    })

    functionTOPbarChart() {
        //manipulate data here and draw your chart
    }

});

Context

StackExchange Code Review Q#156560, answer score: 2

Revisions (0)

No revisions yet.