Reputation: 21
I am a very beginner programmer (emphasis on very). I am trying to figure out how to iterate through an array of colors in order to make three rectangles of different colors. Here is my code so far:
var dataArray = [5, 11, 18];
var colors = ["red", "green", "black"];
var svg = d3.select("body").append("svg")
.attr("width","2000").attr("height","400");
svg.selectAll("rect")
.data(dataArray)
.enter()
.append("rect")
.attr("fill", function(d, i) { return colors*i}) //the line of code in question
.attr("x", function(d,i) { return 70*i + 50; })
.attr("y", function(d,i) { return d*15; })
.attr("height", function(d,i) { return 500; })
.attr("width", "50");
//code end
As you can see, I've been trying to use function(d, i)
to iterate through array colors, unsuccessfully. Full disclosure: the above code was created for a class, but this particular question is not part of the assignment. I'm trying to go just a tiny bit beyond the assignment.
Upvotes: 2
Views: 1961
Reputation: 38161
The other answer is right, colors[i] will give you your colors, so it deserves the checkmark. The fix in that answer will give you:
var dataArray = [5, 11, 18];
var colors = ["red", "green", "black"];
var svg = d3.select("body").append("svg")
.attr("width","2000").attr("height","400");
svg.selectAll("rect")
.data(dataArray)
.enter()
.append("rect")
.attr("fill", function(d, i) { return colors[i]})
.attr("x", function(d,i) { return 70*i + 50; })
.attr("y", function(d,i) { return d*15; })
.attr("height", function(d,i) { return 500; })
.attr("width", "50");
//code end
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
But, looking at the results, the first bar is the tallest, but has the smallest data value. All bars are 500 pixels high, each has a part that is below the edge of the SVG.
I thought I'd just point out a couple potential improvements on your code:
The use of function(d,i)
is only necessary when grabbing either the current element in your data array (d
) or the current increment (i
), so for:
.attr("height", function(d,i) { return 500; })
you can use: .attr('height',500);
But, I doubt you want all items to be 500 pixels tall (especially as your svg is only 400 pixels tall). This will be especially apparent if you have margins.
So, for height, we can use the formula you are currently using for your y coordinate:
.attr("height", function(d,i) { return d*15; })
Now, we have to have the bars end at the same point by manipulating the position of the top of each rectangle: (go up d*15 pixels from the bottom of the svg (which is at 400), in svg coordinate space 0 is at the top):
.attr("y", function(d,i) { return 400 - d*15; })
Which gives you:
var dataArray = [5, 11, 18];
var colors = ["red", "green", "black"];
var svg = d3.select("body").append("svg")
.attr("width","2000").attr("height","400");
svg.selectAll("rect")
.data(dataArray)
.enter()
.append("rect")
.attr("fill", function(d, i) { return colors[i]})
.attr("x", function(d,i) { return 70*i + 50; })
.attr("y", function(d,i) { return 400-d*15; })
.attr("height", function(d,i) { return d*15; })
.attr("width", "50");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
Lastly, Quotations enclose strings, but if you are using numbers then you can drop them:
This: .attr("width", "50");
can be .attr("width",50);
Upvotes: 4
Reputation: 1407
Have you tried using colors[i]
instead of colors*i
?
That will allow you to access the value in place i.
(colors[1] will be 'green', colors[0] will be 'red' etc)
Upvotes: 1