水平堆积角条形图

时间:2017-06-02 20:37:27

标签: javascript angularjs chart.js

我正在尝试实现Angular水平堆积条形图 - 类似于this example

但是,我只想要一个堆叠的酒吧。

我正在使用AngularJS和Chart.js。我在页面上显示了示例。

在PieController中,ChartData包含:

 {"data":["63","38"],"labels":["Ford","GM"]}

在示例中,我想要标签,然后将数字放在图表内,而不是外面的标签。比如[===== Ford 63 ==== | === GM 38 ===]等于代表条形颜色。将有比当前两个更多的数据点。

这是我的页面

<div ng-controller="PieController">
            data {{ChartData}}   //testing purposes
            <div ng-init="getBarChart()">
            <canvas id="Chart1"></canvas>
</div>

这是我的JavaScript控制器

app.controller('PieController', function($scope, ChartService) {


$scope.getBarChart = function(){
    ChartService.get({name: 'main'}, function(data) {
        $scope.ChartData = data;

        var barOptions_stacked = {
            tooltips: {
                enabled: false
            },
            hover: {
                animationDuration: 0
            },
            scales: {
                xAxes: [{
                    ticks: {
                        beginAtZero: true,
                        fontFamily: "'Open Sans Bold', sans-serif",
                        fontSize: 11
                    },
                    scaleLabel: {
                        display: false
                    },
                    gridLines: {},
                    stacked: true
                }],
                yAxes: [{
                    gridLines: {
                        display: false,
                        color: "#fff",
                        zeroLineColor: "#fff",
                        zeroLineWidth: 0
                    },
                    ticks: {
                        fontFamily: "'Open Sans Bold', sans-serif",
                        fontSize: 11
                    },
                    stacked: true
                }]
            },
            legend: {
                display: false
            },

            animation: {
                onComplete: function () {
                    var chartInstance = this.chart;
                    var ctx = chartInstance.ctx;
                    ctx.textAlign = "left";
                    ctx.font = "9px Open Sans";
                    ctx.fillStyle = "#fff";


                    Chart.helpers.each(this.data.datasets.forEach(function (dataset, i) {
                        var meta = chartInstance.controller.getDatasetMeta(i);
                        Chart.helpers.each(meta.data.forEach(function (bar, index) {
                            data = dataset.data[index];
                            if (i == 0) {
                                ctx.fillText(data, 50, bar._model.y + 4);
                            } else {
                                ctx.fillText(data, bar._model.x - 25, bar._model.y + 4);
                            }
                        }), this)
                    }), this);
                }
            },
            pointLabelFontFamily: "Quadon Extra Bold",
            scaleFontFamily: "Quadon Extra Bold",
        };

        var ctx = document.getElementById("Chart1");
        var myChart = new Chart(ctx, {
            type: 'horizontalBar',
            data: {
                labels: ["2014", "2013", "2012", "2011"],

                datasets: [{
                    data: [727, 589, 537, 543, 574],
                    backgroundColor: "rgba(63,103,126,1)",
                    hoverBackgroundColor: "rgba(50,90,100,1)"
                }, {
                    data: [238, 553, 746, 884, 903],
                    backgroundColor: "rgba(163,103,126,1)",
                    hoverBackgroundColor: "rgba(140,85,100,1)"
                }, {
                    data: [1238, 553, 746, 884, 903],
                    backgroundColor: "rgba(63,203,226,1)",
                    hoverBackgroundColor: "rgba(46,185,235,1)"
                }]
            },

            options: barOptions_stacked,
        })

    });//end chat service.get
}

});

有没有一种方法可以使用我在帖子开头概述的数据“ChartData”,而不是在现在正在做的数据集中进行硬编码?

我不知道该怎么做或者它是否可能。

1 个答案:

答案 0 :(得分:0)

为了让标签显示在栏中,请参考$scope.ChartData标签属性:

ctx.fillText($scope.ChartData.labels[index] +" "+ data, 50, bar._model.y + 4);
  

不是在数据集中硬编码,而是现在正在做什么,有没有办法可以使用数据&#34; ChartData&#34;我在帖子的开头概述了什么?

使用 data 变量(由ChartService get函数提供)中的属性,即data.labelsdata.data,而不是硬编码值。

所以更新标签行:

labels: ["2014", "2013", "2012", "2011"],

对此:

labels: data.labels,

同样对于数据集:

datasets: [{
    data: data.data,

因此,在创建图表时,它应如下所示:

var myChart = new Chart(ctx, {
    type: 'horizontalBar',
    data: {
        labels: data.labels,
        datasets: [{
            data: data.data,
            backgroundColor: "rgba(63,103,126,1)",
            hoverBackgroundColor: "rgba(50,90,100,1)"
        }]
    },

    options: barOptions_stacked,
});

展开下面的代码段进行演示。

注意:resize-listener目前存在问题,被CORS问题阻止 - 我正试图找到一种方法来禁用它。

更新

根据你关于堆叠条形的评论(水平) - 是的,这是可能的。每个项目的数据集数组中只有一个元素。一种简单的方法是使用Array.map()创建一个类似于示例的数组:

var bgColors = [
    "rgba(63,103,126,1)",
    "rgba(50,90,100,1)"
];
var hoverBgColors = [
    "rgba(50,90,100,1)",
    "rgba(140,85,100,1)"
];
var datasets = data.data.map(function(value, index) {
    return {
      data: [value],
      backgroundColor: bgColors[index],
      hoverBackgroundColor: hoverBgColors[index]
    }
});

然后在创建Chart对象时使用变量数据集

var myChart = new Chart(ctx, {
    type: 'horizontalBar',
    data: {
        labels: data.labels,
        datasets: datasets
    },
    options: barOptions_stacked,
});

另外,对于第二个标签的位置有一些奇怪的数学,但辅助函数可以像下面那样更新(我尝试将 x 值除以75,但可能需要调整 - 我不确定&#34;适当的&#34;值是什么......):

if (i == 0) {
    ctx.fillText($scope.ChartData.labels[i] + " " + data, 50, bar._model.y + 4);
} else {
    ctx.fillText($scope.ChartData.labels[i] + " " + data, (bar._model.x - 25) / 75, bar._model.y + 4);
}

&#13;
&#13;
var app = angular.module('myApp', []);
app.factory('ChartService', function() {
  return { //dummy chart service
    get: function(obj, callback) {
      var data = {
        "data": ["63", "38"],
        "labels": ["Ford", "GM"]
      };
      callback(data);
    }
  };
});
app.controller('PieController', function($scope, ChartService) {
  $scope.getBarChart = function() {
    ChartService.get({
      name: 'main'
    }, function(data) {
      $scope.ChartData = data;
      var barOptions_stacked = {
        tooltips: {
          enabled: false
        },
        hover: {
          animationDuration: 0
        },
        scales: {
          xAxes: [{
            ticks: {
              beginAtZero: true,
              fontFamily: "'Open Sans Bold', sans-serif",
              fontSize: 11
            },
            scaleLabel: {
              display: false
            },
            gridLines: {},
            stacked: true
          }],
          yAxes: [{
            gridLines: {
              display: false,
              color: "#fff",
              zeroLineColor: "#fff",
              zeroLineWidth: 0
            },
            ticks: {
              fontFamily: "'Open Sans Bold', sans-serif",
              fontSize: 11
            },
            stacked: true
          }]
        },
        legend: {
          display: false
        },
        animation: {
          onComplete: function() {
            var chartInstance = this.chart;
            var ctx = chartInstance.ctx;
            ctx.textAlign = "left";
            ctx.font = "9px Open Sans";
            ctx.fillStyle = "#fff";

            Chart.helpers.each(this.data.datasets.forEach(function(dataset, i) {
              var meta = chartInstance.controller.getDatasetMeta(i);
              Chart.helpers.each(meta.data.forEach(function(bar, index) {
                data = dataset.data[index];
                if (i == 0) {
                  ctx.fillText($scope.ChartData.labels[i] + " " + data, 50, bar._model.y + 4);
                } else {
                  ctx.fillText($scope.ChartData.labels[i] + " " + data, (bar._model.x - 25) / 75, bar._model.y + 4);
                }
              }), this)
            }), this);
          }
        },
        pointLabelFontFamily: "Quadon Extra Bold",
        scaleFontFamily: "Quadon Extra Bold",
      };

      var ctx = document.getElementById("Chart1");
      var bgColors = [
        "rgba(63,103,126,1)",
        "rgba(50,90,100,1)"
      ];
      var hoverBgColors = [
        "rgba(50,90,100,1)",
        "rgba(140,85,100,1)"
      ];
      var datasets = data.data.map(function(value, index) {
        return {
          data: [value],
          backgroundColor: bgColors[index],
          hoverBackgroundColor: hoverBgColors[index]
        }
      });
      var myChart = new Chart(ctx, {
        type: 'horizontalBar',
        data: {
          //use empty labels because the labels are on the bars
          labels: data.labels.map(function() {
            return '';
          }),
          datasets: datasets
        },
        options: barOptions_stacked,
      })
    }); //end chat service.get
  }
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="PieController">
  data {{ChartData}} //testing purposes
  <div ng-init="getBarChart()">
    <canvas id="Chart1"></canvas>
&#13;
&#13;
&#13;