You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
4.6 KiB
177 lines
4.6 KiB
1 year ago
|
/*
|
||
|
* Chart.JS Extension
|
||
|
* @version: 1.0.0 (Mon, 25 Nov 2019)
|
||
|
* @requires: Chart.js
|
||
|
* @author: HtmlStream
|
||
|
* @event-namespace: Chart.JS Extension
|
||
|
* @license: Htmlstream Libraries (https://htmlstream.com/)
|
||
|
* Copyright 2019 Htmlstream
|
||
|
*/
|
||
|
|
||
|
|
||
|
function detectRadius(r, h, w, i) {
|
||
|
if (typeof r === 'object') {
|
||
|
if (r[i] > h / 2) {
|
||
|
r[i] = h / 2;
|
||
|
}
|
||
|
|
||
|
if (r[i] > w / 2) {
|
||
|
r[i] = w / 2;
|
||
|
}
|
||
|
|
||
|
return r[i];
|
||
|
} else {
|
||
|
if (r > h / 2) {
|
||
|
r = h / 2;
|
||
|
}
|
||
|
|
||
|
if (r > w / 2) {
|
||
|
r = w / 2;
|
||
|
}
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
window.Chart.elements.Rectangle.prototype.draw = function () {
|
||
|
var ctx = this._chart.ctx,
|
||
|
vm = this._view,
|
||
|
left,
|
||
|
right,
|
||
|
top,
|
||
|
bottom,
|
||
|
signX,
|
||
|
signY,
|
||
|
borderSkipped,
|
||
|
borderWidth,
|
||
|
defaults = {
|
||
|
options: {
|
||
|
cornerRadius: 0
|
||
|
}
|
||
|
},
|
||
|
dataSettings = $(this._chart.canvas).attr('data-hs-chartjs-options') ? JSON.parse($(this._chart.canvas).attr('data-hs-chartjs-options')) : {},
|
||
|
settings = $.extend(true, dataSettings.type, defaults, dataSettings);
|
||
|
|
||
|
borderWidth = vm.borderWidth;
|
||
|
|
||
|
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'],
|
||
|
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),
|
||
|
radius,
|
||
|
nextCornerId,
|
||
|
nextCorner,
|
||
|
width,
|
||
|
height,
|
||
|
x,
|
||
|
y;
|
||
|
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 = settings.options.cornerRadius;
|
||
|
|
||
|
// Fix radius being too large
|
||
|
ctx.moveTo(x + detectRadius(radius, height, width, typeof radius === 'object' ? 0 : null), y);
|
||
|
|
||
|
ctx.lineTo(x + width - detectRadius(radius, height, width, typeof radius === 'object' ? 0 : null), y);
|
||
|
ctx.quadraticCurveTo(x + width, y, x + width, y + detectRadius(radius, height, width, typeof radius === 'object' ? 0 : null));
|
||
|
|
||
|
ctx.lineTo(x + width, y + height - detectRadius(radius, height, width, typeof radius === 'object' ? 1 : null));
|
||
|
ctx.quadraticCurveTo(x + width, y + height, x + width - detectRadius(radius, height, width, typeof radius === 'object' ? 1 : null), y + height);
|
||
|
|
||
|
ctx.lineTo(x + detectRadius(radius, height, width, typeof radius === 'object' ? 2 : null), y + height);
|
||
|
ctx.quadraticCurveTo(x, y + height, x, y + height - detectRadius(radius, height, width, typeof radius === 'object' ? 0 : null));
|
||
|
|
||
|
ctx.lineTo(x, y + detectRadius(radius, height, width, typeof radius === 'object' ? 3 : null));
|
||
|
ctx.quadraticCurveTo(x, y, x + detectRadius(radius, height, width, typeof radius === 'object' ? 3 : null), y);
|
||
|
}
|
||
|
|
||
|
ctx.fill();
|
||
|
|
||
|
if (borderWidth) {
|
||
|
ctx.stroke();
|
||
|
}
|
||
|
};
|