2017-11-21 33 views
1

私は様々なカスタム例を試しました。 しかし、彼らは、単一のデータを提供しているが、私はラウンドコーナーで非常に最後のデータを必要とするChart.jsを使用して棒の角が丸い積み重ね棒グラフ

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

私は一番上のデータを必要とする のサンプルコードはラウンドである については、上記のリンクを参照してくださいコーナーではないボトムデータ

サンプルコードについては、上記のリンクを参照してください。トップデータが丸いコーナーでボトムデータではないことが必要です。

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 
}); 

答えて

0

私はあなたのフィドルを変更して、上部の矩形の境界線のみが丸いようにしました。トリックは、グラフのgetDatasetMetaを使用して四角形の可視状態をチェックし、最後に表示されるomスタックに応じて決定することです。

これは、2つのデータセットのサンプルデータでのみ機能しますが、任意の量でも動作するように変更できます。

https://jsfiddle.net/a6m34c01/


EDIT:データのabritrary数を処理します。

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

こんにちは、迅速な更新のためのおかげで、私は2のサンプルデータセットは、実際に複数のデータセットがある置くので、私はランダムに –

+0

[OK]を簡単に、更新フィドル、編集の答えのthatsのロジックを必要としています。 – Joschi

+0

こんにちは、データが0の場合は四角形を表示しません。https://jsfiddle.net/ankitkothari/a6m34c01/9/ –

関連する問題