1

I have this array:

var bucket_contents = [8228, 21868, 12361, 15521, 3037, 2656]; 

I am trying to alter the width of a series of rects based on these values using range/domain. This is my code:

var bucket_width = d3.scale.linear()
            .domain([d3.min(bucket_contents), d3.max(bucket_contents)])
            .range([0, 1000]);

bucket.forEach(function(d, i) {
        d.x = (width / bucket.length) * i;
        d.y = (height / 2) - 25;
        d.w = bucket_width(i);
        console.log(bucket_width(i));
    });
d3.select("#plot").selectAll(".bucket")
            .data(bucket)
            .enter()
            .append("rect")
            .attr("class", "bucket")
            .attr("x", function(d, i) { return d.x; })
            .attr("y", function(d, i) { return d.y; })
            .attr('width', function(d, i) { return d.w; })
            .attr('height', '50')
            .style("fill", '#000');

Currently the console log bucket_width(i) inside the forEach loop outputs the following:

-138.24692900270665
-138.1948782011243
-138.14282739954194
-138.09077659795963
-138.03872579637726
-137.98667499479492

Console log on d3.min(..) is 2656 and d3.max(..) is 21868 as expected.

What am I doing wrong? I thought range 'normalizes' any values within that range, i.e. 21868 would return 1000 and 2656 would return 0.

Phrogz
  • 296,393
  • 112
  • 651
  • 745
daviestar
  • 4,531
  • 3
  • 29
  • 47
  • 1
    Instead of using `.domain([d3.min(a),d3.max(a)])` use [`.domain(d3.extent(a))`](https://github.com/mbostock/d3/wiki/Arrays#wiki-d3_extent) (for both simplicity and speed) – Phrogz Dec 04 '13 at 06:04
  • I downvoted because though you included some code, you did not include a reproducible test case, nor all the code needed to reproduce your results. What is `width`? What values are in `bucket`? And so on. In the future, a [JSFiddle](http://jsfiddle.net) is preferred, but at a minimum please include the code necessary to reproduce your problem (and ideally only that code). In retrospect, it may have been too harsh. I will remove the downvote, as you clearly put effort into the question. – Phrogz Dec 04 '13 at 06:08
  • Hey @Phrogz, I just asked a follow up question on this diagram - with a fiddle example :) It's over here - http://stackoverflow.com/questions/20400184 – daviestar Dec 05 '13 at 12:38

1 Answers1

1

Your problem is that you are calling bucket_width(i) instead of bucket_width(d). Hence, you are passing in values of 0, 1, etc. which are less than the min value of 2656 by quite some.

Demo: http://jsfiddle.net/2tq8S/

var contents = [8228, 21868, 12361, 15521, 3037, 2656]; 
var bucket_width = d3.scale.linear().domain(d3.extent(contents)).range([0, 1000]);
contents(function(d, i){
  console.log( d, i, bucket_width(i), bucket_width(d) );
});

Output:

8228   0  -138.24  290.03
21868  1  -138.19 1000.00
12361  2  -138.14  505.15
15521  3  -138.09  669.63
3037   4  -138.03   19.83
2656   5  -137.98    0.00
Phrogz
  • 296,393
  • 112
  • 651
  • 745