2016-06-27 2 views
1

나는 웹 페이지에 다소 복잡한 데이터를 표시하려고 시도했으며 chart.js를 선택했습니다. 그 때문에 여러 개의 막대를 가로로 그룹화해야합니다.Chart.js 스택 및 그룹화 horizontalBar 차트

"정상적인"막대에 대해이 피들을 이미 찾았지만 아직 horizontalBar와 함께 작동하도록 변경할 수 없습니다.

유래 질문 : Chart.js stacked and grouped bar chart

원래 바이올린은 (http://jsfiddle.net/2xjwoLq0/가)

Chart.defaults.groupableBar = Chart.helpers.clone(Chart.defaults.bar); 

을 가지고 그리고 난 그냥 .horizontalBar (물론 이것은을하지 않을 것을 알고 함께 코드에서 사방 .bar 인 교체 절단). 그게 잘 작동하지 않았다 때문에 여기에 수평 막대에 대한 제안

Chart.defaults.groupableBar = Chart.helpers.clone(Chart.defaults.horizontalBar); 

, 나는 두 번째 스택 수정자를 추가하는 시도 : (calculateBarY/calculateBarX)

Horizontal stacked bar chart with chart.js 및 X와 Y의 계산 기능을 뒤집어 어떤 스택이 서로 올바르게 병합되지 않기 때문에 두 가지 중 하나를 사용해야합니다. 사람이 하나 나를 도울 수 있다면

http://jsfiddle.net/2xjwoLq0/3/

나는 감사하겠습니다.

답변

2

비슷한 것을 찾고, 나는 당신이 준 예제를 살펴보고 뭔가를 쓰기로 결정했습니다.

은 오히려 'groupableBar을'코드를 해결하기 위해 노력 또는 재사용보다, 나는 Chart.controllers.horizontalBar에서 Chart.js 코드를 얻을과 기능 calculateBarY, calculateBarHeight의 일부를 다시 작성. 예에서 getBarCount 함수를 다시 사용했습니다. 코드가 강력하게 테스트되지 않은 상태입니다

, 당신은 당신이 하나 개의 스택 그룹을 표시하려고 특히 몇 가지 버그를 발견 할 수 https://jsfiddle.net/b7gnron7/4/은 (대신 horizontalBar를 사용

Chart.defaults.groupableHBar = Chart.helpers.clone(Chart.defaults.horizontalBar); 
 

 
Chart.controllers.groupableHBar = Chart.controllers.horizontalBar.extend({ 
 
    calculateBarY: function(index, datasetIndex, ruler) { 
 
     var me = this; 
 
     var meta = me.getMeta(); 
 
     var yScale = me.getScaleForId(meta.yAxisID); 
 
     var barIndex = me.getBarIndex(datasetIndex); 
 
     var topTick = yScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo); 
 
     topTick -= me.chart.isCombo ? (ruler.tickHeight/2) : 0; 
 
     var stackIndex = this.getMeta().stackIndex; 
 

 
     if (yScale.options.stacked) { 
 
      if(ruler.datasetCount>1) { 
 
       var spBar=ruler.categorySpacing/ruler.datasetCount; 
 
       var h=me.calculateBarHeight(ruler); 
 
       
 
       return topTick + (((ruler.categoryHeight - h)/2)+ruler.categorySpacing-spBar/2)+(h+spBar)*stackIndex; 
 
      } 
 
      return topTick + (ruler.categoryHeight/2) + ruler.categorySpacing; 
 
     } 
 

 
     return topTick + 
 
      (ruler.barHeight/2) + 
 
      ruler.categorySpacing + 
 
      (ruler.barHeight * barIndex) + 
 
      (ruler.barSpacing/2) + 
 
      (ruler.barSpacing * barIndex); 
 
    }, 
 
    calculateBarHeight: function(ruler) { 
 
     var returned=0; 
 
     var me = this; 
 
     var yScale = me.getScaleForId(me.getMeta().yAxisID); 
 
     if (yScale.options.barThickness) { 
 
      returned = yScale.options.barThickness; 
 
     } 
 
     else { 
 
      returned= yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight; 
 
     } 
 
     if(ruler.datasetCount>1) { 
 
      returned=returned/ruler.datasetCount; 
 
     } 
 
     return returned; 
 
    }, 
 
    getBarCount: function() { 
 
     var stacks = []; 
 

 
     // put the stack index in the dataset meta 
 
     Chart.helpers.each(this.chart.data.datasets, function (dataset, datasetIndex) { 
 
      var meta = this.chart.getDatasetMeta(datasetIndex); 
 
      if (meta.bar && this.chart.isDatasetVisible(datasetIndex)) { 
 
       var stackIndex = stacks.indexOf(dataset.stack); 
 
       if (stackIndex === -1) { 
 
        stackIndex = stacks.length; 
 
        stacks.push(dataset.stack); 
 
       } 
 
       meta.stackIndex = stackIndex; 
 
      } 
 
     }, this); 
 

 
     this.getMeta().stacks = stacks; 
 

 
     return stacks.length; 
 
    } 
 
}); 
 

 

 

 

 
var data = { 
 
    labels: ["January", "February", "March"], 
 
    datasets: [ 
 
    { 
 
     label: "Dogs", 
 
     backgroundColor: "rgba(255,0,0,0.2)", 
 
     data: [20, 10, 25], 
 
     stack: 1, 
 
     xAxisID: 'x-axis-0', 
 
     yAxisID: 'y-axis-0' 
 
    }, 
 
    { 
 
     label: "Cats", 
 
     backgroundColor: "rgba(255,255,0,0.2)", 
 
     data: [70, 85, 65], 
 
     stack: 1, 
 
     xAxisID: 'x-axis-0', 
 
     yAxisID: 'y-axis-0' 
 
    }, 
 
    { 
 
     label: "Birds", 
 
     backgroundColor: "rgba(0,255,255,0.2)", 
 
     data: [10, 5, 10], 
 
     stack: 1, 
 
     xAxisID: 'x-axis-0', 
 
     yAxisID: 'y-axis-0' 
 

 
    }, 
 
    { 
 
     label: ":-)", 
 
     backgroundColor: "rgba(0,255,0,0.2)", 
 
     data: [20, 10, 30], 
 
     stack: 2, 
 
     xAxisID: 'x-axis-1', 
 
     yAxisID: 'y-axis-0' 
 
    }, 
 
    { 
 
     label: ":-|", 
 
     backgroundColor: "rgba(0,0,255,0.2)", 
 
     data: [40, 50, 20], 
 
     stack: 2, 
 
     xAxisID: 'x-axis-1', 
 
     yAxisID: 'y-axis-0' 
 
    }, 
 
    { 
 
     label: ":-(", 
 
     backgroundColor: "rgba(0,0,0,0.2)", 
 
     data: [60, 20, 20], 
 
     stack: 2, 
 
     xAxisID: 'x-axis-1', 
 
     yAxisID: 'y-axis-0' 
 
    }, 
 
    ] 
 
}; 
 

 
var ctx = document.getElementById("myChart").getContext("2d"); 
 
new Chart(ctx, { 
 
    type: 'groupableHBar', 
 
    data: data, 
 
    options: { 
 
    scales: { 
 
     yAxes: [{ 
 
     stacked: true, 
 
     type: 'category', 
 
     id: 'y-axis-0' 
 
     }], 
 
     xAxes: [{ 
 
     stacked: true, 
 
     type: 'linear', 
 
     ticks: { 
 
      beginAtZero:true 
 
     }, 
 
     gridLines: { 
 
      display: false, 
 
      drawTicks: true, 
 
     }, 
 
     id: 'x-axis-0' 
 
     }, 
 
     { 
 
     stacked: true, 
 
     position: 'top', 
 
     type: 'linear', 
 
     ticks: { 
 
      beginAtZero:true 
 
     }, 
 
     id: 'x-axis-1', 
 
     gridLines: { 
 
      display: true, 
 
      drawTicks: true, 
 
     }, 
 
     display: false 
 
     }] 
 
    } 
 
    } 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script> 
 
<canvas id="myChart"></canvas>
또한 여기 jsfiddle에 예를 넣어 이 경우).

귀하의 게시물 여전히 해결책이 필요하다는 것을 확실하지 ... 조금 오래된, 그러나 다른 사람을 위해 유용 할 수 있습니다^_ ^에 StackOverflow에

+0

에 오신 것을 환영합니다. 아주 좋은 첫 번째 대답 :) –

+0

@ 로한 감사합니다 :) – Grum999