javascript - yScale not acting consistently d3.js -
i'm drawing bar chart axes, , yscale behaving differently on yaxis on appended bars.
i set yscale range start @ (h - ypadding) leave room @ bottom xaxis labels.
var yscale = d3.scale.linear() .domain([0, d3.max(val)]) .range([h - ypadding, 0]);
-- range inverted, otherwise yaxis labels upside down.
when call yaxis using yscale, obeys starting point of (h - ypadding) , leaves room @ bottom.
but "rects" i'm appending chart, start @ h, instead of (h - ypadding) though i'm calling yscale on these "rects" on yaxis.
if change range [h, 0] instead of [h - ypadding, 0], yaxis reacts change, , bars still start @ h.
why bars ignoring yscale?
<script type="text/javascript"> var xhr = new xmlhttprequest(); function makerequest(){ xhr.open("get", "https://api.coinmarketcap.com/v1/ticker/", true); xhr.send(); xhr.onreadystatechange = processrequest; } function processrequest(){ console.log("testing, state: ", xhr.readystate) if(xhr.readystate == 4 && xhr.status == 200){ dataset = []; for(var = 0; < 10; i++){ addingid = json.parse(xhr.responsetext)[i]; addingid.id = i; dataset.push(addingid); } console.log("this dataset: ", dataset); makechart(); } } function makechart(){ var w = 1000; var h = 600; var padding = 40; var ypadding = 80; var val = []; dataset.foreach(function(ele){ val.push(parseint(ele.market_cap_usd)); }) var max = d3.max(val) var xaxisnames = [] dataset.foreach(function(ele){ xaxisnames.push(ele.name); }) // console.log(">>>>>>>>", xaxisnames) var xscale = d3.scale.ordinal() .domain(d3.range(dataset.length)) .rangeroundbands([padding, w - padding], 0.05) var yscale = d3.scale.linear() .domain([0, d3.max(val)]) .range([h - ypadding, 0]); var yaxis = d3.svg.axis() .scale(yscale) .orient("left") .tickformat(function(d){ if(d > 0){ return d / 1000000000 + " b"; } return ""; }) var xaxis = d3.svg.axis() .scale(xscale) .orient("bottom") .tickformat(function(d, i){ return xaxisnames[i] }) var svg = d3.select("body") .append("svg") .attr("width", w) .attr("height", h); svg.selectall("rect") .data(dataset) .enter() .append("rect") .attr("x", function(d, i){ return xscale(i); }) .attr("y", function(d){ return yscale(d.market_cap_usd); }) .attr("width", xscale.rangeband()) .attr("height", function(d, i){ return h - yscale(d.market_cap_usd) }) svg.append("g") .attr("class", "y axis") .attr("transform", "translate(" + padding + ", 0)") .call(yaxis); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0, " + (h - ypadding) + ")") .call(xaxis) .selectall("text") .attr("y", 15) .attr("font-size", 12) .attr("x", xscale.rangeband() / 2) .attr("transform", "rotate(45)") } makerequest(); </script>
a scale maps input domain output range, nothing more. have set positions , dimensions of svg elements accordingly. let's see:
right now, given scale, when pass minimum value in domain return:
h - ypadding
you want such bars having height of 0 pixels, of course. 0 equation simple, have subtract value:
(h - ypadding) - yscale(minimumdomainvalue)
that give 0 minimum value in domain.
therefore, should height of rectangles:
.attr("height", function(d, i){ return (h - ypadding) - yscale(d.market_cap_usd) })
ps: way, in d3, 1 of few situations scale determines dimensions of svg element path/lines created axis generator. that's why you're seeing different behaviour in axis.
Comments
Post a Comment