d3 scale.linear(): 传递数据作为参数

d3 scale.linear(): pass data as parameter

我正在使用 d3 构建多个条形图,并希望根据输入数据应用相同的比例,每个图表由不同的 JSON 数组组成。 为了找到每个数组的最大值,我写了这个函数:

var maxInArray = function (dataArray,propertyName) {
    var result = d3.max(dataArray, function(d) { 
        return +d[propertyName]; 
    });
    return result;
};

要找到条形宽度,我使用:

var barLength = d3.scale.linear()
    .domain([0, maxInArray(myArray,"myProperty")])
    .range([0, 400]);

最后,对于图表:

d3.select(".mybarchart")
        .selectAll("div")
        .data(myArray)
        .enter().append("div")
        .style("width", function(d) { return barLength(d.myProperty) + "px"; })
        .text(function(d) { return d.title+" ("+d.propertyName + ")"; });

但是这种方法意味着 barLength 中仍然硬编码了 myArray。

我更愿意做的是将当前值、myArray 和 myProperty 传递到这样的函数中:

var barLengthForValue = function (value,dataArray,propertyName) {
    var maxWidth = 400;
    var result = d3.scale.linear()
    .domain([0, maxInArray(dataArray,propertyName)])
    .range([0, maxWidth]);
    return result;
};

为我拥有的每个 JSON 数组使用 barLengthForValue。但是

console.log("barLengthForValue: ",barLengthForValue(10,myArray,"myParameter"));

Returns

function i(n){return o(n)}

大概是因为d3.scale.linear()找不到计算所需的参数。

我阅读了很多关于此事的教程,但是 none 中的教程符合我的要求。他们都使用d3.scale固定数据数组。

我正在尝试的可能吗?具体来说,我可以 "extend" d3.scale.linear() 这样吗?

还有一个JavaScript问题(我猜):d3.scale.linear() "extract"这里的参数10是怎么来的?

var scale= d3.scale.linear();
scale(10);

了解这一点可能有助于我了解如何改进 barLengthForValue()

您可以使用 d3.extent() 清理您的代码。它将找到数组中的最小值和最大值 return 它作为一个方便的 [min, max]。例如:

var barLengthForValue = function (value,dataArray,propertyName) {
    var maxWidth = 400;
    var result = d3.scale.linear()
    .domain(d3.extent(dataArray))
    .range([0, maxWidth]);
    return result;
};

如果你真的只想使用max,你可以使用d3.max()

然后您可以将您的选择设置为一个函数,并随着数据的变化重新定义比例尺的域:

function createChart (data) {
  d3.select(".mybarchart")
        .selectAll("div")
        .data(data)
        .enter().append("div")
        .style("width", function(d) { return barLength(d.myProperty) + "px"; })
        .text(function(d) { return d.title+" ("+d.propertyName + ")"; });

  barLength.domain(d3.extent(data))
}

// call createChart for each dataset you want to plot
[ dataSet1, dataSet2, dataSet3 ].map(createChart)

您需要做的唯一更改是 return result(value) 而不是 result -- 目前您正在 returning scale 对象,它需要应用于一个值以给出映射值。