diff --git a/README.md b/README.md
index 3cb2cc8..4040d48 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,8 @@ without the workload of running a server, installing and maintaining software an
the professional concepts of GIS.
## Status
-* The first version of the library was released on the 31st of March 2016
+* The first (1.0) version of the library was released on the 31st of March 2016
+* The seconc (2.0) version of the library was released on the 20th of March 2017
* The library is under still under active development and we advise users to check out the develop branch for the latest features
* New releases with incremental functionality are frequent at this stage
diff --git a/dist/s4a.js b/dist/s4a.js
index c752ee3..6edcead 100644
--- a/dist/s4a.js
+++ b/dist/s4a.js
@@ -1,6 +1,6 @@
-/*! s4a - v1.0.0 - 2016-05-06
+/*! s4a - v1.0.0 - 2017-04-03
* https://github.com/SDI4Apps/s4a.js
-* Copyright (c) 2016 SDI4Apps Partnership; Licensed */
+* Copyright (c) 2017 SDI4Apps Partnership; Licensed */
'use strict';
/**
@@ -295,6 +295,11 @@ s4a.analytics.Routing = (function() {
s4a.extend('data');
+/**
+ * SensLog communication object
+ *
+ * @class
+ */
s4a.data.SensLog = (function() {
/**
* Class with methods to interact with SensLog
@@ -1135,7 +1140,7 @@ s4a.map.MapHelper = function(nodeSelector, config) {
var _map = new ol.Map({
layers: [
- _config.baseMaps.OFFLINE
+ _config.baseMaps.MAPQUEST
],
target: nodeSelector,
view: new ol.View({
@@ -1507,50 +1512,6 @@ s4a.map.VizLayer = function() {
};
-'use strict';
-
-s4a.extend('mobile');
-
-s4a.mobile.FeatureSync = (function() {
-
- /**
- * [module description]
- * @exports s4a.mobile.FeatureSync
- */
- var module = {};
-
- /**
- * Check out a portion of a feature layer
- */
- module.CheckOut = function() {
-
- };
-
- /**
- * Check in an edited feature layer
- */
- module.CheckIn = function() {
-
- };
-
- /**
- * Get conflicts if any for a featyre layer
- */
- module.GetConflicts = function() {
-
- };
-
- /**
- * Resolve conflict
- */
- module.Resolve = function() {
-
- };
-
- return module;
-
-}());
-
/* global s4a, LocalFileSystem */
'use strict';
@@ -1621,7 +1582,8 @@ s4a.mobile.File = (function() {
};
fileWriter.onerror = function(e) {
- promise.resolve(s4a.mobile.FileResponse.createError(e.toString()));
+ promise.resolve(s4a.mobile.FileResponse
+ .createError('Error writing file: ' + e.toString()));
};
var blob = new Blob([JSON.stringify(contents, null, '\t')], {type: 'text/plain'});
@@ -1629,7 +1591,8 @@ s4a.mobile.File = (function() {
});
} else {
- promise.resolve(s4a.mobile.FileResponse.createError(fileResponse.messages));
+ promise.resolve(s4a.mobile.FileResponse
+ .createError('Error getting file entry: ' + fileResponse.messages));
}
});
@@ -1869,6 +1832,50 @@ s4a.mobile.OfflineTileLayer.clearBaseMapCache = function(baseMapId) {
};
+'use strict';
+
+s4a.extend('mobile');
+
+s4a.mobile.FeatureSync = (function() {
+
+ /**
+ * [module description]
+ * @exports s4a.mobile.FeatureSync
+ */
+ var module = {};
+
+ /**
+ * Check out a portion of a feature layer
+ */
+ module.CheckOut = function() {
+
+ };
+
+ /**
+ * Check in an edited feature layer
+ */
+ module.CheckIn = function() {
+
+ };
+
+ /**
+ * Get conflicts if any for a featyre layer
+ */
+ module.GetConflicts = function() {
+
+ };
+
+ /**
+ * Resolve conflict
+ */
+ module.Resolve = function() {
+
+ };
+
+ return module;
+
+}());
+
'use strict';
s4a.extend('viz');
@@ -2529,75 +2536,336 @@ s4a.viz.Legend = function(chartConfig) {
'use strict';
/**
- * Pie visualization
- *
- * @param {s4a.viz.ViewCoordinator} viewCoordinator
- * @param {s4a.viz.ChartConfig} mChartConfig
- * @constructor
+ * Enumeration of size-scales
+ * @readonly
+ * @enum {number}
*/
-s4a.viz.Pie = function(viewCoordinator, mChartConfig) {
- var chartData, currentData, currentScale, scale, arc, bigArc;
- var _self = this;
- var transitionTime = 400;
-
+s4a.viz.Sizes = {
/**
- * Internal reference to Pie svg element.
- * Use getSvg to retrieve it
- *
- * @private
+ * From 5px to 19px
+ * @type Array
*/
- var svg = d3.select(document.createElementNS(d3.ns.prefix.svg, 'svg'));
-
- function changeCollapsedState(collapsed) {
- currentScale = collapsed ? scale : 1;
-
- var featureWidth = mChartConfig.width * currentScale;
- var featureHeight = mChartConfig.height * currentScale;
- var g = svg.selectAll('g');
-
- if (currentScale === 1) {
- svg.attr('width', featureWidth)
- .attr('height',featureHeight);
-
- $(_self).trigger('resize');
+ 'small': ['5', '7', '9', '11', '13', '15', '17', '19'],
+ /**
+ * From 10px to 50px
+ * @type Array
+ */
+ 'medium': ['10', '15', '25', '30', '35', '40', '45', '50'],
+ /**
+ * From 10px to 80px
+ * @type Array
+ */
+ 'large': ['10', '20', '30', '40', '50', '60', '70', '80']
+};
- g.attr('transform', 'translate(' + featureWidth / 2 + ',' + featureHeight / 2 + ')');
+/**
+ * Enumeration for font sizes
+ * @readonly
+ * @enum {number}
+ */
+s4a.viz.FontSizes = {
+ /**
+ * Small font size
+ * @type Number
+ */
+ 'small': 10,
+ /**
+ * The default font size
+ * @type Number
+ */
+ 'normal': 12,
+ /**
+ * A bigger font-size
+ * @type Number
+ */
+ 'medium': 14,
+ /**
+ * Large font-size
+ * @type Number
+ */
+ 'large': 18
+};
- svg.selectAll('path')
- .transition()
- .duration(transitionTime)
- .attr('d', currentScale === 1 ? bigArc : arc);
- } else {
- svg.selectAll('path')
- .transition()
- .duration(transitionTime)
- .attr('d', currentScale === 1 ? bigArc : arc);
+'use strict';
+/* global s4a */
- setTimeout(function() {
- svg.attr('width', featureWidth)
- .attr('height',featureHeight);
+/**
+ * A top level object that coordinates data and visualizations
+ *
+ * @param {Object} pData
+ * @constructor
+ * @returns {s4a.viz.ViewCoordinator}
+ */
+s4a.viz.ViewCoordinator = function(pData) {
- $(_self).trigger('resize');
+ var _data = pData;
+ var _listeners = [];
+ var _self = {};
- g.attr('transform', 'translate(' + featureWidth / 2 + ',' + featureHeight / 2 + ')');
+ /**
+ * Subscribes an object to publish events from the ViewCoordinator
+ *
+ * @returns {s4a.viz.ViewCoordinator}
+ */
+ _self.publish = function() {
+ for (var i = 0; i < _listeners.length; i++) {
+ var listener = _listeners[i];
+ if (listener.update) {
+ listener.update(_data);
+ console.info('Published ' + i);
+ } else {
+ console.debug('Subscribed object ' + i + ' does not implement the update interface',
+ listener);
+ }
+ }
+ return _self;
+ };
- }, transitionTime);
+ /**
+ * Update the data object
+ *
+ * @param {Object} pData
+ * @returns {s4a.viz.ViewCoordinator}
+ */
+ _self.setData = function(pData) {
+ _data = pData;
+ _self.publish();
+ return _self;
+ };
+ /**
+ * Subscribe an object to the ViewCoordinator
+ *
+ * @param {Object} pObj
+ * @returns {s4a.viz.ViewCoordinator}
+ */
+ _self.subscribe = function(pObj) {
+ if (_listeners.indexOf(pObj) < 0) {
+ _listeners.push(pObj);
}
- }
+ return _self;
+ };
/**
- * Create new pie chart
+ * Unsubscribe an object from the ViewCoordinator
*
- * @param {integer} width optional width of svg
- * @param {integer} height optional height of svg
- * @private
+ * @param {Object} pObj
+ * @returns {s4a.viz.ViewCoordinator}
*/
- function updateChart(width, height) {
- // pick the first series
- currentData = chartData.series[0].values;
+ _self.unsubscribe = function(pObj) {
+ var _modListeners = [];
+ for (var i = 0; i < _listeners.length; i++) {
+ if (_listeners[i] !== pObj) {
+ _modListeners.push(_listeners[i]);
+ }
+ }
+ _listeners = _modListeners;
+ return _self;
+ };
- // and the first color
+ _self.applyFilter = function() {
+ _self.publish();
+ return _self;
+ };
+
+ return _self;
+
+};
+
+'use strict';
+/* global s4a */
+
+/**
+ *
This is an abstract top-level object that coordinates data and visualizations
+ * that take part in a coordinated view
+ *
+ * Any visualization object must implement an interface that contains the methods
+ * update and filter
+ *
+ * The object receives as part of the constructor a ViewCoordinator object
+ * that implicitly contains data
+ *
+ * The object receives as part of the constructor a DOMElement identified by its
+ * ID, typically i DIV in which it is to be drawn
+ *
+ * @abstract
+ * @constructor
+ * @param {s4a.viz.ViewCoordinator} viewCoordinator
+ * @param {DOMElement} domElement
+ * @returns {s4a.viz.VizObj}
+ */
+s4a.viz.VizObj = function(viewCoordinator, domElement) {
+ var _self = this;
+
+ viewCoordinator.subscribe(_self);
+
+ /**
+ * Update the visualization
+ *
+ * @abstract
+ */
+ _self.update = function() {
+ throw new Error('Must be implemented by sub-class');
+ };
+
+ /**
+ * Apply a filter to the visualization
+ *
+ * @abstract
+ */
+ _self.filter = function(filter) {
+ throw new Error('Must be implemented by sub-class');
+ };
+
+ _self.get = function() {
+ throw new Error('Must be implemented by sub-class');
+ };
+};
+
+'use strict';
+/* global s4a */
+
+/**
+ * Enumeration
+ *
+ * @enum {number}
+ * @readonly
+ */
+s4a.viz.VizType = {
+ /**
+ * Chart
+ */
+ CHART: 1,
+
+ /**
+ * Map
+ */
+ MAP: 2
+};
+
+'use strict';
+s4a.extend('viz.chart');
+
+/**
+ * Create a new Bar chart object
+ *
+ * @class
+ * @classdesc
+ * Bar chart object
+ */
+s4a.viz.chart.Bar = function() {
+
+};
+
+'use strict';
+/**
+ * Create a new bubble chart object
+ *
+ * @class
+ * @classdesc
+ * Stacked bubble chart object
+ */
+s4a.viz.chart.Bubble = function() {
+
+};
+
+'use strict';
+/**
+ * Create a new row chart object
+ *
+ * @class
+ * @classdesc
+ * Row chart object
+ */
+s4a.viz.chart.Row = function() {
+
+};
+
+'use strict';
+s4a.extend('viz.chart');
+
+/**
+ * Create a new line chart object
+ *
+ * @class
+ * @classdesc
+ * Bar line chart object
+ */
+s4a.viz.chart.Line = function() {
+
+};
+
+'use strict';
+/**
+ * Pie visualization
+ *
+ * @param {s4a.viz.ViewCoordinator} viewCoordinator
+ * @param {s4a.viz.ChartConfig} mChartConfig
+ * @constructor
+ */
+s4a.viz.Pie = function(viewCoordinator, mChartConfig) {
+ var chartData, currentData, currentScale, scale, arc, bigArc;
+ var _self = this;
+ var transitionTime = 400;
+
+ /**
+ * Internal reference to Pie svg element.
+ * Use getSvg to retrieve it
+ *
+ * @private
+ */
+ var svg = d3.select(document.createElementNS(d3.ns.prefix.svg, 'svg'));
+
+ function changeCollapsedState(collapsed) {
+ currentScale = collapsed ? scale : 1;
+
+ var featureWidth = mChartConfig.width * currentScale;
+ var featureHeight = mChartConfig.height * currentScale;
+ var g = svg.selectAll('g');
+
+ if (currentScale === 1) {
+ svg.attr('width', featureWidth)
+ .attr('height',featureHeight);
+
+ $(_self).trigger('resize');
+
+ g.attr('transform', 'translate(' + featureWidth / 2 + ',' + featureHeight / 2 + ')');
+
+ svg.selectAll('path')
+ .transition()
+ .duration(transitionTime)
+ .attr('d', currentScale === 1 ? bigArc : arc);
+ } else {
+ svg.selectAll('path')
+ .transition()
+ .duration(transitionTime)
+ .attr('d', currentScale === 1 ? bigArc : arc);
+
+ setTimeout(function() {
+ svg.attr('width', featureWidth)
+ .attr('height',featureHeight);
+
+ $(_self).trigger('resize');
+
+ g.attr('transform', 'translate(' + featureWidth / 2 + ',' + featureHeight / 2 + ')');
+
+ }, transitionTime);
+
+ }
+ }
+
+ /**
+ * Create new pie chart
+ *
+ * @param {integer} width optional width of svg
+ * @param {integer} height optional height of svg
+ * @private
+ */
+ function updateChart(width, height) {
+ // pick the first series
+ currentData = chartData.series[0].values;
+
+ // and the first color
var colors = s4a.viz.color[mChartConfig.colors[0]][currentData.length];
mChartConfig.height = mChartConfig.height || mChartConfig.width;
@@ -2737,260 +3005,51 @@ s4a.viz.Pie = function(viewCoordinator, mChartConfig) {
'use strict';
/**
- * Enumeration of size-scales
- * @readonly
- * @enum {number}
- */
-s4a.viz.Sizes = {
- /**
- * From 5px to 19px
- * @type Array
- */
- 'small': ['5', '7', '9', '11', '13', '15', '17', '19'],
- /**
- * From 10px to 50px
- * @type Array
- */
- 'medium': ['10', '15', '25', '30', '35', '40', '45', '50'],
- /**
- * From 10px to 80px
- * @type Array
- */
- 'large': ['10', '20', '30', '40', '50', '60', '70', '80']
-};
-
-/**
- * Enumeration for font sizes
- * @readonly
- * @enum {number}
- */
-s4a.viz.FontSizes = {
- /**
- * Small font size
- * @type Number
- */
- 'small': 10,
- /**
- * The default font size
- * @type Number
- */
- 'normal': 12,
- /**
- * A bigger font-size
- * @type Number
- */
- 'medium': 14,
- /**
- * Large font-size
- * @type Number
- */
- 'large': 18
-};
-
-'use strict';
-/* global s4a */
-
-/**
- * A top level object that coordinates data and visualizations
- *
- * @param {Object} pData
- * @constructor
- * @returns {s4a.viz.ViewCoordinator}
- */
-s4a.viz.ViewCoordinator = function(pData) {
-
- var _data = pData;
- var _listeners = [];
- var _self = {};
-
- /**
- * Subscribes an object to publish events from the ViewCoordinator
- *
- * @returns {s4a.viz.ViewCoordinator}
- */
- _self.publish = function() {
- for (var i = 0; i < _listeners.length; i++) {
- var listener = _listeners[i];
- if (listener.update) {
- listener.update(_data);
- console.info('Published ' + i);
- } else {
- console.debug('Subscribed object ' + i + ' does not implement the update interface',
- listener);
- }
- }
- return _self;
- };
-
- /**
- * Update the data object
- *
- * @param {Object} pData
- * @returns {s4a.viz.ViewCoordinator}
- */
- _self.setData = function(pData) {
- _data = pData;
- _self.publish();
- return _self;
- };
-
- /**
- * Subscribe an object to the ViewCoordinator
- *
- * @param {Object} pObj
- * @returns {s4a.viz.ViewCoordinator}
- */
- _self.subscribe = function(pObj) {
- if (_listeners.indexOf(pObj) < 0) {
- _listeners.push(pObj);
- }
- return _self;
- };
-
- /**
- * Unsubscribe an object from the ViewCoordinator
- *
- * @param {Object} pObj
- * @returns {s4a.viz.ViewCoordinator}
- */
- _self.unsubscribe = function(pObj) {
- var _modListeners = [];
- for (var i = 0; i < _listeners.length; i++) {
- if (_listeners[i] !== pObj) {
- _modListeners.push(_listeners[i]);
- }
- }
- _listeners = _modListeners;
- return _self;
- };
-
- _self.applyFilter = function() {
- _self.publish();
- return _self;
- };
-
- return _self;
-
-};
-
-'use strict';
-/* global s4a */
-
-/**
- * This is an abstract top-level object that coordinates data and visualizations
- * that take part in a coordinated view
- *
- * Any visualization object must implement an interface that contains the methods
- * update and filter
- *
- * The object receives as part of the constructor a ViewCoordinator object
- * that implicitly contains data
- *
- * The object receives as part of the constructor a DOMElement identified by its
- * ID, typically i DIV in which it is to be drawn
- *
- * @abstract
- * @constructor
- * @param {s4a.viz.ViewCoordinator} viewCoordinator
- * @param {DOMElement} domElement
- * @returns {s4a.viz.VizObj}
- */
-s4a.viz.VizObj = function(viewCoordinator, domElement) {
- var _self = this;
-
- viewCoordinator.subscribe(_self);
-
- /**
- * Update the visualization
- *
- * @abstract
- */
- _self.update = function() {
- throw new Error('Must be implemented by sub-class');
- };
-
- /**
- * Apply a filter to the visualization
- *
- * @abstract
- */
- _self.filter = function(filter) {
- throw new Error('Must be implemented by sub-class');
- };
-
- _self.get = function() {
- throw new Error('Must be implemented by sub-class');
- };
-};
-
-'use strict';
-/* global s4a */
-
-/**
- * Enumeration
- *
- * @enum {number}
- * @readonly
- */
-s4a.viz.VizType = {
- /**
- * Chart
- */
- CHART: 1,
-
- /**
- * Map
- */
- MAP: 2
-};
-
-'use strict';
-s4a.extend('viz.chart');
-
-/**
- * Create a new Bar chart object
+ * Create a new Row chart object
*
* @class
* @classdesc
- * Bar chart object
+ * Row chart object
*/
-s4a.viz.chart.Bar = function() {
+s4a.viz.chart.Row = function() {
};
'use strict';
/**
- * Create a new Pie chart object
+ * Create a new Scatter chart object
*
* @class
* @classdesc
- * Pie chart object
+ * Scatter chart object
*/
-s4a.viz.chart.Pie = function() {
+s4a.viz.chart.Scatter = function() {
};
'use strict';
+s4a.extend('viz.chart');
+
/**
- * Create a new Row chart object
+ * Create a new stacked line chart object
*
* @class
* @classdesc
- * Row chart object
+ * Stacked line chart object
*/
-s4a.viz.chart.Row = function() {
+s4a.viz.chart.StackedLine = function() {
};
'use strict';
/**
- * Create a new Scatter chart object
+ * Create a new stacked row chart object
*
* @class
* @classdesc
- * Scatter chart object
+ * Stacked row chart object
*/
-s4a.viz.chart.Scatter = function() {
+s4a.viz.chart.StackedRow = function() {
};
@@ -3424,6 +3483,20 @@ s4a.viz.map.getMap = function(pDomNode, pChartData) {
});
};
+'use strict';
+s4a.extend('viz.map');
+
+/**
+ * Create a new Prism chart object
+ *
+ * @class
+ * @classdesc
+ * Prism chart object
+ */
+s4a.viz.map.Prism = function() {
+
+};
+
'use strict';
/**
* Define namespace utilities
diff --git a/dist/s4a.min.js b/dist/s4a.min.js
index 963adc3..ad11f28 100644
--- a/dist/s4a.min.js
+++ b/dist/s4a.min.js
@@ -1,5 +1,5 @@
-/*! s4a - v1.0.0 - 2016-05-06
+/*! s4a - v1.0.0 - 2016-06-21
* https://github.com/SDI4Apps/s4a.js
* Copyright (c) 2016 SDI4Apps Partnership; Licensed */
-"use strict";var s4a=function(){var a={},b="http://portal.sdi4apps.eu/openapi",c=null;return a.version="1.0",a.proxy=function(a){return void 0!==a&&(c=a),c},a.openApiUrl=function(a){return void 0!==a&&(b=a),b},a.extend=function(a){var b,c,d=a.split("."),e=s4a;for(b=d.length,c=0;b>c;c++)"undefined"==typeof e[d[c]]&&(e[d[c]]={}),e=e[d[c]];return e},a.doPost=function(a,b,c){void 0===c&&(c="json");var d=s4a.openApiUrl()+a;return jQuery.post(d,b,null,c)},a.doGet=function(a,b,c){void 0===c&&(c="json");var d=s4a.openApiUrl()+a;return jQuery.get(d,b,null,c)},a}();s4a.extend("config"),s4a.config=function(){var a={};return a.loadConfig=function(a){a=a||{};var b={center:{x:6.45996,y:49.92294,epsg:"EPSG:4326",zoom:4},baselayers:[new ol.layer.Tile({source:new ol.source.TileWMS({url:"http://opencache.statkart.no/gatekeeper/gk/gk.open?",params:{LAYERS:"norges_grunnkart",VERSION:"1.1.1"}})})],layers:[]};return jQuery.extend(b,a)},a}(),s4a.extend("analytics"),s4a.analytics.Routing=function(){var a={},b="/routing";return a.getShortestRoute=function(a,c){var d={action:"GetShortestPath",from:a,to:c};return s4a.doPost(b,d)},a.getNearestNode=function(a,c,d){void 0===d&&(d=100);var e={action:"GetNearestNode",lon:a,lat:c,radius:d};return s4a.doPost(b,e)},a.getOptimalRoute=function(a,c,d){var e={action:"GetOptimalRoute",nodeIds:a.concat([d,c]),start:c,finish:d};return s4a.doPost(b,e)},a.getReachableArea=function(a,c){var d={action:"GetReachableArea",fromNode:a,distance:c};return s4a.doPost(b,d)},a}(),s4a.extend("data"),s4a.data.SensLog=function(){var a={},b="/../SensLog/ControllerServlet",c="/../SensLog/FeederServlet",d="/../SensLog/DataService",e="/../SensLog/SensorService",f=function(a){var b=a.getFullYear(),c=(a.getMonth()+1).toString();1===c.length&&(c="0"+c);var d=a.getDate().toString();1===d.length&&(d="0"+d);var e=a.getHours().toString();1===e.length&&(e="0"+e);var f=a.getMinutes().toString();1===f.length&&(f="0"+f);var g=a.getSeconds().toString();return 1===g.length&&(g="0"+g),b+"-"+c+"-"+d+"T"+e+":"+f+":"+g};a.toSensLogDate=f;var g=function(a){var b=a.split(" "),c=b[0].split("-"),d=b[1].split("+"),e=d[0].split(":"),f=new Date(+c[0],+c[1]-1,+c[2],+e[0],+e[1],+e[2]);return f};a.toJsDate=g;var h=function(a){var b=a.getFullYear(),c=(a.getMonth()+1).toString();1===c.length&&(c="0"+c);var d=a.getDate().toString();1===d.length&&(d="0"+d);var e=a.getHours().toString();1===e.length&&(e="0"+e);var f=a.getMinutes().toString();1===f.length&&(f="0"+f);var g=a.getSeconds().toString();return 1===g.length&&(g="0"+g),b+"-"+c+"-"+d+" "+e+":"+f+":"+g};return a.toIsoDate=h,a.login=function(a,c){return s4a.doPost(b,{username:a,password:c})},a.insertPosition=function(a,b,d,e){return s4a.doGet(c,{Operation:"InsertPosition",lat:a,lon:b,unit_id:d,date:f(e)},"text")},a.insertObservation=function(a,b,d,e){return s4a.doGet(c,{Operation:"InsertObservation",value:a,unit_id:b,sensor_id:d,date:f(e)},"text")},a.getLastPositions=function(a){return s4a.doGet(d,{Operation:"GetLastPositions",user:a})},a.getLastPosition=function(b,c){return a.getLastPositions(c).then(function(a){for(var c=0;ca.maxx)&&(a.maxx=b),(null===a.miny||ca.maxy)&&(a.maxy=c)},this.extendByCoordinate=function(a){return this.extendByXY(a[0],a[1])},this.extent=a},s4a.extend("map"),s4a.map.GeometryType={point:"point",line:"line",polygon:"polygon",none:"none"},s4a.map.ITool={label:"Button",toolType:null,geomType:s4a.map.GeometryType.none,icon:"button.png",onClick:function(a){console.log("Must be overridden by derived class")},onDoubleClick:function(a){console.log("Must be overridden by derived class")},onActivate:function(){console.log("Must be overridden by derived class")},onDeactivate:function(){console.log("Must be overridden by derived class")}},s4a.map.LayerSwitcher=function(){this.test=1},s4a.extend("map"),s4a.map.Map=function(a,b){var c,d=this,e=[];b=b||s4a.config.loadConfig();var f=[b.center.x,b.center.y],g="EPSG:3857";b.center.epsg!==g&&(f=ol.proj.transform(f,b.center.epsg,g));var h=new ol.Map({layers:[new ol.layer.Group({title:"Base layer",layers:b.baselayers}),new ol.layer.Group({title:"Overlays",layers:b.layers})],renderer:"canvas",target:a,view:new ol.View({center:f,zoom:b.center.zoom})});return h.on("postcompose",function(a){d.redraw()}),d.add=function(a){a.setMap(d),e.push(a)},d.addKey=function(a){c=a},d.createMapLayer=function(a,b){var d={key:c,LAYERS:a};return new ol.layer.Image({source:new ol.source.ImageWMS({url:"http://localhost/a_a3_mapserver/mapserv.ashx",params:$.extend(d,b)})})},d.getDomElement=function(){return $(h.getViewport())},d.getOlMap=function(){return h},d.projectPoint=function(a,b){var c=ol.proj.transform([a,b],"EPSG:4326","EPSG:3857");return h.getPixelFromCoordinate(c)},d.redraw=function(){jQuery.each(e,function(a,b){b.redraw()})},d.removeAt=function(a){e=e.filter(function(b,c){return c!==a})},d.removeObjects=function(a){e=e.filter(function(b){return b!==a})},d},s4a.map.MapHelper=function(a,b){var c=this;if(void 0===a)throw"The parameter nodeSelector is mandatory";var d={zoomLevel:14,extent:[-179,-85,179,85],layers:[],center:{lon:6.11,lat:49.58},activeLayer:0,tools:[],activeTool:0,baseMaps:{MAPQUEST:new ol.layer.Tile({source:new ol.source.MapQuest({layer:"osm"})}),OFFLINE:new ol.layer.Vector({source:new ol.source.Vector({format:new ol.format.GeoJSON,projection:"EPSG:3857",url:"../../data/countries.json",style:new ol.style.Style({fill:new ol.style.Fill({color:"rgba(255, 255, 0, 0)"}),stroke:new ol.style.Stroke({color:"#ff0000",width:1})})})})}};void 0!==b&&jQuery.extend(d,b);var e=new ol.Map({layers:[d.baseMaps.OFFLINE],target:a,view:new ol.View({center:ol.proj.transform([d.center.lon,d.center.lat],"EPSG:4326","EPSG:3857"),zoom:d.zoomLevel})});this.transform=function(a,b){var c=null;return c=b===!0?ol.proj.transform(a,"EPSG:3857","EPSG:4326"):ol.proj.transform(a,"EPSG:4326","EPSG:3857")},this.getExtent=function(){return e.getView().calculateExtent(e.getSize())},this.zoomToExtent=function(a,b){b=b||14,e.getView().fit(a,e.getSize()),e.getView().getZoom()>b&&e.getView().setZoom(b)},this.addTool=function(a){return c},this.addData=function(a){var b=new ol.layer.Vector({source:new ol.source.GeoJSON({projection:"EPSG:3857",url:"data/countries.json"})});return e.addLayer(b),c},this.draw=function(){return c},this.listenDoubleClick=function(a){return this.getMap().on("dblclick",a),c},this.listenSingleClick=function(a){return this.getMap().on("singleclick",a),c},this.getMap=function(){return e}},s4a.map.ToolType={BUTTON:"button",TOOL:"tool",INPUT:"input"},s4a.extend("map"),s4a.map.Transform=function(){var a={},b=function(a,b,c){return ol.proj.transform(c,"EPSG:"+a,"EPSG:"+b)};return a.fromTo=function(a,c,d){return b(a,c,d)},a.to3857=function(a){return b(4326,3857,a)},a.to4326=function(a){return b(3857,4326,a)},a.extentTo3857=function(a){var c=b(4326,3857,[a[0],a[1]]),d=b(4326,3857,[a[2],a[3]]);return[c[0],c[1],d[0],d[1]]},a.extentTo4326=function(a){var c=b(3857,4326,[a[0],a[1]]),d=b(3857,4326,[a[2],a[3]]);return[c[0],c[1],d[0],d[1]]},a}(),s4a.map.VizLayer=function(){var a=this,b=!0,c="s4a-map",d=[];a.add=function(b){e(b.getSvg()),$(b).on("resize",a.redraw),d.push(b)};var e=function(a){var b=d3.select("div.ol-viewport"),d=b.select("div."+c);d.empty()&&(d=b.append("div").classed(c,!0)),d.append(function(){return a.node()}),a.style("position","fixed")};return a.getVisible=function(){return b},a.getPosition=function(b){return a.map.projectPoint(b[0],b[1])},a.redraw=function(){a.map&&jQuery.each(d,function(b,c){var d=c.getGeometry(),e=c.getSvg();if(d&&e){var f,g=(e.selectAll("g"),e.attr("width")/2);switch(d.type){case"point":f=a.getPosition(d.coordinates);break;default:console.warn("s4a.map.VizLayer","Unsupported geometry type",d.type)}if(!f)return;f[0]-=g,f[1]-=g,e.style("left",f[0]+"px").style("top",f[1]+"px")}})},a.removeAt=function(b){$(d[b]).unbind("resize",a.redraw),d=d.filter(function(a,c){return c!==b})},a.removeObjects=function(b){$(b).unbind("resize",a.redraw),d=d.filter(function(a){return a!==b})},a.setMap=function(b){a.map=b},a.setVisible=function(a){b=a,d.forEach(function(b){b.setVisible(a)})},a},s4a.extend("mobile"),s4a.mobile.FeatureSync=function(){var a={};return a.CheckOut=function(){},a.CheckIn=function(){},a.GetConflicts=function(){},a.Resolve=function(){},a}(),s4a.extend("mobile"),s4a.mobile.File=function(){var a={};return a.getFileEntry=function(a,b){var c=jQuery.Deferred();return void 0!==window.cordova&&void 0!==window.cordova.file?(void 0===b&&(b=window.cordova.file.dataDirectory),window.resolveLocalFileSystemURL(b,function(b){b.getFile(a,{create:!0},function(a){c.resolve(s4a.mobile.FileResponse.createSuccess(a))},function(a){c.resolve(s4a.mobile.FileResponse.createError(a))})},function(a){c.resolve(s4a.mobile.FileResponse.createError(a))})):c.resolve(s4a.mobile.FileResponse.createError('Requires Cordova with "cordova-plugin-file".')),c},a.writeFile=function(b,c){var d=jQuery.Deferred();return a.getFileEntry(b).then(function(a){a.isSuccess()?a.data.createWriter(function(a){a.onwriteend=function(){d.resolve(s4a.mobile.FileResponse.createSuccess(c))},a.onerror=function(a){d.resolve(s4a.mobile.FileResponse.createError(a.toString()))};var b=new Blob([JSON.stringify(c,null," ")],{type:"text/plain"});a.write(b)}):d.resolve(s4a.mobile.FileResponse.createError(a.messages))}),d},a.readFile=function(b){var c=jQuery.Deferred();return a.getFileEntry(b).then(function(a){a.isSuccess()?a.data.file(function(a){var b=new FileReader;b.onloadend=function(){c.resolve(s4a.mobile.FileResponse.createSuccess(JSON.parse(this.result)))},b.readAsText(a)},function(a){c.resolve(s4a.mobile.FileResponse.createError(a))}):c.resolve(s4a.mobile.FileResponse.createError(a.messages))}),c},a}(),s4a.extend("mobile"),s4a.mobile.FileResponse=function(a,b,c){this.status=void 0,void 0!==a&&null!==a?this.status=a:a=!0,this.data=void 0,void 0!==b&&null!==b&&(this.data=b),this.messages=[],void 0!==c&&null!==c&&this.messages.push(c),this.isSuccess=function(){return this.status===!0?!0:!1},this.isError=function(){return this.status===!1?!0:!1},this.getMessages=function(){for(var a=0;a=e&&" "!==b[g]&&"-"!==b[g];)g-=1,e++;if(console.log(e),d.push(b.substring(f,g).trim()),f=g,g=f+c,g>=b.length){d.push(b.substring(f,g).trim());break}}return d},m=function(a,b){return 0===a?0:b};return b.updateLegend=function(){for(var b=0;bh){o.text(null);for(var q=Math.ceil(1.15*a.fontSize),r=Math.ceil(p/h),s=l(r,n),t=0;t"),jQuery(a).append(x)),i=x.prop("height",w).prop("width",v)[0].getContext("2d"),j=b.domains.map(function(a){return Number(a)})||null,k=null!==b.colors&&b.colors.length>=1?s4a.viz.color[b.colors[0]][j.length]:s4a.viz.color.Reds[j.length],l=null!==b.colors&&b.colors.length>=2?s4a.viz.color[b.colors[1]][j.length]:s4a.viz.color.Blues[j.length],m=s4a.viz.Sizes.medium,n=d3.scale.threshold().domain(j).range(k),o=d3.scale.threshold().domain(j).range(l),p=null!==m?d3.scale.threshold().domain(j).range(m):null,q={},r={},s=[],t={},u=[];for(var y=0,z=b.mapUnitIDs.length;z>y;y++)r[b.mapUnitIDs[y]]=Number(b.seriesData[y]),q[b.mapUnitIDs[y]]=Number(b.seriesData[y][b.showSeries[0]]),s.push(Number(b.seriesData[y][b.showSeries[0]]));if(2===b.showSeries.length)for(y=0,z=b.mapUnitIDs.length;z>y;y++)t[b.mapUnitIDs[y]]=Number(b.seriesData[y][b.showSeries[1]]),u.push(Number(b.seriesData[y][b.showSeries[1]]));(null===b.title||void 0===b.title||""===b.title)&&(b.showSeries.length>1?b.title=b.seriesLabels[b.showSeries[0]]+" / "+b.seriesLabels[b.showSeries[2]]:b.title=b.seriesLabels[b.showSeries[0]]),queue().defer(d3.json,"./data/data-topojson.json").defer(d3.json,"./data/sea.json").await(function(a,j,l){return c=d3.geo.transverseMercator().scale(1).translate([0,0]),d=d3.geo.path().projection(c),e=topojson.feature(j,j.objects.kommune).features.filter(function(a){return-1!==b.mapUnitIDs.indexOf(a.id.toString())}),f=s4a.viz.map.util.getFeatureCollectionBounds(d,e),g=.95/Math.max((f[1][0]-f[0][0])/v,(f[1][1]-f[0][1])/w),h=[(v-g*(f[1][0]+f[0][0]))/2,(w-g*(f[1][1]+f[0][1]))/2],c.scale(g).translate(h),i.clearRect(0,0,v,w),i.fillStyle="#ffffff",i.fillRect(0,0,v,w),s4a.viz.map.shared._drawLand(i,d,l),("choroplethMap"===b.mapType||"bubbleChoroplethMap"===b.mapType)&&s4a.viz.map.shared._drawPolygons(e,q,n,d,i),s4a.viz.map.shared._drawMunicipality(i,d,j),s4a.viz.map.shared._drawCounty(i,d,j),"bubbleMap"===b.mapType?s4a.viz.map.shared._drawBubbles(e,q,p,n,d,i):"bubbleChoroplethMap"===b.mapType?s4a.viz.map.shared._drawBubbles(e,t,p,o,d,i):"pieChartMap"===b.mapType&&s4a.viz.map.shared._drawPieCharts(e,r,k,d,i),s4a.viz.map.shared._drawLabels(i,d,e,b.fontSize-2),s4a.viz.map.shared._drawRectSymMapLegend(i,n,b.title,Number(b.fontSize)),i})},s4a.viz.map.shared={},s4a.viz.map.shared._drawChartTitle=function(a,b,c,d,e){return a.font="bolder "+b+"px Arial",a.textAlign="start",a.fillStyle="#000000",a.fillText(c,d,e),e+=2*b},s4a.viz.map.shared._drawRectSymMapLegend=function(a,b,c,d){d=void 0!==d?d:s4a.viz.map.FontSizes.normal;var e=10,f=10,g=1.8*d,h=20,i=d+4,j=f+d,k=s4a.viz.map.util.getLongestStringInArray(b.domain());a.font=d+"px Arial";var l=2*a.measureText(k).width;void 0!==c&&null!==c&&""!==c&&(j=s4a.viz.map.shared._drawChartTitle(a,d,c,e,j)),a.font=d+"px Arial",a.textAlign="end";for(var m=b.domain().length-1;m>0;m--){var n;n=m===b.domain().length-1?"> "+jQuery.number(b.domain()[m-1]):1===m?"< "+jQuery.number(b.domain()[m]):jQuery.number(b.domain()[m-1])+" - "+jQuery.number(b.domain()[m]),a.fillStyle=b.range()[m],a.strokeStyle="#000000",a.lineWidth=.2,a.beginPath(),a.rect(e,j-d,h,i),a.globalAlpha=s4a.viz.map.StatAreaAlpha,a.fill(),a.globalAlpha=1,a.stroke(),a.fillStyle="#000000",a.fillText(n,e+h+e+l,j),j+=g}},s4a.viz.map.shared._drawPolygons=function(a,b,c,d,e){e.globalAlpha=s4a.viz.map.StatAreaAlpha;var f=c.domain(),g=Math.max.apply(null,f),h=Math.min.apply(null,f);a.forEach(function(a){var f=b[a.id];f=g>f?f:g-1e-4,f=f>=h?f:h;var i=c(f);void 0!==i&&(e.fillStyle=i,e.beginPath(),d.context(e)(a),e.fill())}),e.globalAlpha=1},s4a.viz.map.shared._drawPieCharts=function(a,b,c,d,e){e.globalAlpha=s4a.viz.map.StatAreaAlpha,a.forEach(function(a){for(var f=25,g=s4a.viz.map.util.valuesToSlices(b[a.id]),h=1.5*Math.PI,i=d.centroid(a),j=0,k=g.length;k>j;j++){var l=Number(g[j])*(2*Math.PI)/100,m=h+l;m>2*Math.PI&&(m-=2*Math.PI),e.fillStyle=c[j],e.lineWidth=2,e.strokeStyle="rgba(0,0,0,0.25)",e.beginPath(),e.moveTo(i[0],i[1]),e.arc(i[0],i[1],f,h,m,!1),e.closePath(),e.fill(),e.stroke(),h+=l}})},s4a.viz.map.shared._drawCircleSymMapLegend=function(a,b,c){var d=12,e=10,f=10,g=1.5*d,h=f+d,i=s4a.viz.map.util.getLengthOfLongest(b.domain())*(d/1.5);a.font=d+"px Arial Bold",a.textAlign="start",a.fillStyle="#000000",a.fillText("Teiknforklaring",e,h),h+=g,a.font=d+"px Arial",a.textAlign="end";for(var j=b.domain().length-1;j>0;j--){var k=jQuery.number(b.domain()[j-1])+" - "+jQuery.number(b.domain()[j]);a.fillStyle=b.range()[j],a.strokeStyle="#000000",a.lineWidth=.2,a.beginPath(),a.arc(e,h-d/2,6,0,2*Math.PI,!1),a.globalAlpha=s4a.viz.map.StatAreaAlpha,a.fill(),a.globalAlpha=1,a.stroke(),a.fillStyle="#000000",a.fillText(k,e+i,h),h+=g}},s4a.viz.map.shared._drawBubbles=function(a,b,c,d,e,f){f.globalAlpha=s4a.viz.map.StatAreaAlpha,a.forEach(function(a){var g=c(b[a.id]),h=d(b[a.id]);if(void 0!==g){var i=e.centroid(a);f.beginPath(),f.arc(i[0],i[1],g,0,2*Math.PI,!1),f.fillStyle=h,f.fill(),f.lineWidth=2,f.strokeStyle="rgba(0,0,0,0.25)",f.stroke()}}),f.globalAlpha=1},s4a.viz.map.shared._drawLabels=function(a,b,c,d){d=void 0!==d?d:s4a.viz.map.FontSizes.small,c.forEach(function(c){var e=b.centroid(c);a.font=d+"px Arial",a.textAlign="center",a.fillStyle="#000000",a.fillText(c.properties.name,e[0],e[1])})},s4a.viz.map.shared._drawGeoJson=function(a,b,c,d,e,f){a.strokeStyle=d||"transparent",a.lineWidth=f,a.fillStyle=e||"transparent",a.beginPath(),b.context(a)(c),"transparent"!==e&&a.fill(),"transparent"!==d&&a.stroke()},s4a.viz.map.shared._drawMunicipality=function(a,b,c){var d=topojson.mesh(c,c.objects.kommune,function(a,b){return a.id!==b.id});s4a.viz.map.shared._drawGeoJson(a,b,d,"#000000",null,.5)},s4a.viz.map.shared._drawCounty=function(a,b,c){var d=topojson.mesh(c,c.objects.fylke,function(a,b){return a.id!==b.id});s4a.viz.map.shared._drawGeoJson(a,b,d,"#000000",null,1)},s4a.viz.map.shared._drawLand=function(a,b,c){var d=topojson.feature(c,c.objects.sea);s4a.viz.map.shared._drawGeoJson(a,b,d,"#999999","#eeeeee",.2)},s4a.viz.map.Symbol=function(){},s4a.viz.map.util={},s4a.viz.map.util.secureReload=function(a){var b=a.indexOf(!0)?"?":"&";return a+b+"rnd="+(100*Math.random()).toString()},s4a.viz.map.util.getLengthOfLongest=function(a){var b=0;if(null!==a&&a.length>1)for(var c,d=a.length-1;d>0;d--){var e=jQuery.number(a[d-1])+" - "+jQuery.number(a[d]);c=e.length,c>b&&(b=c)}return b},s4a.viz.map.util.getLongestStringInArray=function(a){var b=a.slice();return b.sort(function(a,b){return b.toString().length-a.toString().length})[0]},s4a.viz.map.util.getTotal=function(a){for(var b=0,c=0;cd;d++){var f=a.bounds(b[d]);(!c[0][0]||f[0][0]c[1][0])&&(c[1][0]=f[1][0]),(!c[1][1]||f[1][1]>c[1][1])&&(c[1][1]=f[1][1])}return c},s4a.viz.map.util.valuesToSlices=function(a){if(void 0!==a&&"object"==typeof a&&Array.isArray(a)===!0){for(var b=0,c=0,d=a.length;d>c;c++)b+=Number(a[c]);var e=[];for(c=0,d=a.length;d>c;c++)e.push(100*Number(a[c])/b);return e}return a},s4a.viz.map.util={},s4a.viz.map.util.secureReload=function(a){var b=a.indexOf(!0)?"?":"&";return a+b+"rnd="+(100*Math.random()).toString()},s4a.viz.map.util.getLengthOfLongest=function(a){var b=0;if(null!==a&&a.length>1)for(var c,d=a.length-1;d>0;d--){var e=jQuery.number(a[d-1])+" - "+jQuery.number(a[d]);c=e.length,c>b&&(b=c)}return b},s4a.viz.map.util.getLongestStringInArray=function(a){var b=a.slice();return b.sort(function(a,b){return b.toString().length-a.toString().length})[0]},s4a.viz.map.util.getTotal=function(a){for(var b=0,c=0;cd;d++){var f=a.bounds(b[d]);(!c[0][0]||f[0][0]c[1][0])&&(c[1][0]=f[1][0]),(!c[1][1]||f[1][1]>c[1][1])&&(c[1][1]=f[1][1])}return c},s4a.viz.map.util.valuesToSlices=function(a){if(void 0!==a&&"object"==typeof a&&Array.isArray(a)===!0){for(var b=0,c=0,d=a.length;d>c;c++)b+=Number(a[c]);var e=[];for(c=0,d=a.length;d>c;c++)e.push(100*Number(a[c])/b);return e}return a};
\ No newline at end of file
+"use strict";var s4a=function(){var a={},b="http://portal.sdi4apps.eu/openapi",c=null;return a.version="1.0",a.proxy=function(a){return void 0!==a&&(c=a),c},a.openApiUrl=function(a){return void 0!==a&&(b=a),b},a.extend=function(a){var b,c,d=a.split("."),e=s4a;for(b=d.length,c=0;b>c;c++)"undefined"==typeof e[d[c]]&&(e[d[c]]={}),e=e[d[c]];return e},a.doPost=function(a,b,c){void 0===c&&(c="json");var d=s4a.openApiUrl()+a;return jQuery.post(d,b,null,c)},a.doGet=function(a,b,c){void 0===c&&(c="json");var d=s4a.openApiUrl()+a;return jQuery.get(d,b,null,c)},a}();s4a.extend("config"),s4a.config=function(){var a={};return a.loadConfig=function(a){a=a||{};var b={center:{x:6.45996,y:49.92294,epsg:"EPSG:4326",zoom:4},baselayers:[new ol.layer.Tile({source:new ol.source.TileWMS({url:"http://opencache.statkart.no/gatekeeper/gk/gk.open?",params:{LAYERS:"norges_grunnkart",VERSION:"1.1.1"}})})],layers:[]};return jQuery.extend(b,a)},a}(),s4a.extend("analytics"),s4a.analytics.Routing=function(){var a={},b="/routing";return a.getShortestRoute=function(a,c){var d={action:"GetShortestPath",from:a,to:c};return s4a.doPost(b,d)},a.getNearestNode=function(a,c,d){void 0===d&&(d=100);var e={action:"GetNearestNode",lon:a,lat:c,radius:d};return s4a.doPost(b,e)},a.getOptimalRoute=function(a,c,d){var e={action:"GetOptimalRoute",nodeIds:a.concat([d,c]),start:c,finish:d};return s4a.doPost(b,e)},a.getReachableArea=function(a,c){var d={action:"GetReachableArea",fromNode:a,distance:c};return s4a.doPost(b,d)},a}(),s4a.extend("data"),s4a.data.SensLog=function(){var a={},b="/../SensLog/ControllerServlet",c="/../SensLog/FeederServlet",d="/../SensLog/DataService",e="/../SensLog/SensorService",f=function(a){var b=a.getFullYear(),c=(a.getMonth()+1).toString();1===c.length&&(c="0"+c);var d=a.getDate().toString();1===d.length&&(d="0"+d);var e=a.getHours().toString();1===e.length&&(e="0"+e);var f=a.getMinutes().toString();1===f.length&&(f="0"+f);var g=a.getSeconds().toString();return 1===g.length&&(g="0"+g),b+"-"+c+"-"+d+"T"+e+":"+f+":"+g};a.toSensLogDate=f;var g=function(a){var b=a.split(" "),c=b[0].split("-"),d=b[1].split("+"),e=d[0].split(":"),f=new Date(+c[0],+c[1]-1,+c[2],+e[0],+e[1],+e[2]);return f};a.toJsDate=g;var h=function(a){var b=a.getFullYear(),c=(a.getMonth()+1).toString();1===c.length&&(c="0"+c);var d=a.getDate().toString();1===d.length&&(d="0"+d);var e=a.getHours().toString();1===e.length&&(e="0"+e);var f=a.getMinutes().toString();1===f.length&&(f="0"+f);var g=a.getSeconds().toString();return 1===g.length&&(g="0"+g),b+"-"+c+"-"+d+" "+e+":"+f+":"+g};return a.toIsoDate=h,a.login=function(a,c){return s4a.doPost(b,{username:a,password:c})},a.insertPosition=function(a,b,d,e){return s4a.doGet(c,{Operation:"InsertPosition",lat:a,lon:b,unit_id:d,date:f(e)},"text")},a.insertObservation=function(a,b,d,e){return s4a.doGet(c,{Operation:"InsertObservation",value:a,unit_id:b,sensor_id:d,date:f(e)},"text")},a.getLastPositions=function(a){return s4a.doGet(d,{Operation:"GetLastPositions",user:a})},a.getLastPosition=function(b,c){return a.getLastPositions(c).then(function(a){for(var c=0;ca.maxx)&&(a.maxx=b),(null===a.miny||ca.maxy)&&(a.maxy=c)},this.extendByCoordinate=function(a){return this.extendByXY(a[0],a[1])},this.extent=a},s4a.extend("map"),s4a.map.GeometryType={point:"point",line:"line",polygon:"polygon",none:"none"},s4a.map.ITool={label:"Button",toolType:null,geomType:s4a.map.GeometryType.none,icon:"button.png",onClick:function(a){console.log("Must be overridden by derived class")},onDoubleClick:function(a){console.log("Must be overridden by derived class")},onActivate:function(){console.log("Must be overridden by derived class")},onDeactivate:function(){console.log("Must be overridden by derived class")}},s4a.map.LayerSwitcher=function(){this.test=1},s4a.extend("map"),s4a.map.Map=function(a,b){var c,d=this,e=[];b=b||s4a.config.loadConfig();var f=[b.center.x,b.center.y],g="EPSG:3857";b.center.epsg!==g&&(f=ol.proj.transform(f,b.center.epsg,g));var h=new ol.Map({layers:[new ol.layer.Group({title:"Base layer",layers:b.baselayers}),new ol.layer.Group({title:"Overlays",layers:b.layers})],renderer:"canvas",target:a,view:new ol.View({center:f,zoom:b.center.zoom})});return h.on("postcompose",function(a){d.redraw()}),d.add=function(a){a.setMap(d),e.push(a)},d.addKey=function(a){c=a},d.createMapLayer=function(a,b){var d={key:c,LAYERS:a};return new ol.layer.Image({source:new ol.source.ImageWMS({url:"http://localhost/a_a3_mapserver/mapserv.ashx",params:$.extend(d,b)})})},d.getDomElement=function(){return $(h.getViewport())},d.getOlMap=function(){return h},d.projectPoint=function(a,b){var c=ol.proj.transform([a,b],"EPSG:4326","EPSG:3857");return h.getPixelFromCoordinate(c)},d.redraw=function(){jQuery.each(e,function(a,b){b.redraw()})},d.removeAt=function(a){e=e.filter(function(b,c){return c!==a})},d.removeObjects=function(a){e=e.filter(function(b){return b!==a})},d},s4a.map.MapHelper=function(a,b){var c=this;if(void 0===a)throw"The parameter nodeSelector is mandatory";var d={zoomLevel:14,extent:[-179,-85,179,85],layers:[],center:{lon:6.11,lat:49.58},activeLayer:0,tools:[],activeTool:0,baseMaps:{MAPQUEST:new ol.layer.Tile({source:new ol.source.MapQuest({layer:"osm"})}),OFFLINE:new ol.layer.Vector({source:new ol.source.Vector({format:new ol.format.GeoJSON,projection:"EPSG:3857",url:"../../data/countries.json",style:new ol.style.Style({fill:new ol.style.Fill({color:"rgba(255, 255, 0, 0)"}),stroke:new ol.style.Stroke({color:"#ff0000",width:1})})})})}};void 0!==b&&jQuery.extend(d,b);var e=new ol.Map({layers:[d.baseMaps.MAPQUEST],target:a,view:new ol.View({center:ol.proj.transform([d.center.lon,d.center.lat],"EPSG:4326","EPSG:3857"),zoom:d.zoomLevel})});this.transform=function(a,b){var c=null;return c=b===!0?ol.proj.transform(a,"EPSG:3857","EPSG:4326"):ol.proj.transform(a,"EPSG:4326","EPSG:3857")},this.getExtent=function(){return e.getView().calculateExtent(e.getSize())},this.zoomToExtent=function(a,b){b=b||14,e.getView().fit(a,e.getSize()),e.getView().getZoom()>b&&e.getView().setZoom(b)},this.addTool=function(a){return c},this.addData=function(a){var b=new ol.layer.Vector({source:new ol.source.GeoJSON({projection:"EPSG:3857",url:"data/countries.json"})});return e.addLayer(b),c},this.draw=function(){return c},this.listenDoubleClick=function(a){return this.getMap().on("dblclick",a),c},this.listenSingleClick=function(a){return this.getMap().on("singleclick",a),c},this.getMap=function(){return e}},s4a.map.ToolType={BUTTON:"button",TOOL:"tool",INPUT:"input"},s4a.extend("map"),s4a.map.Transform=function(){var a={},b=function(a,b,c){return ol.proj.transform(c,"EPSG:"+a,"EPSG:"+b)};return a.fromTo=function(a,c,d){return b(a,c,d)},a.to3857=function(a){return b(4326,3857,a)},a.to4326=function(a){return b(3857,4326,a)},a.extentTo3857=function(a){var c=b(4326,3857,[a[0],a[1]]),d=b(4326,3857,[a[2],a[3]]);return[c[0],c[1],d[0],d[1]]},a.extentTo4326=function(a){var c=b(3857,4326,[a[0],a[1]]),d=b(3857,4326,[a[2],a[3]]);return[c[0],c[1],d[0],d[1]]},a}(),s4a.map.VizLayer=function(){var a=this,b=!0,c="s4a-map",d=[];a.add=function(b){e(b.getSvg()),$(b).on("resize",a.redraw),d.push(b)};var e=function(a){var b=d3.select("div.ol-viewport"),d=b.select("div."+c);d.empty()&&(d=b.append("div").classed(c,!0)),d.append(function(){return a.node()}),a.style("position","fixed")};return a.getVisible=function(){return b},a.getPosition=function(b){return a.map.projectPoint(b[0],b[1])},a.redraw=function(){a.map&&jQuery.each(d,function(b,c){var d=c.getGeometry(),e=c.getSvg();if(d&&e){var f,g=(e.selectAll("g"),e.attr("width")/2);switch(d.type){case"point":f=a.getPosition(d.coordinates);break;default:console.warn("s4a.map.VizLayer","Unsupported geometry type",d.type)}if(!f)return;f[0]-=g,f[1]-=g,e.style("left",f[0]+"px").style("top",f[1]+"px")}})},a.removeAt=function(b){$(d[b]).unbind("resize",a.redraw),d=d.filter(function(a,c){return c!==b})},a.removeObjects=function(b){$(b).unbind("resize",a.redraw),d=d.filter(function(a){return a!==b})},a.setMap=function(b){a.map=b},a.setVisible=function(a){b=a,d.forEach(function(b){b.setVisible(a)})},a},s4a.extend("mobile"),s4a.mobile.FeatureSync=function(){var a={};return a.CheckOut=function(){},a.CheckIn=function(){},a.GetConflicts=function(){},a.Resolve=function(){},a}(),s4a.extend("mobile"),s4a.mobile.File=function(){var a={};return a.getFileEntry=function(a,b){var c=jQuery.Deferred();return void 0!==window.cordova&&void 0!==window.cordova.file?(void 0===b&&(b=window.cordova.file.dataDirectory),window.resolveLocalFileSystemURL(b,function(b){b.getFile(a,{create:!0},function(a){c.resolve(s4a.mobile.FileResponse.createSuccess(a))},function(a){c.resolve(s4a.mobile.FileResponse.createError(a))})},function(a){c.resolve(s4a.mobile.FileResponse.createError(a))})):c.resolve(s4a.mobile.FileResponse.createError('Requires Cordova with "cordova-plugin-file".')),c},a.writeFile=function(b,c){var d=jQuery.Deferred();return a.getFileEntry(b).then(function(a){a.isSuccess()?a.data.createWriter(function(a){a.onwriteend=function(){d.resolve(s4a.mobile.FileResponse.createSuccess(c))},a.onerror=function(a){d.resolve(s4a.mobile.FileResponse.createError("Error writing file: "+a.toString()))};var b=new Blob([JSON.stringify(c,null," ")],{type:"text/plain"});a.write(b)}):d.resolve(s4a.mobile.FileResponse.createError("Error getting file entry: "+a.messages))}),d},a.readFile=function(b){var c=jQuery.Deferred();return a.getFileEntry(b).then(function(a){a.isSuccess()?a.data.file(function(a){var b=new FileReader;b.onloadend=function(){c.resolve(s4a.mobile.FileResponse.createSuccess(JSON.parse(this.result)))},b.readAsText(a)},function(a){c.resolve(s4a.mobile.FileResponse.createError(a))}):c.resolve(s4a.mobile.FileResponse.createError(a.messages))}),c},a}(),s4a.extend("mobile"),s4a.mobile.FileResponse=function(a,b,c){this.status=void 0,void 0!==a&&null!==a?this.status=a:a=!0,this.data=void 0,void 0!==b&&null!==b&&(this.data=b),this.messages=[],void 0!==c&&null!==c&&this.messages.push(c),this.isSuccess=function(){return this.status===!0?!0:!1},this.isError=function(){return this.status===!1?!0:!1},this.getMessages=function(){for(var a=0;a=e&&" "!==b[g]&&"-"!==b[g];)g-=1,e++;if(console.log(e),d.push(b.substring(f,g).trim()),f=g,g=f+c,g>=b.length){d.push(b.substring(f,g).trim());break}}return d},m=function(a,b){return 0===a?0:b};return b.updateLegend=function(){for(var b=0;bh){o.text(null);for(var q=Math.ceil(1.15*a.fontSize),r=Math.ceil(p/h),s=l(r,n),t=0;t"),jQuery(a).append(x)),i=x.prop("height",w).prop("width",v)[0].getContext("2d"),j=b.domains.map(function(a){return Number(a)})||null,k=null!==b.colors&&b.colors.length>=1?s4a.viz.color[b.colors[0]][j.length]:s4a.viz.color.Reds[j.length],l=null!==b.colors&&b.colors.length>=2?s4a.viz.color[b.colors[1]][j.length]:s4a.viz.color.Blues[j.length],m=s4a.viz.Sizes.medium,n=d3.scale.threshold().domain(j).range(k),o=d3.scale.threshold().domain(j).range(l),p=null!==m?d3.scale.threshold().domain(j).range(m):null,q={},r={},s=[],t={},u=[];for(var y=0,z=b.mapUnitIDs.length;z>y;y++)r[b.mapUnitIDs[y]]=Number(b.seriesData[y]),q[b.mapUnitIDs[y]]=Number(b.seriesData[y][b.showSeries[0]]),s.push(Number(b.seriesData[y][b.showSeries[0]]));if(2===b.showSeries.length)for(y=0,z=b.mapUnitIDs.length;z>y;y++)t[b.mapUnitIDs[y]]=Number(b.seriesData[y][b.showSeries[1]]),u.push(Number(b.seriesData[y][b.showSeries[1]]));(null===b.title||void 0===b.title||""===b.title)&&(b.showSeries.length>1?b.title=b.seriesLabels[b.showSeries[0]]+" / "+b.seriesLabels[b.showSeries[2]]:b.title=b.seriesLabels[b.showSeries[0]]),queue().defer(d3.json,"./data/data-topojson.json").defer(d3.json,"./data/sea.json").await(function(a,j,l){return c=d3.geo.transverseMercator().scale(1).translate([0,0]),d=d3.geo.path().projection(c),e=topojson.feature(j,j.objects.kommune).features.filter(function(a){return-1!==b.mapUnitIDs.indexOf(a.id.toString())}),f=s4a.viz.map.util.getFeatureCollectionBounds(d,e),g=.95/Math.max((f[1][0]-f[0][0])/v,(f[1][1]-f[0][1])/w),h=[(v-g*(f[1][0]+f[0][0]))/2,(w-g*(f[1][1]+f[0][1]))/2],c.scale(g).translate(h),i.clearRect(0,0,v,w),i.fillStyle="#ffffff",i.fillRect(0,0,v,w),s4a.viz.map.shared._drawLand(i,d,l),("choroplethMap"===b.mapType||"bubbleChoroplethMap"===b.mapType)&&s4a.viz.map.shared._drawPolygons(e,q,n,d,i),s4a.viz.map.shared._drawMunicipality(i,d,j),s4a.viz.map.shared._drawCounty(i,d,j),"bubbleMap"===b.mapType?s4a.viz.map.shared._drawBubbles(e,q,p,n,d,i):"bubbleChoroplethMap"===b.mapType?s4a.viz.map.shared._drawBubbles(e,t,p,o,d,i):"pieChartMap"===b.mapType&&s4a.viz.map.shared._drawPieCharts(e,r,k,d,i),s4a.viz.map.shared._drawLabels(i,d,e,b.fontSize-2),s4a.viz.map.shared._drawRectSymMapLegend(i,n,b.title,Number(b.fontSize)),i})},s4a.viz.map.shared={},s4a.viz.map.shared._drawChartTitle=function(a,b,c,d,e){return a.font="bolder "+b+"px Arial",a.textAlign="start",a.fillStyle="#000000",a.fillText(c,d,e),e+=2*b},s4a.viz.map.shared._drawRectSymMapLegend=function(a,b,c,d){d=void 0!==d?d:s4a.viz.map.FontSizes.normal;var e=10,f=10,g=1.8*d,h=20,i=d+4,j=f+d,k=s4a.viz.map.util.getLongestStringInArray(b.domain());a.font=d+"px Arial";var l=2*a.measureText(k).width;void 0!==c&&null!==c&&""!==c&&(j=s4a.viz.map.shared._drawChartTitle(a,d,c,e,j)),a.font=d+"px Arial",a.textAlign="end";for(var m=b.domain().length-1;m>0;m--){var n;n=m===b.domain().length-1?"> "+jQuery.number(b.domain()[m-1]):1===m?"< "+jQuery.number(b.domain()[m]):jQuery.number(b.domain()[m-1])+" - "+jQuery.number(b.domain()[m]),a.fillStyle=b.range()[m],a.strokeStyle="#000000",a.lineWidth=.2,a.beginPath(),a.rect(e,j-d,h,i),a.globalAlpha=s4a.viz.map.StatAreaAlpha,a.fill(),a.globalAlpha=1,a.stroke(),a.fillStyle="#000000",a.fillText(n,e+h+e+l,j),j+=g}},s4a.viz.map.shared._drawPolygons=function(a,b,c,d,e){e.globalAlpha=s4a.viz.map.StatAreaAlpha;var f=c.domain(),g=Math.max.apply(null,f),h=Math.min.apply(null,f);a.forEach(function(a){var f=b[a.id];f=g>f?f:g-1e-4,f=f>=h?f:h;var i=c(f);void 0!==i&&(e.fillStyle=i,e.beginPath(),d.context(e)(a),e.fill())}),e.globalAlpha=1},s4a.viz.map.shared._drawPieCharts=function(a,b,c,d,e){e.globalAlpha=s4a.viz.map.StatAreaAlpha,a.forEach(function(a){for(var f=25,g=s4a.viz.map.util.valuesToSlices(b[a.id]),h=1.5*Math.PI,i=d.centroid(a),j=0,k=g.length;k>j;j++){var l=Number(g[j])*(2*Math.PI)/100,m=h+l;m>2*Math.PI&&(m-=2*Math.PI),e.fillStyle=c[j],e.lineWidth=2,e.strokeStyle="rgba(0,0,0,0.25)",e.beginPath(),e.moveTo(i[0],i[1]),e.arc(i[0],i[1],f,h,m,!1),e.closePath(),e.fill(),e.stroke(),h+=l}})},s4a.viz.map.shared._drawCircleSymMapLegend=function(a,b,c){var d=12,e=10,f=10,g=1.5*d,h=f+d,i=s4a.viz.map.util.getLengthOfLongest(b.domain())*(d/1.5);a.font=d+"px Arial Bold",a.textAlign="start",a.fillStyle="#000000",a.fillText("Teiknforklaring",e,h),h+=g,a.font=d+"px Arial",a.textAlign="end";for(var j=b.domain().length-1;j>0;j--){var k=jQuery.number(b.domain()[j-1])+" - "+jQuery.number(b.domain()[j]);a.fillStyle=b.range()[j],a.strokeStyle="#000000",a.lineWidth=.2,a.beginPath(),a.arc(e,h-d/2,6,0,2*Math.PI,!1),a.globalAlpha=s4a.viz.map.StatAreaAlpha,a.fill(),a.globalAlpha=1,a.stroke(),a.fillStyle="#000000",a.fillText(k,e+i,h),h+=g}},s4a.viz.map.shared._drawBubbles=function(a,b,c,d,e,f){f.globalAlpha=s4a.viz.map.StatAreaAlpha,a.forEach(function(a){var g=c(b[a.id]),h=d(b[a.id]);if(void 0!==g){var i=e.centroid(a);f.beginPath(),f.arc(i[0],i[1],g,0,2*Math.PI,!1),f.fillStyle=h,f.fill(),f.lineWidth=2,f.strokeStyle="rgba(0,0,0,0.25)",f.stroke()}}),f.globalAlpha=1},s4a.viz.map.shared._drawLabels=function(a,b,c,d){d=void 0!==d?d:s4a.viz.map.FontSizes.small,c.forEach(function(c){var e=b.centroid(c);a.font=d+"px Arial",a.textAlign="center",a.fillStyle="#000000",a.fillText(c.properties.name,e[0],e[1])})},s4a.viz.map.shared._drawGeoJson=function(a,b,c,d,e,f){a.strokeStyle=d||"transparent",a.lineWidth=f,a.fillStyle=e||"transparent",a.beginPath(),b.context(a)(c),"transparent"!==e&&a.fill(),"transparent"!==d&&a.stroke()},s4a.viz.map.shared._drawMunicipality=function(a,b,c){var d=topojson.mesh(c,c.objects.kommune,function(a,b){return a.id!==b.id});s4a.viz.map.shared._drawGeoJson(a,b,d,"#000000",null,.5)},s4a.viz.map.shared._drawCounty=function(a,b,c){var d=topojson.mesh(c,c.objects.fylke,function(a,b){return a.id!==b.id});s4a.viz.map.shared._drawGeoJson(a,b,d,"#000000",null,1)},s4a.viz.map.shared._drawLand=function(a,b,c){var d=topojson.feature(c,c.objects.sea);s4a.viz.map.shared._drawGeoJson(a,b,d,"#999999","#eeeeee",.2)},s4a.viz.map.Symbol=function(){},s4a.viz.map.util={},s4a.viz.map.util.secureReload=function(a){var b=a.indexOf(!0)?"?":"&";return a+b+"rnd="+(100*Math.random()).toString()},s4a.viz.map.util.getLengthOfLongest=function(a){var b=0;if(null!==a&&a.length>1)for(var c,d=a.length-1;d>0;d--){var e=jQuery.number(a[d-1])+" - "+jQuery.number(a[d]);c=e.length,c>b&&(b=c)}return b},s4a.viz.map.util.getLongestStringInArray=function(a){var b=a.slice();return b.sort(function(a,b){return b.toString().length-a.toString().length})[0]},s4a.viz.map.util.getTotal=function(a){for(var b=0,c=0;cd;d++){var f=a.bounds(b[d]);(!c[0][0]||f[0][0]c[1][0])&&(c[1][0]=f[1][0]),(!c[1][1]||f[1][1]>c[1][1])&&(c[1][1]=f[1][1])}return c},s4a.viz.map.util.valuesToSlices=function(a){if(void 0!==a&&"object"==typeof a&&Array.isArray(a)===!0){for(var b=0,c=0,d=a.length;d>c;c++)b+=Number(a[c]);var e=[];for(c=0,d=a.length;d>c;c++)e.push(100*Number(a[c])/b);return e}return a},s4a.viz.map.util={},s4a.viz.map.util.secureReload=function(a){var b=a.indexOf(!0)?"?":"&";return a+b+"rnd="+(100*Math.random()).toString()},s4a.viz.map.util.getLengthOfLongest=function(a){var b=0;if(null!==a&&a.length>1)for(var c,d=a.length-1;d>0;d--){var e=jQuery.number(a[d-1])+" - "+jQuery.number(a[d]);c=e.length,c>b&&(b=c)}return b},s4a.viz.map.util.getLongestStringInArray=function(a){var b=a.slice();return b.sort(function(a,b){return b.toString().length-a.toString().length})[0]},s4a.viz.map.util.getTotal=function(a){for(var b=0,c=0;cd;d++){var f=a.bounds(b[d]);(!c[0][0]||f[0][0]c[1][0])&&(c[1][0]=f[1][0]),(!c[1][1]||f[1][1]>c[1][1])&&(c[1][1]=f[1][1])}return c},s4a.viz.map.util.valuesToSlices=function(a){if(void 0!==a&&"object"==typeof a&&Array.isArray(a)===!0){for(var b=0,c=0,d=a.length;d>c;c++)b+=Number(a[c]);var e=[];for(c=0,d=a.length;d>c;c++)e.push(100*Number(a[c])/b);return e}return a};
\ No newline at end of file
diff --git a/src/data/SensLog.js b/src/data/SensLog.js
index 6987223..b1babe4 100644
--- a/src/data/SensLog.js
+++ b/src/data/SensLog.js
@@ -2,6 +2,11 @@
s4a.extend('data');
+/**
+ * SensLog communication object
+ *
+ * @class
+ */
s4a.data.SensLog = (function() {
/**
* Class with methods to interact with SensLog
diff --git a/src/ir/ir.jsdoc b/src/ir/ir.jsdoc
index 6a28a91..0c29496 100644
--- a/src/ir/ir.jsdoc
+++ b/src/ir/ir.jsdoc
@@ -1,4 +1,5 @@
/**
* Information retrieval related methods
+ *
* @namespace s4a.ir
*/
diff --git a/src/map/MapHelper.js b/src/map/MapHelper.js
index d59b0eb..d51ae0e 100644
--- a/src/map/MapHelper.js
+++ b/src/map/MapHelper.js
@@ -53,7 +53,7 @@ s4a.map.MapHelper = function(nodeSelector, config) {
var _map = new ol.Map({
layers: [
- _config.baseMaps.OFFLINE
+ _config.baseMaps.MAPQUEST
],
target: nodeSelector,
view: new ol.View({
diff --git a/src/mobile/File.js b/src/mobile/File.js
index fd4101d..bd7f5c9 100644
--- a/src/mobile/File.js
+++ b/src/mobile/File.js
@@ -68,7 +68,8 @@ s4a.mobile.File = (function() {
};
fileWriter.onerror = function(e) {
- promise.resolve(s4a.mobile.FileResponse.createError(e.toString()));
+ promise.resolve(s4a.mobile.FileResponse
+ .createError('Error writing file: ' + e.toString()));
};
var blob = new Blob([JSON.stringify(contents, null, '\t')], {type: 'text/plain'});
@@ -76,7 +77,8 @@ s4a.mobile.File = (function() {
});
} else {
- promise.resolve(s4a.mobile.FileResponse.createError(fileResponse.messages));
+ promise.resolve(s4a.mobile.FileResponse
+ .createError('Error getting file entry: ' + fileResponse.messages));
}
});
diff --git a/src/viz/Pie.js b/src/viz/Pie.js
deleted file mode 100644
index 8fee5cb..0000000
--- a/src/viz/Pie.js
+++ /dev/null
@@ -1,207 +0,0 @@
-'use strict';
-/**
- * Pie visualization
- *
- * @param {s4a.viz.ViewCoordinator} viewCoordinator
- * @param {s4a.viz.ChartConfig} mChartConfig
- * @constructor
- */
-s4a.viz.Pie = function(viewCoordinator, mChartConfig) {
- var chartData, currentData, currentScale, scale, arc, bigArc;
- var _self = this;
- var transitionTime = 400;
-
- /**
- * Internal reference to Pie svg element.
- * Use getSvg to retrieve it
- *
- * @private
- */
- var svg = d3.select(document.createElementNS(d3.ns.prefix.svg, 'svg'));
-
- function changeCollapsedState(collapsed) {
- currentScale = collapsed ? scale : 1;
-
- var featureWidth = mChartConfig.width * currentScale;
- var featureHeight = mChartConfig.height * currentScale;
- var g = svg.selectAll('g');
-
- if (currentScale === 1) {
- svg.attr('width', featureWidth)
- .attr('height',featureHeight);
-
- $(_self).trigger('resize');
-
- g.attr('transform', 'translate(' + featureWidth / 2 + ',' + featureHeight / 2 + ')');
-
- svg.selectAll('path')
- .transition()
- .duration(transitionTime)
- .attr('d', currentScale === 1 ? bigArc : arc);
- } else {
- svg.selectAll('path')
- .transition()
- .duration(transitionTime)
- .attr('d', currentScale === 1 ? bigArc : arc);
-
- setTimeout(function() {
- svg.attr('width', featureWidth)
- .attr('height',featureHeight);
-
- $(_self).trigger('resize');
-
- g.attr('transform', 'translate(' + featureWidth / 2 + ',' + featureHeight / 2 + ')');
-
- }, transitionTime);
-
- }
- }
-
- /**
- * Create new pie chart
- *
- * @param {integer} width optional width of svg
- * @param {integer} height optional height of svg
- * @private
- */
- function updateChart(width, height) {
- // pick the first series
- currentData = chartData.series[0].values;
-
- // and the first color
- var colors = s4a.viz.color[mChartConfig.colors[0]][currentData.length];
-
- mChartConfig.height = mChartConfig.height || mChartConfig.width;
- mChartConfig.collapsedHeight = mChartConfig.collapsedHeight || mChartConfig.collapsedWidth;
-
- scale = mChartConfig.collapsed ? mChartConfig.collapsedWidth / mChartConfig.width : 1;
-
- currentScale = scale;
-
- var radius = Math.min(mChartConfig.width, mChartConfig.height) / 2;
- var collapsedRadius = Math.min(mChartConfig.collapsedWidth, mChartConfig.collapsedHeight) / 2;
-
- var color = d3.scale.ordinal()
- .range(colors);
-
- arc = d3.svg.arc()
- .outerRadius(collapsedRadius);
-
- bigArc = d3.svg.arc()
- .outerRadius(radius);
-
- if (mChartConfig.innerWidth) {
- bigArc.innerRadius(radius - mChartConfig.innerWidth);
- }
-
- var pie = d3.layout.pie()
- .sort(null)
- .value(function(d) {
- return d.valx;
- });
-
- // delete all current objects
- if (svg) {
- svg.selectAll('*').remove();
- }
-
- var g = svg.selectAll('.arc')
- .data(pie(currentData))
- .enter()
- .append('g')
- .attr('class', 'arc');
-
- // avoid flash
- g.attr('transform', 'translate(' + -4000 + ',' + -4000 + ')');
-
- g.append('path')
- .attr('d', mChartConfig.collapsed ? arc : bigArc)
- .style('fill', function(d) {
- return color(d.data.label);
- });
-
- if (mChartConfig.collapsed) {
- changeCollapsedState(true);
- }
-
- if (mChartConfig.collapsible) {
- g.on('click', function() {
- changeCollapsedState(currentScale === 1);
- });
- }
- }
-
- /**
- * Get the geometry bound to the vizObject
- *
- * @returns {Object} set of lonlat or null
- */
- _self.getGeometry = function() {
- return chartData.geometry;
- };
-
- /**
- * Get the svg representation of the vizObject
- *
- * @returns {d3.svg} set of lonlat or null
- */
- _self.getSvg = function() {
- return svg;
- };
-
- /**
- * Set the visibility of the pie visualization (`true` or `false`).
- *
- * @param {boolean} visible The visibility of the layer.
- */
- _self.setVisible = function(visible) {
- if (svg) {
- svg.attr('display', visible ? null : 'none');
- }
- };
-
- /**
- * Redraw the vizObject
- */
- _self.redraw = function() {
- var g = svg.selectAll('g');
- var featureWidth = mChartConfig.width * currentScale;
- var featureHeight = mChartConfig.height * currentScale;
-
- svg.attr('width', featureWidth)
- .attr('height', featureHeight);
-
- g.attr('transform', 'translate(' + featureWidth / 2 + ',' + featureHeight / 2 + ')');
- };
-
- // Methods inherited from top level vizObj
-
- /**
- * Callback from ViewCoordinator.
- * Update data object for the visualization
- *
- * @param {Object} mChartData
- */
- _self.update = function(mChartData) {
- chartData = mChartData;
- updateChart();
- _self.redraw();
- };
-
- /**
- * Apply a filter to the visualization
- *
- * @abstract
- */
- _self.filter = function() {
- throw new Error('Must be implemented by sub-class');
- };
-
- _self.get = function() {
- throw new Error('Must be implemented by sub-class');
- };
-
- viewCoordinator.subscribe(_self);
-
- return _self;
-};
diff --git a/src/viz/chart/Bubble.js b/src/viz/chart/Bubble.js
new file mode 100644
index 0000000..e2fb4e9
--- /dev/null
+++ b/src/viz/chart/Bubble.js
@@ -0,0 +1,11 @@
+'use strict';
+/**
+ * Create a new bubble chart object
+ *
+ * @class
+ * @classdesc
+ * Stacked bubble chart object
+ */
+s4a.viz.chart.Bubble = function() {
+
+};
diff --git a/src/viz/chart/GroupedBar.js b/src/viz/chart/GroupedBar.js
new file mode 100644
index 0000000..9e63815
--- /dev/null
+++ b/src/viz/chart/GroupedBar.js
@@ -0,0 +1,11 @@
+'use strict';
+/**
+ * Create a new row chart object
+ *
+ * @class
+ * @classdesc
+ * Row chart object
+ */
+s4a.viz.chart.Row = function() {
+
+};
diff --git a/src/viz/chart/Line.js b/src/viz/chart/Line.js
new file mode 100644
index 0000000..3879b64
--- /dev/null
+++ b/src/viz/chart/Line.js
@@ -0,0 +1,13 @@
+'use strict';
+s4a.extend('viz.chart');
+
+/**
+ * Create a new line chart object
+ *
+ * @class
+ * @classdesc
+ * Bar line chart object
+ */
+s4a.viz.chart.Line = function() {
+
+};
diff --git a/src/viz/chart/Pie.js b/src/viz/chart/Pie.js
index 6fc96da..8fee5cb 100644
--- a/src/viz/chart/Pie.js
+++ b/src/viz/chart/Pie.js
@@ -1,11 +1,207 @@
-'use strict';
-/**
- * Create a new Pie chart object
- *
- * @class
- * @classdesc
- * Pie chart object
- */
-s4a.viz.chart.Pie = function() {
-
-};
+'use strict';
+/**
+ * Pie visualization
+ *
+ * @param {s4a.viz.ViewCoordinator} viewCoordinator
+ * @param {s4a.viz.ChartConfig} mChartConfig
+ * @constructor
+ */
+s4a.viz.Pie = function(viewCoordinator, mChartConfig) {
+ var chartData, currentData, currentScale, scale, arc, bigArc;
+ var _self = this;
+ var transitionTime = 400;
+
+ /**
+ * Internal reference to Pie svg element.
+ * Use getSvg to retrieve it
+ *
+ * @private
+ */
+ var svg = d3.select(document.createElementNS(d3.ns.prefix.svg, 'svg'));
+
+ function changeCollapsedState(collapsed) {
+ currentScale = collapsed ? scale : 1;
+
+ var featureWidth = mChartConfig.width * currentScale;
+ var featureHeight = mChartConfig.height * currentScale;
+ var g = svg.selectAll('g');
+
+ if (currentScale === 1) {
+ svg.attr('width', featureWidth)
+ .attr('height',featureHeight);
+
+ $(_self).trigger('resize');
+
+ g.attr('transform', 'translate(' + featureWidth / 2 + ',' + featureHeight / 2 + ')');
+
+ svg.selectAll('path')
+ .transition()
+ .duration(transitionTime)
+ .attr('d', currentScale === 1 ? bigArc : arc);
+ } else {
+ svg.selectAll('path')
+ .transition()
+ .duration(transitionTime)
+ .attr('d', currentScale === 1 ? bigArc : arc);
+
+ setTimeout(function() {
+ svg.attr('width', featureWidth)
+ .attr('height',featureHeight);
+
+ $(_self).trigger('resize');
+
+ g.attr('transform', 'translate(' + featureWidth / 2 + ',' + featureHeight / 2 + ')');
+
+ }, transitionTime);
+
+ }
+ }
+
+ /**
+ * Create new pie chart
+ *
+ * @param {integer} width optional width of svg
+ * @param {integer} height optional height of svg
+ * @private
+ */
+ function updateChart(width, height) {
+ // pick the first series
+ currentData = chartData.series[0].values;
+
+ // and the first color
+ var colors = s4a.viz.color[mChartConfig.colors[0]][currentData.length];
+
+ mChartConfig.height = mChartConfig.height || mChartConfig.width;
+ mChartConfig.collapsedHeight = mChartConfig.collapsedHeight || mChartConfig.collapsedWidth;
+
+ scale = mChartConfig.collapsed ? mChartConfig.collapsedWidth / mChartConfig.width : 1;
+
+ currentScale = scale;
+
+ var radius = Math.min(mChartConfig.width, mChartConfig.height) / 2;
+ var collapsedRadius = Math.min(mChartConfig.collapsedWidth, mChartConfig.collapsedHeight) / 2;
+
+ var color = d3.scale.ordinal()
+ .range(colors);
+
+ arc = d3.svg.arc()
+ .outerRadius(collapsedRadius);
+
+ bigArc = d3.svg.arc()
+ .outerRadius(radius);
+
+ if (mChartConfig.innerWidth) {
+ bigArc.innerRadius(radius - mChartConfig.innerWidth);
+ }
+
+ var pie = d3.layout.pie()
+ .sort(null)
+ .value(function(d) {
+ return d.valx;
+ });
+
+ // delete all current objects
+ if (svg) {
+ svg.selectAll('*').remove();
+ }
+
+ var g = svg.selectAll('.arc')
+ .data(pie(currentData))
+ .enter()
+ .append('g')
+ .attr('class', 'arc');
+
+ // avoid flash
+ g.attr('transform', 'translate(' + -4000 + ',' + -4000 + ')');
+
+ g.append('path')
+ .attr('d', mChartConfig.collapsed ? arc : bigArc)
+ .style('fill', function(d) {
+ return color(d.data.label);
+ });
+
+ if (mChartConfig.collapsed) {
+ changeCollapsedState(true);
+ }
+
+ if (mChartConfig.collapsible) {
+ g.on('click', function() {
+ changeCollapsedState(currentScale === 1);
+ });
+ }
+ }
+
+ /**
+ * Get the geometry bound to the vizObject
+ *
+ * @returns {Object} set of lonlat or null
+ */
+ _self.getGeometry = function() {
+ return chartData.geometry;
+ };
+
+ /**
+ * Get the svg representation of the vizObject
+ *
+ * @returns {d3.svg} set of lonlat or null
+ */
+ _self.getSvg = function() {
+ return svg;
+ };
+
+ /**
+ * Set the visibility of the pie visualization (`true` or `false`).
+ *
+ * @param {boolean} visible The visibility of the layer.
+ */
+ _self.setVisible = function(visible) {
+ if (svg) {
+ svg.attr('display', visible ? null : 'none');
+ }
+ };
+
+ /**
+ * Redraw the vizObject
+ */
+ _self.redraw = function() {
+ var g = svg.selectAll('g');
+ var featureWidth = mChartConfig.width * currentScale;
+ var featureHeight = mChartConfig.height * currentScale;
+
+ svg.attr('width', featureWidth)
+ .attr('height', featureHeight);
+
+ g.attr('transform', 'translate(' + featureWidth / 2 + ',' + featureHeight / 2 + ')');
+ };
+
+ // Methods inherited from top level vizObj
+
+ /**
+ * Callback from ViewCoordinator.
+ * Update data object for the visualization
+ *
+ * @param {Object} mChartData
+ */
+ _self.update = function(mChartData) {
+ chartData = mChartData;
+ updateChart();
+ _self.redraw();
+ };
+
+ /**
+ * Apply a filter to the visualization
+ *
+ * @abstract
+ */
+ _self.filter = function() {
+ throw new Error('Must be implemented by sub-class');
+ };
+
+ _self.get = function() {
+ throw new Error('Must be implemented by sub-class');
+ };
+
+ viewCoordinator.subscribe(_self);
+
+ return _self;
+};
diff --git a/src/viz/chart/StackedLine.js b/src/viz/chart/StackedLine.js
new file mode 100644
index 0000000..227d7f6
--- /dev/null
+++ b/src/viz/chart/StackedLine.js
@@ -0,0 +1,13 @@
+'use strict';
+s4a.extend('viz.chart');
+
+/**
+ * Create a new stacked line chart object
+ *
+ * @class
+ * @classdesc
+ * Stacked line chart object
+ */
+s4a.viz.chart.StackedLine = function() {
+
+};
diff --git a/src/viz/chart/StackedRow.js b/src/viz/chart/StackedRow.js
new file mode 100644
index 0000000..0ba85f0
--- /dev/null
+++ b/src/viz/chart/StackedRow.js
@@ -0,0 +1,11 @@
+'use strict';
+/**
+ * Create a new stacked row chart object
+ *
+ * @class
+ * @classdesc
+ * Stacked row chart object
+ */
+s4a.viz.chart.StackedRow = function() {
+
+};
diff --git a/src/viz/map/Prism.js b/src/viz/map/Prism.js
new file mode 100644
index 0000000..b4010ac
--- /dev/null
+++ b/src/viz/map/Prism.js
@@ -0,0 +1,13 @@
+'use strict';
+s4a.extend('viz.map');
+
+/**
+ * Create a new Prism chart object
+ *
+ * @class
+ * @classdesc
+ * Prism chart object
+ */
+s4a.viz.map.Prism = function() {
+
+};
diff --git a/test/analytics/Routing.test.html b/test/analytics/Routing.test.html
index b79c749..f352423 100644
--- a/test/analytics/Routing.test.html
+++ b/test/analytics/Routing.test.html
@@ -60,7 +60,13 @@
source: geoJsonSource
});
- var myMap = new s4a.map.MapHelper('map');
+ var myMap = new s4a.map.MapHelper('map', {
+ zoomLevel: 8,
+ center: {
+ lon: 14.55,
+ lat: 47.51
+ }
+ });
var myAB = [];
@@ -70,7 +76,6 @@
Routing.getOptimalRoute([1, 2, 3, 5, 6, 7, 10, 100, 14, 16, 23, 1204], 2, 3).then(function (res) {
- console.log(res);
var nodes = res.data;
for (var i = 0; i < nodes.length - 1; i++) {
Routing.getShortestRoute(nodes[i].id, nodes[i + 1].id).then(function (res) {
@@ -122,7 +127,8 @@
geoJsonSource.clear();
if (res.status === 'success' && res.count > 0) {
for (var i = 0; i < res.data.length; i++) {
- var f = vectorFormat.readFeature({type: 'Feature', geometry: JSON.parse(res.data[i].geoJson)}, {
+ console.log(res.data[i]);
+ var f = vectorFormat.readFeature({type: 'Feature', geometry: res.data[i].geometry}, {
featureProjection: 'EPSG:3857'
});
geoJsonSource.addFeature(f);