Created
June 28, 2019 09:48
-
-
Save nwkm/ed32a34ea66d156b3af9dbaa92070a53 to your computer and use it in GitHub Desktop.
Revisions
-
nwkm created this gist
Jun 28, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,137 @@ //draws a rectangle with a rounded top Chart.helpers.drawRoundedTopRectangle = function( ctx: any, x: number, y: number, width: number, height: number, radius: number, ) { ctx.beginPath(); ctx.moveTo(x + radius, y); // top right corner ctx.lineTo(x + width - radius, y); ctx.quadraticCurveTo(x + width, y, x + width, y + radius); // bottom right corner ctx.lineTo(x + width, y + height); // bottom left corner ctx.lineTo(x, y + height); // top left ctx.lineTo(x, y + radius); ctx.quadraticCurveTo(x, y, x + radius, y); ctx.closePath(); }; (Chart as any).elements.RoundedTopRectangle = (Chart as any).elements.Rectangle.extend( { draw() { const ctx = this._chart.ctx; const vm = this._view; let left; let right; let top; let bottom; let signX; let signY; let borderSkipped; let borderWidth = vm.borderWidth; if (!vm.horizontal) { // bar left = vm.x - vm.width / 2; right = vm.x + vm.width / 2; top = vm.y; // If the y-axis stack is true, we should increase bottom value by xxx // vm.base + xxx ===> Help to lower the stacked bar to make they look nice 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. const barSize = Math.min( Math.abs(left - right), Math.abs(top - bottom), ); borderWidth = borderWidth > barSize ? barSize : borderWidth; const halfStroke = borderWidth / 2; // Adjust borderWidth when bar top position is near vm.base(zero). const borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0); const borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0); const borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0); const 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; } } // calculate the bar width and roundess const barWidth = Math.abs(left - right); const roundness = this._chart.config.options.barRoundness || 0.5; const radius = barWidth * roundness * 0.5; // keep track of the original top of the bar const prevTop = top; // move the top down so there is room to draw the rounded top top = prevTop + radius; const barRadius = top - prevTop; ctx.beginPath(); ctx.fillStyle = vm.backgroundColor; ctx.strokeStyle = vm.borderColor; ctx.lineWidth = borderWidth; // draw the rounded top rectangle Chart.helpers.drawRoundedTopRectangle( ctx, left, top - barRadius + 1, barWidth, bottom - prevTop, barRadius, ); ctx.fill(); if (borderWidth) { ctx.stroke(); } // restore the original top value so tooltips and scales still work top = prevTop; }, }, ); Chart.defaults.roundedBar = Chart.helpers.clone(Chart.defaults.bar); Chart.controllers.roundedBar = Chart.controllers.bar.extend({ dataElementType: (Chart as any).elements.RoundedTopRectangle, });