使用Google图表(组合图表)将注释垂直居中放置在其自己的栏中

时间:2018-08-02 03:41:10

标签: javascript charts google-visualization

是否可以将注释垂直放置在条的中心?仅通过annotation.stem.length不能实现。另一件事是使用MutationObserver设置注释的y位置,但我不知道如何获取条形的高度,因此我可以参考要在y属性上设置的y数。有什么方法可以动态地使注释垂直居中放置在条形上?

It'll look like this image

google.charts.load("current", { packages: ["corechart", "bar"] });
google.charts.setOnLoadCallback(drawBVandBA);

function drawBVandBA() {
  var dataArr = [
    ["Month", "Book Orders", "Buying Accounts", "Throughput"],
    ["Jan", 200.25, 1253, 379.09],
    ["Feb", 533.39, 1253, 379.09],
    ["March", 564.79, 1123, 379.09],
    ["Apr", 475.66, 1154, 379.09],
    ["May", 564.75, 1203, 379.09],
    ["Jun", 200.23, 1189, 379.09],
    ["Jul", 475.66, 1201, 379.09],
    ["Aug", 513.43, 1228, 379.09],
    ["Sep", 423.77, 1175, 379.09],
    ["Oct", 399.88, 1024, 379.09],
    ["Nov", 546.47, 1243, 379.09],
    ["Dec", 435.65, 1209, 379.09]
  ];

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

  var view = new google.visualization.DataView(data);
  view.setColumns([
    0,
    1,
    {
      calc: "stringify",
      sourceColumn: 1,
      type: "string",
      role: "annotation"
    },
    2,
    {
      calc: "stringify",
      sourceColumn: 2,
      type: "string",
      role: "annotation"
    }
  ]);

  var options = {
    animation: {
      duration: 1000,
      easing: "out",
      startup: true
    },
    annotations: {
      textStyle: {
        fontSize: 11,
        color: "black",
        auraColor: "none"
      }
    },
    chartArea: {
      backgroundColor: "#B9CDE5",
      right: "6%",
      width: "80%"
    },
    vAxes: {
      0: {
        viewWindowMode: "explicit",
        viewWindow: {
          max: 1400,
          min: 0
        },
        gridlines: {
          color: "transparent",
          count: 8
        }
      },
      1: {
        viewWindow: {
          max: 600,
          min: 0
        },
        gridlines: {
          color: "transparent",
          count: 7
        }
      }
    },
    series: {
      0: {
        annotations: {
          stem: {
            length: 80
          }
        },
        targetAxisIndex: 1,
        color: "#4F81BD",
        type: "bars"
      },
      1: {
        annotations: {
          stem: {
            length: 7
          }
        },
        type: "line",
        targetAxisIndex: 0,
        color: "#C0504D",
        pointShape: "square",
        pointsVisible: true
      }
    },
    backgroundColor: "#8064A2",
    legend: {
      position: "top",
      alignment: "start"
    }
  };

  var container = document.getElementById("bv_and_ba");
  var chart = new google.visualization.ColumnChart(container);

  chart.draw(view, options);

}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="bv_and_ba" style="width: 100%; height: 300px;"></div>

1 个答案:

答案 0 :(得分:1)

有一个图表方法-> chart.getChartLayoutInterface()

这将返回具有其自身方法的对象-> getBoundingBox
需要一个ID字符串

条形元素的

id字符串= bar#series number#row number
第一个系列中的第一个小节= bar#0#0

获取栏的高度-> chartLayout.getBoundingBox('bar#0#0')

一旦我们有高度,我们就可以移动注释

请参阅以下工作片段...

google.charts.load("current", { packages: ["corechart", "bar"] });
google.charts.setOnLoadCallback(drawBVandBA);

function drawBVandBA() {
  var dataArr = [
    ["Month", "Book Orders", "Buying Accounts", "Throughput"],
    ["Jan", 200.25, 1253, 379.09],
    ["Feb", 533.39, 1253, 379.09],
    ["March", 564.79, 1123, 379.09],
    ["Apr", 475.66, 1154, 379.09],
    ["May", 564.75, 1203, 379.09],
    ["Jun", 200.23, 1189, 379.09],
    ["Jul", 475.66, 1201, 379.09],
    ["Aug", 513.43, 1228, 379.09],
    ["Sep", 423.77, 1175, 379.09],
    ["Oct", 399.88, 1024, 379.09],
    ["Nov", 546.47, 1243, 379.09],
    ["Dec", 435.65, 1209, 379.09]
  ];

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

  var view = new google.visualization.DataView(data);
  view.setColumns([0, 1, {
    calc: "stringify",
    sourceColumn: 1,
    type: "string",
    role: "annotation"
  }, 2, {
    calc: "stringify",
    sourceColumn: 2,
    type: "string",
    role: "annotation"
  }]);

  var options = {
    animation: {
      duration: 1000,
      easing: "out",
      startup: true
    },
    annotations: {
      textStyle: {
        fontSize: 11,
        color: "black",
        auraColor: "none"
      }
    },
    chartArea: {
      backgroundColor: "#B9CDE5",
      right: "6%",
      width: "80%"
    },
    vAxes: {
      0: {
        viewWindowMode: "explicit",
        viewWindow: {
          max: 1400,
          min: 0
        },
        gridlines: {
          color: "transparent",
          count: 8
        }
      },
      1: {
        viewWindow: {
          max: 600,
          min: 0
        },
        gridlines: {
          color: "transparent",
          count: 7
        }
      }
    },
    series: {
      0: {
        annotations: {
          stem: {
            color: 'transparent',
            length: 0
          }
        },
        targetAxisIndex: 1,
        color: "#4F81BD",
        type: "bars"
      },
      1: {
        annotations: {
          stem: {
            length: 7
          }
        },
        type: "line",
        targetAxisIndex: 0,
        color: "#C0504D",
        pointShape: "square",
        pointsVisible: true
      }
    },
    backgroundColor: "#8064A2",
    legend: {
      position: "top",
      alignment: "start"
    }
  };

  var container = document.getElementById("bv_and_ba");
  var chart = new google.visualization.ColumnChart(container);

  var annotations = [];
  var chartLayout;
  var annotationsReady = false;

  // get annotation text for element identification
  google.visualization.events.addListener(chart, 'ready', function () {
    chartLayout = chart.getChartLayoutInterface();
    for (var i = 0; i < view.getNumberOfRows(); i++) {
      annotations.push(view.getValue(i, 2));
    }
  });

  // wait until annotations are ready to move
  google.visualization.events.addListener(chart, 'animationfinish', function () {
    annotationsReady = true;
    moveAnnotations();
  });

  function moveAnnotations() {
    // ensure annotations are ready
    if (!annotationsReady) {
      return;
    }

    // move annotations
    Array.prototype.forEach.call(container.getElementsByTagName('text'), function(annotation) {
      // exclude other labels
      if (annotation.getAttribute('text-anchor') === 'middle') {
        var annotationTop;
        var barBounds;

        // check if annotation to be moved
        var rowIndex = annotations.indexOf(annotation.textContent);
        if (rowIndex > -1) {
          // get bar bounds
          barBounds = chartLayout.getBoundingBox('bar#0#' + rowIndex);
          // calculate annotation position
          annotationTop = barBounds.top + (barBounds.height / 2) + (annotation.getBBox().height / 2);
          // move annotation
          annotation.setAttribute('y', annotationTop);
        }
      }
    });
  }

  // prevent chart from moving annotations back to original position
  var observer = new MutationObserver(moveAnnotations);
  observer.observe(container, {
    childList: true,
    subtree: true
  });

  chart.draw(view, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="bv_and_ba" style="width: 100%; height: 300px;"></div>