2017-11-21 4 views
1

Ich habe verschiedene benutzerdefinierte Beispiel versucht. Aber sie sind nur einzelne Daten zur Verfügung stellen, aber ich brauche die allerletzten Daten mit der runden EckeGestapelte Balkendiagramm mit abgerundeten Ecke des Balkens mit Chart.js

https://jsfiddle.net/ankitkothari/7km2ytjo/2/

den Link oben vertretend für der Beispielcode in diesem ich die obersten Daten in Runde ist, müssen Ecke nicht untere Daten

Bitte beziehen Sie sich auf den obigen Link für den Beispiel-Code, in dem ich die obersten Daten in runden Ecke nicht unteren Daten benötigen.

Chart.elements.Rectangle.prototype.draw = function() { 
    debugger; 
    var ctx = this._chart.ctx; 
    var vm = this._view; 
    var left, right, top, bottom, signX, signY, borderSkipped, radius; 
    var borderWidth = vm.borderWidth; 
    // Set Radius Here 
    // If radius is large enough to cause drawing errors a max radius is imposed 
    var cornerRadius = 10; 

    if (!vm.horizontal) { 
     // bar 
     left = vm.x - vm.width/2; 
     right = vm.x + vm.width/2; 
     top = vm.y; 
     bottom = vm.base; 
     signX = 1; 
     signY = bottom > top? 1: -1; 
     borderSkipped = vm.borderSkipped || 'bottom'; 
    } else { 
     // horizontal bar 
     left = vm.base; 
     right = vm.x; 
     top = vm.y - vm.height/2; 
     bottom = vm.y + vm.height/2; 
     signX = right > left? 1: -1; 
     signY = 1; 
     borderSkipped = vm.borderSkipped || 'left'; 
    } 

    // Canvas doesn't allow us to stroke inside the width so we can 
    // adjust the sizes to fit if we're setting a stroke on the line 
    if (borderWidth) { 
     // borderWidth shold be less than bar width and bar height. 
     var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom)); 
     borderWidth = borderWidth > barSize? barSize: borderWidth; 
     var halfStroke = borderWidth/2; 
     // Adjust borderWidth when bar top position is near vm.base(zero). 
     var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0); 
     var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0); 
     var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0); 
     var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0); 
     // not become a vertical line? 
     if (borderLeft !== borderRight) { 
      top = borderTop; 
      bottom = borderBottom; 
     } 
     // not become a horizontal line? 
     if (borderTop !== borderBottom) { 
      left = borderLeft; 
      right = borderRight; 
     } 
    } 

    ctx.beginPath(); 
    ctx.fillStyle = vm.backgroundColor; 
    ctx.strokeStyle = vm.borderColor; 
    ctx.lineWidth = borderWidth; 

    // Corner points, from bottom-left to bottom-right clockwise 
    // | 1 2 | 
    // | 0 3 | 
    var corners = [ 
     [left, bottom], 
     [left, top], 
     [right, top], 
     [right, bottom] 
    ]; 

    // Find first (starting) corner with fallback to 'bottom' 
    var borders = ['bottom', 'left', 'top', 'right']; 
    var startCorner = borders.indexOf(borderSkipped, 0); 
    if (startCorner === -1) { 
     startCorner = 0; 
    } 

    function cornerAt(index) { 
     return corners[(startCorner + index) % 4]; 
    } 

    // Draw rectangle from 'startCorner' 
    var corner = cornerAt(0); 
    ctx.moveTo(corner[0], corner[1]); 

    for (var i = 1; i < 4; i++) { 
     corner = cornerAt(i); 
     nextCornerId = i+1; 
     if(nextCornerId == 4){ 
      nextCornerId = 0 
     } 

     nextCorner = cornerAt(nextCornerId); 

     width = corners[2][0] - corners[1][0]; 
     height = corners[0][1] - corners[1][1]; 
     x = corners[1][0]; 
     y = corners[1][1]; 

     var radius = cornerRadius; 

     // Fix radius being too large 
     if(radius > height/2){ 
      radius = height/2; 
     }if(radius > width/2){ 
      radius = width/2; 
     } 

     ctx.moveTo(x + radius, y); 
     ctx.lineTo(x + width - radius, y); 
     ctx.quadraticCurveTo(x + width, y, x + width, y + radius); 
     ctx.lineTo(x + width, y + height - radius); 
     ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); 
     ctx.lineTo(x + radius, y + height); 
     ctx.quadraticCurveTo(x, y + height, x, y + height - radius); 
     ctx.lineTo(x, y + radius); 
     ctx.quadraticCurveTo(x, y, x + radius, y); 

    } 

    ctx.fill(); 
    if (borderWidth) { 
     ctx.stroke(); 
    } 
}; 
var data = { 
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], 
     datasets: [{ 
      label: '# of Votes', 
      data: [12, 19, 3, 5, 2, 3], 
      backgroundColor: [ 
       'rgba(255, 99, 132, 1)', 
       'rgba(54, 162, 235, 1)', 
       'rgba(255, 206, 86, 1)', 
       'rgba(75, 192, 192, 1)', 
       'rgba(153, 102, 255, 1)', 
       'rgba(255, 159, 64, 1)' 
      ], 
      borderWidth: 5 
     },{ 
      label: '# of Votes', 
      data: [20, 5, 10, 15, 12, 13], 
      backgroundColor: [ 
      'rgba(255, 159, 64, 1)', 
       'rgba(255, 99, 132, 1)',    
       'rgba(255, 206, 86, 1)', 

       'rgba(54, 162, 235, 1)', 
       'rgba(153, 102, 255, 1)', 
       'rgba(75, 192, 192, 1)' 

      ], 
      borderWidth: 5 
     }] 
    }; 
var options = { 
elements:{ point: { 
    radius:25, 
    hoverRadius:35, 
    pointStyle:'rectRounded' 
    }}, 
     scales: { 
      yAxes: [{ 
       ticks: { 
        beginAtZero:true 
       }, 
       stacked : true, 
       radius:25 
      }], 
      xAxes: [{ 
       ticks: { 
        beginAtZero:true 
       }, 
       stacked : true, 

      }] 
     } 
    }; 




var ctxBar = document.getElementById("myChart"); 
var myBarChart = new Chart(ctxBar, { 
    type: 'bar', 
    data: data, 
    options: options 
}); 

Antwort

0

Ich habe Ihre Geige geändert, so dass nur die oberen Rechteckränder rund sind. Der Trick besteht darin, das getDatasetMeta des Diagramms zu verwenden, um den Sichtbarkeitsstatus von Rechtecken zu prüfen und zu entscheiden, ob es sich um den letzten sichtbaren om-Stapel handelt.

Dies funktioniert nur für Ihre Beispieldaten von zwei Datasets, aber könnte geändert werden, um mit einem beliebigen Betrag zu arbeiten.

https://jsfiddle.net/a6m34c01/


EDIT: abritrary Anzahl von Daten umgehen.

https://jsfiddle.net/a6m34c01/8/

Chart.elements.Rectangle.prototype.draw = function() { 
    debugger; 
    var ctx = this._chart.ctx; 
    var vm = this._view; 
    var left, right, top, bottom, signX, signY, borderSkipped, radius; 
    var borderWidth = vm.borderWidth; 
    // Set Radius Here 
    // If radius is large enough to cause drawing errors a max radius is imposed 
    var cornerRadius = 10; 

    if (!vm.horizontal) { 
     // bar 
     left = vm.x - vm.width/2; 
     right = vm.x + vm.width/2; 
     top = vm.y; 
     bottom = vm.base; 
     signX = 1; 
     signY = bottom > top? 1: -1; 
     borderSkipped = vm.borderSkipped || 'bottom'; 
    } else { 
     // horizontal bar 
     left = vm.base; 
     right = vm.x; 
     top = vm.y - vm.height/2; 
     bottom = vm.y + vm.height/2; 
     signX = right > left? 1: -1; 
     signY = 1; 
     borderSkipped = vm.borderSkipped || 'left'; 
    } 

    // Canvas doesn't allow us to stroke inside the width so we can 
    // adjust the sizes to fit if we're setting a stroke on the line 
    if (borderWidth) { 
     // borderWidth shold be less than bar width and bar height. 
     var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom)); 
     borderWidth = borderWidth > barSize? barSize: borderWidth; 
     var halfStroke = borderWidth/2; 
     // Adjust borderWidth when bar top position is near vm.base(zero). 
     var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0); 
     var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0); 
     var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0); 
     var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0); 
     // not become a vertical line? 
     if (borderLeft !== borderRight) { 
      top = borderTop; 
      bottom = borderBottom; 
     } 
     // not become a horizontal line? 
     if (borderTop !== borderBottom) { 
      left = borderLeft; 
      right = borderRight; 
     } 
    } 

    ctx.beginPath(); 
    ctx.fillStyle = vm.backgroundColor; 
    ctx.strokeStyle = vm.borderColor; 
    ctx.lineWidth = borderWidth; 

    // Corner points, from bottom-left to bottom-right clockwise 
    // | 1 2 | 
    // | 0 3 | 
    var corners = [ 
     [left, bottom], 
     [left, top], 
     [right, top], 
     [right, bottom] 
    ]; 

    // Find first (starting) corner with fallback to 'bottom' 
    var borders = ['bottom', 'left', 'top', 'right']; 
    var startCorner = borders.indexOf(borderSkipped, 0); 
    if (startCorner === -1) { 
     startCorner = 0; 
    } 

    function cornerAt(index) { 
     return corners[(startCorner + index) % 4]; 
    } 

    // Draw rectangle from 'startCorner' 
    var corner = cornerAt(0); 
    ctx.moveTo(corner[0], corner[1]); 

    for (var i = 1; i < 4; i++) { 
     corner = cornerAt(i); 
     nextCornerId = i+1; 
     if(nextCornerId == 4){ 
      nextCornerId = 0 
     } 

     nextCorner = cornerAt(nextCornerId); 

     width = corners[2][0] - corners[1][0]; 
     height = corners[0][1] - corners[1][1]; 
     x = corners[1][0]; 
     y = corners[1][1]; 

     var radius = cornerRadius; 

     // Fix radius being too large 
     if(radius > height/2){ 
      radius = height/2; 
     }if(radius > width/2){ 
      radius = width/2; 
     } 



     var lastVisible = 0; 
     for(var findLast=0, findLastTo=this._chart.data.datasets.length;findLast<findLastTo;findLast++) { 
      if (!this._chart.getDatasetMeta(findLast).hidden) { 
      lastVisible =findLast; 
      } 
     } 
     var rounded = this._datasetIndex === lastVisible; 

     if (rounded) { 
      ctx.moveTo(x + radius, y); 
      ctx.lineTo(x + width - radius, y); 
      ctx.quadraticCurveTo(x + width, y, x + width, y + radius); 
      ctx.lineTo(x + width, y + height); 
      ctx.lineTo(x, y + height); 
      ctx.lineTo(x, y + radius); 
      ctx.quadraticCurveTo(x, y, x + radius, y); 
     } else { 
      ctx.moveTo(x, y); 
      ctx.lineTo(x + width, y); 
      ctx.lineTo(x + width, y + height); 
      ctx.lineTo(x , y + height); 
      ctx.lineTo(x, y); 
     } 

    } 

    ctx.fill(); 
    if (borderWidth) { 
     ctx.stroke(); 
    } 
}; 
var data = { 
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], 
     datasets: [{ 
      label: '# of Votes', 
      data: [12, 19, 3, 5, 2, 3], 
      backgroundColor: [ 
       'rgba(255, 99, 132, 1)', 
       'rgba(54, 162, 235, 1)', 
       'rgba(255, 206, 86, 1)', 
       'rgba(75, 192, 192, 1)', 
       'rgba(153, 102, 255, 1)', 
       'rgba(255, 159, 64, 1)' 
      ], 
      borderWidth: 5 
     },{ 
      label: '# of Votes', 
      data: [20, 5, 10, 15, 12, 13], 
      backgroundColor: [ 
      'rgba(255, 159, 64, 1)', 
       'rgba(255, 99, 132, 1)',    
       'rgba(255, 206, 86, 1)', 

       'rgba(54, 162, 235, 1)', 
       'rgba(153, 102, 255, 1)', 
       'rgba(75, 192, 192, 1)' 

      ], 
      borderWidth: 5 
     }] 
    }; 
var options = { 
elements:{ point: { 
    radius:25, 
    hoverRadius:35, 
    pointStyle:'rectRounded' 
    }}, 
     scales: { 
      yAxes: [{ 
       ticks: { 
        beginAtZero:true 
       }, 
       stacked : true, 
       radius:25 
      }], 
      xAxes: [{ 
       ticks: { 
        beginAtZero:true 
       }, 
       stacked : true, 

      }] 
     } 
    }; 




var ctxBar = document.getElementById("myChart"); 
var myBarChart = new Chart(ctxBar, { 
    type: 'bar', 
    data: data, 
    options: options 
}); 
+0

Hallo, danke für die schnelle Aktualisierung, aber ich habe Beispieldatensatz von zwei tatsächlich gibt es mehrere Datensatz wird so muss ich die Logik zufällig –

+0

Ok, das ist einfach, aktualisiert Geige und bearbeitet Antwort . – Joschi

+0

Hallo, ich aktualisierte die Geige, wenn es 0 Daten gibt, dann wird es Quadrat nicht gerundet anzeigen https://jsfiddle.net/ankitkothari/a6m34c01/9/ –

Verwandte Themen