【问题标题】:Chartjs average line over barsChartjs 条形图平均线
【发布时间】:2020-06-27 12:34:39
【问题描述】:

我使用https://www.chartjs.org/。在下面的示例中,我列出了两周内每天的值。为此,我想要这一时期的平均值。

chartjs 可以吗?如果可以,怎么做?

我已经开始了,但它会跟随条形位置,它应该会创建一个点数更少的新路径。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <canvas id="canvas"></canvas>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>
  <script>
    var ctx = document.getElementById('canvas').getContext('2d');
    var mixedChart = new Chart(ctx, {
      type: 'bar',
      data: {
        datasets: [{
          label: 'Bar Dataset',
          data: [1, 2, 3, 1, 3, 4, 7, 2, 4, 3, 1, 6, 5, 2],
          backgroundColor: "#FF9881",
          order: 2
        }, {
          label: 'Line Dataset',
          data: [1, 2],
          type: 'line',
          borderColor: "#FF312D",
          fill: false,
          borderWidth: 1,
          order: 1
        }],
        labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
      },
      options: {
        "scales": {
          "yAxes": [{
            "ticks": {
              "beginAtZero": true
            }
          }]
        }
      }
    });
  </script>
</body>

</html>

【问题讨论】:

    标签: javascript chart.js line average


    【解决方案1】:

    我会计算平均值并将其分布在整个图表中,如下所示:

    const getLineData = (initialData, lengthOfDataChunks) => {
      const numOfChunks = Math.ceil(initialData.length / lengthOfDataChunks);
      const dataChunks = [];
    
      for (var i = 0; i < numOfChunks; i++) dataChunks[i] = [];
    
      initialData.forEach((entry, index) => {
        const chunkNumber = Math.floor(index / lengthOfDataChunks);
        dataChunks[chunkNumber]
        dataChunks[chunkNumber].push(entry);
      });
    
      const averagedChunks = dataChunks.map(chunkEntry => {
        const chunkAverage = chunkEntry.reduce(sumArray) / lengthOfDataChunks;
        return chunkEntry.map(chunkEntryValue => chunkAverage);
      });
    
      return averagedChunks.flat();
    }
    
    const ctx = document.getElementById('canvas').getContext('2d');
    const barData = [1, 2, 3, 1, 3, 4, 7, 2, 4, 3, 1, 6, 5, 2];
    const sumArray = (accumulator, currentValue) => accumulator + currentValue;
    const averageBarValue = barData.reduce(sumArray) / barData.length;
    const lineData = getLineData(barData, 7);
    
    var mixedChart = new Chart(ctx, {
      type: 'bar',
      data: {
        datasets: [{
          label: 'Bar Dataset',
          data: barData,
          backgroundColor: "#FF9881",
          order: 2
        }, {
          label: 'Line Dataset',
          data: lineData,
          type: 'line',
          borderColor: "#FF312D",
          fill: false,
          borderWidth: 1,
          order: 1
        }],
        labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
      },
      options: {
        "scales": {
          "yAxes": [{
            "ticks": {
              "beginAtZero": true
            }
          }]
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>
    
    
    <canvas id="canvas"></canvas>

    我希望你的问题是正确的。如果没有,请告诉我!

    【讨论】:

    • 我认为你的问题可能是对的。我不喜欢这个解决方案。我用新图片更新了我的问题。我真正追求的是在同一时间段内点数更少的新图表。
    • 我更新了我的答案...比我想象的要广泛一些:D 我认为用更少的数据点来做这件事是不可能的
    【解决方案2】:

    如果您的要求只是画一条平坦的平均线,我会选择 他们的官方注释插件 [chartjs-plugin-annotation]。

    我将在此处插入一个非常基本的、自洽的示例,改编自他们的文档。

    index.html

    <html>
        <head>
            <script src="index.js"></script>
        </head>
    
        <body>
            <canvas id="canvas"></canvas>
        </body>
    </html>

    anyname.js [然后您需要将其浏览到 index.js 源文件]:

    /* the following is just a shortcut to register all the needed elements, for any chart.
       more info here:
       https://www.chartjs.org/docs/3.3.0/getting-started/integration.html#bundlers-webpack-rollup-etc */
    const Chart = require("chart.js/auto");
    
    const annotationPlugin = require("chartjs-plugin-annotation");
    
    function average(ctx) {
        const values = ctx.chart.data.datasets[0].data;
        return values.reduce((a, b) => a + b, 0) / values.length;
    }
    
    const data = {
        labels: ["1", "2", "3", "4", "5", "6", "7"],
        datasets: [
            {
                label: "Sample Series",
                data: [40, 100, 54, 34, 13, 78, 41]
            }
        ]
    };
    
    const annotation = {
        type: 'line',
        borderColor: 'black',
        borderDash: [6, 6],
        borderDashOffset: 0,
        borderWidth: 3,
        label: {
            enabled: true,
            content: (ctx) => "Average: " + average(ctx).toFixed(2),
            position: 'end'
        },
        scaleID: 'y',
        value: (ctx) => average(ctx)
    };
    
    const config = {
        type: 'bar',
        data,
        options: {
            plugins: {
                title: {
                    display: true,
                    text: "Sample Chart",
                    font: {
                        size: 14
                    }
                },
                annotation: {
                    annotations: {
                        annotation
                    }
                }
            }
        }
    };
    
    // the annotation plugin needs to be registered, too
    Chart.register(annotationPlugin);
    
    document.addEventListener('DOMContentLoaded', () => {
        const myChart = new Chart(document.getElementById('canvas'), config);
    }, false);

    Node 所需的库 [您需要安装这些库才能使 browserify 工作]:

    • chart.js -- v. 3.7.1
    • chartjs-plugin-annotation -- v. 1.3.1

    参考资料:

    https://www.chartjs.org/chartjs-plugin-annotation/1.2.0/samples/line/average.html

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
    • 我已经完成了要求。反正我不是很懂这个政策。我的意思是,我们说的是一个非常有名的项目的官方文档,而不是在线文章中的一些随机示例:如果文档不再可用,它可能只意味着两件事:参考版本很旧,或者项目已完全停产;在任何一种情况下,我的例子都不再相关。此外,项目文档比我能提供的任何示例都更详尽:例如,在上述情况下,其他未提及的道具也可用于自定义绘制的线!
    猜你喜欢
    • 2023-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多