0

I guess anyone who monitors the d3 questions is getting used to seeing me this week (this is my first time using d3) so here goes another question. I am fetching data via php/ajax but I have placed a sample as hard code below. I wish to bind the fineBinSummary data to a bar chart but can't seem to figure out how. When I inspect the html it makes it as far as setting up the svg and then stops when I start to try to bind data to it.

I successfully bound the detail data (code not shown, just the JSON) but can't get the fineBinSummary data to bind in the same manner. I also will need to extract the length of the fineBinSummary array (you can see that I've just made it the width / 5 but there won't always be 5 bars in the chart. Any assistance is much appreciated.

(document).ready(function() {

var data = [
    {"Id":"93439440411",

        "detail":[{"fineBin":"UNCLASSIFIED","x":"-142000.0","y":"-21000.0","imageId":null,"serverId":null,"fileSpec":null,"color":"HotPink"},
            {"fineBin":"UNCLASSIFIED","x":"-142000.0","y":"16000.0","imageId":null,"serverId":null,"fileSpec":null,"color":"HotPink"},
            {"fineBin":"UNCLASSIFIED","x":"-141000.0","y":"-15000.0","imageId":null,"serverId":null,"fileSpec":null,"color":"HotPink"},
            {"fineBin":"UNCLASSIFIED","x":"-141000.0","y":"24000.0","imageId":null,"serverId":null,"fileSpec":null,"color":"HotPink"},
            {"fineBin":"UNCLASSIFIED","x":"-141000.0","y":"27000.0","imageId":null,"serverId":null,"fileSpec":null,"color":"HotPink"},
            {"fineBin":"UNCLASSIFIED","x":"-140000.0","y":"-15000.0","imageId":null,"serverId":null,"fileSpec":null,"color":"HotPink"}],

        "fineBinSummary":[{"fineBin":"UNCLASSIFIED","count":8212},{"fineBin":"SMALL_PARTICLE","count":104},{"fineBin":"RESIDUE","count":68},
            {"fineBin":"FALSE","count":16},{"fineBin":"258","count":12}]},

    {"Id":"93439440419",

        "detail":[{"fineBin":"UNCLASSIFIED","x":"-142839.40900000001","y":"20448.394","imageId":null,"serverId":null,"fileSpec":null,"color":"HotPink"},
            {"fineBin":"UNCLASSIFIED","x":"-142546.65599999999","y":"26731.720000000001","imageId":null,"serverId":null,"fileSpec":null,"color":"HotPink"},
            {"fineBin":"UNCLASSIFIED","x":"-142499.136","y":"-24443.516","imageId":null,"serverId":null,"fileSpec":null,"color":"HotPink"},
            {"fineBin":"UNCLASSIFIED","x":"-142267.68799999999","y":"32411.870999999999","imageId":null,"serverId":null,"fileSpec":null,"color":"HotPink"},
            {"fineBin":"UNCLASSIFIED","x":"-142000.0","y":"-33000.0","imageId":null,"serverId":null,"fileSpec":null,"color":"HotPink"}],

        "fineBinSummary":[{"fineBin":"UNCLASSIFIED","count":8212},{"fineBin":"SMALL_PARTICLE","count":104},{"fineBin":"RESIDUE","count":68},
                            {"fineBin":"FALSE","count":16},{"fineBin":"258","count":12}]}]

//Constants

var squareSide = 400;
var height = squareSide / 2.0;
var barWidth = squareSide / 5;

//begin building bootstrap courousel stack
var slides = d3.select(".carousel-inner").selectAll('div')
    .data(data)
    .enter()
    .append("div")
    .attr("class","item")
    .append("div")
    .attr("class","container-fluid")
    .append("div")
    .attr("class","row");

//Make the first slide the active slide
d3.selectAll(".item").classed('active', function(d, i) { return i == 0; });

//Build the image side of the slide
var imageSide = slides.append("div")
    .attr("class","col-lg-6 wafer-and-pareto");


//build final location for div that will hold the histogram
var paretoBox = imageSide.append("div")
    .attr("class","row")
    .append("div")
    .attr("class","col-lg-12")
    .append("div")
    .attr("class","pareto-box")
    .append("svg")
    .attr("class","chart")
    .attr("width",squareSide)
    .attr("height",squareSide / 2.0);

Seems to be working up to this point based on reviewing the html but does not successfully execute the code below:

var bar = paretoBox.selectAll("g")
    .data(function(d) {return data.fineBinSummary})
    .enter()
    .append("g")
    .attr("transform",function(d,i) {
        return "translate(" + i * barWidth + ",0)";
    });

bar.append("rect")
    .attr("y",function(d) {
        return y(d.count);
    })
    .attr("height",function(d) {
        return height - y(d.count)
    })
    .attr("width",barWidth - 1);

var y = d3.scale.linear()
    .range([height,0])
    .domain([0,d3.max(data.fineBinSummary,function(d) {
        return d.count;
    })]);

})

2
  • When you say that the code does not execute successfully, what do you mean? Do you get an error message? Commented May 15, 2014 at 20:09
  • Thanks for asking Lars. I do not get an error but when I check the html output using Chrome developer everything is built out right up the the SVG called paretoBox. When that is passed to "bar" I don't get the bars. Commented May 15, 2014 at 20:44

1 Answer 1

1

There are just two small problems with your code. First, in your nested selection, you are referencing the original data instead of the part bound to the current element. Instead of

var bar = paretoBox.selectAll("g")
  .data(function(d) {return data.fineBinSummary})

use

var bar = paretoBox.selectAll("g")
  .data(function(d) {return d.fineBinSummary})

Second, the max element for your scale is determined incorrectly -- data doesn't have a fineBinSummary member. The code should look like this:

var y = d3.scale.linear()
  .range([height,0])
  .domain([0, d3.max(data, function(d) {
    return d3.max(d.fineBinSummary, function(e) { return e.count; });
  })]);
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you very much Lars, you nailed the solution. One question though. This code builds multiple bar charts. It looks like the code for the y scale is forcing it to use the max of ALL of my counts to scale instead of just the max of the counts for the individual bar chart. I tried a few modification but haven't been able to get it to take the local max. Do you have a recommendation on how I might accomplish that?
Sorry, one more thing. I mentioned extracting the length of fineBinSummary to get my bar width, any advice in that area would also be appreciated.
For those it sounds like you would want to do that in a preprocessing step. It may work with the current setup, but would be quite messy. I would recommend iterating over the subsets of the data and doing chart/scale/etc for each in turn.
Lars, I'm still having a hard time figuring the scale part out, specifically around iterating over the subsets. If I added an element to the fineBinSummary that would have the max bar size for each chart (in the form, for example, "max":31 would it be possible to bind with d3?
Yes. It may be better if you ask a separate question about this if you're struggling.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.