javascript - D3: The data on the axis not mapping -
i have tried implement bar chart in d3, have problem mapping on axes. have dataset x , y seems values not mapped correctly.
this code:
var data = [ {x: 2, y: 4}, {x: 5, y: 8}, {x: 8, y: 10}, {x: 2, y: 4}, {x: 5, y: 8}, {x: 8, y: 19}, {x: 2, y: 4}, {x: 5, y: 8}, {x: 8, y: 10}, {x: 2, y: 4}, {x: 5, y: 8}, {x: 8, y: 10}, {x: 2, y: 4}, {x: 5, y: 8}, {x: 8, y: 10}, {x: 2, y: 4}, {x: 3, y: 8}, {x: 8, y: 10}, {x: 24, y: 4}, {x: 15, y: 8}, {x: 18, y: 10} ]; var margin = {top: 20, right: 30, bottom: 30, left: 40}, w = 1000 - margin.left - margin.right, h = 500 - margin.top - margin.bottom; var x = d3.scale.linear() .range([0, w]); var y = d3.scale.linear() .range([h, 0]); var xaxis = d3.svg.axis() .scale(x) .orient("bottom"); //.tickformat(d3.format("%y/%m")); var yaxis = d3.svg.axis() .scale(y) .orient("left"); var zoom = d3.behavior.zoom() .scaleextent([1, 1]) .x(x) .on("zoom", zoomed); var chart = d3.select("#testchart").append("svg") .attr("width", w + margin.left + margin.right) .attr("height", h + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") .call(zoom); var rect = chart.append("rect") .attr("width", w) .attr("height", h) .style("fill", "none") .style("pointer-events", "all"); chart.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + h + ")") .call(xaxis) chart.append("g") .attr("class", "y axis") .call(yaxis); //data.foreach(function (d) { //d.date = new date("20" + d.yy + "/" + d.mm); // coerce number //d.ppm_value = +d.ppm_value; // d.date = format.parse(d.date); //console.log(d.ppm_value); // console.log(d.date); //}); x.domain(data.map(function (d) { console.log("heelllppp!!!!",d.date); return d.x; })); y.domain([0, d3.max(data, function (d) { return d.y; })]); var bars = chart.append("g") .attr("class", "chartobjects"); bars.selectall(".rect") .data(data) .enter().append("rect") .attr("class", "rectbar") .on("click", hello) .attr('x', function (d) { console.log("blaaannaaaaa!!!!!!",d.x); return x(d.x); }) .attr("y", function (d) { return y(d.y); }) .attr("height", function(d) { return h - y(d.y); }) .attr("width", 45) .attr("fill", function(d){ return d.y > 6 ? "blue" : "red"}); function hello(){ alert("hello world!!") } function zoomed() { var tx = math.max(0, d3.event.translate[0]); //ty = math.min(0, d3.event.translate[1]); zoom.translate([tx]); bars.attr("transform", "translate(" + [tx] + ")scale(" + d3.event.scale + ")"); chart.select(".x.axis") .call(xaxis); //chart.select(".y.axis") // .call(yaxis); }
myabe have ideas why.i post picture:
the explanation here has more dataviz principles d3 code.
a bar chart different histogram, , main difference this: in bar chart, each bar represents qualitative variable (or categorical variable). being said, shouldn't use linear scale x axis, ordinal 1 instead:
var x = d3.scale.ordinal() .rangebands([0, w]);
here demo ordinal scale:
var data = [{ x: 2, y: 4 }, { x: 5, y: 8 }, { x: 8, y: 10 }, { x: 2, y: 4 }, { x: 5, y: 8 }, { x: 8, y: 19 }, { x: 2, y: 4 }, { x: 5, y: 8 }, { x: 8, y: 10 }, { x: 2, y: 4 }, { x: 5, y: 8 }, { x: 8, y: 10 }, { x: 2, y: 4 }, { x: 5, y: 8 }, { x: 8, y: 10 }, { x: 2, y: 4 }, { x: 3, y: 8 }, { x: 8, y: 10 }, { x: 24, y: 4 }, { x: 15, y: 8 }, { x: 18, y: 10 }]; var margin = { top: 20, right: 30, bottom: 30, left: 40 }, w = 1000 - margin.left - margin.right, h = 500 - margin.top - margin.bottom; var x = d3.scale.ordinal() .rangebands([0, w], 0.6); var y = d3.scale.linear() .range([h, 0]); var xaxis = d3.svg.axis() .scale(x) .orient("bottom"); //.tickformat(d3.format("%y/%m")); var yaxis = d3.svg.axis() .scale(y) .orient("left"); var chart = d3.select("body").append("svg") .attr("width", w + margin.left + margin.right) .attr("height", h + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var rect = chart.append("rect") .attr("width", w) .attr("height", h) .style("fill", "none") .style("pointer-events", "all"); //data.foreach(function (d) { //d.date = new date("20" + d.yy + "/" + d.mm); // coerce number //d.ppm_value = +d.ppm_value; // d.date = format.parse(d.date); //console.log(d.ppm_value); // console.log(d.date); //}); x.domain(data.map(function(d) { return d.x; })); y.domain([0, d3.max(data, function(d) { return d.y; })]); chart.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + h + ")") .call(xaxis) chart.append("g") .attr("class", "y axis") .call(yaxis); var bars = chart.append("g") .attr("class", "chartobjects"); bars.selectall(".rect") .data(data) .enter().append("rect") .attr("class", "rectbar") .on("click", hello) .attr('x', function(d) { return x(d.x); }) .attr("y", function(d) { return y(d.y); }) .attr("height", function(d) { return h - y(d.y); }) .attr("width", x.rangeband()) .attr("fill", function(d) { return d.y > 6 ? "blue" : "red" }); function hello() { alert("hello world!!") } function zoomed() { var tx = math.max(0, d3.event.translate[0]); //ty = math.min(0, d3.event.translate[1]); zoom.translate([tx]); bars.attr("transform", "translate(" + [tx] + ")scale(" + d3.event.scale + ")"); chart.select(".x.axis") .call(xaxis); //chart.select(".y.axis") // .call(yaxis); }
.axis path,.axis line { fill: none; stroke: black; shape-rendering: crispedges; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
but if want keep linear scale , positioning bars according x
value in dataset, dont use map
, returns array x
values: set domain [minvalue, maxvalue]
, whatever values are.
Comments
Post a Comment