mutanthumb
mutanthumb

Reputation: 161

Would like to use length (from d3.nest) as radius

I'm having a mental block about using the result of:

    .rollup(function(leaves) { return leaves.length;})

as the radius of a circle in a scatter plot. My complete code (and sample data) is in a plunk here https://plnkr.co/edit/Cwuce6inLV5jouCWTFfN

The scatter works with a static value of 5 but I'd like to use value based on the .rollup from the d3.nest as explained in this other SO question I had: Capturing leaves.length value from d3.nest

I think I'm missing a key concept about in this section of code:

d3.tsv("etds_small.tsv", function(error, dataset) {
  dataset.forEach(function(d) {
    if(deptlist.indexOf(d.dept) == -1) deptlist.push(d.dept);
    if(years.indexOf(d.year) == -1) years.push(d.year);
  })

  var deptYearCount = d3.nest()
    //.key(function(d) { return d.college;} )
    .key(function(d) { return d.dept})
    .key(function(d) { return d.year })
    .rollup(function(leaves) { return leaves.length;})
        .map(dataset);

        console.log(dataset);   // retains the college, dept, and year labels
        console.log(deptYearCount);  // replaces labels with "key"

  x.domain(years.sort(d3.ascending));
  y.domain(deptlist.sort(d3.ascending));
  //console.log(y.domain());
  //console.log(x.domain());

    svg.selectAll(".dot")
          .data(dataset)  //should this be deptYearCount from the d3.nest above?
        .enter().append("circle")
          .attr("class", "dot")
          .attr("r", 5)  // Would like to use length (from d3.nest) as radius
          //.attr("r", function(d) {return d.values.length*1.5;}) works with .data(debtYearCount)
          .style("opacity", 0.3)
          .style("fill", "#e31a1c" )
          .attr("cx", function(d) {
            return x(d.year);
          })
          .attr("cy", function(d) {
            return y(d.dept);
          });

Upvotes: 0

Views: 214

Answers (1)

wdickerson
wdickerson

Reputation: 869

Give this a try for your radius:

.attr("r", function(d) {return Object.keys(deptYearCount[d.dept]).length*1.5;})

Because you are using .map(dataset) instead of .entries(dataset), d3.next() is returning one-big-object instead of an array of objects. That one-big-object does not contain a property called values.

Updated explanation:

First, look at the structure of the object deptYearCount. It has property names like Earth Sciences., Education., etc.

Our d3 data is iterating over an array of objects. Each object has property dept that looks like Earth Sciences., Education., etc.

So, deptYearCount[d.dept] is getting us to the correct property within deptYearCount.

For example, at one round of our iteration we are looking at deptYearCount["Education."]. That turns out to be another object with properties like 2007,2008, etc. Therefore, the number of properties in deptYearCount["Education."] is the value we want for the radius.

How do we find the number of properties of deptYearCount["Education."]? One way is the Object.keys(someObject) function. It returns an array of strings corresonding to the property names, and we just need its .length.

Upvotes: 2

Related Questions