我是D3库中用于数据可视化的新手。
我正在尝试创建一个垂直图例。
下面是我的实现。
我们可以看到rect
(最右端)的列和垂直刻度之间有巨大的差距。
我想,由于我的知识有限,我在g.call
中缺少了一些东西。
有人可以请问我在做什么错吗?
<!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>
答案 0 :(得分:1)
您的轴刻度/标签和图例矩形之间存在较大的间隙,因为您在矩形(.attr("x", 600)
)上将x设置为600,这意味着您将矩形相对于矩形定位在右侧600像素父容器。
发生的情况是,首先添加g元素,然后将其水平向右平移350个像素(垂直向下平移40个像素)。稍后将rect添加到此g元素时,相对于g element位置放置rect。因此,将rect的x属性设置为600意味着实际上将rect定位在SVG左侧的右侧950像素(350 + 600)。
要解决此问题,应降低rect的x属性。负值也有效。
在此处检查SVG矩形元素的引用:SVG