/*! * 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] );