Plotly.js中具有(计算的)平均线的堆积条形图

时间:2019-08-28 10:14:57

标签: javascript plotly

我有一个(堆积的)条形图,我希望在图表上绘制一条平均线。

让我们来this example

var trace1 = {
  x: ['giraffes', 'orangutans', 'monkeys'],
  y: [20, 14, 23],
  name: 'SF Zoo',
  type: 'bar'
};

var trace2 = {
  x: ['giraffes', 'orangutans', 'monkeys'],
  y: [12, 18, 29],
  name: 'LA Zoo',
  type: 'bar'
};

var data = [trace1, trace2];

var layout = {barmode: 'stack'};

Plotly.newPlot('myDiv', data, layout, {showSendToCloud:true});

结果: result chart

预期输出: enter image description here

我找到了similar question,但是在那种情况下,添加带有“固定”值的行非常容易。在这种情况下,我有一个堆积的条形图nicolaskruchten/pivottable,因此用户可以轻松地拖放列。这使得计算平均值更加困难。

我可以遍历所有结果并计算平均值,但是由于Plotly非常强大并且具有诸如聚合函数之类的功能,因此我认为应该有更好的方法。

如何在(堆积的)条形图中添加(计算的)平均线?

1 个答案:

答案 0 :(得分:1)

  

Plotly.js没有提供任何直接选项来绘制平均线。
  但是您可以通过简单的方法this来实现。

//Find average value for Y
function getAverageY() {
    allYValues = trace1.y.map(function (num, idx) {
        return num + trace2.y[idx];
    });
    if (allYValues.length) {
        sum = allYValues.reduce(function (a, b) {
            return a + b;
        });
        avg = sum / allYValues.length;
    }
    return avg;
}

//Create average line in shape
var layout = {
    barmode: 'stack',
    shapes: [{
        type: 'line',
        xref: 'paper',
        x0: 0,
        y0: getAverageY(),
        x1: 1,
        y1: getAverageY(),
        line: {
            color: 'green',
            width: 2,
            dash: 'dot'
        }
    }]
};
  

已更新:

     

平均加载此图形后,您需要更新图形   任意数量的行。

//Check graph is loaded    
if (document.getElementById('myDiv')) {
    //draw average line
    drawAvgLine(document.getElementById('myDiv'))
}

function drawAvgLine(graph) {
    var graphData = graph.data; //Loaded traces
    //making new layout
    var newLayout = {
        barmode: 'stack',
        shapes: [{
            type: 'line',
            xref: 'paper',
            x0: 0,
            y0: getAverageY(graphData),
            x1: 1,
            y1: getAverageY(graphData),
            line: {
                color: 'green',
                width: 2,
                dash: 'dot'
            }
        }]
    };
    //Update plot pass existing data
    Plotly.update('myDiv', graphData, newLayout)
}
//Calculate avg value
function getAverageY(graphData) {
    var total = [],
        undefined;
    for (var i = 0, n = graphData.length; i < n; i++) {
        var arg = graphData[i].y
        for (var j = 0, n1 = arg.length; j < n1; j++) {
            total[j] = (total[j] == undefined ? 0 : total[j]) + arg[j];
        }
    }
    return total.reduce(function (a, b) {
        return a + b;
    }) / total.length;
}