diff --git a/.gitignore b/.gitignore index 884b522..c88e3ee 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ app/bower_components target .checkDependencies test-results.xml -private/ \ No newline at end of file +private/ +/app/scripts/.local.js \ No newline at end of file diff --git a/app/index.html b/app/index.html index 3386f2c..e0577a8 100644 --- a/app/index.html +++ b/app/index.html @@ -6,8 +6,9 @@ - CLARTIY Scenario Analysis + CLARITY Scenario Analysis + @@ -23,9 +24,12 @@ + + + - + - + diff --git a/samples/claritiyCriteriaFunction.json b/app/samples/claritiyCriteriaFunction.json similarity index 100% rename from samples/claritiyCriteriaFunction.json rename to app/samples/claritiyCriteriaFunction.json diff --git a/samples/clarityHWIndicatorSets.json b/app/samples/clarityHWIndicatorSets.json similarity index 100% rename from samples/clarityHWIndicatorSets.json rename to app/samples/clarityHWIndicatorSets.json diff --git a/samples/clarityHWIndicatorSetsAggregated.json b/app/samples/clarityHWIndicatorSetsAggregated.json similarity index 100% rename from samples/clarityHWIndicatorSetsAggregated.json rename to app/samples/clarityHWIndicatorSetsAggregated.json diff --git a/app/samples/emikatScenarioData.json b/app/samples/emikatScenarioData.json new file mode 100644 index 0000000..951dd3b --- /dev/null +++ b/app/samples/emikatScenarioData.json @@ -0,0 +1,263 @@ +{ + "name": "TAB Impact Results for Impact Assessment Drupal Table", + "description": null, + "columnnames": [ + "HAZARD_EVENT_ID", + "HAZEVENT_NAME", + "IMPACTCASE_ID", + "EARTYPE_ID", + "NAME", + "QUANTITYUNIT", + "VULNERABILITYCLASS_ID", + "VULCLASS_NAME", + "EXPOSEDQUANTITY", + "DAMAGELEVEL1QUANTITY", + "DAMAGELEVEL2QUANTITY", + "DAMAGELEVEL3QUANTITY", + "DAMAGELEVEL4QUANTITY", + "DAMAGELEVEL5QUANTITY", + "SZM_SZENARIO_REF" + ], + "rows": [ + { + "rownum": 0, + "values": [ + 3, + "Heat wave 32°, 6 days", + 1, + 1, + "people", + "number of people", + 26, + "Age 15-65", + 337355.6662325851, + 236277.49887164417, + 87214.87361277906, + 12877.203135764006, + 950.6682674434248, + 35.75970062065402, + 2846 + ] + }, + { + "rownum": 1, + "values": [ + 1, + "Heat wave 28°, 6 days", + 1, + 1, + "people", + "number of people", + 25, + "Age<14", + 139574.36679340914, + 78366.54057476184, + 47947.42392707267, + 11734.435739422286, + 1435.9410855705933, + 90.0254665817489, + 2846 + ] + }, + { + "rownum": 2, + "values": [ + 2, + "Heat wave 30°, 6 days", + 1, + 1, + "people", + "number of people", + 25, + "Age<14", + 114271.6565188171, + 64159.8784423072, + 39255.28507728316, + 9607.16097850651, + 1175.6268022655902, + 73.70521845463703, + 2846 + ] + }, + { + "rownum": 3, + "values": [ + 2, + "Heat wave 30°, 6 days", + 1, + 1, + "people", + "number of people", + 26, + "Age 15-65", + 430805.76740318455, + 301728.1741796098, + 111374.06101790829, + 16444.286947546956, + 1214.010652542174, + 45.665411344737564, + 2846 + ] + }, + { + "rownum": 4, + "values": [ + 3, + "Heat wave 32°, 6 days", + 1, + 1, + "people", + "number of people", + 25, + "Age<14", + 90475.87692282363, + 50799.309664103945, + 31080.816095789913, + 7606.578400532551, + 930.8158217820096, + 58.35694061522125, + 2846 + ] + }, + { + "rownum": 5, + "values": [ + 4, + "Haet wave 34°, 6 days", + 1, + 1, + "people", + "number of people", + 26, + "Age 15-65", + 245296.10211014666, + 171800.72929200664, + 63415.17479802567, + 9363.197513646408, + 691.2444157463933, + 26.001386823675546, + 2846 + ] + }, + { + "rownum": 6, + "values": [ + 4, + "Haet wave 34°, 6 days", + 1, + 1, + "people", + "number of people", + 21, + "Age>65", + 46532.0355980936, + 19389.015125049238, + 18550.414779500396, + 7099.253075094346, + 1358.4562472507446, + 134.94290323447143, + 2846 + ] + }, + { + "rownum": 7, + "values": [ + 1, + "Heat wave 28°, 6 days", + 1, + 1, + "people", + "number of people", + 26, + "Age 15-65", + 525366.538832429, + 367956.74183399545, + 135820.3844516537, + 20053.766153772645, + 1480.4829064297849, + 55.688853116237475, + 2846 + ] + }, + { + "rownum": 8, + "values": [ + 2, + "Heat wave 30°, 6 days", + 1, + 1, + "people", + "number of people", + 21, + "Age>65", + 85802.17894101325, + 35752.13772332034, + 34205.8108544454, + 13090.581034493567, + 2504.9088120039405, + 248.8263189289384, + 2846 + ] + }, + { + "rownum": 9, + "values": [ + 3, + "Heat wave 32°, 6 days", + 1, + 1, + "people", + "number of people", + 21, + "Age>65", + 64833.71786210868, + 27014.978392501303, + 25846.54512919038, + 9891.485833068335, + 1892.7555592664007, + 188.01778180011516, + 2846 + ] + }, + { + "rownum": 10, + "values": [ + 4, + "Haet wave 34°, 6 days", + 1, + 1, + "people", + "number of people", + 25, + "Age<14", + 66266.00651339456, + 37206.24214506262, + 22764.096153520382, + 5571.181965600621, + 681.7446750098032, + 42.74157420113949, + 2846 + ] + }, + { + "rownum": 11, + "values": [ + 1, + "Heat wave 28°, 6 days", + 1, + 1, + "people", + "number of people", + 21, + "Age>65", + 103864.23160243589, + 43278.251888334584, + 41406.41070639549, + 15846.254222888836, + 3032.212377401513, + 301.20627164706406, + 2846 + ] + } + ] +} \ No newline at end of file diff --git a/app/samples/populationDamageClasses.json b/app/samples/populationDamageClasses.json new file mode 100644 index 0000000..84e05f3 --- /dev/null +++ b/app/samples/populationDamageClasses.json @@ -0,0 +1,32 @@ +[ + { + "key": "D1", + "displayName": "Fatigue, discomfort", + "iconResource": "flower_16.png", + "unit": "Persons" + }, + { + "key": "D2", + "displayName": "Heat cramps, heat exhaustion", + "iconResource": "flower_16.png", + "unit": "Persons" + }, + { + "key": "D3", + "displayName": "Heat cramps, heatstroke", + "iconResource": "flower_homeless_16.png", + "unit": "Persons" + }, + { + "key": "D4", + "displayName": "Heatstroke, sunstroke", + "iconResource": "flower_injured_16.png", + "unit": "Persons" + }, + { + "key": "D5", + "displayName": "Death", + "iconResource": "flower_dead_16.png", + "unit": "Persons" + } +] \ No newline at end of file diff --git a/samples/sampleCriteriaFunction_1.json b/app/samples/sampleCriteriaFunction_1.json similarity index 100% rename from samples/sampleCriteriaFunction_1.json rename to app/samples/sampleCriteriaFunction_1.json diff --git a/samples/sampleDecisionStrategy_1.json b/app/samples/sampleDecisionStrategy_1.json similarity index 100% rename from samples/sampleDecisionStrategy_1.json rename to app/samples/sampleDecisionStrategy_1.json diff --git a/samples/sampleIndicatorSet_1.json b/app/samples/sampleIndicatorSet_1.json similarity index 100% rename from samples/sampleIndicatorSet_1.json rename to app/samples/sampleIndicatorSet_1.json diff --git a/samples/sampleIndicatorSet_2.json b/app/samples/sampleIndicatorSet_2.json similarity index 100% rename from samples/sampleIndicatorSet_2.json rename to app/samples/sampleIndicatorSet_2.json diff --git a/samples/sampleIndicatorSet_3.json b/app/samples/sampleIndicatorSet_3.json similarity index 100% rename from samples/sampleIndicatorSet_3.json rename to app/samples/sampleIndicatorSet_3.json diff --git a/app/samples/transformedEmikatScenarioData.json b/app/samples/transformedEmikatScenarioData.json new file mode 100644 index 0000000..8a30ddc --- /dev/null +++ b/app/samples/transformedEmikatScenarioData.json @@ -0,0 +1,158 @@ +[ + { + "name": "Heat wave 28°, 6 days", + "iccdata": { + "indicatorset": { + "displayName": "people", + "iconResource": "flower_injured_16.png", + "indicator1": { + "displayName": "D1", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 43278.251888334584 + }, + "indicator2": { + "displayName": "D2", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 41406.41070639549 + }, + "indicator3": { + "displayName": "D3", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 15846.254222888836 + }, + "indicator4": { + "displayName": "D4", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 3032.212377401513 + }, + "indicator5": { + "displayName": "D5", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 301.20627164706406 + } + } + } + }, + { + "name": "Heat wave 30°, 6 days", + "iccdata": { + "indicatorset": { + "displayName": "people", + "iconResource": "flower_injured_16.png", + "indicator1": { + "displayName": "D1", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 35752.13772332034 + }, + "indicator2": { + "displayName": "D2", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 34205.8108544454 + }, + "indicator3": { + "displayName": "D3", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 13090.581034493567 + }, + "indicator4": { + "displayName": "D4", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 2504.9088120039405 + }, + "indicator5": { + "displayName": "D5", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 248.8263189289384 + } + } + } + }, + { + "name": "Heat wave 32°, 6 days", + "iccdata": { + "indicatorset": { + "displayName": "people", + "iconResource": "flower_injured_16.png", + "indicator1": { + "displayName": "D1", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 27014.978392501303 + }, + "indicator2": { + "displayName": "D2", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 25846.54512919038 + }, + "indicator3": { + "displayName": "D3", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 9891.485833068335 + }, + "indicator4": { + "displayName": "D4", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 1892.7555592664007 + }, + "indicator5": { + "displayName": "D5", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 188.01778180011516 + } + } + } + }, + { + "name": "Haet wave 34°, 6 days", + "iccdata": { + "indicatorset": { + "displayName": "people", + "iconResource": "flower_injured_16.png", + "indicator1": { + "displayName": "D1", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 37206.24214506262 + }, + "indicator2": { + "displayName": "D2", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 22764.096153520382 + }, + "indicator3": { + "displayName": "D3", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 5571.181965600621 + }, + "indicator4": { + "displayName": "D4", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 681.7446750098032 + }, + "indicator5": { + "displayName": "D5", + "iconResource": "flower_injured_16.png", + "unit": "number of people", + "value": 42.74157420113949 + } + } + } + } +] \ No newline at end of file diff --git a/app/scripts/connectors/nodeConnector.js b/app/scripts/connectors/nodeConnector.js index a660472..dd9f7a8 100644 --- a/app/scripts/connectors/nodeConnector.js +++ b/app/scripts/connectors/nodeConnector.js @@ -18,13 +18,8 @@ window.Drupal.behaviors.myBehavior = { // to get node and group id! var groupId = drupalSettings.csisHelpers.entityinfo.study; - // FIXME: this does not work if the iframe is embedded in a separate node that is then referenced - // from the node containg the actual data! var nodeId = drupalSettings.csisHelpers.entityinfo.step; - // ugly workaround parsing the node id from URL study/$1/step/$2 - nodeId = window.location.pathname.split('/')[4]; - console.log('groupId = ' + groupId + ', nodeId = ' + nodeId); var connectCount = 0; // for some unknown the reason angular directive controler of the embedded child iframe diff --git a/app/scripts/controllers/drupalContextProviderDirectiveController.js b/app/scripts/controllers/drupalContextProviderDirectiveController.js index d263f0f..2c9258c 100644 --- a/app/scripts/controllers/drupalContextProviderDirectiveController.js +++ b/app/scripts/controllers/drupalContextProviderDirectiveController.js @@ -5,15 +5,25 @@ angular.module( [ '$scope', '$timeout', + '$http', 'de.cismet.crisma.ICMM.services.icmm', 'de.cismet.crisma.ICMM.Worldstates', 'eu.myclimateservice.csis.scenario-analysis.services.drupalService', - function ($scope, $timeout, Icmm, Worldstates, drupalService) { + function ($scope, $timeout, $http, Icmm, Worldstates, drupalService) { 'use strict'; var showIndicatorFileLoadingError, showFileLoading, loadIndicatorObjects, loadIndicatorObject, onloadCfFile, onloadDsFile, onSeamlessEvent, - onloadIccObjects, loadCriteriaFunctions, loadDecisionStrategies; - var restApi = drupalService.restApi; + onloadIccObjects, loadCriteriaFunctions, loadDecisionStrategies, + damageClasses; + var drupalRestApi = drupalService.drupalRestApi; + var emikatRestApi = drupalService.emikatRestApi; + + // TODO: Load this kinf of information from the Data Package + $http.get('samples/populationDamageClasses.json').success(function (data) { + damageClasses = data; + }).error(function (data, status) { + console.error('Could not load populationDamageClasses: ', status, data); + }); console.log('window.seamless.connect()'); var parent = window.seamless.connect(); @@ -21,7 +31,7 @@ angular.module( // inside the onConnect() method, otherwise the event is not recieved (race condition?) // strangley, the onConnect callback is called twice. See comment in nodeConncetor.js parent.receive(function (data) { - //console.log(' parent.receive:' + data); + //console.log('parent.receive:' + data); onSeamlessEvent(data); }); @@ -151,20 +161,21 @@ angular.module( $scope.showCfFileLoadingError = function (message) { $scope.cfFileLoadError = true; - $scope.cfFileLoadErrorMsg = 'Criteria functions not loaded. ' + message; + $scope.cfFileLoadErrorMsg = ' Criteria functions not loaded. ' + message; //$scope.$apply(); }; $scope.showDsFileLoadingError = function (message) { $scope.dsFileLoadError = true; - $scope.dsFileLoadErrorMsg = 'Decision strategies not loaded. ' + message; + $scope.dsFileLoadErrorMsg = ' Decision strategies not loaded. ' + message; //$scope.$apply(); }; + // onloadIccObjects = function (file) { return function (e) { console.log('load icc file: ' + file.name); - + var fileObj; try { fileObj = JSON.parse(e.target.result); @@ -269,14 +280,14 @@ angular.module( } } } - + // FIXME: don't use displayName as **unique** key !!!111!!11 :o( /**if (loadedIndicatorLength !== indicatorMapLength) { - msg = 'indicator data in file has more indicators ('+loadedIndicatorLength+') defined than the first loaded indicator set ('+indicatorMapLength+').'; - console.error(msg); - showIndicatorFileLoadingError(msg); - return; - }**/ + msg = 'indicator data in file has more indicators ('+loadedIndicatorLength+') defined than the first loaded indicator set ('+indicatorMapLength+').'; + console.error(msg); + showIndicatorFileLoadingError(msg); + return; + }**/ // we need an id to distinct the icc objects. eg. the ranking table use this id // to keep track of the indicator objects @@ -312,7 +323,9 @@ angular.module( console.error(err.toString()); } }; + // + // onloadCfFile = function (theFile) { return function (e) { var criteriaFunctionArray; @@ -397,7 +410,9 @@ angular.module( $scope.showCfFileLoadingError('msg'); } }; + // + // onloadDsFile = function (theFile) { return function (e) { var decisionStrategyArray; @@ -476,18 +491,21 @@ angular.module( } $scope.decisionStrategies = decisionStrategyArray; - console.log(decisionStrategyArray.length + 'decision strategies loaded'); + console.log(decisionStrategyArray.length + ' decision strategies loaded'); } else { msg = 'decision strategy object is not an array or empty'; console.log(msg + ': ' + decisionStrategyArray.toString()); $scope.showCfFileLoadingError('msg'); } }; + // onSeamlessEvent = function (eventData) { console.log('load node from node id: ' + eventData.nodeId); - restApi.getNode(eventData.nodeId).then(function (node) { + // FIXME: This is only for testing purposes! We load load the JSON from the + // IA/RA EU-GL step, but ir should come from the Data Package or EMIKAT REST API! + drupalRestApi.getNode(eventData.nodeId).then(function (node) { var indicatorArray = drupalService.nodeHelper.getIndicatorArray(node); var criteriaFunctionArray = drupalService.nodeHelper.getCriteriaFunction(node); var decisionStrategyArray = drupalService.nodeHelper.getDecisionStrategy(node); @@ -498,8 +516,19 @@ angular.module( console.log(error.data.message); showIndicatorFileLoadingError(error.data.message.toString()); }); + + // FIXME: get scenario and view ids from Data Package + emikatRestApi.getImpactScenario(2846, 2812).then(function (impactScenario) { + //TODO: do something useful here! + console.log(impactScenario); + }, function (error) { + console.log(error.message); + }); }; + + // + /* * When the newFile property has changed the User want's to add a new list of files. */ @@ -575,17 +604,26 @@ angular.module( } }, true); - - - - - // TODO: get node / EU-GL Step Entity id from Drpal API, e.g. - // via request parameter passed to iFrame or via seamless.js parent.receive callback -// $timeout(function () { -// onSeamlessEvent({nodeId:2}) -// }, 1000); - - + // + + // if local file /scripts/.local.js exists, load some test data + if (window.emikatProperties) { + console.warn('/scripts/.local.js found, loading test data'); + emikatRestApi.getImpactScenario( + window.emikatProperties.scenarioId, + window.emikatProperties.viewId, + window.emikatProperties.credentials).then(function (impactScenario) { + //console.log(impactScenario); + var worldstates = drupalService.emikatHelper.transformImpactScenario(impactScenario, damageClasses, true); + + // this is a total mess: worldstates object is awkwardly modified modified by infamous ICCM_Helper + //console.log(JSON.stringify(worldstates)); + + loadIndicatorObjects(worldstates); + }, function (error) { + console.log(error.message); + }); + } } ] ); diff --git a/app/scripts/services/drupalService.js b/app/scripts/services/drupalService.js index aaaca7f..8113d2d 100644 --- a/app/scripts/services/drupalService.js +++ b/app/scripts/services/drupalService.js @@ -17,20 +17,21 @@ angular.module( ['$http', '$resource', '$q', function ($http, $resource, $q) { 'use strict'; - var $this, nodePath, nodeFields; + var $this, nodePath, emikatPath, nodeFields; $this = this; nodePath = '/node/:nodeId'; + emikatPath = '/scenarios/:scenarioId/feature/view.:viewId/table/data'; nodeFields = []; //nodeFields['indicators'] = 'field_mcda_indicators' nodeFields['indicators'] = 'field_mcda_indicators'; nodeFields['criteriaFunction'] = 'field_mcda_criteria_function'; - nodeFields['decisionStrategy'] = 'field_mcda_decision_strategy'; + nodeFields['decisionStrategy'] = 'field_mcda_decision_strategy'; - // + // $this.drupalRestApi = {}; $this.drupalRestApi.host = ''; $this.drupalRestApi.token = undefined; - // + $this.drupalRestApi.emikatCredentials = undefined; $this.drupalRestApi.initToken = function () { return $http({method: 'GET', url: $this.drupalRestApi.host + '/rest/session/token'}) @@ -56,27 +57,58 @@ angular.module( } }; + $this.drupalRestApi.initEmikatCredentials = function () { + return $http({method: 'GET', url: $this.drupalRestApi.host + '/jsonapi/user/user'}) + .then(function initEmikatCredentialsSuccessCallback(response) { + // data.data?! fXXk yeah! :o + if (response !== null && response.data !== null && response.data.data[0] !== null && response.data.data[0].attributes.field_basic_auth_credentials !== null) { + $this.emikatRestApi.emikatCredentials = response.data.data[0].attributes.field_basic_auth_credentials; + console.log('EMIKAT Authentication Info API.'); + return $this.emikatRestApi.emikatCredentials; + } else + { + console.log('error retrieving EMIKAT Credentials: ' + response); + $q.reject(response); + } + }, function initEmikatCredentialsErrorCallback(response) { + $this.emikatRestApi.emikatCredentials = undefined; + console.log('error retrieving EMIKAT Credentials: ' + response); + $q.reject(undefined); + }); + }; + + /** + * return a promise! + */ + $this.drupalRestApi.getEmikatCredentials = function () { + if (!$this.drupalRestApi.emikatCredentials || $this.drupalRestApi.emikatCredentials === null || $this.drupalRestApi.emikatCredentials === undefined) { + return $this.drupalRestApi.initEmikatCredentials(); + } else { + $q.when($this.drupalRestApi.emikatCredentials); + } + }; + $this.drupalRestApi.getNode = function (nodeId) { return $this.drupalRestApi.getToken().then(function tokenSuccessCallback(token) { var nodeResource = $resource($this.drupalRestApi.host + nodePath, - { - nodeId: '@nodeId', - _format: 'hal_json' - - }, { - get: { - method: 'GET', - isArray: false, - headers: { - 'Content-Type': 'application/hal+json', - 'X-CSRF-Token': token + { + nodeId: '@nodeId', + _format: 'hal_json' + + }, { + get: { + method: 'GET', + isArray: false, + headers: { + 'Content-Type': 'application/hal+json', + 'X-CSRF-Token': token + } } - } - }); + }); - var nodeInstance = nodeResource.get({nodeId: nodeId}); - return nodeInstance.$promise; + var nodeInstance = nodeResource.get({nodeId: nodeId}); + return nodeInstance.$promise; }, function tokenErrorCallback(response) { return $q.reject(response); @@ -85,29 +117,67 @@ angular.module( // init the token //$this.drupalRestApi.initToken(); + // + + // + $this.emikatRestApi = {}; + $this.emikatRestApi.host = 'https://service.emikat.at/EmiKatTst/api'; + + $this.emikatRestApi.getImpactScenario = function (scenarioId, viewId, credentials) { + var getImpactScenario = function (scenarioId, viewId, credentials) { + var impactScenarioResource = $resource($this.emikatRestApi.host + emikatPath, + { + scenarioId: '@scenarioId', + viewId: '@nodeId' + }, { + get: { + method: 'GET', + isArray: false, + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Basic ' + btoa(credentials) + } + } + }); + + var impactScenario = impactScenarioResource.get({scenarioId: scenarioId, viewId: viewId}); + return impactScenario.$promise; + }; + if (!credentials) { + return $this.drupalRestApi.getEmikatCredentials().then(function credentialsSuccessCallback(emikatCredentials) { + return getImpactScenario(scenarioId, viewId, emikatCredentials); + }, function credentialsErrorCallback(response) { + return $q.reject(response); + }); + } else { + return getImpactScenario(scenarioId, viewId, credentials); + } + }; + // + // $this.drupalNodeHelper = {}; var getObjectFromDrupalField; $this.drupalNodeHelper.getIndicatorArray = function (node) { return getObjectFromDrupalField(node, nodeFields['indicators']); }; - + $this.drupalNodeHelper.getCriteriaFunction = function (node) { return getObjectFromDrupalField(node, nodeFields['criteriaFunction']); }; - + $this.drupalNodeHelper.getDecisionStrategy = function (node) { return getObjectFromDrupalField(node, nodeFields['decisionStrategy']); - }; - - getObjectFromDrupalField = function(node, field) { + }; + + getObjectFromDrupalField = function (node, field) { if (!node || node === null || node === undefined || !node[field] || node[field] === null || node[field] === undefined) { console.log('node object is null or field "' + field + '" is empty!'); return []; } else { var objects = []; - for(var i = 0; i < node[field].length; i++) { + for (var i = 0; i < node[field].length; i++) { // this is madness: parse into object and later stringify again // so that it can be used by the akward ICMM library (won't touch this thing!) var object = JSON.parse(node[field][i].value); @@ -116,10 +186,106 @@ angular.module( return objects; } }; + // + + // + $this.emikatHelper = {}; + + /** + * Parses, aggregates and transforms emikat API response to ICC DATA Vector + * + * @param {ScenarioData} scenarioData emikat scenario data as obtained from EMIKAT REST PAI + * @param {Array} damageClasses Damage Class information + * @param {boolean} aggregate + * @param {type} icon + * @returns {Array} + */ + $this.emikatHelper.transformImpactScenario = function (scenarioData, damageClasses, aggregate = false, icon = 'flower_injured_16.png') { + var worldstates = [], cMap = {}; + if (!scenarioData || !scenarioData.name || scenarioData.name === null || !scenarioData.rows || !scenarioData.columnnames) { + console.warn('EMIKAT Sceanrio Data is null, cannot transform result to ICC Data Array'); + return worldstates; + } else { + console.info('transforming (and aggregeting: '+aggregate+') EMIKAT Scenario: ' + scenarioData.name); + } + + // fill associative map + for (var i = 0, len = scenarioData.columnnames.length; i < len; i++) { + cMap[scenarioData.columnnames[i]] = i; + } + + // iterate rows + for (i = 0; i < scenarioData.rows.length; i++) { + var column = scenarioData.rows[i].values; + // yes, they start at 1 not at 0! :o + var worldstate = worldstates[column[cMap['HAZARD_EVENT_ID']]-1]; + if (!worldstate || worldstate === null) { + worldstate = {}; + worldstate.name = column[cMap['HAZEVENT_NAME']]; + worldstate.iccdata = {}; + // yes, they start at 1 not at 0! :o + worldstates[column[cMap['HAZARD_EVENT_ID']]-1] = worldstate; + } + + // aggregate by vulnerability class + var indicatorSetKey = 'indicatorset'; + if (aggregate === false) { + indicatorSetKey += column[cMap['VULNERABILITYCLASS_ID']]; + } + + // indicator set (group of indicators) + var indicatorSet = worldstate.iccdata[indicatorSetKey]; + if (!indicatorSet || indicatorSet === null) { + indicatorSet = {}; + indicatorSet.displayName = column[cMap['NAME']]; + if (aggregate === false) { + indicatorSet.displayName += ': ' + column[cMap['VULCLASS_NAME']]; + } + + indicatorSet.iconResource = icon; + worldstate.iccdata[indicatorSetKey] = indicatorSet; + } + + // FIXME: Always 5 damage classes?! + for (var j = 0; j < 5; j++) { + var indicatorKey = 'indicator' + (j+1); + var indicator = indicatorSet[indicatorKey]; + if (!indicator || indicator === null) { + indicator = {}; + + if(damageClasses && damageClasses!== null && damageClasses[j] && damageClasses[j].displayName) { + indicator.displayName = damageClasses[j].displayName; + indicator.iconResource = damageClasses[j].iconResource; + } else { + indicator.displayName = 'D' + (j+1); + indicator.iconResource = icon; + } + + indicator.unit = column[cMap['QUANTITYUNIT']]; + indicator.value = 0; + indicatorSet[indicatorKey] = indicator; + } + + if (aggregate === false) { + indicator.value = column[cMap['DAMAGELEVEL' + (j+1) + 'QUANTITY']]; + } else { + indicator.value += column[cMap['DAMAGELEVEL' + (j+1) + 'QUANTITY']]; + } + } + } + // just to be sure: remove null elements + return worldstates.filter(n => n); + }; + + + + // return { - restApi: $this.drupalRestApi, - nodeHelper: $this.drupalNodeHelper + drupalRestApi: $this.drupalRestApi, + emikatRestApi: $this.emikatRestApi, + nodeHelper: $this.drupalNodeHelper, + emikatHelper: $this.emikatHelper }; } ]); diff --git a/bower.json b/bower.json index d53eb33..5b07785 100644 --- a/bower.json +++ b/bower.json @@ -16,17 +16,17 @@ "package.json" ], "dependencies": { - "seamless.js": "1.3.0", - "angular-strap": "2.1.3", - "angular": "1.2.29", - "angular-resource": "1.2.29", + "seamless.js": "1.4.0", + "angular-strap": "2.1.6", + "angular": "1.2.32", + "angular-resource": "1.2.32", "angular-commons": "0.2.0", "json3": "3.2.6", "es5-shim": "2.1.0", "jquery": "2.1.4", "jquery-ui": "1.10.4", "ng-table": "0.3.3", - "bootstrap": "3.3.7", + "bootstrap": "3.4.1", "icmm_js": "1.1.2", "dynatree": "1.2.8", "crisma-worldstate-tree-widget-angular": "1.0.10", @@ -36,21 +36,20 @@ "jquery-knob": "1.2.13", "ngDialog": "0.2.14", "radar-chart-d3": "1.2.1", - "angular-bootstrap": "0.11.2", - "seamless": "seamless.js#1.3.0", - "html2canvas": "https://github.com/niklasvh/html2canvas/releases/download/v1.0.0-alpha.12/html2canvas.js" + "html2canvas": "https://github.com/niklasvh/html2canvas/releases/download/v1.0.0-alpha.12/html2canvas.js", + "angular-bootstrap": "0.11.2" }, "devDependencies": { - "angular-mocks": "1.2.29", - "angular-scenario": "1.2.29" + "angular-mocks": "1.2.32", + "angular-scenario": "1.2.32" }, "resolutions": { - "bootstrap": "3.3.7", + "bootstrap": "3.4.1", "d3": "3.3.13", "icmm_js": "1.1.2", - "angular": "1.2.29", + "angular": "1.2.32", "jquery": "2.1.4", - "angular-resource": "1.2.29", + "angular-resource": "1.2.32", "dynatree": "1.2.8", "html2canvas": "v1.0.0-alpha.12" } diff --git a/nbproject/customs.json b/nbproject/customs.json index acd03d5..70c151f 100644 --- a/nbproject/customs.json +++ b/nbproject/customs.json @@ -1,10 +1,28 @@ { "elements": { + "criteria-function-manager": {}, + "relation-analysis-chart": {}, + "tab-content": {}, "indicator-band": { "attributes": { "criteria-function": {} } - } + }, + "tab": {}, + "worldstate-ranking-table": {}, + "indicator-criteria-table": {}, + "drupal-context-provider": {}, + "indicator-bar-charts": {}, + "tab-heading": {}, + "tabset": {}, + "decision-strategy-manager": {} }, - "attributes": {} + "attributes": { + "dropdown": { + "context": "div" + }, + "collapse": { + "context": "div" + } + } } \ No newline at end of file diff --git a/nbproject/project.properties b/nbproject/project.properties index dc93023..8b1e61c 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -7,7 +7,10 @@ auxiliary.org-netbeans-modules-css-prep.sass_2e_mappings=/scss:/css auxiliary.org-netbeans-modules-javascript-grunt.action_2e_build=build auxiliary.org-netbeans-modules-javascript-grunt.action_2e_clean=clean auxiliary.org-netbeans-modules-javascript-grunt.action_2e_rebuild=--force clean dist +auxiliary.org-netbeans-modules-javascript-nodejs.enabled=false +auxiliary.org-netbeans-modules-javascript-nodejs.node_2e_default=true auxiliary.org-netbeans-modules-javascript-nodejs.run_2e_enabled=false +auxiliary.org-netbeans-modules-javascript-nodejs.sync_2e_enabled=true auxiliary.org-netbeans-modules-javascript2-requirejs.enabled=true auxiliary.org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder=js/libs browser.autorefresh.Chrome=false