/* * 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 calculate_grid(range, step) { var min = range.get("min"); var max = range.get("max"); var grid = []; var i, cls; for (i = min; i <= max; i += step) { if (i == 0) { cls = "toolkit-highlight"; } else { cls = ""; } grid.push({ pos: i, label: i === min ? "" : i + "dB", "class": cls }); } return grid; } TK.FrequencyResponse = TK.class({ /** * TK.FrequencyResponse is a {@link TK.Chart} drawing frequencies on the x axis and dB * values on the y axis. This widget automatically draws a {@link TK.Grid} depending * on the ranges. * * @class TK.FrequencyResponse * * @extends TK.Chart * * @param {Object} [options={ }] - An object containing initial options. * * @property {Number} [options.db_grid=12] - Distance in decibels between y axis grid lines. * @property {Object} [options.range_x={min:20, max:20000, scale:"frequency"}] - Either a function returning a {@link TK.Range} * or an object containing options for a new {@link TK.Range} * @property {Object} [options.range_y={min:-36, max: 36, scale: "linear"}] - Either a function returning a {@link TK.Range} * or an object containing options for a new {@link TK.Range} * @property {Array} [options.grid_x=[{pos: 20, label: "20 Hz"}, {pos: 30}, {pos: 40}, {pos: 50}, {pos: 60}, {pos: 70}, {pos: 80}, {pos: 90}, {pos: 100, label: "100 Hz"}, {pos: 200}, {pos: 300}, {pos: 400}, {pos: 500}, {pos: 600}, {pos: 700}, {pos: 800}, {pos: 900}, {pos: 1000, label: "1000 Hz"}, {pos: 2000}, {pos: 3000}, {pos: 4000}, {pos: 5000}, {pos: 6000}, {pos: 7000}, {pos: 8000}, {pos: 9000}, {pos: 10000, label: "10000 Hz"}, {pos: 20000, label: "20000 Hz"}]] - An array containing objects with the following optional members: * @property {Number} [options.grid_x.pos] - The value where to draw grid line and corresponding label. * @property {String} [options.grid_x.color] - A valid CSS color string to colorize the elements. * @property {String} [options.grid_x.class] - A class name for the elements. * @property {String} [options.grid_x.label] - A label string. * @property {String} [options.scale="linear"] - The type of the decibels scale. See {@link TK.Range} for more details. * @property {Number} [options.depth=0] - The depth of the z axis (basis of options.range_z) */ _class: "FrequencyResponse", Extends: TK.Chart, _options: Object.assign(Object.create(TK.Chart.prototype._options), { db_grid: "number", grid_x: "array", scale: "boolean", depth: "number", }), options: { db_grid: 12, // dB grid distance range_x: {min:20, max:20000, scale:"frequency"}, // TK.Range x options range_y: {min:-36, max: 36, scale: "linear"}, // TK.Range y options range_z: {min:0.1, max:10, scale:"linear"}, grid_x: [ {pos: 20, label: "20Hz"}, {pos: 30}, {pos: 40}, {pos: 50}, {pos: 60}, {pos: 70}, {pos: 80}, {pos: 90}, {pos: 100, label: "100Hz"}, {pos: 200}, {pos: 300}, {pos: 400}, {pos: 500}, {pos: 600}, {pos: 700}, {pos: 800}, {pos: 900}, {pos: 1000, label: "1kHz"}, {pos: 2000}, {pos: 3000}, {pos: 4000}, {pos: 5000}, {pos: 6000}, {pos: 7000}, {pos: 8000}, {pos: 9000}, {pos: 10000, label: "10kHz"}, {pos: 20000, label: "20kHz"}], // Frequency grid scale: false, // the mode of the // dB scale depth: 0, // the depth of the z axis (basis of range_z) }, static_events: { set_scale: function(value, key) { this.range_y.set("scale", value); }, set_db_grid: function(value) { this.set("grid_y", calculate_grid(this.range_y, value)); }, }, initialize: function (options) { if (options.scale) this.set("scale", options.scale, true); TK.Chart.prototype.initialize.call(this, options); /** * @member {HTMLDivElement} TK.FrequencyResponse#element - The main DIV container. * Has class toolkit-frequency-response. */ TK.add_class(this.element, "toolkit-frequency-response"); /** * @member {SVGGroup} TK.Chart#_handles - The SVG group containing all handles. * Has class toolkit-response-handles. */ TK.add_class(this._handles, "toolkit-response-handles"); // do not overwrite custom grids, please if (this.options.db_grid && !this.options.grid_y.length) this.set("db_grid", this.options.db_grid); this.range_y.add_event("set", function (key, value) { if (key === "scale") this.options.scale = value; }.bind(this)); if (this.options.depth) this.set("depth", this.options.depth); }, redraw: function() { var I = this.invalid; var O = this.options; if (I.scale) { I.scale = false; // tell chart to redraw I.ranges = true; } TK.Chart.prototype.redraw.call(this); }, }); })(this, this.TK);