Files
Chamilo/web/assets/chart.js/src/elements/element.rectangle.js
2025-04-10 11:37:29 +02:00

214 lines
4.1 KiB
JavaScript

'use strict';
var defaults = require('../core/core.defaults');
var Element = require('../core/core.element');
var helpers = require('../helpers/index');
var defaultColor = defaults.global.defaultColor;
defaults._set('global', {
elements: {
rectangle: {
backgroundColor: defaultColor,
borderColor: defaultColor,
borderSkipped: 'bottom',
borderWidth: 0
}
}
});
function isVertical(vm) {
return vm && vm.width !== undefined;
}
/**
* Helper function to get the bounds of the bar regardless of the orientation
* @param bar {Chart.Element.Rectangle} the bar
* @return {Bounds} bounds of the bar
* @private
*/
function getBarBounds(vm) {
var x1, x2, y1, y2, half;
if (isVertical(vm)) {
half = vm.width / 2;
x1 = vm.x - half;
x2 = vm.x + half;
y1 = Math.min(vm.y, vm.base);
y2 = Math.max(vm.y, vm.base);
} else {
half = vm.height / 2;
x1 = Math.min(vm.x, vm.base);
x2 = Math.max(vm.x, vm.base);
y1 = vm.y - half;
y2 = vm.y + half;
}
return {
left: x1,
top: y1,
right: x2,
bottom: y2
};
}
function swap(orig, v1, v2) {
return orig === v1 ? v2 : orig === v2 ? v1 : orig;
}
function parseBorderSkipped(vm) {
var edge = vm.borderSkipped;
var res = {};
if (!edge) {
return res;
}
if (vm.horizontal) {
if (vm.base > vm.x) {
edge = swap(edge, 'left', 'right');
}
} else if (vm.base < vm.y) {
edge = swap(edge, 'bottom', 'top');
}
res[edge] = true;
return res;
}
function parseBorderWidth(vm, maxW, maxH) {
var value = vm.borderWidth;
var skip = parseBorderSkipped(vm);
var t, r, b, l;
if (helpers.isObject(value)) {
t = +value.top || 0;
r = +value.right || 0;
b = +value.bottom || 0;
l = +value.left || 0;
} else {
t = r = b = l = +value || 0;
}
return {
t: skip.top || (t < 0) ? 0 : t > maxH ? maxH : t,
r: skip.right || (r < 0) ? 0 : r > maxW ? maxW : r,
b: skip.bottom || (b < 0) ? 0 : b > maxH ? maxH : b,
l: skip.left || (l < 0) ? 0 : l > maxW ? maxW : l
};
}
function boundingRects(vm) {
var bounds = getBarBounds(vm);
var width = bounds.right - bounds.left;
var height = bounds.bottom - bounds.top;
var border = parseBorderWidth(vm, width / 2, height / 2);
return {
outer: {
x: bounds.left,
y: bounds.top,
w: width,
h: height
},
inner: {
x: bounds.left + border.l,
y: bounds.top + border.t,
w: width - border.l - border.r,
h: height - border.t - border.b
}
};
}
function inRange(vm, x, y) {
var skipX = x === null;
var skipY = y === null;
var bounds = !vm || (skipX && skipY) ? false : getBarBounds(vm);
return bounds
&& (skipX || x >= bounds.left && x <= bounds.right)
&& (skipY || y >= bounds.top && y <= bounds.bottom);
}
module.exports = Element.extend({
_type: 'rectangle',
draw: function() {
var ctx = this._chart.ctx;
var vm = this._view;
var rects = boundingRects(vm);
var outer = rects.outer;
var inner = rects.inner;
ctx.fillStyle = vm.backgroundColor;
ctx.fillRect(outer.x, outer.y, outer.w, outer.h);
if (outer.w === inner.w && outer.h === inner.h) {
return;
}
ctx.save();
ctx.beginPath();
ctx.rect(outer.x, outer.y, outer.w, outer.h);
ctx.clip();
ctx.fillStyle = vm.borderColor;
ctx.rect(inner.x, inner.y, inner.w, inner.h);
ctx.fill('evenodd');
ctx.restore();
},
height: function() {
var vm = this._view;
return vm.base - vm.y;
},
inRange: function(mouseX, mouseY) {
return inRange(this._view, mouseX, mouseY);
},
inLabelRange: function(mouseX, mouseY) {
var vm = this._view;
return isVertical(vm)
? inRange(vm, mouseX, null)
: inRange(vm, null, mouseY);
},
inXRange: function(mouseX) {
return inRange(this._view, mouseX, null);
},
inYRange: function(mouseY) {
return inRange(this._view, null, mouseY);
},
getCenterPoint: function() {
var vm = this._view;
var x, y;
if (isVertical(vm)) {
x = vm.x;
y = (vm.y + vm.base) / 2;
} else {
x = (vm.x + vm.base) / 2;
y = vm.y;
}
return {x: x, y: y};
},
getArea: function() {
var vm = this._view;
return isVertical(vm)
? vm.width * Math.abs(vm.y - vm.base)
: vm.height * Math.abs(vm.x - vm.base);
},
tooltipPosition: function() {
var vm = this._view;
return {
x: vm.x,
y: vm.y
};
}
});