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

时间:2015-04-30 18:13:14

标签: javascript d3.js scale linear

我正在使用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"));

返回

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

大概是因为d3.scale.linear()找不到进行计算所需的参数。 我在这个问题上阅读了很多教程,但没有一个能做到我想要的。它们都使用带有固定数据数组的d3.scale。 我正在尝试的是什么?具体来说,我可以这种方式“扩展”d3.scale.linear()吗? 还有一个javascript问题(我猜):d3.scale.linear()如何在这里“提取”参数10?

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

理解这可能有助于我理解如何改进barLengthForValue()。

2 个答案:

答案 0 :(得分:2)

您可以使用d3.extent()清除代码。它将在数组中找到最小值和最大值,并将其作为方便的[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)

答案 1 :(得分:1)

您需要做的唯一更改是返回result(value)而不是result - 在您返回缩放对象时,需要将其应用于值以提供映射值。