【发布时间】:2021-07-12 01:13:12
【问题描述】:
在下面的 d3 折线图中,作者创建了一个边距对象,其属性为 top、right、bottom 和 left。
var margin = {top: 20, right: 20, bottom: 60, left: 80}
然后按以下方式设置宽度变量。
width = 700 - margin.left - margin.right // 700 - 80 - 20 = 600
// So, width variable is 600
只有到那时,在设置 svg 的宽度时重新添加边距。
attr('width', width + margin.left + margin.right) // 600 + 80 + 20 = 700
// So, width attr of the svg is 700
为什么不直接设置宽度 700 而不必减去边距? svg 最终被设置为。这种模式的目的是什么我以前见过它并试图理解这样做的目的。谢谢。
完整代码如下。
var margin = {top: 20, right: 20, bottom: 60, left: 80},
width = 700 - margin.left - margin.right,
height = 700 - margin.top - margin.bottom;
var svg = d3.select("body") //create Svg element
.append("svg")
.attr('width', width + margin.right + margin.left)
.attr('height', height + margin.top + margin.bottom)
.style("border", "solid 1px red")
.attr("transform","translate(100,0)"); // To align svg at the center in the output tab.
var data = [
{ date:"2020/01/01 00:00:00", patients: 600 },
{ date:"2020/02/01 00:00:00", patients: 500 },
{ date:"2020/03/01 00:00:00", patients: 400 },
{ date:"2020/04/01 00:00:00", patients: 500 },
{ date:"2020/05/01 00:00:00", patients: 300 },
{ date:"2020/06/01 00:00:00", patients: 100 },
{ date:"2020/07/01 00:00:00", patients: 50 },
{ date:"2020/08/01 00:00:00", patients: 500 },
{ date:"2020/09/01 00:00:00", patients: 550 },
{ date:"2020/10/01 00:00:00", patients: 550 },
];
data=data.map(d => ({
date: new Date(d.date),
patients: d.patients
}))
var xscale = d3.scaleTime()
.domain(d3.extent(data, d=>d.date))
.range([0,width]);
var yscale= d3.scaleLinear() // drawing y scale
.domain([0,600])
.range([height,0])
var chart=svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
.attr('width', width)
.attr('height', height)
chart.append('g')
.call(d3.axisBottom(xscale).tickFormat(d3.timeFormat("%b")))
.attr('transform', 'translate(0,' + height + ')')
chart.append('g')
.call(d3.axisLeft(yscale))
svg.append("text") // labelling x-axis
.text("Month")
.attr("transform","translate(350,680)");
svg.append("text") // labelling y-axis
.text("Number of patients")
.attr('transform', "translate(40,400) rotate(-90)");
var generator = d3.line()
.x(function (d) { return xscale(d.date); })
.y(function (d) { return yscale(d.patients); });
chart.append('path')
.datum(data)
.attr("d", generator)
.attr("fill","none")
.attr("stroke","blue");
【问题讨论】:
-
这有点令人困惑。他们可以定义
svgWidth=700和svgHeight=700。他们减去边距为内部图创建空间。我会定义innerWidth = svgWidth - margin.left - margin.right,与innerHeight = svgHeight - margin.top - margin.bottom相同 -
为什么有人做某事不一定由我们在这里回答;但是,对于
width,使用 d3 来指代绘图区域的宽度(x 比例域为 [0,width])并不是非常罕见的做法,尽管使用 d3 的更多 standard convention 将使用宽度作为 svg宽度,绘图区域的宽度减去边距([margin.left,width-margin.right] 的 x 比例域)。无论哪种方式,您都需要知道绘图区域和 SVG 区域。
标签: d3.js