【问题标题】:nvd3 descrete bar chart values overlappingnvd3 离散条形图值重叠
【发布时间】:2024-01-08 22:38:01
【问题描述】:

我正在使用 nvd3.js 创建我的自定义离散条形图,我需要传递 2 个值数组而不是一个。 这是来自 nvd3 离散条形图示例的默认数据数组:

historicalBarChart = [
            {
                key: "Cumulative Return",
                values: [
                    {
                        "label": "May",
                        "value": 32,
                    },
                    {
                        "label": "Jun",
                        "value": 22
                    },
                    {
                        "label": "Jul",
                        "value": 37
                    },
                    {
                        "label": "Aug",
                        "value": 42
                    },
                    {
                        "label": "Sep",
                        "value": 18
                    },
                    {
                        "label": "Oct",
                        "value": 14
                    },
                    {
                        "label": "Nov",
                        "value": 34
                    },
                    {
                        "label": "Dec",
                        "value": 5
                    }
                ]
            }
        ];

这是图表的图片http://www.dodaj.rs/f/47/BU/3mMgYntS/screen-shot-2013-12-21-a.png 这就是我的样子:

当我添加第二个数据数组时,我的栏在这张图片上看起来像 http://www.dodaj.rs/f/k/MP/4yKWKm66/screen-shot-2013-12-21-a.png

正如您在第二张图片中看到的那样,条形变细了,每个月都有 2 个条形的空间,但它们重叠而不是一个相邻。我已经尝试了所有方法,但我是 nvd3 的新手,我不知道如何使条不重叠。

【问题讨论】:

标签: javascript d3.js nvd3.js


【解决方案1】:

为什么多个值会映射到我的图表中的同一位置?

问题在于 NVD3 代码中使用的底层比例。 d3 中的序数比例将相应的值映射到其在图表中的位置。您必须有唯一数据 每个条目 在域中用于映射 strong> 到 一个值,如果您希望它将两个月映射到不同的区域。如果在将域中的任何值传递给序数函数时再次使用它们,它们将被映射到为第一个值映射的相应位置。

var domain= ["January","February",...,"December"];

var set1 = [{"Month":"January", "Value":2},{{"Month":"February", "Value":3}}];
var set2 = [{"Month":"January", "Value":6},{{"Month":"August", "Value":20}}];

var ordinalScale = d3.scale().ordinal().domain([domain]);

if (ordinalScale(set1[0].Month) == ordinalScale(set2[0].Month))
{
    console.log("true") 
}

如果代码编译,这将打印为 true。

直观地理解问题:

您面临的问题是您使用的是一对一功能。这样想

假设您有一个域 (x = 1..10)。定义函数 f(x) = x + 1

如果你把 x 放进去会发生什么?

f(1) = 2

f(2) = 3

f(1) = 2

请注意您如何多次输入为相同输入生成的相同 x?这应该会发生,因为您将 f(x) 定义为这样。

解决方案:

解决此问题的一种方法是使用不同类型的图表,例如分组图表。 您自己可以解决此问题的另一种方法是为每条数据生成一个唯一值作为您的域值,例如在下面对上述数据进行修改。

var set1 = [{"Month":"January", "Value":2, "Serial":1},{{"Month":"February", "Value":3},"Serial":2}];
var set2 = [{"Month":"January", "Value":6,"Serial":3},{{"Month":"August", "Value":20, "Serial":4}}];

使用它可以解决您的问题,但会创建一个新问题。由于您使用域值来生成标签,因此您将显示值而不是月份。要解决此问题,您可以使用刻度格式化程序来显示月份而不是序列号。

【讨论】: