--- a/cms/app-client/app/adapters/application.js Fri Nov 04 19:03:25 2016 +0100
+++ b/cms/app-client/app/adapters/application.js Sun Nov 06 03:44:16 2016 +0100
@@ -4,6 +4,7 @@
const TYPE_PATH_MAP = {
transcript: 'transcript',
geostat: 'stats/geostats',
+ datestat: 'stats/datestats',
theme: 'stats/themes'
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/app/components/visu-chrono-year.js Sun Nov 06 03:44:16 2016 +0100
@@ -0,0 +1,61 @@
+import Ember from 'ember';
+import _ from 'lodash/lodash';
+
+export default Ember.Component.extend({
+
+ colors: Ember.inject.service(),
+ filter: Ember.inject.service(),
+
+ tagName: 'li',
+ classNameBindings: ['isDisabled:disabled', 'isDark:light-color', 'isHighlighted:highlighted'],
+ attributeBindings: ['style', 'title', 'id'],
+
+ isDisabled: Ember.computed('range', 'year', 'count', function() {
+ let year = parseInt(this.get('year'));
+ let count = this.get('count');
+ return (!_.inRange(year, this.get('range')[0], this.get('range')[1]+1)) || count === 0;
+ }),
+
+ isHighlighted: Ember.computed('filter.dateList.[]', function() {
+ return _.contains(this.get('filter.dateList'), this.get('year'));
+ }),
+ isDark: Ember.computed('backgroundColor', 'isDisabled', function() {
+ let backgroundColor = this.get('backgroundColor');
+ if(this.get('isDisabled')) {
+ return false;
+ }
+ return this.get('colors').getPerceptiveLuminance(this.get('backgroundColor')) >= 0.5;
+ }),
+
+ backgroundColor: Ember.computed('count', 'maxCount', 'minCount', function() {
+ return this.get('colors').shadeLinear(this.get('count'), this.get('minCount'), this.get('maxCount'));
+ }),
+
+ style: Ember.computed('backgroundColor', 'isDisabled', 'isHighlighted', function() {
+ let backgroundColor = this.get('backgroundColor');
+ if(this.get('isDisabled') || this.get('isHighlighted')) {
+ return null;
+ }
+ return Ember.String.htmlSafe(`background-color: ${backgroundColor};`);
+ }),
+ id: Ember.computed.alias('year'),
+ count: Ember.computed('datestats.[]', function() {
+ let year = this.get('year');
+ let count = this.get('datestats').get(`${year}`);
+ return count?count:0;
+ }),
+ title: Ember.computed('count', 'isDsabled', function() {
+ if(this.get('isDisabled')) {
+ return null;
+ }
+ let year = this.get('year');
+ let count = this.get('count');
+ return `${year} (${count})`;
+ }),
+
+ year: null,
+ datestats: null,
+ range: null,
+ maxCount: null,
+ minCount: null,
+});
--- a/cms/app-client/app/components/visu-chrono.js Fri Nov 04 19:03:25 2016 +0100
+++ b/cms/app-client/app/components/visu-chrono.js Sun Nov 06 03:44:16 2016 +0100
@@ -4,89 +4,35 @@
export default Ember.Component.extend({
range: [],
+ rawdatestats: null,
decades: Ember.computed('range', function() {
var range = this.get('range');
- return _.range(Math.floor(range[0]/10)*10, Math.floor(range[1]/10)*10, 10);
+ return _.range(Math.floor(range[0]/10)*10, (Math.floor(range[1]/10)+1)*10, 10);
}),
+ datestats: Ember.computed('rawdatestats.[]', function() {
+ var res = {};
+ this.get('rawdatestats').forEach(function(s) {
+ res[s.get('id')] = s.get('count');
+ });
+ return Ember.Object.create(res);
+ }),
+
+ counts: Ember.computed.mapBy('rawdatestats', 'count'),
+ maxCount: Ember.computed.max('counts'),
+ minCount: Ember.computed.min('counts'),
+
filter: Ember.inject.service(),
- dateObserver: Ember.observer('date', function() {
- var self = this;
- this.$('li').removeClass('highlighted');
- this.get('date').forEach(function(date) {
- self.$('li#' + date).addClass('highlighted');
- });
- }),
-
- date: Ember.computed('filter.date', {
- get: function() {
- const dates = this.get('filter').get('date');
- console.log("get DATES", dates);
- if(dates === null) {
- return [];
- }
- const res = _.reduce(dates, function(res, d) {
- let m = d.match(/^(\d+)(?:-(\d+))?$/);
- if(m) {
- let start = parseInt(m[1]);
- let end = parseInt(m[2]);
- if(isNaN(end)) {
- res.push(parseInt(m[1]));
- } else {
- res = res.concat(_.range(start,end+1));
- }
- }
- return res;
- }, []).sort();
- console.log("GET DATE", res);
- return res;
- },
- set: function(key, values) {
- var srcDateList = _.clone(values).sort();
- let start = null;
- let end = null;
- var pushValues = function(s,e,valuesList) {
- if(s === e) {
- valuesList.push(s.toString());
- } else {
- valuesList.push(s.toString()+"-"+e.toString());
- }
- };
- let dateList = _.reduce(srcDateList, function(res, d, i) {
- if(start === null) {
- start = end = d;
- }
- if(d > (end + 1)) {
- pushValues(start, end, res);
- start = end = d;
- } else {
- end = d;
- }
- if(i === (srcDateList.length - 1)) {
- pushValues(start, end, res);
- }
- return res;
- }, []);
- console.log("SET DATE",key, values, dateList);
- if(dateList.length === 0) {
- dateList = null;
- }
- this.get('filter').set('date', dateList);
- return srcDateList;
- }
- }),
+ date: Ember.computed.alias('filter.dateList'),
elementId: "chrono-table",
didInsertElement: function(){
+
var self = this;
- if (this.get('date') !== null){
- this.highlightQuery(this.get('date'));
- }
-
var isMouseDown = false,
isHighlighted,
didHighlight,
@@ -98,6 +44,9 @@
isMouseDown = true;
var element = parseInt(Ember.$(this).attr('id'));
+ if(!_.inRange(element, self.get('range')[0], self.get('range')[1]+1)) {
+ return false;
+ }
var elements = [element];
if(event.shiftKey) {
while(previousElement !== element) {
@@ -155,16 +104,6 @@
});
},
- highlightQuery: function(dates){
- console.log("highlightQuery", dates);
- if(dates === null) {
- return;
- }
- dates.map(function(date){
- Ember.$("#" + date).toggleClass("highlighted", true);
- });
- },
-
actions : {
selectDecade: function(decade) {
--- a/cms/app-client/app/components/visu-langues.js Fri Nov 04 19:03:25 2016 +0100
+++ b/cms/app-client/app/components/visu-langues.js Sun Nov 06 03:44:16 2016 +0100
@@ -7,6 +7,7 @@
constants: Ember.inject.service(),
filter: Ember.inject.service(),
+ colors: Ember.inject.service(),
filterObserver: Ember.observer('filter.language', function() {
Ember.$('.node').removeClass("selected");
@@ -47,7 +48,6 @@
})
.round(false);
- console.log('width', width, Ember.$('#' + self.get('elementId')).parent().width(), Ember.$('#' + self.get('elementId')).parent().parent().width(), Ember.$('#' + self.get('elementId')).parent().parent().parent().width());
var element = d3.select('#' + self.get('elementId'))
.style("width", width + margin.left + margin.right + 'px')
.style("height", height + margin.bottom + margin.top + 'px')
@@ -122,14 +122,6 @@
.style("top", function(d) { return y(d.y) + 'px'; });
}
- function hexadecimalToInteger(hexadecimal) {
- var integer = [];
- for(var i = 1; i < 7; i += 2) {
- integer.push(parseInt(hexadecimal.slice(i, i + 2), 16));
- }
- return integer;
- }
-
function display(d) {
breadcrumbs
.datum(d.parent)
@@ -149,21 +141,9 @@
var dMin = Math.min.apply(null, d._children.map(function(d){ return d.count; }));
var dMax = Math.max.apply(null, d._children.map(function(d){ return d.count; }));
- function shade(d) {
- var color = "#777777";
- var aColor = hexadecimalToInteger(color);
- var solidColor = "#333333";
- var aSolidColor = hexadecimalToInteger(solidColor);
- var aFillColor = [];
- for(var i = 0; i < 3; i++) {
- aFillColor.push((d.count - dMin) * (aSolidColor[i] - aColor[i]) / (dMax - dMin) + aColor[i]);
- }
- return '#' + (aFillColor.map(i => parseInt(i).toString(16))).join('');
- }
-
node.attr("class", function(d) { return "node" + ( d.id === self.get('filter').get('language') ? " selected" : "" ); })
.call(position)
- .style("background-color", function(d) { return shade(d); })
+ .style("background-color", function(d) { return self.get('colors').shadeLinear(d.count,dMin,dMax); })
.on("click", selectHandler);
node.filter(function(d) { return d._children; })
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/app/helpers/range.js Sun Nov 06 03:44:16 2016 +0100
@@ -0,0 +1,8 @@
+import Ember from 'ember';
+import _ from 'lodash/lodash';
+
+export function range([start, nb, step]) {
+ return _.range(start, start+nb, step);
+}
+
+export default Ember.Helper.helper(range);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/app/models/datestat.js Sun Nov 06 03:44:16 2016 +0100
@@ -0,0 +1,5 @@
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ count: DS.attr('number')
+});
--- a/cms/app-client/app/routes/tabs/chrono.js Fri Nov 04 19:03:25 2016 +0100
+++ b/cms/app-client/app/routes/tabs/chrono.js Sun Nov 06 03:44:16 2016 +0100
@@ -7,7 +7,8 @@
model: function() {
return RSVP.hash({
- range: [1948, 2015]
+ range: [1948, 2015],
+ datestats: this.get('store').findAll('datestat')
});
},
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/app/serializers/datestat.js Sun Nov 06 03:44:16 2016 +0100
@@ -0,0 +1,21 @@
+import DS from 'ember-data';
+
+export default DS.Serializer.extend({
+
+ normalizeResponse: function(store, primaryModelClass, payload) {
+ var data = [];
+ Object.keys(payload['datestats']).forEach(function(key) {
+ data.push({
+ 'id': key,
+ 'type': 'datestat',
+ 'attributes': {
+ 'count': payload['datestats'][key]
+ }
+ });
+ });
+ return {
+ 'data': data
+ };
+ }
+
+});
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/app/services/colors.js Sun Nov 06 03:44:16 2016 +0100
@@ -0,0 +1,46 @@
+import Ember from 'ember';
+import chroma from 'chroma';
+
+export const LINEAR_COLOR_START = "#777777";
+export const LINEAR_COLOR_END = "#333333";
+
+export function shadeLinear(v, vmin, vmax) {
+ var s = chroma.scale([LINEAR_COLOR_START, LINEAR_COLOR_END]).mode('lab').domain([vmin,vmax]);
+ return s(v).hex();
+}
+
+export function shade(d) {
+ var aColor = chroma(LINEAR_COLOR_START).rgb();
+ var aSolidColor = chroma(LINEAR_COLOR_END).rgb();
+ var aFillColor = [];
+ for(var i = 0; i < 3; i++) {
+ aFillColor.push((d.count - dMin) * (aSolidColor[i] - aColor[i]) / (dMax - dMin) + aColor[i]);
+ }
+ return chroma.rgb(aFillColor).hex();
+}
+
+export function getComplement(c) {
+ let chromaColorHsl = chroma(c).hsl();
+ console.log(chromaColorHsl[0]);
+ chromaColorHsl[0] += 180;
+ if (chromaColorHsl[0] > 360) {
+ chromaColorHsl[0] -= 360;
+ }
+ chromaColorHsl[0] /= 360;
+
+ return chroma.hsl(chromaColorHsl).hex();
+
+}
+
+export function getPerceptiveLuminance(c) {
+ var rgb = chroma(c).rgb();
+ return 1 - ( 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2])/255;
+}
+
+export default Ember.Service.extend({
+ shadeLinear: shadeLinear,
+ getComplement: getComplement,
+ getPerceptiveLuminance: getPerceptiveLuminance,
+ LINEAR_COLOR_START: LINEAR_COLOR_START,
+ LINEAR_COLOR_END: LINEAR_COLOR_END
+});
--- a/cms/app-client/app/services/filter.js Fri Nov 04 19:03:25 2016 +0100
+++ b/cms/app-client/app/services/filter.js Sun Nov 06 03:44:16 2016 +0100
@@ -89,6 +89,60 @@
return Ember.A(JSON.parse(value));
}
return value;
- }
+ },
+ dateList: Ember.computed('date.[]', {
+ get: function() {
+ const dates = this.get('date');
+ if(dates === null) {
+ return [];
+ }
+ const res = _.reduce(dates, function(res, d) {
+ let m = d.match(/^(\d+)(?:-(\d+))?$/);
+ if(m) {
+ let start = parseInt(m[1]);
+ let end = parseInt(m[2]);
+ if(isNaN(end)) {
+ res.push(parseInt(m[1]));
+ } else {
+ res = res.concat(_.range(start,end+1));
+ }
+ }
+ return res;
+ }, []).sort();
+ return res;
+ },
+ set: function(key, values) {
+ var srcDateList = _.clone(values).sort();
+ let start = null;
+ let end = null;
+ var pushValues = function(s,e,valuesList) {
+ if(s === e) {
+ valuesList.push(s.toString());
+ } else {
+ valuesList.push(s.toString()+"-"+e.toString());
+ }
+ };
+ let dateList = _.reduce(srcDateList, function(res, d, i) {
+ if(start === null) {
+ start = end = d;
+ }
+ if(d > (end + 1)) {
+ pushValues(start, end, res);
+ start = end = d;
+ } else {
+ end = d;
+ }
+ if(i === (srcDateList.length - 1)) {
+ pushValues(start, end, res);
+ }
+ return res;
+ }, []);
+ if(dateList.length === 0) {
+ dateList = null;
+ }
+ this.set('date', dateList);
+ return srcDateList;
+ }
+ }),
});
--- a/cms/app-client/app/styles/tabs/chrono.scss Fri Nov 04 19:03:25 2016 +0100
+++ b/cms/app-client/app/styles/tabs/chrono.scss Sun Nov 06 03:44:16 2016 +0100
@@ -25,8 +25,8 @@
margin: 0px;
padding: 0px;
font-size: 0px;
+ float: right;
display: inline-block;
- float: right;
}
#chrono-table li {
@@ -43,8 +43,21 @@
box-sizing: border-box;
}
+#chrono-table li.disabled {
+ cursor: default;
+ color: $corpus-grey;
+}
+
#chrono-table li.highlighted {
font-weight: bold;
color: $corpus-white;
background-color: $corpus-blue;
}
+
+#chrono-table li.light-color {
+ color: $corpus-white;
+}
+
+#chrono-table li.dark-color {
+ color: $corpus-black;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/app/templates/components/visu-chrono-year.hbs Sun Nov 06 03:44:16 2016 +0100
@@ -0,0 +1,1 @@
+{{ year }}
--- a/cms/app-client/app/templates/components/visu-chrono.hbs Fri Nov 04 19:03:25 2016 +0100
+++ b/cms/app-client/app/templates/components/visu-chrono.hbs Sun Nov 06 03:44:16 2016 +0100
@@ -1,90 +1,10 @@
-<div class="interval">
- {{input type="checkbox" checked=(is-checked date 1960) indeterminate=(is-indeterminate date 1960) click=(action 'selectDecade' 1960)}}
- <ul class="1960">
- <li title="1960" id="1960">1960</li>
- <li title="1961" id="1961">1961</li>
- <li title="1962" id="1962">1962</li>
- <li title="1963" id="1963">1963</li>
- <li title="1964" id="1964">1964</li>
- <li title="1965" id="1965">1965</li>
- <li title="1966" id="1966">1966</li>
- <li title="1967" id="1967">1967</li>
- <li title="1968" id="1968">1968</li>
- <li title="1969" id="1969">1969</li>
- </ul>
-</div>
+{{#each decades as |decade| }}
<div class="interval">
- {{input type="checkbox" checked=(is-checked date 1970) indeterminate=(is-indeterminate date 1970) click=(action 'selectDecade' 1970)}}
- <ul class="1970">
- <li title="1970" id="1970">1970</li>
- <li title="1971" id="1971">1971</li>
- <li title="1972" id="1972">1972</li>
- <li title="1973" id="1973">1973</li>
- <li title="1974" id="1974">1974</li>
- <li title="1975" id="1975">1975</li>
- <li title="1976" id="1976">1976</li>
- <li title="1977" id="1977">1977</li>
- <li title="1978" id="1978">1978</li>
- <li title="1979" id="1979">1979</li>
- </ul>
-</div>
-<div class="interval">
- {{input type="checkbox" checked=(is-checked date 1980) indeterminate=(is-indeterminate date 1980) click=(action 'selectDecade' 1980)}}
- <ul class="1980">
- <li title="1980" id="1980">1980</li>
- <li title="1981" id="1981">1981</li>
- <li title="1982" id="1982">1982</li>
- <li title="1983" id="1983">1983</li>
- <li title="1984" id="1984">1984</li>
- <li title="1985" id="1985">1985</li>
- <li title="1986" id="1986">1986</li>
- <li title="1987" id="1987">1987</li>
- <li title="1988" id="1988">1988</li>
- <li title="1989" id="1989">1989</li>
+ {{input type="checkbox" checked=(is-checked date decade) indeterminate=(is-indeterminate date decade) click=(action 'selectDecade' decade)}}
+ <ul class="{{ decade }}">
+ {{#each (range decade 10) as |year| }}
+ {{ visu-chrono-year datestats=datestats year=year range=range maxCount=maxCount minCount=minCount }}
+ {{/each}}
</ul>
</div>
-<div class="interval">
- {{input type="checkbox" checked=(is-checked date 1990) indeterminate=(is-indeterminate date 1990) click=(action 'selectDecade' 1990)}}
- <ul class="1990">
- <li title="1990" id="1990">1990</li>
- <li title="1991" id="1991">1991</li>
- <li title="1992" id="1992">1992</li>
- <li title="1993" id="1993">1993</li>
- <li title="1994" id="1994">1994</li>
- <li title="1995" id="1995">1995</li>
- <li title="1996" id="1996">1996</li>
- <li title="1997" id="1997">1997</li>
- <li title="1998" id="1998">1998</li>
- <li title="1999" id="1999">1999</li>
- </ul>
-</div>
-<div class="interval">
- {{input type="checkbox" checked=(is-checked filter.date 2000) indeterminate=(is-indeterminate filter.date 2000) click=(action 'selectDecade' 2000)}}
- <ul class="2000">
- <li title="2000" id="2000">2000</li>
- <li title="2001" id="2001">2001</li>
- <li title="2002" id="2002">2002</li>
- <li title="2003" id="2003">2003</li>
- <li title="2004" id="2004">2004</li>
- <li title="2005" id="2005">2005</li>
- <li title="2006" id="2006">2006</li>
- <li title="2007" id="2007">2007</li>
- <li title="2008" id="2008">2008</li>
- <li title="2009" id="2009">2009</li>
- </ul>
-</div>
-<div class="interval">
- {{input type="checkbox" checked=(is-checked date 2010) indeterminate=(is-indeterminate filter.date 2010) click=(action 'selectDecade' 2010)}}
- <ul class="2010">
- <li title="2010" id="2010">2010</li>
- <li title="2011" id="2011">2011</li>
- <li title="2012" id="2012">2012</li>
- <li title="2013" id="2013">2013</li>
- <li title="2014" id="2014">2014</li>
- <li title="2015" id="2015">2015</li>
- <li title="2016" id="2016">2016</li>
- <li title="2017" id="2017">2017</li>
- <li title="2018" id="2018">2018</li>
- <li title="2019" id="2019">2019</li>
- </ul>
-</div>
+{{/each}}
\ No newline at end of file
--- a/cms/app-client/app/templates/tabs/chrono.hbs Fri Nov 04 19:03:25 2016 +0100
+++ b/cms/app-client/app/templates/tabs/chrono.hbs Sun Nov 06 03:44:16 2016 +0100
@@ -1,4 +1,4 @@
<div id="tabs-chrono">
<p>Cocher les cases de gauche pour sélectionner des décennies ou cliquez pour sélectionner une année et glisser pour en selectionner plusieurs.</p>
- {{ visu-chrono range=model.range }}
+ {{ visu-chrono range=model.range rawdatestats=model.datestats }}
</div>
--- a/cms/app-client/bower.json Fri Nov 04 19:03:25 2016 +0100
+++ b/cms/app-client/bower.json Sun Nov 06 03:44:16 2016 +0100
@@ -13,6 +13,7 @@
"lodash": "~4.11.1",
"Faker": "~3.1.0",
"store": "https://github.com/marcuswestin/store.js.git#v1.3.20",
- "popcorn-js": "popcornjs#^1.5.11"
+ "popcorn-js": "popcornjs#^1.5.11",
+ "chroma-js": "gka/chroma.js#master"
}
}
--- a/cms/app-client/ember-cli-build.js Fri Nov 04 19:03:25 2016 +0100
+++ b/cms/app-client/ember-cli-build.js Sun Nov 06 03:44:16 2016 +0100
@@ -29,9 +29,12 @@
// along with the exports of each module as its value.
app.import('bower_components/popcorn-js/popcorn.js');
app.import('bower_components/ammap3/ammap/ammap.js');
+ app.import('bower_components/chroma-js/chroma.js');
app.import('vendor/data/maps/worldLow.js');
app.import('vendor/data/maps/continentsLow.js');
app.import('vendor/data/maps/france2016Low.js');
+
+ //shims
app.import('vendor/shims/ammaps.js', {
exports: {
'ammaps': ['defaults']
@@ -42,6 +45,12 @@
'popcorn': ['defaults']
}
});
+ app.import('vendor/shims/chroma.js', {
+ exports: {
+ 'chroma': ['defaults']
+ }
+ });
+
return app.toTree();
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/tests/integration/components/visu-chrono-year-test.js Sun Nov 06 03:44:16 2016 +0100
@@ -0,0 +1,24 @@
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('visu-chrono-year', 'Integration | Component | visu chrono year', {
+ integration: true
+});
+
+test('it renders', function(assert) {
+ // Set any properties with this.set('myProperty', 'value');
+ // Handle any actions with this.on('myAction', function(val) { ... });
+
+ this.render(hbs`{{visu-chrono-year}}`);
+
+ assert.equal(this.$().text().trim(), '');
+
+ // Template block usage:
+ this.render(hbs`
+ {{#visu-chrono-year}}
+ template block text
+ {{/visu-chrono-year}}
+ `);
+
+ assert.equal(this.$().text().trim(), 'template block text');
+});
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/app-client/vendor/shims/chroma.js Sun Nov 06 03:44:16 2016 +0100
@@ -0,0 +1,9 @@
+(function() {
+ function vendorModule() {
+ 'use strict';
+
+ return { 'default': self['chroma'] };
+ }
+
+ define('chroma', [], vendorModule);
+})();