%PDF-1.5 %���� ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY
| Server IP : 14.207.165.8 / Your IP : 216.73.216.26 Web Server : Apache/2.4.18 (Ubuntu) System : Linux 246 4.4.0-210-generic #242-Ubuntu SMP Fri Apr 16 09:57:56 UTC 2021 x86_64 User : root ( 0) PHP Version : 7.0.33-0ubuntu0.16.04.16 Disable Function : exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /proc/thread-self/root/var/www/html/ppaobm/vendor/bower-asset/chartjs/src/core/ |
Upload File : |
'use strict';
var defaults = require('./core.defaults');
var helpers = require('../helpers/index');
function filterByPosition(array, position) {
return helpers.where(array, function(v) {
return v.position === position;
});
}
function sortByWeight(array, reverse) {
array.forEach(function(v, i) {
v._tmpIndex_ = i;
return v;
});
array.sort(function(a, b) {
var v0 = reverse ? b : a;
var v1 = reverse ? a : b;
return v0.weight === v1.weight ?
v0._tmpIndex_ - v1._tmpIndex_ :
v0.weight - v1.weight;
});
array.forEach(function(v) {
delete v._tmpIndex_;
});
}
function findMaxPadding(boxes) {
var top = 0;
var left = 0;
var bottom = 0;
var right = 0;
helpers.each(boxes, function(box) {
if (box.getPadding) {
var boxPadding = box.getPadding();
top = Math.max(top, boxPadding.top);
left = Math.max(left, boxPadding.left);
bottom = Math.max(bottom, boxPadding.bottom);
right = Math.max(right, boxPadding.right);
}
});
return {
top: top,
left: left,
bottom: bottom,
right: right
};
}
function addSizeByPosition(boxes, size) {
helpers.each(boxes, function(box) {
size[box.position] += box.isHorizontal() ? box.height : box.width;
});
}
defaults._set('global', {
layout: {
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0
}
}
});
/**
* @interface ILayoutItem
* @prop {string} position - The position of the item in the chart layout. Possible values are
* 'left', 'top', 'right', 'bottom', and 'chartArea'
* @prop {number} weight - The weight used to sort the item. Higher weights are further away from the chart area
* @prop {boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down
* @prop {function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)
* @prop {function} update - Takes two parameters: width and height. Returns size of item
* @prop {function} getPadding - Returns an object with padding on the edges
* @prop {number} width - Width of item. Must be valid after update()
* @prop {number} height - Height of item. Must be valid after update()
* @prop {number} left - Left edge of the item. Set by layout system and cannot be used in update
* @prop {number} top - Top edge of the item. Set by layout system and cannot be used in update
* @prop {number} right - Right edge of the item. Set by layout system and cannot be used in update
* @prop {number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update
*/
// The layout service is very self explanatory. It's responsible for the layout within a chart.
// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need
// It is this service's responsibility of carrying out that layout.
module.exports = {
defaults: {},
/**
* Register a box to a chart.
* A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.
* @param {Chart} chart - the chart to use
* @param {ILayoutItem} item - the item to add to be layed out
*/
addBox: function(chart, item) {
if (!chart.boxes) {
chart.boxes = [];
}
// initialize item with default values
item.fullWidth = item.fullWidth || false;
item.position = item.position || 'top';
item.weight = item.weight || 0;
chart.boxes.push(item);
},
/**
* Remove a layoutItem from a chart
* @param {Chart} chart - the chart to remove the box from
* @param {ILayoutItem} layoutItem - the item to remove from the layout
*/
removeBox: function(chart, layoutItem) {
var index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;
if (index !== -1) {
chart.boxes.splice(index, 1);
}
},
/**
* Sets (or updates) options on the given `item`.
* @param {Chart} chart - the chart in which the item lives (or will be added to)
* @param {ILayoutItem} item - the item to configure with the given options
* @param {object} options - the new item options.
*/
configure: function(chart, item, options) {
var props = ['fullWidth', 'position', 'weight'];
var ilen = props.length;
var i = 0;
var prop;
for (; i < ilen; ++i) {
prop = props[i];
if (options.hasOwnProperty(prop)) {
item[prop] = options[prop];
}
}
},
/**
* Fits boxes of the given chart into the given size by having each box measure itself
* then running a fitting algorithm
* @param {Chart} chart - the chart
* @param {number} width - the width to fit into
* @param {number} height - the height to fit into
*/
update: function(chart, width, height) {
if (!chart) {
return;
}
var layoutOptions = chart.options.layout || {};
var padding = helpers.options.toPadding(layoutOptions.padding);
var leftPadding = padding.left;
var rightPadding = padding.right;
var topPadding = padding.top;
var bottomPadding = padding.bottom;
var leftBoxes = filterByPosition(chart.boxes, 'left');
var rightBoxes = filterByPosition(chart.boxes, 'right');
var topBoxes = filterByPosition(chart.boxes, 'top');
var bottomBoxes = filterByPosition(chart.boxes, 'bottom');
var chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea');
// Sort boxes by weight. A higher weight is further away from the chart area
sortByWeight(leftBoxes, true);
sortByWeight(rightBoxes, false);
sortByWeight(topBoxes, true);
sortByWeight(bottomBoxes, false);
var verticalBoxes = leftBoxes.concat(rightBoxes);
var horizontalBoxes = topBoxes.concat(bottomBoxes);
var outerBoxes = verticalBoxes.concat(horizontalBoxes);
// Essentially we now have any number of boxes on each of the 4 sides.
// Our canvas looks like the following.
// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
// B1 is the bottom axis
// There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays
// These locations are single-box locations only, when trying to register a chartArea location that is already taken,
// an error will be thrown.
//
// |----------------------------------------------------|
// | T1 (Full Width) |
// |----------------------------------------------------|
// | | | T2 | |
// | |----|-------------------------------------|----|
// | | | C1 | | C2 | |
// | | |----| |----| |
// | | | | |
// | L1 | L2 | ChartArea (C0) | R1 |
// | | | | |
// | | |----| |----| |
// | | | C3 | | C4 | |
// | |----|-------------------------------------|----|
// | | | B1 | |
// |----------------------------------------------------|
// | B2 (Full Width) |
// |----------------------------------------------------|
//
// What we do to find the best sizing, we do the following
// 1. Determine the minimum size of the chart area.
// 2. Split the remaining width equally between each vertical axis
// 3. Split the remaining height equally between each horizontal axis
// 4. Give each layout the maximum size it can be. The layout will return it's minimum size
// 5. Adjust the sizes of each axis based on it's minimum reported size.
// 6. Refit each axis
// 7. Position each axis in the final location
// 8. Tell the chart the final location of the chart area
// 9. Tell any axes that overlay the chart area the positions of the chart area
// Step 1
var chartWidth = width - leftPadding - rightPadding;
var chartHeight = height - topPadding - bottomPadding;
var chartAreaWidth = chartWidth / 2; // min 50%
// Step 2
var verticalBoxWidth = (width - chartAreaWidth) / verticalBoxes.length;
// Step 3
// TODO re-limit horizontal axis height (this limit has affected only padding calculation since PR 1837)
// var horizontalBoxHeight = (height - chartAreaHeight) / horizontalBoxes.length;
// Step 4
var maxChartAreaWidth = chartWidth;
var maxChartAreaHeight = chartHeight;
var outerBoxSizes = {top: topPadding, left: leftPadding, bottom: bottomPadding, right: rightPadding};
var minBoxSizes = [];
var maxPadding;
function getMinimumBoxSize(box) {
var minSize;
var isHorizontal = box.isHorizontal();
if (isHorizontal) {
minSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2);
maxChartAreaHeight -= minSize.height;
} else {
minSize = box.update(verticalBoxWidth, maxChartAreaHeight);
maxChartAreaWidth -= minSize.width;
}
minBoxSizes.push({
horizontal: isHorizontal,
width: minSize.width,
box: box,
});
}
helpers.each(outerBoxes, getMinimumBoxSize);
// If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478)
maxPadding = findMaxPadding(outerBoxes);
// At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could
// be if the axes are drawn at their minimum sizes.
// Steps 5 & 6
// Function to fit a box
function fitBox(box) {
var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {
return minBox.box === box;
});
if (minBoxSize) {
if (minBoxSize.horizontal) {
var scaleMargin = {
left: Math.max(outerBoxSizes.left, maxPadding.left),
right: Math.max(outerBoxSizes.right, maxPadding.right),
top: 0,
bottom: 0
};
// Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends
// on the margin. Sometimes they need to increase in size slightly
box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);
} else {
box.update(minBoxSize.width, maxChartAreaHeight);
}
}
}
// Update, and calculate the left and right margins for the horizontal boxes
helpers.each(verticalBoxes, fitBox);
addSizeByPosition(verticalBoxes, outerBoxSizes);
// Set the Left and Right margins for the horizontal boxes
helpers.each(horizontalBoxes, fitBox);
addSizeByPosition(horizontalBoxes, outerBoxSizes);
function finalFitVerticalBox(box) {
var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {
return minSize.box === box;
});
var scaleMargin = {
left: 0,
right: 0,
top: outerBoxSizes.top,
bottom: outerBoxSizes.bottom
};
if (minBoxSize) {
box.update(minBoxSize.width, maxChartAreaHeight, scaleMargin);
}
}
// Let the left layout know the final margin
helpers.each(verticalBoxes, finalFitVerticalBox);
// Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)
outerBoxSizes = {top: topPadding, left: leftPadding, bottom: bottomPadding, right: rightPadding};
addSizeByPosition(outerBoxes, outerBoxSizes);
// We may be adding some padding to account for rotated x axis labels
var leftPaddingAddition = Math.max(maxPadding.left - outerBoxSizes.left, 0);
outerBoxSizes.left += leftPaddingAddition;
outerBoxSizes.right += Math.max(maxPadding.right - outerBoxSizes.right, 0);
var topPaddingAddition = Math.max(maxPadding.top - outerBoxSizes.top, 0);
outerBoxSizes.top += topPaddingAddition;
outerBoxSizes.bottom += Math.max(maxPadding.bottom - outerBoxSizes.bottom, 0);
// Figure out if our chart area changed. This would occur if the dataset layout label rotation
// changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do
// without calling `fit` again
var newMaxChartAreaHeight = height - outerBoxSizes.top - outerBoxSizes.bottom;
var newMaxChartAreaWidth = width - outerBoxSizes.left - outerBoxSizes.right;
if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {
helpers.each(verticalBoxes, function(box) {
box.height = newMaxChartAreaHeight;
});
helpers.each(horizontalBoxes, function(box) {
if (!box.fullWidth) {
box.width = newMaxChartAreaWidth;
}
});
maxChartAreaHeight = newMaxChartAreaHeight;
maxChartAreaWidth = newMaxChartAreaWidth;
}
// Step 7 - Position the boxes
var left = leftPadding + leftPaddingAddition;
var top = topPadding + topPaddingAddition;
function placeBox(box) {
if (box.isHorizontal()) {
box.left = box.fullWidth ? leftPadding : outerBoxSizes.left;
box.right = box.fullWidth ? width - rightPadding : outerBoxSizes.left + maxChartAreaWidth;
box.top = top;
box.bottom = top + box.height;
// Move to next point
top = box.bottom;
} else {
box.left = left;
box.right = left + box.width;
box.top = outerBoxSizes.top;
box.bottom = outerBoxSizes.top + maxChartAreaHeight;
// Move to next point
left = box.right;
}
}
helpers.each(leftBoxes.concat(topBoxes), placeBox);
// Account for chart width and height
left += maxChartAreaWidth;
top += maxChartAreaHeight;
helpers.each(rightBoxes, placeBox);
helpers.each(bottomBoxes, placeBox);
// Step 8
chart.chartArea = {
left: outerBoxSizes.left,
top: outerBoxSizes.top,
right: outerBoxSizes.left + maxChartAreaWidth,
bottom: outerBoxSizes.top + maxChartAreaHeight
};
// Step 9
helpers.each(chartAreaBoxes, function(box) {
box.left = chart.chartArea.left;
box.top = chart.chartArea.top;
box.right = chart.chartArea.right;
box.bottom = chart.chartArea.bottom;
box.update(maxChartAreaWidth, maxChartAreaHeight);
});
}
};