/*
* niViz -- snow profiles visualization
* Copyright (C) 2015 WSL/SLF - Fluelastrasse 11 - 7260 Davos Dorf - Switzerland.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
(function (niviz, moment) {
'use strict';
// --- Module Dependencies ---
var Graph = niviz.Graph;
var Common = niviz.Common;
var Cartesian = niviz.Cartesian;
var BarGraph = niviz.BarGraph;
var t = niviz.Translate.gettext;
var hsgrid = niviz.Grid.hsgrid;
var extend = niviz.util.extend;
/** @module niviz */
/**
* Visualization of a singular snow profile SLF style with an additional
* visualization of the structure profile according to Monti et Schweizer
* "Snow profile visualisations to highlight structural instability
* conditions" (2013). A miniature version exists which may be used in
* combination with a timeline graph.
*
* @class StructureProfile
* @constructor
* @extends SLFProfile
*
* @param {Station} station A niViz station object
* @param {Object} canvas A svg element that will be used as SnapSVG paper
* @param {Object} properties
*/
function StructureProfile (station, canvas, properties) {
StructureProfile.uber.call(this, station, canvas, properties);
extend(this.properties, properties);
this.draw(station.current || station.profiles[station.profiles.length - 1]);
var self = this;
station.emitter.on('profile', function (object) {
self.draw(object);
});
}
Graph.implement(StructureProfile, 'StructureProfile', 'profile', 'SLFProfile');
/**
* Deregister events
* @method destroy
*/
StructureProfile.prototype.destroy = function () {
this.station.emitter.off('profile');
};
/**
* Overwrite current properties with the ones passed as parameter.
*
* @method setProperties
* @param {Object} properties
*/
StructureProfile.prototype.setProperties = function (properties) {
extend(this.properties, properties);
this.draw(this.profile);
};
/**
* Configure all properties and axes dependent on canvas size and whether
* the graph shall be used in miniature or normal mode.
*
* @method configure
* @private
*/
StructureProfile.prototype.configure = function () {
var p = this.properties, hsmin, hsmax, pchange = false;
if (this.hsgrid) {
hsmin = this.hsgrid.min;
hsmax = this.hsgrid.max;
}
p.height = this.canvas.height();
p.width = this.canvas.width();
if (p.miniature) {
this.miniconfig();
this.left = 0;
} else {
this.hsgrid = hsgrid(this.station, p.table.max, p.table.min, false);
this.left = p.width - 400;
}
this.cart = 100;
this.right = p.width - 4 * p.fontsize;
this.cartesian.addx('flags', 0, 7, this.right - this.cart, this.left + 2 * p.fontsize);
if (hsmin !== this.hsgrid.min || hsmax !== this.hsgrid.max) pchange = true;
if (!this.bargraph || pchange) {
this.setbarcfg();
if (!this.bargraph) this.bargraph = new BarGraph(this.paper, this.barcfg);
else this.bargraph.reconfigure(this.barcfg);
}
};
/**
* Configure bargraph properties.
* @method setbarcfg
* @private
*/
StructureProfile.prototype.setbarcfg = function () {
var p = this.properties;
this.barcfg = {
font: p.font,
fontsize: p.fontsize,
grid_color: p.grid_color,
cartesian: this.cartesian,
valuefunc: valuefunc,
primary: {
lbl: t('Structure index'), pos: 'bottom',
min: 0, max: 7, inc: 1, axis: 'flags'
},
showdate: p.miniature,
hs : this.hsgrid,
bars: {x: 'flags', y: 'hs'},
top: p.table ? p.table.top : this.top,
left: this.left,
right: this.right,
height: p.table ? p.height - p.table.top - p.table.bottom : this.height,
cart: this.cart,
canvas: this.canvas,
callbacks: [{
f: this.arrow,
param: ['flags', 'arrow']
}]
};
};
/**
* Configure parameters for miniature mode.
* @method miniconfig
* @private
*/
StructureProfile.prototype.miniconfig = function () {
var p = this.properties;
p.grid_color = '#000';//'#707070';
p.fontsize = 14;
p.font = {
fontSize: p.fontsize + 'px',
textAnchor: 'middle',
fontFamily: 'LatoWeb, Helvetica, Arial'
};
this.top = 3 * p.fontsize;
this.bottom = p.height - 3 * p.fontsize;
this.height = p.height - 6 * p.fontsize;
if (!this.cartesian) {
this.cartesian = new Cartesian();
this.hsgrid = hsgrid(this.station, null, null, Common.defaults.autoscale);
this.cartesian.addy('hs', this.hsgrid.min, this.hsgrid.max, this.bottom, this.top);
}
if (!this.paper) this.paper = Snap(this.canvasnode);
};
/**
* Callback for BarGraph. Draw the red arrows to highlight instable structures.
*
* @method arrow
* @private
* @param {String} feature
* @param {String} type
*/
StructureProfile.prototype.arrow = function (feature, type) {
feature = this.profile[feature];
if (this.elements[type]) this.elements[type].remove();
if (!feature) return;
var ii = 0, paper = this.paper, set = paper.g(), origin = this.coord(0, 0);
for ( ; ii < feature.layers.length; ++ii) {
if (feature.layers[ii].value.sum < 5) continue;
if (!this.bars[ii]) continue;
var y = this.bars[ii].center, x = origin.x + 3;
set.add(paper.line(this.properties.xright, y, x, y));
set.add(paper.polygon(x, y, x + 10, y - 5, x + 10, y + 5, x, y));
}
set.attr({
'fill' : '#D00',
'stroke': '#D00',
'arrow-end': 'block-wide-long',
'stroke-width': 3
});
this.elements[type] = set;
};
var valuefunc = function (value) {
return 7 - value.value.sum;
};
/**
* Draw the StructureProfile by drawing the bargraph.
*
* @method draw
* @param {Profile} profile The niViz profile to render
*/
StructureProfile.prototype.draw = function (profile) {
var p = this.properties;
if (profile) this.profile = profile;
if (!p.miniature) { // draw the full SLFProfile AND the StructureProfile
StructureProfile.uber.prototype.draw.call(this, profile);
this.canvas.width(this.canvas.width() + 400);
p.width = this.canvas.width();
this.paper.attr({ width: p.width + 'px', height: p.height + 'px' });
}
this.configure();
this.bargraph.draw(profile);
};
// --- Helpers ---
// --- Module Exports ---
niviz.StructureProfile = StructureProfile;
}(niviz, moment));