在Google图表中绘制可视化线条

12

我正在编写一个Google图表,它有堆叠柱状图。在此基础上,我想要绘制两条线,表示最小和最大允许值。

进入图像描述

我想到的唯一解决方案是修改 ComboCharts 的第一个示例。我的结果看起来像这样:

进入图像描述

这还不够。由于图表是可变的,因此如果只显示1个季度,则该线仅为点。我的问题是:

  • 是否有一种方法可以将线画得更远,以使其触及图形的左右边界?
  • 我能在图表中绘制标记线,而不必假装它是另一个数据点吗?

如果您愿意,可以在此处尝试一下ComboChart。

2个回答

14

如果使用离散(基于字符串)的x轴,您无法使线条边缘对齐。 如果切换到连续(数字、日期、日期时间、时间)轴,则可以在真实数据之前添加一行和一行,这些行包含目标线(对于其他数据系列为null):

function drawChart() {
    var data = new google.visualization.DataTable();
    data.addColumn('number', 'Quarter');
    data.addColumn('number', 'Value 1');
    data.addColumn('number', 'Value 2');
    data.addColumn('number', 'Value 3');
    data.addColumn('number', 'Goal 1');
    data.addColumn('number', 'Goal 2');
    data.addRows([
        [0, null, null, null, 10, 14],
        [1, 5, 4, 7, null, null],
        [2, 6, 9, 6, null, null],
        [3, 2, 6, 4, null, null],
        [4, 3, 6, 4, null, null],
        [5, null, null, null, 10, 14]
    ]);
    
    var chart = new google.visualization.ComboChart(document.querySelector('#chart_div'));
    chart.draw(data, {
        height: 400,
        width: 600,
        isStacked: true,
        legend: {
            position: 'top'
        },
        seriesType: 'bars',
        interpolateNulls: true,
        series: {
            3: {
                type: 'line'
            },
            4: {
                type: 'line'
            }
        },
        hAxis: {
            format: 'Q#',
            ticks: [1, 2, 3, 4],
            viewWindow: {
                min: 0.5,
                max: 4.5
            }
        },
        chartArea: {
            left: '10%',
            width: '80%'
        }
    });
}
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});

查看示例:http://jsfiddle.net/asgallant/W67qU/

以下是一些解释(由Jorr.it于2022年11月24日编辑): 在DataTable的顶部和底部添加了仅包含目标的额外行。使用hAxis.viewWindow选项,两个新的目标点刚好被截断在图表上,但结果是整个图表宽度上的完整线条。最后需要设置“interpolateNulls”选项以连接柱形行中所有空值“上方”的两个不可见点。


2
非常好的答案。非常感谢。hAxis就是解决方法 ;) - Gordon Mohrin
谢谢。我花了一个小时才发现哪些行代码添加了这个功能。最好对这段代码进行注释。 - Carlos
1
@Carlos 如有需要,请随意编辑答案并添加适当的注释。我写这个答案已经很久了,甚至都不记得代码具体是做什么的了,也没有时间去弄清楚。 - asgallant

3
也许有点晚了,但我遇到了同样的问题。我试图在一条具有大量数据点的线图中设置最大和最小行,并且我想避免添加具有大量重复点的新系列,因此我使用了覆盖层 (https://developers.google.com/chart/interactive/docs/overlays#javascript2)。
以下是一个示例,这只是我现在正在工作的草稿,但可能会有所帮助:
<html>
  <head>
    <script
      type="text/javascript"
      src="https://www.gstatic.com/charts/loader.js"
    ></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
    <style>
      #container {
        position: relative;
        width: 900px;
        height: 500px;
      }
      .min-bar {
        height: 1px;
        background-color: red;
        position: absolute;
        left: 0;
        right: 0;
      }
    </style>
    <script type="text/javascript">
      $(function() {
        $.get(
          "https://firebasestorage.googleapis.com/v0/b/manasav-pricetracker.appspot.com/o/products%2F-L6O-CtBKZAc2NTCFq7Z.data?alt=media&token=60e06bb6-59b7-41a9-8fd0-f82f4ddc75f2",
          function(data) {
            google.charts.load("current", { packages: ["corechart"] });
            google.charts.setOnLoadCallback(drawChart);

            var downloadedData = JSON.parse("[" + data);

            function drawChart() {
              var dataTable = [["Time", "New"]];
              let min = Number.MAX_VALUE;

              let rowMin;
              for (var i in downloadedData) {
                var d = downloadedData[i];
                if (d.new < min) {
                  rowMin = i;
                  min = d.new;
                }
                dataTable.push([new Date(d.date), d.new]);
              }

              var data = google.visualization.arrayToDataTable(dataTable);

              var options = {
                title: "Price evolution",
                legend: { position: "bottom" },
                trendlines: { 0: {} }
              };

              var chart = new google.visualization.LineChart(
                document.getElementById("curve_chart")
              );

              function placeMarker(dataTable) {
                var cli = this.getChartLayoutInterface();
                var chartArea = cli.getChartAreaBoundingBox();
                document.querySelector(".min-bar").style.top =
                  Math.floor(cli.getYLocation(min)) + "px";

                document.querySelector(".min-bar").style.left =
                  Math.floor(cli.getXLocation(dataTable.getValue(0,0))) - 25 + "px";

                  document.querySelector(".min-bar").style.right =
                  (document.querySelector("#container").offsetWidth - Math.floor(cli.getXLocation(dataTable.getValue(dataTable.getNumberOfRows()-1,0)))) - 25 + "px";
                // document.querySelector(".min-bar").style.top =
                // Math.floor(cli.getXLocation(dataTable.getValue(rowMin, 1))) +
                // "px";
              }
              google.visualization.events.addListener(
                chart,
                "ready",
                placeMarker.bind(chart, data)
              );
              chart.draw(data, options);
            }
          }
        );
      });
    </script>
  </head>
  <body>
    <div id="container">
      <div id="curve_chart" style="width: 900px; height: 500px"></div>
      <div class="min-bar"></div>
    </div>
  </body>
</html>

Jsfiddle演示 => https://jsfiddle.net/jRubia/8z7ao1nh/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接