2016-09-29 74 views
0

我使用ionic framework,我在那裏顯示在圖表中的一些數據將某個應用,使用chart.js ...chart.js之 - 創建與狀態的單個條形圖

基本上,我試圖讓柱狀圖,在那裏我只有1個單槓,通過多年的模擬活動的狀態,你可以在下圖中看到:

enter image description here

我找不到任何可以幫助我,我開始用線條做這個,但我需要使用幾個工具,如grandientChart.controllers.line.extend,它開始看起來更像是一種解決方法......它不是真的很好,並且沒有多大意義......

有沒有一種方法可以做到這一點?或者你有什麼想法,我應該調查以實現這一目標?

回答

0

那麼,我沒有找到一個很好的解決方案,但我找到了一個。

所以基本上,我對這個問題描述我想創造一個柱狀圖,但我也希望該圖表將有不同的顏色沿着時間......

以下是我解決了這個。

首先我創建並排列顏色,並計算顏色可見的時間百分比。然後我把它的顏色數組,被稱爲「activityGradientArray」

var generateFilteredActivityGradientArray = function(){ 
      var filteredActivityColorWithSpaces = $scope.filteredActivityColorWithSpaces; 

      //define ratio length 
      var ratioActivity = (1.0)/filteredActivityColorWithSpaces.length; 

      var newRatio = 0.0; 
      var oldRatio = 0.0; 
      var ratioCounter = 0.0; 
      var oldColor = ""; 
      var newColor = ""; 

      var colorScheme = []; 

      for (var i = 0; i < filteredActivityColorWithSpaces.length; i++) { 

       newColor = filteredActivityColorWithSpaces[i].color; 

       if (oldColor != newColor) { 
        colorScheme.push({ratio: ratioCounter, color: newColor}); 

        oldColor = newColor; 
        oldRatio = newRatio; 
       } 

       ratioCounter = ratioCounter + ratioActivity; 
      } 

      $scope.activityGradientArray = []; 

      for (var i = 1; i < colorScheme.length; i++) { 
       $scope.activityGradientArray.push({ratio: colorScheme[i-1].ratio, color: colorScheme[i-1].color}); 
       $scope.activityGradientArray.push({ratio: colorScheme[i].ratio, color: colorScheme[i-1].color}); 
      } 

      var lastPosition = colorScheme.length-1; 
      $scope.activityGradientArray.push({ratio: colorScheme[lastPosition].ratio, color: colorScheme[lastPosition].color}); 
      $scope.activityGradientArray.push({ratio: 1, color: colorScheme[lastPosition].color}); 

     }; 

然後我延長Chart.controllers.line,並使用activityGradientArray的梯度應用到chart.chart.ctx內,使用addColorStop

var chartControllersLine = function(){ 

      return Chart.controllers.line.extend({ 
       update: function() { 

        if(($scope.filteredChart.temperature.isNull()) && ($scope.filteredChart.activity.isNull())) { 
         return; 
        } 

        // get the min and max values 
        var minY = Math.min.apply(null, this.chart.data.datasets[$scope.CHART_DATASET_TEMPERATURE].data); 
        var maxY = Math.max.apply(null, this.chart.data.datasets[$scope.CHART_DATASET_TEMPERATURE].data); 

        $scope.minYValue = minY; 

        var yScale = this.getScaleForId(this.getDataset().yAxisID); 
        var xAxis = this.chart.scales['x-axis-0']; 


        if((undefined == yScale) || (undefined == xAxis)){ 
         return; 
        } 

        var ctx = this.chart.chart.ctx; 
        // figure out the pixels for these and the value 0 
        var top = yScale.getPixelForValue(maxY)+5; //add 
        var bottom = yScale.getPixelForValue(minY)+5; 
        var left = xAxis.chart.chartArea.left; 
        var right = xAxis.chart.chartArea.right; 

        var minimumPixelPosition; 
        var maximumPixelPosition; 
        var minimumMarginPixelPosition; 
        var maximumMarginPixelPosition; 

        if(($scope.homeConfig.rangeChartMin > minY)){ 
         minimumPixelPosition = yScale.getPixelForValue($scope.homeConfig.rangeChartMin); 

        } else { 
         minimumPixelPosition = yScale.getPixelForValue(minY); 
        } 

        if(($scope.homeConfig.rangeChartMax < maxY)) { 
         maximumPixelPosition = yScale.getPixelForValue($scope.homeConfig.rangeChartMax); 
        } else { 
         maximumPixelPosition = yScale.getPixelForValue(maxY); 
        } 

        var isAllOutside = false; 
        if((($scope.homeConfig.rangeChartMax > maxY) && ($scope.homeConfig.rangeChartMin > maxY)) || 
         (($scope.homeConfig.rangeChartMax < minY) && ($scope.homeConfig.rangeChartMin < minY))) { 
         isAllOutside = true; 
        } 

        var ratioMinimumTemperature = Math.abs(Math.min((minimumPixelPosition - top)/(bottom - top), 1)); 
        var ratioMaximumTemperature = Math.abs(Math.min((maximumPixelPosition - top)/(bottom - top), 1)); 

        var ratioMinimumMarginTemperature = Math.abs(Math.min(((minimumPixelPosition+5) - top)/(bottom - top), 1)); 
        var ratioMaximumMarginTemperature = Math.abs(Math.min(((maximumPixelPosition+5) - top)/(bottom - top), 1)); 


        if(ratioMinimumTemperature < 0) 
         ratioMinimumTemperature = 0; 
        if(ratioMinimumTemperature > 1) 
         ratioMinimumTemperature = 1; 

        if(ratioMaximumTemperature < 0) 
         ratioMaximumTemperature = 0; 
        if(ratioMaximumTemperature > 1) 
         ratioMaximumTemperature = 1; 

        if(!$scope.filteredChart.activity.isNull()) { 

         var gradientActivity = ctx.createLinearGradient(left, 0, right, 0); 

         for(var i = 0; i<$scope.activityGradientArray.length; i++){ 
          gradientActivity.addColorStop($scope.activityGradientArray[i].ratio, $scope.activityGradientArray[i].color); 
         } 
         this.chart.data.datasets[$scope.CHART_DATASET_ACTIVITY].borderColor = gradientActivity; 

        } 

        var auxApply = Chart.controllers.line.prototype.update.apply(this, arguments); 

        return auxApply; 
       } 
      }); 

     }; 

這裏的是我定義數據集的地方:

var lineChartData = function() { 
      return { 
       xAxisID: "x-axis-0", 
       labels: angular.isDefined($scope.filteredChart.labels) ? $scope.filteredChart.labels : [], 
       datasets: [ 
        { 
         yAxisID: "y-axis-activity", 
         label: "Activity", 
         fill: false, 
         data: angular.isDefined($scope.filteredChart.activity) ? $scope.filteredChart.activity : [], 
         borderWidth: 20, 
         pointRadius: 0, 
         borderColor: $scope.lineActivityColors, 
         borderCapStyle: 'butt', 
         borderDash: [], 
         borderDashOffset: 0.0, 
         borderJoinStyle: 'miter', 
         pointBorderWidth: 0, 
         pointHoverRadius: 5, 
         pointHitRadius: 10, 

        }] 
     } 


     }; 

最後,在我初始化所有ab的圖表Ove方法:

$(document).ready(function() { 
       var ctx = resetHomeChart(); 

       if(null == ctx) 
        return; 

       $scope.pointTemperatureColors = []; 
       $scope.lineActivityColors = []; 

       Chart.defaults.NegativeTransparentLine = Chart.helpers.clone(Chart.defaults.line); 
       Chart.controllers.NegativeTransparentLine = chartControllersLine(); 

       $scope.lineChart = new Chart(ctx, { 
        data: lineChartData(), 
        type: 'NegativeTransparentLine', 
        pointDotRadius: 10, 
        bezierCurve: false, 
        scaleShowVerticalLines: false, 
        scaleGridLineColor: "black", 
        options: options() 
       }); 

       var maxTemperature = Math.max.apply(Math, $scope.lineChart.data.datasets[$scope.CHART_DATASET_TEMPERATURE].data.map(function(o) { 
        return o == null ? -Infinity : o; 
       })); 
       var minTemperature = Math.min.apply(Math, $scope.lineChart.data.datasets[$scope.CHART_DATASET_TEMPERATURE].data.map(function(o) { 
        return o == null ? Infinity : o; 
       })); 

       if((Infinity == maxTemperature || -Infinity == maxTemperature) && (Infinity == minTemperature || -Infinity == minTemperature)){ 
        maxTemperature = 0; 
        minTemperature = 0; 
       } 

       var yScaleMaxValue = maxTemperature + 2; 
       var yScaleMinValue = minTemperature - 4; 
       $scope.lineChart.options.scales.yAxes[0].ticks.max = Math.floor(yScaleMaxValue); 
       $scope.lineChart.options.scales.yAxes[1].ticks.max = Math.floor(yScaleMaxValue); 

       $scope.lineChart.options.scales.yAxes[0].ticks.min = Math.round(yScaleMinValue); 
       $scope.lineChart.options.scales.yAxes[1].ticks.min = Math.round(yScaleMinValue); 


       //adjust bar position on the chart 
       for (var i = 0; i < $scope.lineChart.data.datasets[$scope.CHART_DATASET_ACTIVITY].data.length; i++) { 
        if(null != $scope.lineChart.data.datasets[$scope.CHART_DATASET_ACTIVITY].data[i]) { 
         $scope.lineChart.data.datasets[$scope.CHART_DATASET_ACTIVITY].data[i] = yScaleMinValue + 2; 
        } 
       } 

       $scope.lineChart.update(); 

      }); 

     }; 

再次,這不是一個理想的解決方案。它需要更多的處理比我所期望的,但它的工作原理,但它確實對我來說,至少...

如果有人有更好的解決方案,請分享