轴生成中链接语法的行为
Behavior of chaining syntax in axes generation
我正在编写 d3.js (d3 v4) 代码来生成一个简单的条形图,我设法做到了,但我对代码在生成轴时的行为感到困惑。
所以基本上,我将图表代码封装到一个包含基本访问器的函数中。
下面是一些显示图表功能核心的代码。
function chart(selection){
selection.each(function(data){
var x = d3.scale.ordinal().rangeRoundBands([0, width], 0.5);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
x.domain(data.map(function(d) { return d.name; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
var div = d3.select(this)
var svg = div.selectAll("svg")
.data([data]).enter()
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 5)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("fill", "#1CE6FF")
.attr("x", function(d) { return x(d.name); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
});
所以我有两个问题:1) 是否可以像上面代码中那样使用多个代码块调用 svg.append("g")?
2)当我替换以下代码时:
var svg = div.selectAll("svg")
.data([data]).enter()
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
有了这个(基本上是将两个块合并到一个链代码块中):
var svg = div.selectAll("svg")
.data([data]).enter()
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")").append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
...为什么我的 y 轴没有显示在正确的位置? <g class="y axis">...</g>
标签嵌套在 <text>
标签中,而 <text>
标签本身嵌套在 x 轴标签中。为什么 2 块代码与单块代码的行为不一样?
代码的结构定义了生成的 SVG 的结构。在函数 chart()
中,变量 svg
保存对最后附加的 <g>
的引用,而不是对先前附加的 <svg>
本身的引用。请注意,第一次创建后的所有语句如何附加到 svg
的同一外部组。这是一种非常好的方法。
但是,如果您连接语句,就像您在上一个片段中所做的那样,svg
的值会发生变化,因为右侧,即表达式的 return 值发生变化。自您上次选择以来,附加 x 轴 svg
的所有文本元素都包含这些文本。鉴于此,很容易理解这会破坏其余代码,这些代码现在会将其他内容附加到文本元素。即使它在语法上是有效的(事实并非如此),它很可能仍会破坏布局。
如果你想重新安排代码结构,你必须确保在需要时有正确的参考。
我正在编写 d3.js (d3 v4) 代码来生成一个简单的条形图,我设法做到了,但我对代码在生成轴时的行为感到困惑。
所以基本上,我将图表代码封装到一个包含基本访问器的函数中。
下面是一些显示图表功能核心的代码。
function chart(selection){
selection.each(function(data){
var x = d3.scale.ordinal().rangeRoundBands([0, width], 0.5);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
x.domain(data.map(function(d) { return d.name; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
var div = d3.select(this)
var svg = div.selectAll("svg")
.data([data]).enter()
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 5)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("fill", "#1CE6FF")
.attr("x", function(d) { return x(d.name); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
});
所以我有两个问题:1) 是否可以像上面代码中那样使用多个代码块调用 svg.append("g")? 2)当我替换以下代码时:
var svg = div.selectAll("svg")
.data([data]).enter()
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
有了这个(基本上是将两个块合并到一个链代码块中):
var svg = div.selectAll("svg")
.data([data]).enter()
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")").append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
...为什么我的 y 轴没有显示在正确的位置? <g class="y axis">...</g>
标签嵌套在 <text>
标签中,而 <text>
标签本身嵌套在 x 轴标签中。为什么 2 块代码与单块代码的行为不一样?
代码的结构定义了生成的 SVG 的结构。在函数 chart()
中,变量 svg
保存对最后附加的 <g>
的引用,而不是对先前附加的 <svg>
本身的引用。请注意,第一次创建后的所有语句如何附加到 svg
的同一外部组。这是一种非常好的方法。
但是,如果您连接语句,就像您在上一个片段中所做的那样,svg
的值会发生变化,因为右侧,即表达式的 return 值发生变化。自您上次选择以来,附加 x 轴 svg
的所有文本元素都包含这些文本。鉴于此,很容易理解这会破坏其余代码,这些代码现在会将其他内容附加到文本元素。即使它在语法上是有效的(事实并非如此),它很可能仍会破坏布局。
如果你想重新安排代码结构,你必须确保在需要时有正确的参考。