2016-09-29 2 views
0

나는 chart.js 사용하여, 나는 차트에서 일부 데이터를 표시 ionic framework를 사용하여 응용 프로그램을 만들고있어 ...Chart.js - 국가들과 하나의 막대 차트 만들기

나는 기본적으로 만들려고 해요 내가 나를 도울 수있는 일을 찾을 수 없습니다

enter image description here

: 당신이 다음 이미지에서 볼 수 있듯이 나는 단지 1 개 수평 막대가 막대 차트, 즉, 다년간 활동의 상태를 시뮬레이션 , 그리고 나는 이것을 라인으로 만들기 시작했으나, grandient,와 같은 몇 가지 도구를 사용해야한다. 10, 그리고 그것은 해결 방법처럼 보이기 시작했습니다 ... 그것은 실제로 그렇게 잘 작동하지 않고 그것을 만드는 것이별로 의미가 없습니다 ...

내가 할 수있는 방법이 있습니까? 또는 이것을 달성하기 위해 조사해야 할 사항이 있습니까?

답변

0

음, 좋은 해결책을 찾지 못했지만 발견했습니다. 내가 질문에 설명 된대로

그래서 기본적으로, 나는 막대 차트를 만들고 싶었 그러나 나는 또한 차트

여기 내가 이것을 해결하는 방법은 ... 시간에 따라 서로 다른 색상을 가지고 것을 원했다.

먼저 색상을 만들고 배열하고 색상을 볼 수있는 시간의 백분율을 계산합니다. 그리고 나는 여기 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 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을 확장하고 chart.chart.ctx에 그라디언트를 적용 할 activityGradientArray을 사용하여 "activityGradientArray"라는 색상의 배열 안에 넣어 여기에 데이터 세트를 정의하는 곳이 있습니다 :

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, 

        }] 
     } 


     }; 

그리고 마지막으로 모든 차트를 방법 :

$(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(); 

      }); 

     }; 

다시 말하지만 이상적인 해결책은 아닙니다. 예상했던 것보다 약간의 처리가 필요하지만 적어도 저에게는 효과적이었습니다 ...

더 좋은 해결책이 있다면 누구나

관련 문제