/* * This file is part of Toolkit. * * Toolkit is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * Toolkit is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU General * Public License along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ "use strict"; (function(w, TK){ function _get_coords_single(deg, inner, pos) { deg = deg * Math.PI / 180; return { x: Math.cos(deg) * inner + pos, y: Math.sin(deg) * inner + pos } } var format_translate = TK.FORMAT("translate(%f, %f)"); var format_viewbox = TK.FORMAT("0 0 %d %d"); /** * TK.Gauge draws a single {@link TK.Circular} into a SVG image. It inherits * all options of {@link TK.Circular}. * * @class TK.Gauge * * @extends TK.Widget * * @param {Object} [options={ }] - An object containing initial options. * * @property {Number} [options.x=0] - Displacement of the {@link TK.Circular} * in horizontal direction. This allows drawing gauges which are only * represented by a segment of a circle. * @property {Number} [options.y=0] - Displacement of the {@link TK.Circular} * in vertical direction. * @property {Object} [options.title] - Optional gauge title. * @property {Number} [options.title.pos] - Position inside of the circle in * degrees. * @property {String} [options.title.title] - Title string. * @property {Number} [options.title.margin] - Margin of the title string. * @property {String} [options.title.align] - Alignment of the title, either * inner or outer. */ TK.Gauge = TK.class({ _class: "Gauge", Extends: TK.Widget, _options: Object.assign(Object.create(TK.Circular.prototype._options), { width: "number", height: "number", title: "object", }), options: Object.assign({}, TK.Circular.prototype.options, { width: 120, // width of the element height: 120, // height of the svg size: 120, title: {pos: 90, margin: 0, align: "inner", title:""} }), initialize: function (options) { if (typeof options.title === "string") options.title = {title: options.title}; TK.Widget.prototype.initialize.call(this, options); var O = this.options; var E, S; if (!(E = this.element)) this.element = E = TK.element("div"); /** * @member {SVGImage} TK.Gauge#svg - The main SVG image. */ this.svg = S = TK.make_svg("svg"); /** * @member {HTMLDivElement} TK.Gauge#element - The main DIV container. * Has class toolkit-gauge. */ TK.add_class(E, "toolkit-gauge"); this.widgetize(E, true, true, true); /** * @member {SVGText} TK.Gauge#_title - The title of the gauge. * Has class toolkit-title. */ this._title = TK.make_svg("text", {"class": "toolkit-title"}); S.appendChild(this._title); var co = TK.object_and(O, TK.Circular.prototype._options); co = TK.object_sub(co, TK.Widget.prototype._options); co.container = S; /** * @member {TK.Circular} TK.Gauge#circular - The {@link TK.Circular} module. */ this.circular = new TK.Circular(co); this.add_child(this.circular); this.widgetize(this.element); E.appendChild(S); }, resize: function() { TK.Widget.prototype.resize.call(this); this.invalid.title = true; this.trigger_draw(); }, redraw: function() { var I = this.invalid, O = this.options; var S = this.svg; TK.Widget.prototype.redraw.call(this); if (I.validate("width", "height")) { S.setAttribute("viewBox", format_viewbox(O.width, O.height)); } if (I.validate("title", "size", "x", "y")) { var _title = this._title; _title.textContent = O.title.title; if (O.title.title) { TK.S.add(function() { var t = O.title; var outer = O.size / 2; var margin = t.margin; var align = t.align === "inner"; var bb = _title.getBoundingClientRect(); var angle = t.pos % 360; var outer_p = outer - margin; var coords = _get_coords_single(angle, outer_p, outer); var mx = ((coords.x - outer) / outer_p) * (bb.width + bb.height / 2.5) / (align ? -2 : 2); var my = ((coords.y - outer) / outer_p) * bb.height / (align ? -2 : 2); mx += O.x; my += O.y; TK.S.add(function() { _title.setAttribute("transform", format_translate(coords.x + mx, coords.y + my)); _title.setAttribute("text-anchor", "middle"); }.bind(this), 1); /** * Is fired when the title changed. * * @event TK.Gauge#titledrawn */ this.fire_event("titledrawn"); }.bind(this)); } } }, // GETTERS & SETTERS set: function (key, value) { if (key === "title") { if (typeof value === "string") value = {title: value}; value = Object.assign(this.options.title, value); } // TK.Circular does the snapping if (!TK.Widget.prototype._options[key] && TK.Circular.prototype._options[key]) value = this.circular.set(key, value); return TK.Widget.prototype.set.call(this, key, value); } }); })(this, this.TK);