简体   繁体   中英

D3 Data Visualisation aligning tick labels and rect

I am new to D3 library for Data Visualisation. I am trying to create a vertical legend. And below is my implementation. We can see there is huge gap between the column of rect s(are on extreme right) and vertical ticks.

I guess, I am missing something in g.call because of my limited knowledge.

Can someone please, what mistake I am doing ?

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> .counties { fill: none; } .states { fill: none; stroke: #fff; stroke-linejoin: round; } </style> <svg width="1260" height="600"></svg> <script src="https://d3js.org/d3.v5.min.js"></script> <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> <script src="https://d3js.org/topojson.v2.min.js"></script> </head> <body> <script> var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"); var poverty = d3.map(); var path = d3.geoPath(); var x = d3.scaleLinear() //.domain([1, 10]) .domain([1, 10]) .rangeRound([600, 860]); //console.log("x:==>", x); var y = d3.scaleLinear() //.domain([1, 10]) .domain([1, 10]) .rangeRound([15, 160]); var color = d3.scaleThreshold() //.domain(d3.range(2, 10)) .domain(d3.range(2, 10)) .range(d3.schemeBlues[9]); var g = svg.append("g") .attr("class", "key") //.attr("transform", "translate(0,40)"); .attr("transform", "translate(350,40)"); g.selectAll("rect") .data(color.range().map(function(d) { d = color.invertExtent(d); if (d[0] == null) d[0] = x.domain()[0]; if (d[1] == null) d[1] = x.domain()[1]; return d; })) .enter().append("rect") /*.attr("height", 8) .attr("x", function(d) { return x(d[0]); }) .attr("width", function(d) { return x(d[1]) - x(d[0]); }) .attr("fill", function(d) { return color(d[0]); })*/ .attr("height", 15) .attr("x", 600) .attr("y", function(d) { return y(d[0]); }) .attr("width", function(d) { return x(d[1]) - x(d[0]); }) .attr("fill", function(d) { return color(d[0]); }) ; g.append("text") .attr("class", "caption") /*.attr("x", x.range()[0]) .attr("y", -6)*/ .attr("x",x.range()[0]) .attr("y", -6) .attr("fill", "#000") .attr("text-anchor", "start") .attr("font-weight", "bold") .text("Poverty rate"); g.call(d3.axisRight(y) //.tickSize(13) .tickFormat(function(x, i) { return i ? 2*x : 2*x + "%"; }) .tickValues(color.domain())) .select(".domain") .remove(); var promises = [ d3.json("https://snippetnuggets.com/TnD/us.json"), d3.csv("https://snippetnuggets.com/TnD/county_poverty.csv", function(d) { poverty.set(d.id, +d.rate); console.log(d); }) ] Promise.all(promises).then(ready) function ready([us]) { svg.append("g") .attr("class", "counties") .selectAll("path") .data(topojson.feature(us, us.objects.counties).features) .enter().append("path") .attr("fill", function(d) { return color(d.rate = poverty.get(d.id)); }) .attr("d", path) .append("title") .text(function(d) { return d.rate + "%"; }); svg.append("path") .datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })) .attr("class", "states") .attr("d", path); } </script> </body> </html> 

Your large gap between your axis ticks/labels and legend rects is there because you set x to 600 on your rects ( .attr("x", 600) ), which means you position the rects 600 pixels to the right, relative to the rects' parent container.

What happens is that first you append ag element, which you translate 350 pixels horizontally to the right (and 40 vertically downwards). When you later append rects to this g element, the rects are positioned relative to the g elements position. Therefore, setting the x attribute on the rects to 600 means in effect that you position the rects 950 pixels (350 + 600) to the right of the left side of the SVG.

To fix this, you should lower your x attribute on the rects. Negative values are valid too.

Check the reference for SVG rect elements here: SVG

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM