具有负值的条形图

编程入门 行业动态 更新时间:2024-10-26 06:34:27
本文介绍了具有负值的条形图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我需要创建一个可以有负值的d3条形图。理想情况下,应该根据数据的范围计算轴零点位置,但我会建议采用假设对称正负范围的解决方案,即它始终位于图表中间。

I need to create a d3 bar chart that can have negative values. Ideally the axis zero position should be calculated based on the extent of the data, but I'd settle for a solution that assumes symmetric positive and negative extent, i.e. that it would be always in the middle of the chart.

这里是我想要实现的示例。

Here's an example of what I'd like to achieve.

推荐答案

数组数组,这包括一些正值和负值:

OK, let's say you have an array of numbers as your dataset, and this includes some positive and negative values:

var data = [-15, -20, -22, -18, 2, 6, -26, -18];

您将需要两个尺度来构建条形图。您需要一个定量标尺(通常是线性标尺)来计算沿着 x 轴和第二个顺序量表来计算栏沿着 y轴的位置。

You'll want two scales to construct a bar chart. You need one quantitative scale (typically a linear scale) to compute the bar positions along the x-axis, and a second ordinal scale to compute the bar positions along the y-axis.

对于量化比例,您通常需要计算数据的域,它基于最小值和最大值。一个简单的方法是通过 d3.extent :

For the quantitative scale, you typically need to compute the domain of your data, which is based on the minimum and maximum value. An easy way to do that is via d3.extent:

var x = d3.scale.linear() .domain(d3.extent(data)) .range([0, width]);

您可能还需要 nice 缩放到一定程度。作为另一个例子,有时你希望零值在画布的中间居中,在这种情况下,您需要采取最大和最大值的较大值:

You might also want to nice the scale to round the extent slightly. As another example, sometimes you want the zero-value to be centered in the middle of the canvas, in which case you'll want to take the greater of the minimum and maximum value:

var x0 = Math.max(-d3.min(data), d3.max(data)); var x = d3.scale.linear() .domain([-x0, x0]) .range([0, width]) .nice();

或者,您可以对任何所需的域进行硬编码。

Alternatively, you can hard-code whatever domain you want.

var x = d3.scale.linear() .domain([-30, 30]) .range([0, width]);

对于 y 轴,您需要使用 rangeRoundBands 将垂直空间划分为每个条的带。这也允许您指定条形之间的填充量。通常,序数量表与一些标识数据(例如名称或唯一ID)一起使用。但是,您也可以使用顺序标度结合数据的索引:

For the y-axis, you'll want to use rangeRoundBands to divide the vertical space into bands for each bar. This also lets you specify the amount of padding between bars. Often an ordinal scale is used with some identifying data—such as a name or a unique id. However, you can also use ordinal scales in conjunction with the data's index:

var y = d3.scale.ordinal() .domain(d3.range(data.length)) .rangeRoundBands([0, height], .2);

既然你有两个尺度,你可以创建rect元素来显示条形。一个棘手的部分是,在SVG中,rects基于它们的顶层定位( x 和 y 属性)左角。因此,我们需要使用 x 和 y 标尺来计算左上角的位置,这取决于关联值是正还是负:如果值为正,则数据值确定条的右边缘,而如果它为负,则确定条的左边缘。因此,这里的条件:

Now that you've got your two scales, you can create the rect elements to display the bars. The one tricky part is that in SVG, rects are positioned (the x and y attributes) based on their top-left corner. So we need to use the x- and y-scales to compute the position of the top-left corner, and that depends on whether the associated value is positive or negative: if the value is positive, then the data value determines the right edge of the bar, while if it's negative, it determines the left edge of the bar. Hence the conditionals here:

svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", function(d, i) { return x(Math.min(0, d)); }) .attr("y", function(d, i) { return y(i); }) .attr("width", function(d, i) { return Math.abs(x(d) - x(0)); }) .attr("height", y.rangeBand());

最后,您可以添加轴以在顶部显示刻度线。您还可以计算填充样式(或甚至渐变)以更改区分正值和负值的外观。将它们放在一起:

Lastly, you can add an axis to display tick marks on top. You might also compute a fill style (or even a gradient) to alter the differentiate the appearance of positive and negative values. Putting it all together:

  • 带有负值的条形图
  • Bar Chart with Negative Values

更多推荐

具有负值的条形图

本文发布于:2023-07-18 04:32:22,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1141053.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:负值   条形图

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!