UNPKG

psychart

Version:

View air conditions on a psychrometric chart

192 lines (191 loc) 7.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Chart = void 0; /** * Represents a generic SVG chart to be inherited by another class. */ var Chart = /** @class */ (function () { /** * Create a new instance of this chart. * @param options Supply some options to customize this chart. * @param defaults Supply all default options for this chart. */ function Chart(options, defaults) { /** * SVG Namespace URI */ this.NS = 'http://www.w3.org/2000/svg'; // Set the unique ID for this chart this.id = Chart.id_count++; // Set the default options this.options = Chart.setDefaults(options, defaults); // Create the base elements this.base = document.createElement('div'); this.svg = document.createElementNS(this.NS, 'svg'); this.base.appendChild(this.svg); // Set the size of the SVG element. this.svg.setAttribute('viewBox', '0 0 ' + this.options.size.x + ' ' + this.options.size.y); this.svg.setAttribute('width', this.options.size.x + 'px'); this.svg.setAttribute('height', this.options.size.y + 'px'); } /** * Produce a deep copy of an object. * @param obj Any object * @returns A deep copy of an object. */ Chart.deepCopy = function (obj) { return JSON.parse(JSON.stringify(obj)); }; /** * Take an object with all optional values, and set all unset values to their defaults. * @param options An object with all parameters optional. * @param defaults An object with all parameters default. * @returns An object with all parameters that are unset as their default values. */ Chart.setDefaults = function (options, defaults) { var _a; var required = Chart.deepCopy(defaults); for (var key in defaults) { required[key] = (_a = options[key]) !== null && _a !== void 0 ? _a : defaults[key]; } return required; }; /** * Remove all the children from a parent element. * @param parent Any element to clear the children of */ Chart.clearChildren = function (parent) { while (parent.firstChild) { parent.removeChild(parent.firstChild); } }; /** * Generate a text element to append onto a parent element. * @param content The contents of the text element * @param location The location of the text element, in pixels * @param color The fill color of the text * @param anchor How the text is anchored relative to its location * @returns A `<text>` element */ Chart.prototype.createLabel = function (content, location, color, anchor) { var text = document.createElementNS(this.NS, 'text'); var padding = this.options.font.size / 2; text.textContent = content; text.setAttribute('fill', color.toString()); text.setAttribute('font-family', this.options.font.name); text.setAttribute('font-size', this.options.font.size + 'px'); /** * Shorthand to set all alignment properties for the text element */ function setProps(xPad, yPad, textAnchor, dominantBaseline) { // Use the `x`, `y`, `text-anchor`, and `dominant-baseline` properties to set the text anchor text.setAttribute('x', (location.x + xPad * padding) + 'px'); text.setAttribute('y', (location.y + yPad * padding) + 'px'); text.setAttribute('text-anchor', textAnchor); text.setAttribute('dominant-baseline', dominantBaseline); } switch (anchor) { case (0 /* TextAnchor.C */): { setProps(0, 0, 'middle', 'middle'); break; } case (1 /* TextAnchor.NW */): { setProps(1, 1, 'start', 'hanging'); break; } case (2 /* TextAnchor.N */): { setProps(0, 1, 'middle', 'hanging'); break; } case (3 /* TextAnchor.NE */): { setProps(-1, 1, 'end', 'hanging'); break; } case (4 /* TextAnchor.E */): { setProps(-1, 0, 'end', 'middle'); break; } case (5 /* TextAnchor.SE */): { setProps(-1, -1, 'end', 'alphabetic'); break; } case (6 /* TextAnchor.S */): { setProps(0, -1, 'middle', 'alphabetic'); break; } case (7 /* TextAnchor.SW */): { setProps(1, -1, 'start', 'alphabetic'); break; } case (8 /* TextAnchor.W */): { setProps(1, 0, 'start', 'middle'); break; } default: { throw new Error("Text anchor ".concat(anchor, " is invalid!")); } } return text; }; /** * Draw a tooltip onto the chart. * @param content The text content of the tooltip * @param location The position of the tooltip * @param color The background color * @param parent The element to append onto */ Chart.prototype.drawTooltip = function (content, location, color, parent) { var _this = this; var base = document.createElementNS(this.NS, 'g'); var back = document.createElementNS(this.NS, 'rect'); var lines = content.split('\n').map(function (line, i) { return _this.createLabel(line, { x: 0, y: i * _this.options.font.size }, color.getContrastingColor(), 1 /* TextAnchor.NW */); }); // Append elements to the base & parent (required to compute line width) base.appendChild(back); base.append.apply(base, lines); parent.append(base); // Split the text by line and compute the size of the tooltip based on maximum line width var padding = this.options.font.size * 0.4; var width = Math.max.apply(Math, lines.map(function (line) { return line.getBBox().width; })) + padding * 2; var height = lines.length * this.options.font.size + padding * 2; // Compute the colors used in this tooltip var background = color.toString(); var foreground = color.getContrastingColor().toString(); // Create and define styling properties for the tooltip background back.setAttribute('stroke', foreground); back.setAttribute('fill', background); back.setAttribute('x', '0'); back.setAttribute('y', '0'); back.setAttribute('width', width + 'px'); back.setAttribute('height', height + 'px'); back.setAttribute('rx', padding + 'px'); back.setAttribute('stroke-width', '1px'); // Adjust the position if the background is out-of-bounds var dx = 0, dy = 0; if (location.x + width + padding > this.options.size.x) { dx = -(width + padding); } else { dx = padding; } if (location.y + height + padding > this.options.size.y) { dy = -(height + padding); } else { dy = padding; } base.setAttribute('transform', 'translate(' + (location.x + dx) + ',' + (location.y + dy) + ')'); }; /** * Return the base `<div>` element for this chart to append on the parent. * @returns The base element. */ Chart.prototype.getElement = function () { return this.base; }; /** * Initialization counter for any chart */ Chart.id_count = 0; return Chart; }()); exports.Chart = Chart;