2016-06-27 7 views
1

Ich habe versucht, etwas komplexe Daten auf meiner Webseite anzuzeigen und wählte chart.js dazu. Dazu muss ich mehrere gestapelte Balken horizontal gruppieren.Chart.js gestapelt und gruppiert horizontalBar-Diagramm

Ich habe diese Geige schon für "normale" Bars gefunden, konnte sie aber noch nicht so gut ändern, dass sie mit horizontalem Balken funktioniert.

Stackoverflow Frage: Chart.js stacked and grouped bar chart

Die ursprüngliche Fiddle (http://jsfiddle.net/2xjwoLq0/) hat

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

Und ich ersetzt nur die .bar überall im Code mit .horizontalBar (wohl wissend, dass dies nicht das machen Schnitt).

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

Da dies nicht ganz funktioniert hat, habe ich versucht, den zweiten gestapelten Modifikator Zugabe wie hier für horizontalen Balken vorgeschlagen: Horizontal stacked bar chart with chart.js und blätterte die Funktionen für die X- und Y-Berechnung (calculateBarY/calculateBarX)

Welche funktionieren entweder, weil die Stapel nicht richtig miteinander verschmolzen werden.

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

Ich würde mich freuen, wenn jemand mir auf diesem helfen könnte.

Antwort

2

Auf der Suche nach etwas Ähnlichem, habe ich einen Blick auf Beispiel genommen, das Sie gaben, und beschließen, etwas zu schreiben.

Anstatt zu versuchen, den Code oder die Wiederverwendung des ‚groupableBar‘ zu beheben, erhalte ich Chart.js Code aus Chart.controllers.horizontalBar und einen Teil in Funktionen umschreiben calculateBarY, calculateBarHeight. Nur die getBarCount Funktion aus Ihrem Beispiel wiederverwendet.

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>

setzen auch Beispiel auf jsfiddle hier: https://jsfiddle.net/b7gnron7/4/

-Code nicht stark getestet wird, könnte man einige Fehler gefunden, besonders wenn Sie nur eine gestapelte Gruppe anzuzeigen versuchen (verwenden horizontalBar statt in diesem Fall).

Ihr Beitrag ist ein wenig alt ... nicht sicher, dass Sie immer noch eine Lösung brauchen, aber es könnte für andere^_^

+0

Willkommen bei Stackoverflow nützlich sein. Sehr gute erste Antwort :) –

+0

@Rohan Danke :) – Grum999