d3.js将数组数据映射从规范化图表更改为常规堆积图表

时间:2015-08-08 07:40:58

标签: javascript d3.js

我能够创建标准化堆叠条形图和常规堆叠条形图。我希望能够根据用户的选择在两者之间进行转换。

我已经创建了一个函数,可以使用以下代码将我的数据映射到正态分布:

        function dataMapNormalize(data) {
        /*
         http://jsfiddle.net/dB96T/4/
         manually create data points for stacked bar chart with y0 values
         */

         data = data.map(function (d, i) {
            console.log("length:" + d.length);
            var j,
                columnTotal = 0,
                y0 = 0;
            for (j = 0; j < d.length; j++) {
                columnTotal += d[j].value;
            }

            for (j = 0; j < d.length; j++) {
                var y = d[j].value / columnTotal;
                d[j] = {x: i, y: y, y0: y0};
                y0 += y;
            }
            return d;
        });
        console.log(JSON.stringify(data));

        y = d3.scale.linear()
            .domain([0, 1])
            .range([height, 0]);

        x = d3.scale.ordinal()
            .rangeRoundBands([100, width], .05)
            .domain(data.map(function (d) {
                return d[0].x
            }));
    }

dataMapNormalize(ond);

此功能永久性地更改了我的阵列&#34; ond&#34;到一个矩形坐标数组,这很棒......除非我想显示一个非标准化的堆积条形图。如果我尝试将ond传递给下面的函数,我会得到NAN。

function dataMapStack(data) {

        var stackTotals  = new Array();

        data = data.map(function (d, i) {
            var j,
                columnTotal = 0,
                y0 = 0;
            for (j = 0; j < d.length; j++) {
                columnTotal += d[j].value;
            }
            stackTotals.push(columnTotal);
            for (j = 0; j < d.length; j++) {
                var y = d[j].value;
                d[j] = {x: i, y: y, y0: y0};
                y0 += y;
            }
            return d;
        });

        y = d3.scale.linear()
            .domain([0, d3.max(stackTotals)])
            .range([height, 0]);

        x = d3.scale.ordinal()
            .rangeRoundBands([100, width], .05)
            .domain(data.map(function (d) {
                return d[0].x
            }));
    }

我确信有更优雅的方式来解决这个问题。打开任何建议。

1 个答案:

答案 0 :(得分:0)

我想出来了。我只是在data.map函数中添加了更多元素,以便数组现在具有yp(百分比/标准化)和y(常规堆栈)值。 (呃!)我很可能会将x / y比例移出函数。这是一个很大的帮助:http://bl.ocks.org/tmaybe/6144082

function dataMap(data) {
        /*
         http://jsfiddle.net/dB96T/4/

         create rectangle dimensions for stacked bar chart

         yp = y percentage/normalized
         y = regular stack
         */

         data = data.map(function (d, i) {
            console.log("length:" + d.length);
            var j,
                columnTotal = 0,
                yp0 = 0,
                y0 = 0;

            // Count total of each stack
            for (j = 0; j < d.length; j++) {
                columnTotal += d[j].value;
            }

            for (j = 0; j < d.length; j++) {
                var y = d[j].value;
                var yp = d[j].value / columnTotal;
                d[j] = {x: i, yp: yp, yp0: yp0, y:y, y0:y0};
                yp0 += yp;
                y0 +=y;
            }
            return d;
        });
        console.log(JSON.stringify(data));

        y = d3.scale.linear()
            .domain([0, 1])
            .range([height, 0]);

        x = d3.scale.ordinal()
            .rangeRoundBands([100, width], .05)
            .domain(data.map(function (d) {
                return d[0].x
            }));
    }