【问题标题】:google charts bar horizontal move annotation position to center of stacked chart谷歌图表栏水平移动注释位置到堆叠图表的中心
【发布时间】:2020-03-30 17:16:08
【问题描述】:

我正在使用 Google Chart 的柱形图。该图表是一个堆积柱形图,其中堆积柱形的每个数据点都有注释。注释位于栏内的右侧,但我希望它们位于栏内的中心。

我正在查看此页面,并提供了一个开始解决方案。 This page 使用函数“moveAnnotations()”,但我无法获取水平条形图的代码。

感谢您的帮助,我迷路了。 :(

 
/** Valeurs pour le graph bar 1 */
var data_graph_bar_1 = [
    ['Years', 'Beer & other', 'Water', 'CSD', 'Sensitive'],
    ['2014', 71, 56, 79, 59],
    ['2019', 70, 74, 75, 65]
];
 
        // Load the Visualization API and the corechart package.
        google.charts.load('current', {'packages':['corechart']});

        // Set a callback to run when the Google Visualization API is loaded.
        google.charts.setOnLoadCallback(function(){drawChart(data_graph_bar_1)});

        // Callback that creates and populates a data table,
      // instantiates the pie chart, passes in the data and
      // draws it.
      function drawChart(datas) {

            var data = google.visualization.arrayToDataTable(datas);
            var view = new google.visualization.DataView(data);

            view.setColumns([0,
                1, {
                calc: function (dt, row) {
                    return dt.getValue(row, 1);
                },
                type: "number",
                role: "annotation"
                },
                2, {
                calc: function (dt, row) {
                    return dt.getValue(row, 2);
                },
                type: "number",
                role: "annotation"
                },
                3, {
                calc: function (dt, row) {
                    return dt.getValue(row, 3);
                },
                type: "number",
                role: "annotation"
                },
                4, {
                calc: function (dt, row) {
                    return dt.getValue(row, 4);
                },
                type: "number",
                role: "annotation"
                },
                {
                calc: function (dt, row) {
                    return 0;
                },
                label: "Total",
                type: "number",
                },
                {
                calc: function (dt, row) {
                    return dt.getValue(row, 1) + dt.getValue(row, 2)+ dt.getValue(row, 3)+ dt.getValue(row, 4);
                },
                type: "number",
                role: "annotation"
                }
            ]);
            var options = {
                height: 130,
                colors: ['#B4CC00', '#3399FF', '#E64B00','#FF8B00'],
                legend: 'none',
                bar: { groupWidth: '75%' },
                isStacked: true,
                displayAnnotations: true,
                annotations: {
                    textStyle: {
                    // The color of the text.
                        color: '#000000',
                        fontSize: 15
                    },
                },
                hAxis: {
                    gridlines: {
                        count: 0
                    },
                    textPosition: 'none',
                    textStyle : {
                        fontSize: 15
                    }
                },
                vAxis: {
                    textStyle: {
                        bold: true,
                        fontSize: '20',
                    }
                },
                chartArea:{
                    left:50,
                },
            };
            
            // Instantiate and draw our chart, passing in some options.
            var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
            chart.draw(view, options);
        }
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

【问题讨论】:

    标签: charts annotations google-visualization stacked-chart react-google-charts


    【解决方案1】:

    而不是调整标签的'y'属性,
    我们只需要调整'x'属性...

    首先,我们需要定位注释标签。
    在这里,我们循环所有的行和列,然后使用值来查找标签。

    我们排除带有黑色的标签,因为它们显示在工具提示中,
    我们不想移动这些。

      for (var r = 0; r < data.getNumberOfRows(); r++) {
        for (var c = 1; c < data.getNumberOfColumns(); c++) {
          var labels = chart.getContainer().getElementsByTagName('text');
          Array.prototype.forEach.call(labels, function(label, index) {
            if ((label.textContent === data.getValue(r, c).toFixed(0)) &&
                (label.getAttribute('fill') !== '#000000')) {
              barBounds = chartLayout.getBoundingBox('bar#' + (c - 1) + '#' + r);
              xAdj = (barBounds.width / 2);
              label.setAttribute('x', barBounds.left + xAdj);
              label.setAttribute('text-anchor', 'middle');
            }
          });
        }
      }
    

    请参阅以下工作 sn-p...

    var data_graph_bar_1 = [
        ['Years', 'Beer & other', 'Water', 'CSD', 'Sensitive'],
        ['2014', 71, 56, 79, 59],
        ['2019', 70, 74, 75, 65]
    ];
    
    google.charts.load('current', {'packages':['corechart']});
    google.charts.setOnLoadCallback(function(){drawChart(data_graph_bar_1)});
    
    function drawChart(datas) {
    
        var data = google.visualization.arrayToDataTable(datas);
        var view = new google.visualization.DataView(data);
    
        view.setColumns([0,
            1, {
            calc: function (dt, row) {
                return dt.getValue(row, 1);
            },
            type: "number",
            role: "annotation"
            },
            2, {
            calc: function (dt, row) {
                return dt.getValue(row, 2);
            },
            type: "number",
            role: "annotation"
            },
            3, {
            calc: function (dt, row) {
                return dt.getValue(row, 3);
            },
            type: "number",
            role: "annotation"
            },
            4, {
            calc: function (dt, row) {
                return dt.getValue(row, 4);
            },
            type: "number",
            role: "annotation"
            },
            {
            calc: function (dt, row) {
                return 0;
            },
            label: "Total",
            type: "number",
            },
            {
            calc: function (dt, row) {
                return dt.getValue(row, 1) + dt.getValue(row, 2)+ dt.getValue(row, 3)+ dt.getValue(row, 4);
            },
            type: "number",
            role: "annotation"
            }
        ]);
        var options = {
            height: 130,
            colors: ['#B4CC00', '#3399FF', '#E64B00','#FF8B00'],
            legend: 'none',
            bar: { groupWidth: '75%' },
            isStacked: true,
            displayAnnotations: true,
            annotations: {
                textStyle: {
                // The color of the text.
                    color: '#000000',
                    fontSize: 15
                },
            },
            hAxis: {
                gridlines: {
                    count: 0
                },
                textPosition: 'none',
                textStyle : {
                    fontSize: 15
                }
            },
            vAxis: {
                textStyle: {
                    bold: true,
                    fontSize: '20',
                }
            },
            chartArea:{
                left:50,
            },
        };
    
        // Instantiate and draw our chart, passing in some options.
        var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
    
        google.visualization.events.addListener(chart, 'ready', function () {
          var observer = new MutationObserver(moveAnnotations);
          observer.observe(chart.getContainer(), {
            childList: true,
            subtree: true
          });
        });
    
        function moveAnnotations() {
          var chartLayout = chart.getChartLayoutInterface();
          var barBounds;
          var xAdj;
    
          for (var r = 0; r < data.getNumberOfRows(); r++) {
            for (var c = 1; c < data.getNumberOfColumns(); c++) {
              var labels = chart.getContainer().getElementsByTagName('text');
              Array.prototype.forEach.call(labels, function(label, index) {
                if ((label.textContent === data.getValue(r, c).toFixed(0)) && (label.getAttribute('fill') !== '#000000')) {
                  barBounds = chartLayout.getBoundingBox('bar#' + (c - 1) + '#' + r);
                  xAdj = (barBounds.width / 2);
                  label.setAttribute('x', barBounds.left + xAdj);
                  label.setAttribute('text-anchor', 'middle');
                }
              });
            }
          }
        }
    
        chart.draw(view, options);
    }
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>

    编辑

    如果有多个注解具有相同的值,
    然后我们需要添加另一个条件。

    类似于从图表界面获取条形边界,
    我们可以得到注释边界。

    labelBounds = chartLayout.getBoundingBox('annotationtext#' + (c - 1) + '#' + r + '#0');
    

    并且由于注释的初始对齐是向右,
    text-anchor="end",
    这意味着&lt;text&gt; 元素上的'x' 属性与边界的left 属性之间的差异将等于边界的宽度。
    我们可以使用这种差异来确保我们在移动之前拥有正确的注释。

    ((parseFloat(label.getAttribute('x')) - labelBounds.left) === labelBounds.width)
    

    请参阅以下工作 sn-p...

    var data_graph_bar_1 = [
        ['Years', 'Beer & other', 'Water', 'CSD', 'Sensitive'],
        ['2014', 71, 56, 74, 59],
        ['2019', 70, 74, 75, 65]
    ];
    
    google.charts.load('current', {'packages':['corechart']});
    google.charts.setOnLoadCallback(function(){drawChart(data_graph_bar_1)});
    
    function drawChart(datas) {
    
        var data = google.visualization.arrayToDataTable(datas);
        var view = new google.visualization.DataView(data);
    
        view.setColumns([0,
            1, {
            calc: function (dt, row) {
                return dt.getValue(row, 1);
            },
            type: "number",
            role: "annotation"
            },
            2, {
            calc: function (dt, row) {
                return dt.getValue(row, 2);
            },
            type: "number",
            role: "annotation"
            },
            3, {
            calc: function (dt, row) {
                return dt.getValue(row, 3);
            },
            type: "number",
            role: "annotation"
            },
            4, {
            calc: function (dt, row) {
                return dt.getValue(row, 4);
            },
            type: "number",
            role: "annotation"
            },
            {
            calc: function (dt, row) {
                return 0;
            },
            label: "Total",
            type: "number",
            },
            {
            calc: function (dt, row) {
                return dt.getValue(row, 1) + dt.getValue(row, 2)+ dt.getValue(row, 3)+ dt.getValue(row, 4);
            },
            type: "number",
            role: "annotation"
            }
        ]);
        var options = {
            height: 130,
            colors: ['#B4CC00', '#3399FF', '#E64B00','#FF8B00'],
            legend: 'none',
            bar: { groupWidth: '75%' },
            isStacked: true,
            displayAnnotations: true,
            annotations: {
                textStyle: {
                // The color of the text.
                    color: '#000000',
                    fontSize: 15
                },
            },
            hAxis: {
                gridlines: {
                    count: 0
                },
                textPosition: 'none',
                textStyle : {
                    fontSize: 15
                }
            },
            vAxis: {
                textStyle: {
                    bold: true,
                    fontSize: '20',
                }
            },
            chartArea:{
                left:50,
            },
        };
    
        // Instantiate and draw our chart, passing in some options.
        var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
    
        google.visualization.events.addListener(chart, 'ready', function () {
          var observer = new MutationObserver(moveAnnotations);
          observer.observe(chart.getContainer(), {
            childList: true,
            subtree: true
          });
        });
    
        function moveAnnotations() {
          var chartLayout = chart.getChartLayoutInterface();
          var barBounds;
          var xAdj;
    
          for (var r = 0; r < data.getNumberOfRows(); r++) {
            for (var c = 1; c < data.getNumberOfColumns(); c++) {
              var labels = chart.getContainer().getElementsByTagName('text');
              Array.prototype.forEach.call(labels, function(label, index) {
                labelBounds = chartLayout.getBoundingBox('annotationtext#' + (c - 1) + '#' + r + '#0');
                barBounds = chartLayout.getBoundingBox('bar#' + (c - 1) + '#' + r);
                if ((label.textContent === data.getValue(r, c).toFixed(0)) && (label.getAttribute('fill') !== '#000000') && ((parseFloat(label.getAttribute('x')) - labelBounds.left) === labelBounds.width)) {
                  xAdj = (barBounds.width / 2);
                  label.setAttribute('x', barBounds.left + xAdj);
                  label.setAttribute('text-anchor', 'middle');
                }
              });
            }
          }
        }
    
        chart.draw(view, options);
    }
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>

    【讨论】:

    • 谢谢!!这是完美的。你救了我的命
    • 干杯!很高兴随时提供帮助。听起来答案可能值得一票?
    • 嗨,我有一个小问题。 ^^ 使用循环,如果我有两个相同的数字,它们将放在另一个下方。我无法更改代码以使其工作。我还没有想出如何修复这个错误。 : s 你能再救我一次吗?
    • 你知道吗,如果是饼图,我们可以把数字放在外面吗?我找不到解决方案。
    • 这是唯一的选择 --> legend.position = 'labeled'
    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多