2

根据特定标准,我创建了一个最多包含 4 个图表的网页。一切看起来都很棒。现在客户希望 4 个图表中的气泡大小比率保持一致(即,2000 的值在每个图表中用相同大小的气泡表示。)

是否可以配置bubble.nodes()生成器来执行此任务?

我知道我可以提供一个 radius() 计算器,但我没有数学背景来计算给定数据集的最佳半径。

我正在使用包布局。经过一夜好眠,我想我想出了一个可行的解决方案。在为每个图表生成布局后,我可以找到每个图表中最大气泡的半径与值的比率,scale()并对其他 SVG 应用转换以使比率相同(或足够接近)。

4

2 回答 2

1

您可以尝试使用具有固定、手动设置的输入域和输出范围的d3.scale.linear(),将您的任意数据映射到一致的、可预测的值。

例子:

function getSize(d){ return d.size; }

var params = [
        this.aggregatedDataFromAllCharts_beforePacking, 
        getSize
], dataScale = d3.scale.linear()
        .domain([d3.min.apply(window, params), d3.max.apply(window, params)])
        .range([0, 1000]);

为了调整包的大小(根圆),您可能必须使用第二个比例,它将每个数据集的聚合值映射到根圆的具体 svg 圆半径。类似于以下内容:

var aggregatedSizes = [];
// for all datasets
aggregatedSizes.push(d3.sum(dataset, getSize));
var packSizeScale = d3.scale.linear()
        .domain(Math.min(aggregatedSizes), Math.max(aggregatedSizes))
        .range(this.minCircleRadius, this.maxCircleRadius );

...其中 min- 和 maxCircleRadius 是您要显示的最小和最大圆尺寸。

// for each of your data sets
var packedCircles = d3.layout.pack().nodes(dataset).value(function(d) { 
        return dataScale(d.size);
}).size([packSizeScale(d3.sum(dataset, getSize) *2)]);

还有一个很好的关于 D3 音阶的教程,作者 Scott Murray

于 2014-04-02T09:23:13.367 回答
0

在我看来,由于您正在可视化气泡图并且它的半径(半径为复数?)您应该使用d3.scaleSqrt而不是d3.scaleLineard3.scale.linear()在以前的版本中)。推理很简单:半径为 10 的圆的大小不是半径为 5 的圆的两倍,因为圆的面积等于 πr^2。

正如@craPkit 所指出的,当在多个图表中制作一致的气泡大小时,需要这些多个图表中所有数据集的最小值和最大值的变量。在最常见的示例中,当比较国家/地区的人口时,maximalValue将是数据集中人口最多的县的人口,而将是人口最少的县的minimalValue人口,即使这些国家都没有出现在特定的图表中。

在第二步中,必须将maximalValueand传递minimalValue给图表并将它们用作域来设置给定圆的值的半径。这可能看起来像这样:

let someFixedMaximalRadiusSize = 50;

someSelectedSVGElement.append('circle')
                      .attr('r', d => {
                        d3.scaleSqrt()
                        .domain([minimalValue < 0 ? minimalValue : 0,
                                 maximalValue])
                        .range([0, someFixedMaximalRadiusSize])(d.value)});

其中 someSelectedSVGElement 表示某些选择,例如使用d3.select(). 希望这个答案会对某人有所帮助。

于 2020-03-22T20:19:56.423 回答