From 0bfc1bb61796a1f8def75604390a093f4261b2e4 Mon Sep 17 00:00:00 2001 From: Christian Matyas Date: Wed, 3 Feb 2016 15:00:11 +0100 Subject: [PATCH] version with topic and region view --- .gitignore | 1 + .idea/vcs.xml | 6 + .idea/workspace.xml | 603 +- Web.config | 11 +- app/app.js | 2 +- app/app.routes.js | 14 +- .../colorbrewer-picker.component.html | 27 + .../colorbrewer-picker.component.js | 19 + .../region-view/region-view.component.html | 30 + .../region-view/region-view.component.js | 125 + .../regions-map/regions-map.component.html | 25 + .../regions-map/regions-map.component.js | 373 +- .../regions-pie/regions-pie.component.html | 6 + .../regions-pie/regions-pie.component.js | 119 + .../topic-table/topic-table.component.html | 39 +- .../topic-table/topic-table.component.js | 24 +- .../topic-table/topic-table.component.spec.js | 8 +- .../topic-view/topic-view.component.html | 33 + .../topic-view/topic-view.component.js | 43 + .../topics-buttons.component.html | 6 + .../topics-buttons.component.js | 17 + .../topics-navigation.component.html | 22 +- .../topics-navigation.component.js | 44 + app/controllers.js | 21 +- app/services/ColorBrewer.service.js | 318 + app/services/RegionData.service.js | 34 + app/services/RegionData.service.spec.js | 58 + app/services/TopicData.service.js | 25 +- app/services/TopicData.service.spec.js | 44 +- app/vendor/d3/angular-nvd3.js | 579 + app/vendor/d3/angular-nvd3.min.js | 1 + app/vendor/d3/d3pie.js | 2155 +++ app/vendor/d3/d3pie.min.js | 9 + app/vendor/d3/nv.d3.css | 647 + app/vendor/d3/nv.d3.js | 14104 ++++++++++++++++ app/vendor/d3/nv.d3.min.css | 2 + app/vendor/d3/nv.d3.min.css.map | 1 + app/vendor/d3/nv.d3.min.js | 11 + app/vendor/d3/nv.d3.min.js.map | 1 + app/views/impressum.html | 60 + app/views/main.html | 9 +- app/views/topic.html | 9 - css/index.css | 121 +- index.html | 52 +- karma.conf.js | 4 + 45 files changed, 19499 insertions(+), 363 deletions(-) create mode 100644 .gitignore create mode 100644 .idea/vcs.xml create mode 100644 app/components/colorbrewer-picker/colorbrewer-picker.component.html create mode 100644 app/components/colorbrewer-picker/colorbrewer-picker.component.js create mode 100644 app/components/region-view/region-view.component.html create mode 100644 app/components/region-view/region-view.component.js create mode 100644 app/components/regions-map/regions-map.component.html create mode 100644 app/components/regions-pie/regions-pie.component.html create mode 100644 app/components/regions-pie/regions-pie.component.js create mode 100644 app/components/topic-view/topic-view.component.html create mode 100644 app/components/topic-view/topic-view.component.js create mode 100644 app/components/topics-buttons/topics-buttons.component.html create mode 100644 app/components/topics-buttons/topics-buttons.component.js create mode 100644 app/services/ColorBrewer.service.js create mode 100644 app/services/RegionData.service.js create mode 100644 app/services/RegionData.service.spec.js create mode 100644 app/vendor/d3/angular-nvd3.js create mode 100644 app/vendor/d3/angular-nvd3.min.js create mode 100644 app/vendor/d3/d3pie.js create mode 100644 app/vendor/d3/d3pie.min.js create mode 100644 app/vendor/d3/nv.d3.css create mode 100644 app/vendor/d3/nv.d3.js create mode 100644 app/vendor/d3/nv.d3.min.css create mode 100644 app/vendor/d3/nv.d3.min.css.map create mode 100644 app/vendor/d3/nv.d3.min.js create mode 100644 app/vendor/d3/nv.d3.min.js.map create mode 100644 app/views/impressum.html delete mode 100644 app/views/topic.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index de94cbe..3385c4f 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,7 +1,23 @@ - + + + + + + + + + + + + + + + + + - - + + - + - - + + - - - - - + + + - - + + - - - - + + @@ -59,37 +71,69 @@ - + + + + + + + + + + + - + + + + + + + + + + + - - + + - - + + + + + + + + + + + + + + - - + + - - + + - + @@ -101,25 +145,36 @@ + + @@ -131,12 +186,12 @@ true - - + @@ -162,6 +217,7 @@ + @@ -212,6 +268,20 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + - - - @@ -328,19 +519,46 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + @@ -352,8 +570,27 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - @@ -393,9 +730,6 @@ - - - @@ -411,7 +745,6 @@ - @@ -419,7 +752,6 @@ - @@ -427,7 +759,6 @@ - @@ -435,9 +766,6 @@ - - - @@ -445,9 +773,6 @@ - - - @@ -463,7 +788,6 @@ - @@ -474,24 +798,45 @@ - + + + + + + + + - + - + - - + + - + + + + + + + + - + + + + + + + + @@ -502,90 +847,140 @@ - + - + - + - - + + - + - - + + - + + + + + + + + + + + + + + + - - - - + - - - - - + + + + + + + + + - + - + - - + + + - + - + - + - - + + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + diff --git a/Web.config b/Web.config index 3efb09f..a42b389 100644 --- a/Web.config +++ b/Web.config @@ -1,6 +1,13 @@ - + - + + + + + + + + \ No newline at end of file diff --git a/app/app.js b/app/app.js index 9720320..24ac053 100644 --- a/app/app.js +++ b/app/app.js @@ -1,7 +1,7 @@ (function () { 'user strict'; - angular.module('biloAtlas', ['ngRoute']); + angular.module('biloAtlas', ['ngRoute','nvd3']); /* .config(['$compileProvider', function ($compileProvider) { //Add ms-appx-web prefix to whitelist otherwise windows 10 add "unsafe:" prefix to links and breaks angularjs links diff --git a/app/app.routes.js b/app/app.routes.js index 3c7d2aa..5e0481f 100644 --- a/app/app.routes.js +++ b/app/app.routes.js @@ -6,16 +6,16 @@ function($routeProvider) { $routeProvider. when('/', { - templateUrl: 'app/views/main.html', - controller: 'atlasController' + templateUrl: 'app/views/main.html' }). when('/topic/:topicid', { - templateUrl: 'app/views/topic.html', - controller: 'topicController' + template: '', }). - when('/region/:region', { - templateUrl: 'app/views/region.html', - controller: 'regionController' + when('/region/:regionid', { + template: '', + }). + when('/impressum', { + templateUrl: 'app/views/impressum.html' }). otherwise({ redirectTo: '/' diff --git a/app/components/colorbrewer-picker/colorbrewer-picker.component.html b/app/components/colorbrewer-picker/colorbrewer-picker.component.html new file mode 100644 index 0000000..1ad8e2f --- /dev/null +++ b/app/components/colorbrewer-picker/colorbrewer-picker.component.html @@ -0,0 +1,27 @@ +
+
+
+ +   + +
+
+ + +
+
+
+ + +
+
+
+ +   + +
+
+
+ + + diff --git a/app/components/colorbrewer-picker/colorbrewer-picker.component.js b/app/components/colorbrewer-picker/colorbrewer-picker.component.js new file mode 100644 index 0000000..4665288 --- /dev/null +++ b/app/components/colorbrewer-picker/colorbrewer-picker.component.js @@ -0,0 +1,19 @@ +/** + * Created by CMatyas on 15.12.2015. + */ +(function(){ + 'use strict' + + angular.module('biloAtlas'). + component('colorbrewerPicker',{ + templateUrl: 'app/components/colorbrewer-picker/colorbrewer-picker.component.html', + bindings: { + schema: '=' + }, + controller: function(ColorBrewer){ + this.opencolors = false + this.colors = ColorBrewer.colors; + //this.schema = this.colors.PuBu[6]; + } + }); +})(); \ No newline at end of file diff --git a/app/components/region-view/region-view.component.html b/app/components/region-view/region-view.component.html new file mode 100644 index 0000000..fbd584a --- /dev/null +++ b/app/components/region-view/region-view.component.html @@ -0,0 +1,30 @@ +
+

{{topic.name}} in {{regionView.region}}

+
+

{{layer.name}}

+
+
+

+ {{layer.description}} +

+ +
+
+ Quelle: +
+
{{layer.source}}
+ +
+ Berechnung: +
+
{{layer.calculation}}
+
+
+
+ +
+
+ + +
+
\ No newline at end of file diff --git a/app/components/region-view/region-view.component.js b/app/components/region-view/region-view.component.js new file mode 100644 index 0000000..1fb9578 --- /dev/null +++ b/app/components/region-view/region-view.component.js @@ -0,0 +1,125 @@ +(function(){ + 'use strict' + + angular.module('biloAtlas') + .component('regionView', { + templateUrl: 'app/components/region-view/region-view.component.html', + binding: {}, + controller: function(RegionData, $routeParams){ + this.topics = []; + + this.options = { + chart: { + type: 'lineChart', + height: 250, + margin : { + top: 20, + right: 20, + bottom: 40, + left: 55 + }, + x: function(d){ return d.year; }, + y: function(d){ return d.value; }, + useInteractiveGuideline: true, + dispatch: { + stateChange: function(e){ console.log("stateChange"); }, + changeState: function(e){ console.log("changeState"); }, + tooltipShow: function(e){ console.log("tooltipShow"); }, + tooltipHide: function(e){ console.log("tooltipHide"); } + }, + xAxis: { + axisLabel: 'Jahr' + }, + yAxis: { + axisLabel: '%', + axisLabelDistance: -10 + }, + callback: function(chart){ + + } + }, + title: { + enable: false + }, + subtitle: { + enable: false + }, + caption: { + enable: false + } + }; + + + this.getLayerData = function(id){ + return this.layersData[id].data; + } + this.getLayerOptions = function(id){ + return this.layersData[id].options; + } + + RegionData.getRegionById($routeParams.regionid).then(function(regionTopics){ + + + //Prepare data for linecharts + var layersData = []; + regionTopics.topics.forEach(function(topic){ + topic.layers.forEach(function(layer){ + var layerData = []; + layerData.push({values: layer.data.map(function(d) { return {value: d.value, year: d.year}} ), key: layer.name}); + layerData.push({values: layer.data.map(function(d){ return {value: d.averageUF.toPrecision(2), year: d.year}; }), key: 'Oberfranken', color: '#CCC'}); + layersData[layer.id] = {options: getOptions(layer.name, layer.unit), data: layerData}; + }.bind(layersData)) + }.bind(layersData)) + + this.layersData = layersData; + this.topics = regionTopics.topics; + this.region = regionTopics.region.name; + }.bind(this)); + + + function getOptions(name, unit){ + return { + chart: { + type: 'lineChart', + height: 250, + margin : { + top: 20, + right: 20, + bottom: 40, + left: 55 + }, + x: function(d){ return d.year; }, + y: function(d){ return d.value; }, + useInteractiveGuideline: true, + dispatch: { + stateChange: function(e){ console.log("stateChange"); }, + changeState: function(e){ console.log("changeState"); }, + tooltipShow: function(e){ console.log("tooltipShow"); }, + tooltipHide: function(e){ console.log("tooltipHide"); } + }, + xAxis: { + axisLabel: 'Jahr' + }, + yAxis: { + axisLabel: unit, + axisLabelDistance: -10 + }, + callback: function(chart){ + + } + }, + title: { + enable: false + }, + subtitle: { + enable: false + }, + caption: { + enable: true, + html: '
'+name+'
' + + } + }; + } + }}); +})() \ No newline at end of file diff --git a/app/components/regions-map/regions-map.component.html b/app/components/regions-map/regions-map.component.html new file mode 100644 index 0000000..a7c02f2 --- /dev/null +++ b/app/components/regions-map/regions-map.component.html @@ -0,0 +1,25 @@ +
+ + + +
+ +
+ +
+ +
+ + +
+
0
+
{{maxValue}}
+
+
+ + +
+ +
diff --git a/app/components/regions-map/regions-map.component.js b/app/components/regions-map/regions-map.component.js index fd61c44..b754401 100644 --- a/app/components/regions-map/regions-map.component.js +++ b/app/components/regions-map/regions-map.component.js @@ -2,177 +2,222 @@ 'use strict' angular.module('biloAtlas') - .directive('regionsMap', function(d3Service) { + .directive('regionsMap', function(ColorBrewer) { return { restrict: 'EA', scope: { - mainStats: '=info1', - additionalStats: '=info2', - active: '@', - selection: '=' + stats: '=', + year: '=' }, - link: function (scope, element, attrs) { - d3Service.d3().then(function (d3) { - /****************************** - * D3 TEST - *******************************/ - var width = element[0].clientWidth; - var height = 400; - - //currently selected region - var active = d3.select(null); - - var projection_oberfranken; - var pathTopo; - - var maxValue = d3.max(scope.mainStats, function (d) { return d.value; }); - var regionColors = d3.scale.ordinal() - .domain([0, maxValue]) - .range(colorbrewer.PuBu[9]); - - var svg_topo = d3.select(element[0]).append("svg") - .attr("width", width) - .attr("height", height); - - - var regions = svg_topo.append("g") - .attr("class", "black"); - - var locations, - labels, - oberfranken; - - - d3.json("data/maps/oberfranken.js", function (error, d) { - if (error) return log(error); - oberfranken = d; - - var center = d3.geo.centroid(oberfranken); - var scale = 150; - var offset = [width / 2, height / 2]; - - // projection - projection_oberfranken = d3.geo.albers() - .rotate([0, 0]) - .center(center) - .scale(scale) - .translate(offset); - pathTopo = d3.geo.path() - .projection(projection_oberfranken); - - var bounds = pathTopo.bounds(oberfranken); - var hscale = 0.5 * scale * width / (bounds[1][0] - bounds[0][0]); - var vscale = 0.5 * scale * height / (bounds[1][1] - bounds[0][1]); - scale = (hscale < vscale) ? hscale : vscale; - offset = [width - (bounds[0][0] + bounds[1][0]) / 2, - height - (bounds[0][1] + bounds[1][1]) / 2]; - - // new projection - projection_oberfranken = d3.geo.mercator().center(center) - .scale(scale).translate(offset); - pathTopo = d3.geo.path() - .projection(projection_oberfranken); - - regions.selectAll("path") - .data(oberfranken.features) - .enter() - .append("path") - .attr("fill", function (d) { return regionColors(getStat(d.properties.ID_3)); }) - .attr("title", function (d) { return d.properties.NAME_3; }) - .attr("class", function (d) { return "subunit " + d.properties.NAME_3.replace(" ", "_"); }) - .attr("d", pathTopo) - .on("click", clicked) - .on("mouseover", function (d) { - lifbi.tooltip.showTooltip(d.properties.NAME_3); - d3.select(this).attr("fill", "#FFFFCC"); - scope.active = d.properties.ID_3; - }) - .on("mouseout", function (d) { - lifbi.tooltip.hideTooltip(); - d3.select(this).attr("fill", function (d) { return regionColors(getStat(d.properties.ID_3)) }); - }); - }); - - d3.json("data/maps/oberfranken_cities.js", function (graph) { - locations = svg_topo.selectAll(".locations") - .data(graph.locations) - .enter().append("circle") - .attr("class", "node") - .attr("id", function (d) { return "node_" + d.id; }) - .attr("title", function (d) { return d.name; }) - .attr("r", function (d) { return d.type == 0 ? 6 : 4 }) - .attr("cx", function (d) { return projection_oberfranken([d.lat, d.lon])[0]; }) - .attr("cy", function (d) { return projection_oberfranken([d.lat, d.lon])[1]; }) - .style("fill", function (d) { return d.type == 0 ? "#fff" : "#f00" }) - .style("stroke", "#666"); - - var labelDistance = 10; - labels = svg_topo.selectAll(".place-label") - .data(graph.locations).enter().append("text").attr("class", "place-label") - .attr("transform", function (d) { return "translate(" + projection_oberfranken([d.lat, d.lon]) + ")"; }) - .attr("dy", ".35em") - .text(function (d) { return d.name; }) - .attr("x", function (d) { return d.lat > 10 ? labelDistance : -1 * labelDistance; }) - .style("text-anchor", function (d) { return d.lat > 10 ? "start" : "end"; }); - }); - - - function getStat(id) { - for (var i = 0; i < scope.mainStats.length; ++i) { - if (scope.mainStats[i].id == id) { - return scope.mainStats[i].value; - } - } - return 0; + templateUrl: 'app/components/regions-map/regions-map.component.html', + controller: function($scope){ + var self = $scope; + self.schemecolors = ColorBrewer.colors.PuBu[9]; + }, + link: function (scope, element, attrs) { + scope.render = function(data){ + //d3Service.d3().then(function (d3) { + console.log("starting render function"); + + /****************************** + * D3 TEST + *******************************/ + var width = element[0].clientWidth; + var height = 400; + + //currently selected region + var active = d3.select(null); + + var projection_oberfranken; + var pathTopo; + + var colors = scope.schemecolors; + var regionScale = d3.scale.linear() + .domain([0, scope.maxValue]) + .range([0,colors.length-1]); + //.range(ColorBrewer.colors.PuBu[9]); + var regionColors = function(value){ + if(value == 0) return "#FFF"; + return colors[Math.floor(regionScale(value))]; + } + scope.regionColors = ["#FFF"].concat(colors); + + //HACK.... Remove entire map, data could also be + d3.select(element[0]).select("svg").remove(); + var svg_topo = d3.select("#regions-map").append("svg") + .attr("width", width) + .attr("height", height); + + + var regions = svg_topo.append("g") + .attr("class", "black"); + + var locations, + labels, + oberfranken; + + + d3.json("data/maps/oberfranken.js", function (error, d) { + if (error) return log(error); + oberfranken = d; + + var center = d3.geo.centroid(oberfranken); + var scale = 150; + var offset = [width / 2, height / 2]; + + // projection + projection_oberfranken = d3.geo.albers() + .rotate([0, 0]) + .center(center) + .scale(scale) + .translate(offset); + pathTopo = d3.geo.path() + .projection(projection_oberfranken); + + var bounds = pathTopo.bounds(oberfranken); + var hscale = 0.6 * scale * width / (bounds[1][0] - bounds[0][0]); + var vscale = 0.6 * scale * height / (bounds[1][1] - bounds[0][1]); + scale = (hscale < vscale) ? hscale : vscale; + offset = [width - (bounds[0][0] + bounds[1][0]) / 2, + height - (bounds[0][1] + bounds[1][1]) / 2]; + + // new projection + projection_oberfranken = d3.geo.mercator().center(center) + .scale(scale).translate(offset); + pathTopo = d3.geo.path() + .projection(projection_oberfranken); + + regions.selectAll("path") + .data(oberfranken.features) + .enter() + .append("path") + .attr("fill", function (d) { return regionColors(getStat(d.properties.ID_3)); }) + .attr("title", function (d) { return d.properties.NAME_3; }) + .attr("class", function (d) { return "subunit " + d.properties.NAME_3.replace(" ", "_"); }) + .attr("d", pathTopo) + .on("click", clicked) + .on("mouseover", function (d) { + lifbi.tooltip.showTooltip(d.properties.NAME_3 + " " + getStat(d.properties.ID_3)); + d3.select(this).attr("fill", "#FFFFCC"); + scope.active = d.properties.ID_3; + scope.selection = d.properties.ID_3; + scope.$apply(); + }) + .on("mouseout", function (d) { + lifbi.tooltip.hideTooltip(); + d3.select(this).attr("fill", function (d) { return regionColors(getStat(d.properties.ID_3)) }); + }); + + d3.json("data/maps/oberfranken_cities.js", function (graph) { + locations = svg_topo.selectAll(".locations") + .data(graph.locations) + .enter().append("circle") + .attr("class", "node") + .attr("id", function (d) { return "node_" + d.id; }) + .attr("title", function (d) { return d.name; }) + .attr("r", function (d) { return d.type == 0 ? 6 : 4 }) + .attr("cx", function (d) { return projection_oberfranken([d.lat, d.lon])[0]; }) + .attr("cy", function (d) { return projection_oberfranken([d.lat, d.lon])[1]; }) + .style("fill", function (d) { return d.type == 0 ? "#fff" : "#f00" }) + .style("stroke", "#666"); + + var labelDistance = 10; + labels = svg_topo.selectAll(".place-label") + .data(graph.locations).enter().append("text").attr("class", "place-label") + .attr("transform", function (d) { return "translate(" + projection_oberfranken([d.lat, d.lon]) + ")"; }) + .attr("dy", ".35em") + .text(function (d) { return d.name; }) + .attr("x", function (d) { return d.lat > 10 ? labelDistance : -1 * labelDistance; }) + .style("text-anchor", function (d) { return d.lat > 10 ? "start" : "end"; }); + }); + }); + + function getStat(id) { + if(!data) return 0; + + for (var i = 0; i < data.length; ++i) { + if (data[i].id == id ) { + return data[i].value; + } + } + return 0; + } + + //Zoom on click + function fitToScreen() { + var d = oberfranken; + var bounds = pathTopo.bounds(d), + dx = bounds[1][0] - bounds[0][0], + dy = bounds[1][1] - bounds[0][1], + x = (bounds[0][0] + bounds[1][0]) / 2, + y = (bounds[0][1] + bounds[1][1]) / 2, + scale = .9 / Math.max(dx / width, dy / height), + translatex = width / 2 - scale * x, + translatey = height / 2 - scale * y, + translate = [translatex, translatey]; + regions//.transition() + //.duration(750) + .style("stroke-width", 1.5 / scale + "px") + .attr("transform", "translate(" + translate + ")scale(" + scale + ")"); + locations//.transition() + //.duration(750) + .attr("cx", translatex) + .attr("cy", translatey); + labels//.transition() + //.duration(750) + .attr("transform", "translate(" + translate + ")"); + } + + //Zoom on click + function clicked(d) { + if (active.node() === this) return fitToScreen(); + active.classed("active", false); + active = d3.select(this).classed("active", true); + var bounds = pathTopo.bounds(d), + dx = bounds[1][0] - bounds[0][0], + dy = bounds[1][1] - bounds[0][1], + x = (bounds[0][0] + bounds[1][0]) / 2, + y = (bounds[0][1] + bounds[1][1]) / 2, + scale = .9 / Math.max(dx / width, dy / height), + translate = [width / 2 - scale * x, height / 2 - scale * y], + translatex = width / 2 - scale * x, + translatey = height / 2 - scale * y; + regions.transition() + .duration(750) + .style("stroke-width", 1.5 / scale + "px") + .attr("transform", "translate(" + translate + ")scale(" + scale + ")"); + locations.attr("cx", translatex) + .attr("cy", translatey); + } + //} + //); + } + + scope.$watch('stats', function(data){ + //Calculate max using all years + scope.maxValue = 0; + if(data == undefined) { + return; } - - //Zoom on click - function fitToScreen() { - var d = oberfranken; - var bounds = pathTopo.bounds(d), - dx = bounds[1][0] - bounds[0][0], - dy = bounds[1][1] - bounds[0][1], - x = (bounds[0][0] + bounds[1][0]) / 2, - y = (bounds[0][1] + bounds[1][1]) / 2, - scale = .9 / Math.max(dx / width, dy / height), - translatex = width / 2 - scale * x, - translatey = height / 2 - scale * y, - translate = [translatex, translatey]; - regions//.transition() - //.duration(750) - .style("stroke-width", 1.5 / scale + "px") - .attr("transform", "translate(" + translate + ")scale(" + scale + ")"); - locations//.transition() - //.duration(750) - .attr("cx", translatex) - .attr("cy", translatey); - labels//.transition() - //.duration(750) - .attr("transform", "translate(" + translate + ")"); + data.forEach( + function (d) { if(d.value > scope.maxValue) scope.maxValue = d.value; } + ); + + scope.render(data.filter(function(d){return d.year == scope.year})); + }) + scope.$watch('year', function(year){ + if(scope.stats == undefined) { + return; } - - //Zoom on click - function clicked(d) { - if (active.node() === this) return fitToScreen(); - active.classed("active", false); - active = d3.select(this).classed("active", true); - var bounds = pathTopo.bounds(d), - dx = bounds[1][0] - bounds[0][0], - dy = bounds[1][1] - bounds[0][1], - x = (bounds[0][0] + bounds[1][0]) / 2, - y = (bounds[0][1] + bounds[1][1]) / 2, - scale = .9 / Math.max(dx / width, dy / height), - translate = [width / 2 - scale * x, height / 2 - scale * y], - translatex = width / 2 - scale * x, - translatey = height / 2 - scale * y; - regions.transition() - .duration(750) - .style("stroke-width", 1.5 / scale + "px") - .attr("transform", "translate(" + translate + ")scale(" + scale + ")"); - locations.attr("cx", translatex) - .attr("cy", translatey); + scope.render(scope.stats.filter(function(d){return d.year == year})); + }) + + scope.$watch('schemecolors', function(year){ + if(scope.stats == undefined) { + return; } - }); + scope.render(scope.stats.filter(function(d){return d.year == scope.year})); + }) } } } diff --git a/app/components/regions-pie/regions-pie.component.html b/app/components/regions-pie/regions-pie.component.html new file mode 100644 index 0000000..430da65 --- /dev/null +++ b/app/components/regions-pie/regions-pie.component.html @@ -0,0 +1,6 @@ +
+ +
+
0
+
{{maxValue}}
+
\ No newline at end of file diff --git a/app/components/regions-pie/regions-pie.component.js b/app/components/regions-pie/regions-pie.component.js new file mode 100644 index 0000000..837946d --- /dev/null +++ b/app/components/regions-pie/regions-pie.component.js @@ -0,0 +1,119 @@ +(function () { + 'use strict' + + angular.module('biloAtlas') + .directive('regionsPie', function(ColorBrewer) { + return { + restrict: 'EA', + scope: { + stats: '=', + year: '=' + }, + templateUrl: 'app/components/regions-pie/regions-pie.component.html', + controller: function($scope){ + var self = $scope; + self.schemecolors = ColorBrewer.colors.PuBu[9]; + }, + link: function (scope, element, attrs) { + + + scope.render = function(data){ + //d3Service.d3().then(function (d3) { + var colors = scope.schemecolors; + var regionScale = d3.scale.linear() + .domain([0, scope.maxValue]) + .range([0,colors.length-1]); + //.range(ColorBrewer.colors.PuBu[9]); + var regionColors = function(value){ + if(value == 0) return "#FFF"; + return colors[Math.floor(regionScale(value))]; + } + scope.regionColors = ["#FFF"].concat(colors); + + data = data.map(function(i){ return {label: i.name, value: i.value, color: regionColors(i.value)}}); + + //update data + //if(scope.pie != undefined){ + // scope.pie.updateProp("data.content", data); + // return; + //} + + + console.log("starting rendering pie function"); + + /****************************** + * D3 TEST + *******************************/ + var width = element[0].clientWidth; + var height = 400; + + //currently selected region + var active = d3.select(null); + + //HACK.... Remove entire map, data could also be + d3.select(element[0]).select("svg").remove(); + + scope.pie = new d3pie("regions-pie", { + header: { + title: { + text: "" + } + }, + data: { + sortOrder: "value-desc", + content: data + }, + labels: { + outer: { + format: "label-value2" + }, + inner: { + format: "none" + }, + mainLabel: { + color: "#333", + font: "arial", + fontSize: 10 + } + }, + tooltips: { + enabled: true, + type: "placeholder", + string: "{label} {value}" + } + }); + + + //}) + }; + + scope.$watch('stats', function(data){ + //Calculate max using all years + scope.maxValue = 0; + if(data == undefined) { + return; + } + data.forEach( + function (d) { if(d.value > scope.maxValue) scope.maxValue = d.value; } + ); + + scope.render(data.filter(function(d){return d.year == scope.year})); + }) + scope.$watch('year', function(year){ + if(scope.stats == undefined) { + return; + } + scope.render(scope.stats.filter(function(d){return d.year == year})); + }) + + scope.$watch('schemecolors', function(year){ + if(scope.stats == undefined) { + return; + } + scope.render(scope.stats.filter(function(d){return d.year == scope.year})); + }) + } + } + } + ) +})(); \ No newline at end of file diff --git a/app/components/topic-table/topic-table.component.html b/app/components/topic-table/topic-table.component.html index 2fe6d6e..e64e40f 100644 --- a/app/components/topic-table/topic-table.component.html +++ b/app/components/topic-table/topic-table.component.html @@ -1,15 +1,36 @@ -

{{topicTable.topic.name}}

-

{{topicTable.topic.description}}

+ +

{{topicTable.layer.name}}

+

+ {{topicTable.layer.description}} +

- +
+
+ Quelle: +
+
{{topicTable.layer.source}}
+ +
+ Berechnung: +
+
{{topicTable.layer.calculation}}
+
+ Durchschnitt Oberfranken: +
+
{{topicTable.average()}}{{topicTable.unit()}}
+
+ +
- - - + + + + - - - + + + +
RegionValue
Region Wert Jahr
{{stat.name}}{{stat.value}}
{{stat.name}}{{stat.value}}{{topicTable.unit()}}{{stat.year}}
diff --git a/app/components/topic-table/topic-table.component.js b/app/components/topic-table/topic-table.component.js index 3e35f6c..3aa3823 100644 --- a/app/components/topic-table/topic-table.component.js +++ b/app/components/topic-table/topic-table.component.js @@ -5,11 +5,27 @@ .component('topicTable', { templateUrl: 'app/components/topic-table/topic-table.component.html', bindings: { - id: '@' + id: '@', + layer: '=', + year: '=' }, - controller: function(TopicData){ - this.topic = TopicData.getTopicById(this.id); - this.sortOrder = 'name'; + controller: function($routeParams,TopicData){ + this.sortOrder = '-value'; + this.unit = function(){ + return this.layer.unit; + } + + this.average = function(){ + if(this.layer != [] && this.layer.data != undefined){ + var dataOfYear = this.layer.data.filter(d => d.year == this.year ).map( x => x.value); + + if(dataOfYear.length > 0){ + var sum = dataOfYear.reduce((p, c) => p + c) + return parseFloat((sum / dataOfYear.length)+'').toFixed(2); + } + } + return 0.0; + } } }) })() \ No newline at end of file diff --git a/app/components/topic-table/topic-table.component.spec.js b/app/components/topic-table/topic-table.component.spec.js index 6a6a4bf..afff409 100644 --- a/app/components/topic-table/topic-table.component.spec.js +++ b/app/components/topic-table/topic-table.component.spec.js @@ -10,10 +10,10 @@ })); it('should show a topic', function () { - var template = ''; - var scope = $rootScope.$new(); // create a new scope - var element = $compile(template)(scope); // compile the template against the scope - scope.$apply(); // trigger dirty checking + // var template = ''; + // var scope = $rootScope.$new(); // create a new scope + // var element = $compile(template)(scope); // compile the template against the scope + // scope.$apply(); // trigger dirty checking // now the directive is ready to check if expectations are satisfied }); diff --git a/app/components/topic-view/topic-view.component.html b/app/components/topic-view/topic-view.component.html new file mode 100644 index 0000000..2c11e21 --- /dev/null +++ b/app/components/topic-view/topic-view.component.html @@ -0,0 +1,33 @@ +
+

{{topicView.topic.name}}

+ + +
+ +
+

+ {{topicView.topic.description}} +

+ + + +
+
+ + +
+
+
+
+
\ No newline at end of file diff --git a/app/components/topic-view/topic-view.component.js b/app/components/topic-view/topic-view.component.js new file mode 100644 index 0000000..67da5f5 --- /dev/null +++ b/app/components/topic-view/topic-view.component.js @@ -0,0 +1,43 @@ +(function(){ + 'use strict' + + angular.module('biloAtlas') + .component('topicView', { + templateUrl: 'app/components/topic-view/topic-view.component.html', + bindings: { + id: '@' + }, + controller: function(TopicData, $routeParams){ + this.topic; + this.topicId = $routeParams.topicid + this.layer = []; + this.selection = 0; + this.years = []; + this.year = false; + this.showMap = true; + + TopicData.getTopicById(this.topicId).then(function(topic){ + this.topic = topic; + if(this.topic.layers.length > 0){ + this.selectLayer(this.topic.layers[0]); + } + }.bind(this)); + + this.selectLayer = function(layer){ + this.layer = layer; + this.years = []; + layer.data.forEach(function(d){ + if(this.years.indexOf(d.year) == -1){ + this.years.push(d.year); + } + }.bind(this)); + + this.years.sort(); + this.year = this.years[this.years.length-1]; + } + this.layerVisible = function(id){ + return id == this.layer.id; + } + } + }) +})() \ No newline at end of file diff --git a/app/components/topics-buttons/topics-buttons.component.html b/app/components/topics-buttons/topics-buttons.component.html new file mode 100644 index 0000000..f03fb7b --- /dev/null +++ b/app/components/topics-buttons/topics-buttons.component.html @@ -0,0 +1,6 @@ +
+

{{topic.name}}

+

{{topic.description}}

+ mehr +
+ \ No newline at end of file diff --git a/app/components/topics-buttons/topics-buttons.component.js b/app/components/topics-buttons/topics-buttons.component.js new file mode 100644 index 0000000..0234def --- /dev/null +++ b/app/components/topics-buttons/topics-buttons.component.js @@ -0,0 +1,17 @@ +/** + * Created by CMatyas on 15.12.2015. + */ +(function(){ + 'use strict' + + angular.module('biloAtlas'). + component('topicsButtons',{ + templateUrl: 'app/components/topics-buttons/topics-buttons.component.html', + controller: function(TopicData,$routeParams){ + this.topics = []; + TopicData.getTopics().then(function(topics){ + this.topics = topics; + }.bind(this)); + } + }); +})(); \ No newline at end of file diff --git a/app/components/topics-navigation/topics-navigation.component.html b/app/components/topics-navigation/topics-navigation.component.html index f366fe8..0e6aaca 100644 --- a/app/components/topics-navigation/topics-navigation.component.html +++ b/app/components/topics-navigation/topics-navigation.component.html @@ -1,5 +1,5 @@ -