为什么在设置svg宽度时,减去边距只将它们加回来

  • 本文关键字:回来 设置 svg d3.js
  • 更新时间 :
  • 英文 :


在下面的d3折线图中,作者创建了一个具有上、右、下和左属性的边距对象。

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");

这是D3的标准做法,因为至少早在版本3之前。Mike Bostock在他的例子中使用了这个惯例。我一直觉得它很有用。您引用了一个相当简单的例子,但随着d3代码变得越来越复杂,您需要更频繁地引用该绘图宽度,而不是svg的总宽度。

最新更新