add d3js for langue visu
authornowmad@nowmads-macbook-pro.local
Fri, 15 Jan 2016 15:49:42 +0100
changeset 84 36f84e8f1ad5
parent 83 645786bb8587
child 85 e95ca73cec54
add d3js for langue visu add modal update css
cms/app-client/app/components/visu-carto.js
cms/app-client/app/components/visu-langues.js
cms/app-client/app/controllers/application.js
cms/app-client/app/routes/tabs/carto.js
cms/app-client/app/routes/tabs/chrono.js
cms/app-client/app/styles/app.scss
cms/app-client/app/styles/modal.scss
cms/app-client/app/styles/results.scss
cms/app-client/app/styles/tabs/langues.scss
cms/app-client/app/templates/application.hbs
cms/app-client/app/templates/player.hbs
cms/app-client/app/templates/results.hbs
cms/app-client/bower.json
cms/app-client/config/environment.js
cms/app-client/npm-debug.log
cms/app-client/package.json
cms/app-client/public/langues.json
--- a/cms/app-client/app/components/visu-carto.js	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/app/components/visu-carto.js	Fri Jan 15 15:49:42 2016 +0100
@@ -4,21 +4,14 @@
   // storage: Ember.inject.service(),
   didInsertElement: function(){
     var _this = this;
-    // console.log("maps : ", AmCharts.maps);
-    //
-    // console.log('test: ', this.get("query"));
-    //
-    // this.get("sounds").map(item => {
-  	// 	console.log(item.get('title'));
-  	// });
 
     var continentsDataProvider;
 
     var franceDataProvider = {
-        mapVar: AmCharts.maps.franceDepartmentsLow,
+        mapVar: AmCharts.maps.france2016Low,
         getAreasFromMap:true,
 
-        areas: this.initArea(AmCharts.maps.franceDepartmentsLow)
+        areas: this.initArea(AmCharts.maps.france2016Low)
     };
 
     var worldDataProvider = {
@@ -89,7 +82,9 @@
             color: "#E0EEEF"
         },
 
-        dataProvider: continentsDataProvider
+        dataProvider: continentsDataProvider,
+
+        listeners: [{event:"clickMapObject", method:handleMapObjectClick}]
 
     });
 
@@ -98,6 +93,12 @@
         map.validateNow();
     }
     function handleMapObjectClick (event) {
+      console.log("bbox: ", event.mapObject.displayObject.node.getBBox());
+      // console.log("event", event);
+      // console.log("originalTarget", event.event.originalTarget);
+      // console.log("getTotalLength", event.event.originalTarget.getTotalLength());
+      // console.log("getBBox", event.event.originalTarget.getBBox());
+      // console.log("event", event.event.originalTarget.attributes[1].d);
         if (event.mapObject.id == "backButton") {
             handleGoHome();
         }
@@ -106,7 +107,6 @@
 
     // monitor when home icon was clicked and also go to continents map
     map.addListener("homeButtonClicked", handleGoHome);
-    map.addListener("clickMapObject", handleMapObjectClick);
   },
   initArea: function(area, dataProvider){
     var _this = this;
--- a/cms/app-client/app/components/visu-langues.js	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/app/components/visu-langues.js	Fri Jan 15 15:49:42 2016 +0100
@@ -4,70 +4,194 @@
   didInsertElement: function(){
     var _this = this;
 
-    var data = google.visualization.arrayToDataTable([
-      ['Location', 'Parent', 'Market trade volume (size)', 'Market increase/decrease (color)'],
-      ['Global',    null,     0,    0],
-      ['Français',	'Global',	859,	859],
-      ['Alsacien',	'Global',	851,	851],
-      ['Breton',    'Global',	403,	403],
-      ['Occitan',	'Global',	344,	344],
-      ['Judéo-espagnol',	'Global',	77,	77],
-      ['Undetermined',	'Global',	45,	45],
-      ['Langues régionales',	'Global',	175,	175],
-      ['Langues non territoriales',	'Global',	48,	48],
-      ['Les Creoles',	'Global',	47,	47],
-      ['Guyane',	'Global',	59,	59],
-      ['Mayotte',	'Global',	20,	20],
-      ['Polynésie française',	'Global',	13,	13],
-      ['Wallis et Futuna',	'Global',	43,	43],
-      ['Nouvelle-Calédonie',	'Global',	68,	68],
-      ['Langues d’oïl', 'Langues régionales',	75,	75],
-      ['Francoprovençal',	'Langues régionales',	60,	60],
-      ['Corse',	'Langues régionales',	40,	40],
-      ['Langue des signes française (LSF)',	'Langues non territoriales',	40,	40],
-      ['Berbère',	'Langues non territoriales',	8,	8],
-      ['Creole de la Réunion',	'Les Creoles',	32,	32],
-      ['Creole de la Guadeloupe',	'Les Creoles',	15,	15],
-      ['Ndyuka-Trio Pidgin (njt)',	'Guyane',	31,	31],
-      ['Palikúr (plu)', 'Guyane',	6,	6],
-      ['Guianese Creole French (gcr)',	'Guyane',	4,	4],
-      ['Eastern Maroon Creole (djk)',	'Guyane',	16,	16],
-      ['Sranan Tongo (srn)',	'Guyane',	2,	2],
-      ['Maore Comorian (swb)',	'Mayotte',	2, 2],
-      ['Mauritian Sign Language (lsy)',	'Mayotte',	18,	18],
-      ['West Uvean (uve)',	'Polynésie française',	13,	13],
-      ['East Futuna (fud)',	'Wallis et Futuna',	23,	23],
-      ['Wallisian (wls)',	'Wallis et Futuna',	20,	20],
-      ['Nemi (nem)',	'Nouvelle-Calédonie',	15,	15],
-      ['Xârâcùù (ane)',	'Nouvelle-Calédonie',	12,	12],
-      ['Cemuhî (cam)',	'Nouvelle-Calédonie',	9,	9],
-      ['Xaragure (axx)',	'Nouvelle-Calédonie',	9,	9],
-      ['Iaai (iai)',	'Nouvelle-Calédonie',	8,	8],
-      ['Nêlêmwa-Nixumwak (nee)',	'Nouvelle-Calédonie',	4,	4],
-      ['Dehu (dhv)',	'Nouvelle-Calédonie',	2,	2],
-      ['Nengone (nen)',	'Nouvelle-Calédonie',	2,	2],
-      ['Ajië (aji)',	'Nouvelle-Calédonie',	1,	1],
-      ['Numee (kdk)',	'Nouvelle-Calédonie',	1,	1],
-      ['Yuaga (nua)',	'Nouvelle-Calédonie',	1,	1],
-      ['Bwatoo (bwa)',	'Nouvelle-Calédonie',	4,	4]
-    ]);
+    var margin = {top: 20, right: 0, bottom: 0, left: 0},
+        width = 560,
+        height = 600 - margin.top - margin.bottom,
+        formatNumber = d3.format(",d"),
+        transitioning;
+
+    var x = d3.scale.linear()
+        .domain([0, width])
+        .range([0, width]);
+
+    var y = d3.scale.linear()
+        .domain([0, height])
+        .range([0, height]);
+
+    var treemap = d3.layout.treemap()
+        .children(function(d, depth) { return depth ? null : d._children; })
+        .sort(function(a, b) { return a.value - b.value; })
+        .ratio(height / width * 0.5 * (1 + Math.sqrt(5)))
+        .round(false);
+
+    var svg = d3.select("#chart_div").append("svg")
+        .attr("width", width + margin.left + margin.right)
+        .attr("height", height + margin.bottom + margin.top)
+        .style("margin-left", -margin.left + "px")
+        .style("margin.right", -margin.right + "px")
+      .append("g")
+        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
+        .style("shape-rendering", "crispEdges");
+
+    var grandparent = svg.append("g")
+        .attr("class", "grandparent");
+
+    grandparent.append("rect")
+        .attr("y", -margin.top)
+        .attr("width", width)
+        .attr("height", margin.top);
+
+    grandparent.append("text")
+        .attr("x", 6)
+        .attr("y", 6 - margin.top)
+        .attr("dy", ".75em");
+
+    d3.json("langues.json", function(root) {
+      initialize(root);
+      accumulate(root);
+      layout(root);
+      display(root);
+
+      function initialize(root) {
+        root.x = root.y = 0;
+        root.dx = width;
+        root.dy = height;
+        root.depth = 0;
+      }
+
+      // Aggregate the values for internal nodes. This is normally done by the
+      // treemap layout, but not here because of our custom implementation.
+      // We also take a snapshot of the original children (_children) to avoid
+      // the children being overwritten when when layout is computed.
+      function accumulate(d) {
+        return (d._children = d.children)
+            ? d.value = d.children.reduce(function(p, v) { return p + accumulate(v); }, 0)
+            : d.value;
+      }
+
+      // Compute the treemap layout recursively such that each group of siblings
+      // uses the same size (1×1) rather than the dimensions of the parent cell.
+      // This optimizes the layout for the current zoom state. Note that a wrapper
+      // object is created for the parent node for each group of siblings so that
+      // the parent’s dimensions are not discarded as we recurse. Since each group
+      // of sibling was laid out in 1×1, we must rescale to fit using absolute
+      // coordinates. This lets us use a viewport to zoom.
+      function layout(d) {
+        if (d._children) {
+          treemap.nodes({_children: d._children});
+          d._children.forEach(function(c) {
+            c.x = d.x + c.x * d.dx;
+            c.y = d.y + c.y * d.dy;
+            c.dx *= d.dx;
+            c.dy *= d.dy;
+            c.parent = d;
+            layout(c);
+          });
+        }
+      }
+
+      function display(d) {
+        grandparent
+            .datum(d.parent)
+            .on("click", transition)
+          .select("text")
+            .text(name(d));
 
-    var tree = new google.visualization.TreeMap(document.getElementById('chart_div'));
+        var g1 = svg.insert("g", ".grandparent")
+            .datum(d)
+            .attr("class", "depth");
+
+        var g = g1.selectAll("g")
+            .data(d._children)
+          .enter().append("g");
+
+        g.classed("bla", true).on("click", selectHandler)
+
+        g.filter(function(d) { return d._children; })
+            .classed("children", true)
+            .on("click", transition);
+
+        // g.selectAll(".child")
+        //     .data(function(d) { return d._children || [d]; })
+        //   .enter().append("rect")
+        //     .attr("class", "child")
+        //     .call(rect);
+
+        g.append("rect")
+            .attr("class", "parent")
+            // .attr("fill", (d.color || "#bbb"))
+            .call(rect)
+          .append("title")
+            .text(function(d) { return formatNumber(d.value); });
+
+        g.append("text")
+            .attr("dy", ".75em")
+            .text(function(d) { return d.name; })
+            .call(text);
+
+        function transition(d) {
+          if (transitioning || !d) return;
+          selectHandler(d);
+          transitioning = true;
+
+          var g2 = display(d),
+              t1 = g1.transition().duration(750),
+              t2 = g2.transition().duration(750);
+
+          // Update the domain only after entering new elements.
+          x.domain([d.x, d.x + d.dx]);
+          y.domain([d.y, d.y + d.dy]);
+
+          // Enable anti-aliasing during the transition.
+          svg.style("shape-rendering", null);
 
-    tree.draw(data, {
-      minColor: '#E0EEEF',
-      midColor: '#7CACAE',
-      maxColor: '#2D7073',
-      headerHeight: 15,
-      fontColor: 'black',
-      showScale: true
+          // Draw child nodes on top of parent nodes.
+          svg.selectAll(".depth").sort(function(a, b) { return a.depth - b.depth; });
+
+          // Fade-in entering text.
+          g2.selectAll("text").style("fill-opacity", 0);
+
+          // Transition to the new view.
+          t1.selectAll("text").call(text).style("fill-opacity", 0);
+          t2.selectAll("text").call(text).style("fill-opacity", 1);
+          t1.selectAll("rect").call(rect);
+          t2.selectAll("rect").call(rect);
+
+          // Remove the old node when the transition is finished.
+          t1.remove().each("end", function() {
+            svg.style("shape-rendering", "crispEdges");
+            transitioning = false;
+          });
+        }
+
+        function selectHandler (d){
+          if (d.name === "Global"){
+            return _this.sendAction('action', null);
+          }
+          _this.sendAction('action', d.name);
+        }
+
+        return g;
+      }
+
+      function text(text) {
+        text.attr("x", function(d) { return x(d.x) + 6; })
+            .attr("y", function(d) { return y(d.y) + 6; });
+      }
+
+      function rect(rect) {
+        rect.attr("x", function(d) { return x(d.x); })
+            .attr("y", function(d) { return y(d.y); })
+            .attr("width", function(d) { return x(d.x + d.dx) - x(d.x); })
+            .attr("height", function(d) { return y(d.y + d.dy) - y(d.y); })
+            .attr("fill", function(d) { return (d.color || "#bbb")});
+      }
+
+      function name(d) {
+        return d.parent
+            ? name(d.parent) + "." + d.name
+            : d.name;
+      }
     });
-
-    function selectHandler (){
-      _this.sendAction('action', data.getValue(tree.getSelection()[0].row, 0));
-    }
-
-    google.visualization.events.addListener(tree, 'select', selectHandler);
-
   }
 });
--- a/cms/app-client/app/controllers/application.js	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/app/controllers/application.js	Fri Jan 15 15:49:42 2016 +0100
@@ -7,6 +7,8 @@
   discours: null,
   date: [],
   thematique: null,
+  isShowingModal: false,
+  currentDetails: null,
   currentItem: {title: "example", master: 'http://www.noiseaddicts.com/samples_1w72b820/3921.mp3'},
   filteredSounds: Ember.computed('location', 'langue', 'discours', 'date', 'thematique', 'model', function() {
     var location = this.get('location');
@@ -65,6 +67,10 @@
         $(".result-item").toggleClass("details", false);
         $("#"+item.id).toggleClass("details", true);
       }
+    },
+    toggleModal: function(item){
+      this.set("isShowingModal", !this.isShowingModal);
+      this.set("currentDetails", item);
     }
   }
 });
--- a/cms/app-client/app/routes/tabs/carto.js	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/app/routes/tabs/carto.js	Fri Jan 15 15:49:42 2016 +0100
@@ -3,5 +3,10 @@
 export default Ember.Route.extend({
   renderTemplate() {
     this.render({ outlet: 'carto' });
+  },
+  actions: {
+    queryParamsDidChange: function() {
+      console.log("carto params");
+    },
   }
 });
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/app/routes/tabs/chrono.js	Fri Jan 15 15:49:42 2016 +0100
@@ -0,0 +1,10 @@
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+  actions: {
+    queryParamsDidChange: function() {
+      console.log("chrono params");
+      // console.log("visu-chrono ?", this.controller.get('visu-chrono'));
+    },
+  }
+});
--- a/cms/app-client/app/styles/app.scss	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/app/styles/app.scss	Fri Jan 15 15:49:42 2016 +0100
@@ -25,6 +25,7 @@
     @import 'container';
     @import 'player';
     @import 'results';
+    @import 'modal';
 
     &-container{
       display: block;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/app/styles/modal.scss	Fri Jan 15 15:49:42 2016 +0100
@@ -0,0 +1,30 @@
+.overlay {
+    background-color: gray;
+    height: 100vh;
+    left: 0;
+    opacity: 0.77;
+    position: fixed;
+    right: 0;
+    top: 0;
+    z-index: 50;
+}
+
+.dialog {
+    background: #fff none repeat scroll 0 0;
+    border: 4px solid #ccc;
+    border-radius: 10px;
+    box-shadow: 0 0 10px #222;
+    height: 300px;
+    left: 50%;
+    margin-left: -250px;
+    margin-top: -150px;
+    padding: 10px;
+    position: fixed;
+    top: 50%;
+    width: 500px;
+    z-index: 50;
+}
+
+.dialog h1{
+  margin-top: 0;
+}
--- a/cms/app-client/app/styles/results.scss	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/app/styles/results.scss	Fri Jan 15 15:49:42 2016 +0100
@@ -77,3 +77,7 @@
 .result-item.playing .fa {
   // background: url('images/playing.gif') no-repeat;
 }
+
+.result-item button{
+  margin-top: 5px;
+}
--- a/cms/app-client/app/styles/tabs/langues.scss	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/app/styles/tabs/langues.scss	Fri Jan 15 15:49:42 2016 +0100
@@ -1,4 +1,45 @@
-#chart_div{
+#chart_div {
   width: 560px;
   height: 540px;
+  background: #ddd;
 }
+
+text {
+  pointer-events: none;
+}
+
+.grandparent text {
+  font-weight: bold;
+}
+
+rect {
+  /*fill: none;*/
+  stroke: #fff;
+}
+
+rect.parent,
+.grandparent rect {
+  stroke-width: 2px;
+}
+
+.grandparent rect {
+  fill: green;
+}
+
+.grandparent:hover rect {
+  fill: lightgreen;
+}
+
+.children rect.parent,
+.grandparent rect {
+  cursor: pointer;
+}
+
+.children rect.parent {
+  /*fill: #bbb;*/
+  fill-opacity: .5;
+}
+
+.children:hover rect.child {
+  /*fill: #bbb;*/
+}
--- a/cms/app-client/app/templates/application.hbs	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/app/templates/application.hbs	Fri Jan 15 15:49:42 2016 +0100
@@ -1,3 +1,4 @@
+<div id="info-modal"></div>
 <div class="corpus-app-container">
   {{outlet}}
   <div class="carto">{{outlet "carto"}}</div>
--- a/cms/app-client/app/templates/player.hbs	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/app/templates/player.hbs	Fri Jan 15 15:49:42 2016 +0100
@@ -12,3 +12,15 @@
     Description: {{ currentItem.description }}
   </p>
 </div>
+
+<div id="container">
+	<div id="audio_player">
+		<span class="btn btn_play" id="action_play" title="">Play</span>
+		<div class="background"></div>
+		<div class="progress">
+			<div class="slice">
+				<div class="pie"></div>
+			</div>
+		</div>
+	</div>
+</div>
--- a/cms/app-client/app/templates/results.hbs	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/app/templates/results.hbs	Fri Jan 15 15:49:42 2016 +0100
@@ -29,6 +29,22 @@
       <div class="description">
         {{item.description}}
       </div>
+      <button class="pull-right" {{action 'toggleModal' item}}>Details</button>
     </div>
   {{/each}}
+  {{#if isShowingModal}}
+    {{#ember-wormhole to='info-modal'}}
+      <div class="overlay" {{action 'toggleModal'}}></div>
+      <div class="dialog">
+        <h1>{{currentDetails.title}}</h1>
+        <p><b>Description: </b>{{currentDetails.description}}</p>
+        <p><b>Interviewer: </b>{{currentDetails.interviewer}}</p>
+        <p><b>Type de Discours: </b>{{currentDetails.type}}</p>
+        <p><b>Localisation: </b>{{currentDetails.spatial}}</p>
+        <p><b>Langue: </b>{{currentDetails.language}}</p>
+        <p><b>Date de Creation: </b>{{currentDetails.created}}</p>
+        <button class="pull-right" {{action 'toggleModal'}}>Close</button>
+      </div>
+    {{/ember-wormhole}}
+  {{/if}}
 </div>
--- a/cms/app-client/bower.json	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/bower.json	Fri Jan 15 15:49:42 2016 +0100
@@ -13,7 +13,7 @@
     "loader.js": "ember-cli/loader.js#3.2.1",
     "qunit": "~1.18.0",
     "bootstrap-sass": "~3.3.5",
-    "ammap3": "~3.17.3",
+    "ammap3": "~3.18.6",
     "font-awesome": "~4.4.0"
   }
 }
--- a/cms/app-client/config/environment.js	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/config/environment.js	Fri Jan 15 15:49:42 2016 +0100
@@ -5,7 +5,7 @@
     rootElement: '#corpus-app',
     modulePrefix: 'app-client',
     environment: environment,
-    baseURL: '/corpus',
+    baseURL: '/corpus/',
     // locationType: '',
     // contentSecurityPolicy: {
     //   'default-src': "'none'",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/npm-debug.log	Fri Jan 15 15:49:42 2016 +0100
@@ -0,0 +1,45 @@
+0 info it worked if it ends with ok
+1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'start' ]
+2 info using npm@3.5.2
+3 info using node@v5.2.0
+4 verbose run-script [ 'prestart', 'start', 'poststart' ]
+5 info lifecycle app-client@0.0.0~prestart: app-client@0.0.0
+6 silly lifecycle app-client@0.0.0~prestart: no script for prestart, continuing
+7 info lifecycle app-client@0.0.0~start: app-client@0.0.0
+8 verbose lifecycle app-client@0.0.0~start: unsafe-perm in lifecycle true
+9 verbose lifecycle app-client@0.0.0~start: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/nowmad/workspace/IRI/corpus_parole/cms/app-client/node_modules/.bin:/Library/PostgreSQL/9.5/bin/:/usr/local/apache-ant/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/nowmad/Library/Android/sdk/tools:/Users/nowmad/Library/Android/sdk/platform-tools
+10 verbose lifecycle app-client@0.0.0~start: CWD: /Users/nowmad/workspace/IRI/corpus_parole/cms/app-client
+11 silly lifecycle app-client@0.0.0~start: Args: [ '-c', 'ember serve --environment=development' ]
+12 silly lifecycle app-client@0.0.0~start: Returned: code: 1  signal: null
+13 info lifecycle app-client@0.0.0~start: Failed to exec start script
+14 verbose stack Error: app-client@0.0.0 start: `ember serve --environment=development`
+14 verbose stack Exit status 1
+14 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:232:16)
+14 verbose stack     at emitTwo (events.js:88:13)
+14 verbose stack     at EventEmitter.emit (events.js:173:7)
+14 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:24:14)
+14 verbose stack     at emitTwo (events.js:88:13)
+14 verbose stack     at ChildProcess.emit (events.js:173:7)
+14 verbose stack     at maybeClose (internal/child_process.js:819:16)
+14 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:212:5)
+15 verbose pkgid app-client@0.0.0
+16 verbose cwd /Users/nowmad/workspace/IRI/corpus_parole/cms/app-client
+17 error Darwin 15.2.0
+18 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
+19 error node v5.2.0
+20 error npm  v3.5.2
+21 error code ELIFECYCLE
+22 error app-client@0.0.0 start: `ember serve --environment=development`
+22 error Exit status 1
+23 error Failed at the app-client@0.0.0 start script 'ember serve --environment=development'.
+23 error Make sure you have the latest version of node.js and npm installed.
+23 error If you do, this is most likely a problem with the app-client package,
+23 error not with npm itself.
+23 error Tell the author that this fails on your system:
+23 error     ember serve --environment=development
+23 error You can get information on how to open an issue for this project with:
+23 error     npm bugs app-client
+23 error Or if that isn't available, you can get their info via:
+23 error     npm owner ls app-client
+23 error There is likely additional logging output above.
+24 verbose exit [ 1, true ]
--- a/cms/app-client/package.json	Fri Jan 15 15:48:42 2016 +0100
+++ b/cms/app-client/package.json	Fri Jan 15 15:49:42 2016 +0100
@@ -24,6 +24,7 @@
     "ember-cli-app-version": "0.5.0",
     "ember-cli-babel": "^5.1.3",
     "ember-cli-content-security-policy": "0.4.0",
+    "ember-cli-d3": "1.1.2",
     "ember-cli-dependency-checker": "^1.0.1",
     "ember-cli-font-awesome": "1.3.0",
     "ember-cli-htmlbars": "0.7.9",
@@ -37,6 +38,7 @@
     "ember-cli-uglify": "^1.2.0",
     "ember-data": "1.13.8",
     "ember-disable-proxy-controllers": "^1.0.0",
-    "ember-export-application-global": "^1.0.3"
+    "ember-export-application-global": "^1.0.3",
+    "ember-wormhole": "0.3.4"
   }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/public/langues.json	Fri Jan 15 15:49:42 2016 +0100
@@ -0,0 +1,195 @@
+{
+ "name": "Global",
+ "children": [
+  {
+    "id": "id de langue (code Lexvo de la langues)",
+    "name": "Français",
+    "value": 859,
+    "color": "lightblue"
+  },
+  {
+    "name": "Alsacien",
+    "value": 851
+  },
+  {
+    "name": "Breton",
+    "value": 403
+  },
+  {
+    "name": "Occitan",
+    "value": 344
+  },
+  {
+    "name": "Judéo-espagnol",
+    "value": 77
+  },
+  {
+    "name": "Undetermined",
+    "value": 45
+  },
+  {
+    "name": "Langues régionales",
+    "value": 175,
+    "children": [
+      {
+        "name": "Langues d'oïl",
+        "value": 75
+      },
+      {
+        "name": "Francoprovençal",
+        "value": 60
+      },
+      {
+        "name": "Corse",
+        "value": 40
+      }
+    ]
+  },
+  {
+    "name": "Langues non territoriales",
+    "value": 48,
+    "children": [
+      {
+        "name": "Langue des signes française (LSF)",
+        "value": 40
+      },
+      {
+        "name": "Berbère",
+        "value": 8
+      }
+    ]
+  },
+  {
+    "name": "Les Creoles",
+    "value": 47,
+    "children": [
+      {
+        "name": "Creole de la Réunion",
+        "value": 32
+      },
+      {
+        "name": "Creole de la Guadeloupe",
+        "value": 15
+      }
+    ]
+  },
+  {
+    "name": "Guyane",
+    "value": 59,
+    "children": [
+      {
+        "name": "Ndyuka-Trio Pidgin (njt)",
+        "value": 31
+      },
+      {
+        "name": "Palikúr (plu)",
+        "value": 6
+      },
+      {
+        "name": "Guianese Creole French (gcr)",
+        "value": 4
+      },
+      {
+        "name": "Eastern Maroon Creole (djk)",
+        "value": 16
+      },
+      {
+        "name": "Sranan Tongo (srn)",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "name": "Mayotte",
+    "value": 20,
+    "children": [
+      {
+        "name": "Maore Comorian (swb)",
+        "value": 2
+      },
+      {
+        "name": "Mauritian Sign Language (lsy)",
+        "value": 18
+      }
+    ]
+  },
+  {
+    "name": "Polynésie française",
+    "value": 13,
+    "children": [
+      {
+        "name": "West Uvean (uve)",
+        "value": 13
+      }
+    ]
+  },
+  {
+    "name": "Wallis et Futuna",
+    "value": 43,
+    "children": [
+      {
+        "name": "LanEast Futuna (fud)",
+        "value": 23
+      },
+      {
+        "name": "Wallisian (wls)",
+        "value": 20
+      }
+    ]
+  },
+  {
+    "name": "Nouvelle-Calédonie",
+    "value": 68,
+    "children": [
+      {
+        "name": "Wallisian (wls)",
+        "value": 15
+      },
+      {
+        "name": "Xârâcùù (ane)",
+        "value": 12
+      },
+      {
+        "name": "Cemuhî (cam)",
+        "value": 9
+      },
+      {
+        "name": "Xaragure (axx)",
+        "value": 9
+      },
+      {
+        "name": "Iaai (iai)",
+        "value": 8
+      },
+      {
+        "name": "Nêlêmwa-Nixumwak (nee)",
+        "value": 4
+      },
+      {
+        "name": "Dehu (dhv)",
+        "value": 2
+      },
+      {
+        "name": "Nengone (nen)",
+        "value": 2
+      },
+      {
+        "name": "Ajië (aji)",
+        "value": 1
+      },
+      {
+        "name": "Numee (kdk)",
+        "value": 1
+      },
+      {
+        "name": "Yuaga (nua)",
+        "value": 1
+      },
+      {
+        "name": "Bwatoo (bwa)",
+        "value": 4
+      }
+    ]
+  }
+ ]
+}