0

Alright so I have a JSON that looks like this:

var anotherBlob = [
{
"daily_percentile_90th": 1159.8000000000002, 
"min_percentile_90th": 1159.8, 
"sparks": [
    3107.9, 
    2856.0, 
    2778.8, 
    2987.5, 
    3364.2, 
    3112.6, 
    2934.7, 
    2798.6, 
    2933.0, 
    2813.8, 
    2916.8, 
    2948.1, 
    2859.0, 
    1159.8
], 
"max_percentile_90th": 3364.2, 
"daily_percentile_50th": 804.0, 
"timerName": "Search:Books:SearchResults", 
"daily_average": 876.2513661202186
}, 
{
"daily_percentile_90th": 1598.8000000000002, 
"min_percentile_90th": 1598.8, 
"sparks": [
    4024.0, 
    3233.0, 
    3845.4, 
    3300.6, 
    4364.1, 
    4141.1, 
    4017.3, 
    4228.0, 
    4261.4, 
    5518.9, 
    5118.8, 
    4321.7, 
    4239.0, 
    1598.8
], 
"max_percentile_90th": 5518.9, 
"daily_percentile_50th": 1159.0, 
"timerName": "Temple:Shared", 
"daily_average": 1213.0819672131147
}, 
{
"daily_percentile_90th": 586.2, 
"min_percentile_90th": 586.2, 
"sparks": [
    15149.6, 
    15616.2, 
    15078.0, 
    15126.8, 
    15441.8, 
    15454.0, 
    12184.0, 
    11328.6, 
    13511.6, 
    11969.4, 
    12047.5, 
    11245.0, 
    14799.6, 
    11849.0
}];

And I am making a D3 graph based on the values in "sparks" - the problem is that I don't know how to iterate through the array because it is inside of a JSON. I can create a graph just fine based on any of the daily percentiles or averages, but I can't access the "sparks" data.

Here is what I have creating a graph based on the daily__percentile_90th and one based on the min_percentile_90th, but how should I change it to use the "sparks" data instead?

var daily90th = function(d) { return d.daily_percentile_90th }
var dailyMin = function(d) { return d.min_percentile_90th }
//These two lines go above the JSON in order to work.

(function() {
  var data = anotherBlob.slice()
  var x = d3.time.scale()
    .range([10, 280])
    .domain(d3.extent(data, dailyMin))

  var y = d3.scale.linear()
    .range([180, 10])
    .domain(d3.extent(data, daily90th))

  var svg = d3.select("#demo").append("svg:svg")
  .attr("width", 300)
  .attr("height", 200)
  svg.selectAll("circle").data(anotherBlob).enter()
   .append("svg:circle")
   .attr("r", 4)
   .attr("cx", function(d) { return x(dailyMin(d)) })
   .attr("cy", function(d) { return y(daily90th(d)) })
   .attr("style", "cursor: pointer;")
   .on("click", function(d) {
      d3.select("#demo .value").text("Timer Name: " + d.timerName)
   })
})();

Thank you. Any help will be much appreciated!

1

1 Answer 1

1

You can create another data selection in an existing data selection. As explained in the link given by Lars Kotthoff in comments, you have to do :

var dp90 = d3.selectAll("circle").data(data);
dp90.enter().append("g")... // Or "circle", "rect"... :)

This will create a selection with your global JSON.

Now, to access to "sparks" field, you can :

var sparks = dp90.selectAll(".spark").data(function(d){ return d.sparks });
sparks.enter().append("circle").attr("class", "spark")...

It will now iterate on each sparks array element, creating a circle for each one.

Hope it helps.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much for your answer, I really appreciate it! I guess I'm just too new to D3 to see how that would work though?
Selection is a very difficult part to understand in d3js. Here, we associate each entry of 'data' (your global JSON) to a g element (for instance). That mean that g will now have a __data__ attribute containing object with "daily_percentile..., sparks, ...". You can now use this entry as a new selection data, a sub-selection, where you precise that new data entries come from d.sparks. Here is how data() works : github.com/mbostock/d3/wiki/Selections#data

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.