summaryrefslogtreecommitdiff
path: root/html/assets/js/chart.js/chartjs-plugin-annotation.js
diff options
context:
space:
mode:
authorGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-04-17 12:12:22 +0300
committerGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-04-17 12:12:22 +0300
commit68fc9e55e538e03f94509731ab41a0c8cf96710f (patch)
tree3edb1e81864ac3eb35ba0fe8087ed24da1b812bf /html/assets/js/chart.js/chartjs-plugin-annotation.js
parent84b2da85a1b452922dadb6a609533b9945afe51d (diff)
downloadclassroom-68fc9e55e538e03f94509731ab41a0c8cf96710f.tar.gz
classroom-68fc9e55e538e03f94509731ab41a0c8cf96710f.tar.bz2
classroom-68fc9e55e538e03f94509731ab41a0c8cf96710f.zip
setup a real server environment (apache DocumentRoot=/var/www/public)
Diffstat (limited to 'html/assets/js/chart.js/chartjs-plugin-annotation.js')
-rw-r--r--html/assets/js/chart.js/chartjs-plugin-annotation.js928
1 files changed, 0 insertions, 928 deletions
diff --git a/html/assets/js/chart.js/chartjs-plugin-annotation.js b/html/assets/js/chart.js/chartjs-plugin-annotation.js
deleted file mode 100644
index abce828..0000000
--- a/html/assets/js/chart.js/chartjs-plugin-annotation.js
+++ /dev/null
@@ -1,928 +0,0 @@
-/*!
- * chartjs-plugin-annotation.js
- * http://chartjs.org/
- * Version: 0.5.7
- *
- * Copyright 2016 Evert Timberg
- * Released under the MIT license
- * https://github.com/chartjs/Chart.Annotation.js/blob/master/LICENSE.md
- */
-(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-
-},{}],2:[function(require,module,exports){
-module.exports = function(Chart) {
- var chartHelpers = Chart.helpers;
-
- var helpers = require('./helpers.js')(Chart);
- var events = require('./events.js')(Chart);
-
- var annotationTypes = Chart.Annotation.types;
-
- function setAfterDataLimitsHook(axisOptions) {
- helpers.decorate(axisOptions, 'afterDataLimits', function(previous, scale) {
- if (previous) previous(scale);
- helpers.adjustScaleRange(scale);
- });
- }
-
- function draw(drawTime) {
- return function(chartInstance, easingDecimal) {
- var defaultDrawTime = chartInstance.annotation.options.drawTime;
-
- helpers.elements(chartInstance)
- .filter(function(element) {
- return drawTime === (element.options.drawTime || defaultDrawTime);
- })
- .forEach(function(element) {
- element.transition(easingDecimal).draw();
- });
- };
- }
-
- return {
- beforeInit: function(chartInstance) {
- var chartOptions = chartInstance.options;
-
- // Initialize chart instance plugin namespace
- var ns = chartInstance.annotation = {
- elements: {},
- options: helpers.initConfig(chartOptions.annotation || {}),
- onDestroy: [],
- firstRun: true,
- supported: false
- };
-
- // Add the annotation scale adjuster to each scale's afterDataLimits hook
- chartInstance.ensureScalesHaveIDs();
- if (chartOptions.scales) {
- ns.supported = true;
- chartHelpers.each(chartOptions.scales.xAxes, setAfterDataLimitsHook);
- chartHelpers.each(chartOptions.scales.yAxes, setAfterDataLimitsHook);
- }
- },
- beforeUpdate: function(chartInstance) {
- var ns = chartInstance.annotation;
-
- if (!ns.supported) {
- return;
- }
-
- if (!ns.firstRun) {
- ns.options = helpers.initConfig(chartInstance.options.annotation || {});
- } else {
- ns.firstRun = false;
- }
-
- var elementIds = [];
-
- // Add new elements, or update existing ones
- ns.options.annotations.forEach(function(annotation) {
- var id = annotation.id || helpers.objectId();
-
- // No element with that ID exists, and it's a valid annotation type
- if (!ns.elements[id] && annotationTypes[annotation.type]) {
- var cls = annotationTypes[annotation.type];
- var element = new cls({
- id: id,
- options: annotation,
- chartInstance: chartInstance,
- });
- element.initialize();
- ns.elements[id] = element;
- annotation.id = id;
- elementIds.push(id);
- } else if (ns.elements[id]) {
- // Nothing to do for update, since the element config references
- // the same object that exists in the chart annotation config
- elementIds.push(id);
- }
- });
-
- // Delete removed elements
- Object.keys(ns.elements).forEach(function(id) {
- if (elementIds.indexOf(id) === -1) {
- ns.elements[id].destroy();
- delete ns.elements[id];
- }
- });
- },
- afterScaleUpdate: function(chartInstance) {
- helpers.elements(chartInstance).forEach(function(element) {
- element.configure();
- });
- },
- beforeDatasetsDraw: draw('beforeDatasetsDraw'),
- afterDatasetsDraw: draw('afterDatasetsDraw'),
- afterDraw: draw('afterDraw'),
- afterInit: function(chartInstance) {
- // Detect and intercept events that happen on an annotation element
- var watchFor = chartInstance.annotation.options.events;
- if (chartHelpers.isArray(watchFor) && watchFor.length > 0) {
- var canvas = chartInstance.chart.canvas;
- var eventHandler = events.dispatcher.bind(chartInstance);
- events.collapseHoverEvents(watchFor).forEach(function(eventName) {
- chartHelpers.addEvent(canvas, eventName, eventHandler);
- chartInstance.annotation.onDestroy.push(function() {
- chartHelpers.removeEvent(canvas, eventName, eventHandler);
- });
- });
- }
- },
- destroy: function(chartInstance) {
- var deregisterers = chartInstance.annotation.onDestroy;
- while (deregisterers.length > 0) {
- deregisterers.pop()();
- }
- }
- };
-};
-
-},{"./events.js":4,"./helpers.js":5}],3:[function(require,module,exports){
-module.exports = function(Chart) {
- var chartHelpers = Chart.helpers;
-
- var AnnotationElement = Chart.Element.extend({
- initialize: function() {
- this.hidden = false;
- this.hovering = false;
- this._model = chartHelpers.clone(this._model) || {};
- this.setDataLimits();
- },
- destroy: function() {},
- setDataLimits: function() {},
- configure: function() {},
- inRange: function() {},
- getCenterPoint: function() {},
- getWidth: function() {},
- getHeight: function() {},
- getArea: function() {},
- draw: function() {}
- });
-
- return AnnotationElement;
-};
-
-},{}],4:[function(require,module,exports){
-module.exports = function(Chart) {
- var chartHelpers = Chart.helpers;
- var helpers = require('./helpers.js')(Chart);
-
- function collapseHoverEvents(events) {
- var hover = false;
- var filteredEvents = events.filter(function(eventName) {
- switch (eventName) {
- case 'mouseenter':
- case 'mouseover':
- case 'mouseout':
- case 'mouseleave':
- hover = true;
- return false;
-
- default:
- return true;
- }
- });
- if (hover && filteredEvents.indexOf('mousemove') === -1) {
- filteredEvents.push('mousemove');
- }
- return filteredEvents;
- }
-
- function dispatcher(e) {
- var ns = this.annotation;
- var elements = helpers.elements(this);
- var position = chartHelpers.getRelativePosition(e, this.chart);
- var element = helpers.getNearestItems(elements, position);
- var events = collapseHoverEvents(ns.options.events);
- var dblClickSpeed = ns.options.dblClickSpeed;
- var eventHandlers = [];
- var eventHandlerName = helpers.getEventHandlerName(e.type);
- var options = (element || {}).options;
-
- // Detect hover events
- if (e.type === 'mousemove') {
- if (element && !element.hovering) {
- // hover started
- ['mouseenter', 'mouseover'].forEach(function(eventName) {
- var eventHandlerName = helpers.getEventHandlerName(eventName);
- var hoverEvent = helpers.createMouseEvent(eventName, e); // recreate the event to match the handler
- element.hovering = true;
- if (typeof options[eventHandlerName] === 'function') {
- eventHandlers.push([ options[eventHandlerName], hoverEvent, element ]);
- }
- });
- } else if (!element) {
- // hover ended
- elements.forEach(function(element) {
- if (element.hovering) {
- element.hovering = false;
- var options = element.options;
- ['mouseout', 'mouseleave'].forEach(function(eventName) {
- var eventHandlerName = helpers.getEventHandlerName(eventName);
- var hoverEvent = helpers.createMouseEvent(eventName, e); // recreate the event to match the handler
- if (typeof options[eventHandlerName] === 'function') {
- eventHandlers.push([ options[eventHandlerName], hoverEvent, element ]);
- }
- });
- }
- });
- }
- }
-
- // Suppress duplicate click events during a double click
- // 1. click -> 2. click -> 3. dblclick
- //
- // 1: wait dblClickSpeed ms, then fire click
- // 2: cancel (1) if it is waiting then wait dblClickSpeed ms then fire click, else fire click immediately
- // 3: cancel (1) or (2) if waiting, then fire dblclick
- if (element && events.indexOf('dblclick') > -1 && typeof options.onDblclick === 'function') {
- if (e.type === 'click' && typeof options.onClick === 'function') {
- clearTimeout(element.clickTimeout);
- element.clickTimeout = setTimeout(function() {
- delete element.clickTimeout;
- options.onClick.call(element, e);
- }, dblClickSpeed);
- e.stopImmediatePropagation();
- e.preventDefault();
- return;
- } else if (e.type === 'dblclick' && element.clickTimeout) {
- clearTimeout(element.clickTimeout);
- delete element.clickTimeout;
- }
- }
-
- // Dispatch the event to the usual handler, but only if we haven't substituted it
- if (element && typeof options[eventHandlerName] === 'function' && eventHandlers.length === 0) {
- eventHandlers.push([ options[eventHandlerName], e, element ]);
- }
-
- if (eventHandlers.length > 0) {
- e.stopImmediatePropagation();
- e.preventDefault();
- eventHandlers.forEach(function(eventHandler) {
- // [handler, event, element]
- eventHandler[0].call(eventHandler[2], eventHandler[1]);
- });
- }
- }
-
- return {
- dispatcher: dispatcher,
- collapseHoverEvents: collapseHoverEvents
- };
-};
-
-},{"./helpers.js":5}],5:[function(require,module,exports){
-function noop() {}
-
-function elements(chartInstance) {
- // Turn the elements object into an array of elements
- var elements = chartInstance.annotation.elements;
- return Object.keys(elements).map(function(id) {
- return elements[id];
- });
-}
-
-function objectId() {
- return Math.random().toString(36).substr(2, 6);
-}
-
-function isValid(rawValue) {
- if (rawValue === null || typeof rawValue === 'undefined') {
- return false;
- } else if (typeof rawValue === 'number') {
- return isFinite(rawValue);
- } else {
- return !!rawValue;
- }
-}
-
-function decorate(obj, prop, func) {
- var prefix = '$';
- if (!obj[prefix + prop]) {
- if (obj[prop]) {
- obj[prefix + prop] = obj[prop].bind(obj);
- obj[prop] = function() {
- var args = [ obj[prefix + prop] ].concat(Array.prototype.slice.call(arguments));
- return func.apply(obj, args);
- };
- } else {
- obj[prop] = function() {
- var args = [ undefined ].concat(Array.prototype.slice.call(arguments));
- return func.apply(obj, args);
- };
- }
- }
-}
-
-function callEach(fns, method) {
- fns.forEach(function(fn) {
- (method ? fn[method] : fn)();
- });
-}
-
-function getEventHandlerName(eventName) {
- return 'on' + eventName[0].toUpperCase() + eventName.substring(1);
-}
-
-function createMouseEvent(type, previousEvent) {
- try {
- return new MouseEvent(type, previousEvent);
- } catch (exception) {
- try {
- var m = document.createEvent('MouseEvent');
- m.initMouseEvent(
- type,
- previousEvent.canBubble,
- previousEvent.cancelable,
- previousEvent.view,
- previousEvent.detail,
- previousEvent.screenX,
- previousEvent.screenY,
- previousEvent.clientX,
- previousEvent.clientY,
- previousEvent.ctrlKey,
- previousEvent.altKey,
- previousEvent.shiftKey,
- previousEvent.metaKey,
- previousEvent.button,
- previousEvent.relatedTarget
- );
- return m;
- } catch (exception2) {
- var e = document.createEvent('Event');
- e.initEvent(
- type,
- previousEvent.canBubble,
- previousEvent.cancelable
- );
- return e;
- }
- }
-}
-
-module.exports = function(Chart) {
- var chartHelpers = Chart.helpers;
-
- function initConfig(config) {
- config = chartHelpers.configMerge(Chart.Annotation.defaults, config);
- if (chartHelpers.isArray(config.annotations)) {
- config.annotations.forEach(function(annotation) {
- annotation.label = chartHelpers.configMerge(Chart.Annotation.labelDefaults, annotation.label);
- });
- }
- return config;
- }
-
- function getScaleLimits(scaleId, annotations, scaleMin, scaleMax) {
- var ranges = annotations.filter(function(annotation) {
- return !!annotation._model.ranges[scaleId];
- }).map(function(annotation) {
- return annotation._model.ranges[scaleId];
- });
-
- var min = ranges.map(function(range) {
- return Number(range.min);
- }).reduce(function(a, b) {
- return isFinite(b) && !isNaN(b) && b < a ? b : a;
- }, scaleMin);
-
- var max = ranges.map(function(range) {
- return Number(range.max);
- }).reduce(function(a, b) {
- return isFinite(b) && !isNaN(b) && b > a ? b : a;
- }, scaleMax);
-
- return {
- min: min,
- max: max
- };
- }
-
- function adjustScaleRange(scale) {
- // Adjust the scale range to include annotation values
- var range = getScaleLimits(scale.id, elements(scale.chart), scale.min, scale.max);
- if (typeof scale.options.ticks.min === 'undefined' && typeof scale.options.ticks.suggestedMin === 'undefined') {
- scale.min = range.min;
- }
- if (typeof scale.options.ticks.max === 'undefined' && typeof scale.options.ticks.suggestedMax === 'undefined') {
- scale.max = range.max;
- }
- if (scale.handleTickRangeOptions) {
- scale.handleTickRangeOptions();
- }
- }
-
- function getNearestItems(annotations, position) {
- var minDistance = Number.POSITIVE_INFINITY;
-
- return annotations
- .filter(function(element) {
- return element.inRange(position.x, position.y);
- })
- .reduce(function(nearestItems, element) {
- var center = element.getCenterPoint();
- var distance = chartHelpers.distanceBetweenPoints(position, center);
-
- if (distance < minDistance) {
- nearestItems = [element];
- minDistance = distance;
- } else if (distance === minDistance) {
- // Can have multiple items at the same distance in which case we sort by size
- nearestItems.push(element);
- }
-
- return nearestItems;
- }, [])
- .sort(function(a, b) {
- // If there are multiple elements equally close,
- // sort them by size, then by index
- var sizeA = a.getArea(), sizeB = b.getArea();
- return (sizeA > sizeB || sizeA < sizeB) ? sizeA - sizeB : a._index - b._index;
- })
- .slice(0, 1)[0]; // return only the top item
- }
-
- return {
- initConfig: initConfig,
- elements: elements,
- callEach: callEach,
- noop: noop,
- objectId: objectId,
- isValid: isValid,
- decorate: decorate,
- adjustScaleRange: adjustScaleRange,
- getNearestItems: getNearestItems,
- getEventHandlerName: getEventHandlerName,
- createMouseEvent: createMouseEvent
- };
-};
-
-
-},{}],6:[function(require,module,exports){
-// Get the chart variable
-var Chart = require('chart.js');
-Chart = typeof(Chart) === 'function' ? Chart : window.Chart;
-
-// Configure plugin namespace
-Chart.Annotation = Chart.Annotation || {};
-
-Chart.Annotation.drawTimeOptions = {
- afterDraw: 'afterDraw',
- afterDatasetsDraw: 'afterDatasetsDraw',
- beforeDatasetsDraw: 'beforeDatasetsDraw'
-};
-
-Chart.Annotation.defaults = {
- drawTime: 'afterDatasetsDraw',
- dblClickSpeed: 350, // ms
- events: [],
- annotations: []
-};
-
-Chart.Annotation.labelDefaults = {
- backgroundColor: 'rgba(0,0,0,0.8)',
- fontFamily: Chart.defaults.global.defaultFontFamily,
- fontSize: Chart.defaults.global.defaultFontSize,
- fontStyle: 'bold',
- fontColor: '#fff',
- xPadding: 6,
- yPadding: 6,
- cornerRadius: 6,
- position: 'center',
- xAdjust: 0,
- yAdjust: 0,
- enabled: false,
- content: null
-};
-
-Chart.Annotation.Element = require('./element.js')(Chart);
-
-Chart.Annotation.types = {
- line: require('./types/line.js')(Chart),
- box: require('./types/box.js')(Chart)
-};
-
-var annotationPlugin = require('./annotation.js')(Chart);
-
-module.exports = annotationPlugin;
-Chart.pluginService.register(annotationPlugin);
-
-},{"./annotation.js":2,"./element.js":3,"./types/box.js":7,"./types/line.js":8,"chart.js":1}],7:[function(require,module,exports){
-// Box Annotation implementation
-module.exports = function(Chart) {
- var helpers = require('../helpers.js')(Chart);
-
- var BoxAnnotation = Chart.Annotation.Element.extend({
- setDataLimits: function() {
- var model = this._model;
- var options = this.options;
- var chartInstance = this.chartInstance;
-
- var xScale = chartInstance.scales[options.xScaleID];
- var yScale = chartInstance.scales[options.yScaleID];
- var chartArea = chartInstance.chartArea;
-
- // Set the data range for this annotation
- model.ranges = {};
-
- if (!chartArea) {
- return;
- }
-
- var min = 0;
- var max = 0;
-
- if (xScale) {
- min = helpers.isValid(options.xMin) ? options.xMin : xScale.getPixelForValue(chartArea.left);
- max = helpers.isValid(options.xMax) ? options.xMax : xScale.getPixelForValue(chartArea.right);
-
- model.ranges[options.xScaleID] = {
- min: Math.min(min, max),
- max: Math.max(min, max)
- };
- }
-
- if (yScale) {
- min = helpers.isValid(options.yMin) ? options.yMin : yScale.getPixelForValue(chartArea.bottom);
- max = helpers.isValid(options.yMax) ? options.yMax : yScale.getPixelForValue(chartArea.top);
-
- model.ranges[options.yScaleID] = {
- min: Math.min(min, max),
- max: Math.max(min, max)
- };
- }
- },
- configure: function() {
- var model = this._model;
- var options = this.options;
- var chartInstance = this.chartInstance;
-
- var xScale = chartInstance.scales[options.xScaleID];
- var yScale = chartInstance.scales[options.yScaleID];
- var chartArea = chartInstance.chartArea;
-
- // clip annotations to the chart area
- model.clip = {
- x1: chartArea.left,
- x2: chartArea.right,
- y1: chartArea.top,
- y2: chartArea.bottom
- };
-
- var left = chartArea.left,
- top = chartArea.top,
- right = chartArea.right,
- bottom = chartArea.bottom;
-
- var min, max;
-
- if (xScale) {
- min = helpers.isValid(options.xMin) ? xScale.getPixelForValue(options.xMin) : chartArea.left;
- max = helpers.isValid(options.xMax) ? xScale.getPixelForValue(options.xMax) : chartArea.right;
- left = Math.min(min, max);
- right = Math.max(min, max);
- }
-
- if (yScale) {
- min = helpers.isValid(options.yMin) ? yScale.getPixelForValue(options.yMin) : chartArea.bottom;
- max = helpers.isValid(options.yMax) ? yScale.getPixelForValue(options.yMax) : chartArea.top;
- top = Math.min(min, max);
- bottom = Math.max(min, max);
- }
-
- // Ensure model has rect coordinates
- model.left = left;
- model.top = top;
- model.right = right;
- model.bottom = bottom;
-
- // Stylistic options
- model.borderColor = options.borderColor;
- model.borderWidth = options.borderWidth;
- model.backgroundColor = options.backgroundColor;
- },
- inRange: function(mouseX, mouseY) {
- var model = this._model;
- return model &&
- mouseX >= model.left &&
- mouseX <= model.right &&
- mouseY >= model.top &&
- mouseY <= model.bottom;
- },
- getCenterPoint: function() {
- var model = this._model;
- return {
- x: (model.right + model.left) / 2,
- y: (model.bottom + model.top) / 2
- };
- },
- getWidth: function() {
- var model = this._model;
- return Math.abs(model.right - model.left);
- },
- getHeight: function() {
- var model = this._model;
- return Math.abs(model.bottom - model.top);
- },
- getArea: function() {
- return this.getWidth() * this.getHeight();
- },
- draw: function() {
- var view = this._view;
- var ctx = this.chartInstance.chart.ctx;
-
- ctx.save();
-
- // Canvas setup
- ctx.beginPath();
- ctx.rect(view.clip.x1, view.clip.y1, view.clip.x2 - view.clip.x1, view.clip.y2 - view.clip.y1);
- ctx.clip();
-
- ctx.lineWidth = view.borderWidth;
- ctx.strokeStyle = view.borderColor;
- ctx.fillStyle = view.backgroundColor;
-
- // Draw
- var width = view.right - view.left,
- height = view.bottom - view.top;
- ctx.fillRect(view.left, view.top, width, height);
- ctx.strokeRect(view.left, view.top, width, height);
-
- ctx.restore();
- }
- });
-
- return BoxAnnotation;
-};
-
-},{"../helpers.js":5}],8:[function(require,module,exports){
-// Line Annotation implementation
-module.exports = function(Chart) {
- var chartHelpers = Chart.helpers;
- var helpers = require('../helpers.js')(Chart);
-
- var horizontalKeyword = 'horizontal';
- var verticalKeyword = 'vertical';
-
- var LineAnnotation = Chart.Annotation.Element.extend({
- setDataLimits: function() {
- var model = this._model;
- var options = this.options;
-
- // Set the data range for this annotation
- model.ranges = {};
- model.ranges[options.scaleID] = {
- min: options.value,
- max: options.endValue || options.value
- };
- },
- configure: function() {
- var model = this._model;
- var options = this.options;
- var chartInstance = this.chartInstance;
- var ctx = chartInstance.chart.ctx;
-
- var scale = chartInstance.scales[options.scaleID];
- var pixel, endPixel;
- if (scale) {
- pixel = helpers.isValid(options.value) ? scale.getPixelForValue(options.value) : NaN;
- endPixel = helpers.isValid(options.endValue) ? scale.getPixelForValue(options.endValue) : pixel;
- }
-
- if (isNaN(pixel)) {
- return;
- }
-
- var chartArea = chartInstance.chartArea;
-
- // clip annotations to the chart area
- model.clip = {
- x1: chartArea.left,
- x2: chartArea.right,
- y1: chartArea.top,
- y2: chartArea.bottom
- };
-
- if (this.options.mode == horizontalKeyword) {
- model.x1 = chartArea.left;
- model.x2 = chartArea.right;
- model.y1 = pixel;
- model.y2 = endPixel;
- } else {
- model.y1 = chartArea.top;
- model.y2 = chartArea.bottom;
- model.x1 = pixel;
- model.x2 = endPixel;
- }
-
- model.line = new LineFunction(model);
- model.mode = options.mode;
-
- // Figure out the label:
- model.labelBackgroundColor = options.label.backgroundColor;
- model.labelFontFamily = options.label.fontFamily;
- model.labelFontSize = options.label.fontSize;
- model.labelFontStyle = options.label.fontStyle;
- model.labelFontColor = options.label.fontColor;
- model.labelXPadding = options.label.xPadding;
- model.labelYPadding = options.label.yPadding;
- model.labelCornerRadius = options.label.cornerRadius;
- model.labelPosition = options.label.position;
- model.labelXAdjust = options.label.xAdjust;
- model.labelYAdjust = options.label.yAdjust;
- model.labelEnabled = options.label.enabled;
- model.labelContent = options.label.content;
-
- ctx.font = chartHelpers.fontString(model.labelFontSize, model.labelFontStyle, model.labelFontFamily);
- var textWidth = ctx.measureText(model.labelContent).width;
- var textHeight = ctx.measureText('M').width;
- var labelPosition = calculateLabelPosition(model, textWidth, textHeight, model.labelXPadding, model.labelYPadding);
- model.labelX = labelPosition.x - model.labelXPadding;
- model.labelY = labelPosition.y - model.labelYPadding;
- model.labelWidth = textWidth + (2 * model.labelXPadding);
- model.labelHeight = textHeight + (2 * model.labelYPadding);
-
- model.borderColor = options.borderColor;
- model.borderWidth = options.borderWidth;
- model.borderDash = options.borderDash || [];
- model.borderDashOffset = options.borderDashOffset || 0;
- },
- inRange: function(mouseX, mouseY) {
- var model = this._model;
-
- return (
- // On the line
- model.line &&
- model.line.intersects(mouseX, mouseY, this.getHeight())
- ) || (
- // On the label
- model.labelEnabled &&
- model.labelContent &&
- mouseX >= model.labelX &&
- mouseX <= model.labelX + model.labelWidth &&
- mouseY >= model.labelY &&
- mouseY <= model.labelY + model.labelHeight
- );
- },
- getCenterPoint: function() {
- return {
- x: (this._model.x2 + this._model.x1) / 2,
- y: (this._model.y2 + this._model.y1) / 2
- };
- },
- getWidth: function() {
- return Math.abs(this._model.right - this._model.left);
- },
- getHeight: function() {
- return this._model.borderWidth || 1;
- },
- getArea: function() {
- return Math.sqrt(Math.pow(this.getWidth(), 2) + Math.pow(this.getHeight(), 2));
- },
- draw: function() {
- var view = this._view;
- var ctx = this.chartInstance.chart.ctx;
-
- if (!view.clip) {
- return;
- }
-
- ctx.save();
-
- // Canvas setup
- ctx.beginPath();
- ctx.rect(view.clip.x1, view.clip.y1, view.clip.x2 - view.clip.x1, view.clip.y2 - view.clip.y1);
- ctx.clip();
-
- ctx.lineWidth = view.borderWidth;
- ctx.strokeStyle = view.borderColor;
-
- if (ctx.setLineDash) {
- ctx.setLineDash(view.borderDash);
- }
- ctx.lineDashOffset = view.borderDashOffset;
-
- // Draw
- ctx.beginPath();
- ctx.moveTo(view.x1, view.y1);
- ctx.lineTo(view.x2, view.y2);
- ctx.stroke();
-
- if (view.labelEnabled && view.labelContent) {
- ctx.beginPath();
- ctx.rect(view.clip.x1, view.clip.y1, view.clip.x2 - view.clip.x1, view.clip.y2 - view.clip.y1);
- ctx.clip();
-
- ctx.fillStyle = view.labelBackgroundColor;
- // Draw the tooltip
- chartHelpers.drawRoundedRectangle(
- ctx,
- view.labelX, // x
- view.labelY, // y
- view.labelWidth, // width
- view.labelHeight, // height
- view.labelCornerRadius // radius
- );
- ctx.fill();
-
- // Draw the text
- ctx.font = chartHelpers.fontString(
- view.labelFontSize,
- view.labelFontStyle,
- view.labelFontFamily
- );
- ctx.fillStyle = view.labelFontColor;
- ctx.textAlign = 'center';
- ctx.textBaseline = 'middle';
- ctx.fillText(
- view.labelContent,
- view.labelX + (view.labelWidth / 2),
- view.labelY + (view.labelHeight / 2)
- );
- }
-
- ctx.restore();
- }
- });
-
- function LineFunction(view) {
- // Describe the line in slope-intercept form (y = mx + b).
- // Note that the axes are rotated 90° CCW, which causes the
- // x- and y-axes to be swapped.
- var m = (view.x2 - view.x1) / (view.y2 - view.y1);
- var b = view.x1 || 0;
-
- this.m = m;
- this.b = b;
-
- this.getX = function(y) {
- // Coordinates are relative to the origin of the canvas
- return m * (y - view.y1) + b;
- };
-
- this.getY = function(x) {
- return ((x - b) / m) + view.y1;
- };
-
- this.intersects = function(x, y, epsilon) {
- epsilon = epsilon || 0.001;
- var dy = this.getY(x),
- dx = this.getX(y);
- return (
- (!isFinite(dy) || Math.abs(y - dy) < epsilon) &&
- (!isFinite(dx) || Math.abs(x - dx) < epsilon)
- );
- };
- }
-
- function calculateLabelPosition(view, width, height, padWidth, padHeight) {
- var line = view.line;
- var ret = {}, xa = 0, ya = 0;
-
- switch (true) {
- // top align
- case view.mode == verticalKeyword && view.labelPosition == "top":
- ya = padHeight + view.labelYAdjust;
- xa = (width / 2) + view.labelXAdjust;
- ret.y = view.y1 + ya;
- ret.x = (isFinite(line.m) ? line.getX(ret.y) : view.x1) - xa;
- break;
-
- // bottom align
- case view.mode == verticalKeyword && view.labelPosition == "bottom":
- ya = height + padHeight + view.labelYAdjust;
- xa = (width / 2) + view.labelXAdjust;
- ret.y = view.y2 - ya;
- ret.x = (isFinite(line.m) ? line.getX(ret.y) : view.x1) - xa;
- break;
-
- // left align
- case view.mode == horizontalKeyword && view.labelPosition == "left":
- xa = padWidth + view.labelXAdjust;
- ya = -(height / 2) + view.labelYAdjust;
- ret.x = view.x1 + xa;
- ret.y = line.getY(ret.x) + ya;
- break;
-
- // right align
- case view.mode == horizontalKeyword && view.labelPosition == "right":
- xa = width + padWidth + view.labelXAdjust;
- ya = -(height / 2) + view.labelYAdjust;
- ret.x = view.x2 - xa;
- ret.y = line.getY(ret.x) + ya;
- break;
-
- // center align
- default:
- ret.x = ((view.x1 + view.x2 - width) / 2) + view.labelXAdjust;
- ret.y = ((view.y1 + view.y2 - height) / 2) + view.labelYAdjust;
- }
-
- return ret;
- }
-
- return LineAnnotation;
-};
-
-},{"../helpers.js":5}]},{},[6]); \ No newline at end of file