2017-11-08 3 views
0

막대의 값 (기준이 아닌)에 둥근 모서리가 필요한 차트 차트 스타일을 지정합니다. 대부분의 경우 둥근 모서리가 맨 위에 있음을 의미합니다 그러나 바가 음수 값을 갖는 경우도 있습니다. 내가 여기에 답을 사용한 적이chartJS v.2의 둥근 모서리 - 음수 값을 가진 막대 차트

: How to create rounded bars for Bar Chart.js v2? jordanwillis (https://stackoverflow.com/users/7581592/jordanwillis) 값이 긍정적 때 값이 음수하지 않을 때 좋은 작품에 의해 제공. 캔버스에 quadraticCurves 년대는 네거티브에 대해 올바르게 계산하도록 내가 확장을 업데이트해야 bars with negative values get inverted corners

:

은 참조 예를 첨부.

답변

0

나는 또한 동일한 문제에 직면했다. 둥근 corners-

Chart.elements.Rectangle.prototype.draw = function() { 

     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 = 20; 

     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); 
     var width, height, x, y, nextCorner, nextCornerId 
     var x_tl, x_tr, y_tl, y_tr; 
     var x_bl, x_br, y_bl, y_br; 
     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]; 

     radius = cornerRadius; 

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

     if (height < 0) { 
      // Negative values in a standard bar chart 
      x_tl = x; x_tr = x + width; 
      y_tl = y + height; y_tr = y + height; 

      x_bl = x; x_br = x + width; 
      y_bl = y; y_br = y; 

      // Draw 
      ctx.moveTo(x_bl + radius, y_bl); 
      ctx.lineTo(x_br - radius, y_br); 
      ctx.quadraticCurveTo(x_br, y_br, x_br, y_br - radius); 
      ctx.lineTo(x_tr, y_tr + radius); 
      ctx.quadraticCurveTo(x_tr, y_tr, x_tr - radius, y_tr); 
      ctx.lineTo(x_tl + radius, y_tl); 
      ctx.quadraticCurveTo(x_tl, y_tl, x_tl, y_tl + radius); 
      ctx.lineTo(x_bl, y_bl - radius); 
      ctx.quadraticCurveTo(x_bl, y_bl, x_bl + radius, y_bl); 

     } else if (width < 0) { 
      // Negative values in a horizontal bar chart 
      x_tl = x + width; x_tr = x; 
      y_tl = y; y_tr = y; 

      x_bl = x + width; x_br = x; 
      y_bl = y + height; y_br = y + height; 

      // Draw 
      ctx.moveTo(x_bl + radius, y_bl); 
      ctx.lineTo(x_br - radius, y_br); 
      ctx.quadraticCurveTo(x_br, y_br, x_br, y_br - radius); 
      ctx.lineTo(x_tr, y_tr + radius); 
      ctx.quadraticCurveTo(x_tr, y_tr, x_tr - radius, y_tr); 
      ctx.lineTo(x_tl + radius, y_tl); 
      ctx.quadraticCurveTo(x_tl, y_tl, x_tl, y_tl + radius); 
      ctx.lineTo(x_bl, y_bl - radius); 
      ctx.quadraticCurveTo(x_bl, y_bl, x_bl + radius, y_bl); 

     } else { 
      //Positive Value 
      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(); 
     } 
    }; 

에 대한 코드 아래 사용 나는 수평 막대 차트를 사용했다. 아래 그림과 같이 차트를 그립니다. enter image description here