# HG changeset patch # User ymh # Date 1479228177 -3600 # Node ID feb0d3e0fef9fc06e7df498019e55d7136014625 # Parent 788971813bdc2892e544264ce991d00d2034c0e5 add dynamic date range calculation for dates, and add color gradient component, add color gradient for language and chrono diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/adapters/application.js --- a/cms/app-client/app/adapters/application.js Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/adapters/application.js Tue Nov 15 17:42:57 2016 +0100 @@ -5,6 +5,7 @@ transcript: 'transcript', geostat: 'stats/geostats', datestat: 'stats/datestats', + dateminmax: 'stats/dateminmax', theme: 'stats/themes' }; diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/components/color-gradient.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/app/components/color-gradient.js Tue Nov 15 17:42:57 2016 +0100 @@ -0,0 +1,30 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + + classNames: ['color-gradient'], + + colors: Ember.inject.service(), + + domainStart: 0, + domainEnd: 100, + scale: null, + + scaleProxy: Ember.computed('scale', function() { + let scaleRaw = this.get('scale'); + if(scaleRaw === null) { + return this.get('colors').getScaleLinear(this.get('domainStart'), this.get('domainEnd')); + } else { + return scaleRaw; + } + }), + + domainMed: Ember.computed('domainStart', 'domainEnd', function() { + return Math.round((this.get('domainEnd')-this.get('domainStart'))/2); + }), + + colorList: Ember.computed('scale', function() { + return this.get('scaleProxy').colors(100); + }) + +}); diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/components/visu-carto.js --- a/cms/app-client/app/components/visu-carto.js Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/components/visu-carto.js Tue Nov 15 17:42:57 2016 +0100 @@ -7,6 +7,7 @@ export default Ember.Component.extend({ constants: Ember.inject.service(), + colors: Ember.inject.service(), map: null, @@ -175,8 +176,8 @@ 'areasSettings': { 'autoZoom': false, 'selectable': true, - 'color': '#777777', - 'colorSolid': '#333333', + 'color': this.get('colors').LINEAR_COLOR_START, + 'colorSolid': this.get('colors').LINEAR_COLOR_END, 'colorOutline': '#253946', 'selectedColor': '#0085cb', 'rollOverColor': '#0085cb', diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/components/visu-chrono-year.js --- a/cms/app-client/app/components/visu-chrono-year.js Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/components/visu-chrono-year.js Tue Nov 15 17:42:57 2016 +0100 @@ -10,6 +10,8 @@ classNameBindings: ['isDisabled:disabled', 'isDark:light-color', 'isHighlighted:highlighted'], attributeBindings: ['style', 'title', 'id'], + colorScale: null, + isDisabled: Ember.computed('range', 'year', 'count', function() { let year = parseInt(this.get('year')); let count = this.get('count'); @@ -27,8 +29,9 @@ return this.get('colors').getPerceptiveLuminance(backgroundColor) >= 0.5; }), - backgroundColor: Ember.computed('count', 'maxCount', 'minCount', function() { - return this.get('colors').shadeLinear(this.get('count'), this.get('minCount'), this.get('maxCount')); + backgroundColor: Ember.computed('count', function() { + return this.get('scale')(this.get('count')); + //return this.get('colors').shadeLinear(this.get('count'), this.get('minCount'), this.get('maxCount')); }), style: Ember.computed('backgroundColor', 'isDisabled', 'isHighlighted', function() { @@ -56,6 +59,4 @@ year: null, datestats: null, range: null, - maxCount: null, - minCount: null, }); diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/components/visu-chrono.js --- a/cms/app-client/app/components/visu-chrono.js Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/components/visu-chrono.js Tue Nov 15 17:42:57 2016 +0100 @@ -3,11 +3,21 @@ export default Ember.Component.extend({ - range: [], + colors: Ember.inject.service(), + filter: Ember.inject.service(), + + range: null, rawdatestats: null, - decades: Ember.computed('range', function() { - var range = this.get('range'); + rangeArray: Ember.computed('range', 'range.[]', function() { + let range = this.get('range'); + let resArray = []; + range.forEach(function(s) { resArray.push(parseInt(s.id)); }); + return resArray.sort(); + }), + + decades: Ember.computed('rangeArray', function() { + var range = this.get('rangeArray'); return _.range(Math.floor(range[0]/10)*10, (Math.floor(range[1]/10)+1)*10, 10); }), @@ -22,8 +32,9 @@ counts: Ember.computed.mapBy('rawdatestats', 'count'), maxCount: Ember.computed.max('counts'), minCount: Ember.computed.min('counts'), - - filter: Ember.inject.service(), + colorScale: Ember.computed('maxCount', 'minCount', function() { + return this.get('colors').getScaleLinear(this.get('minCount'), this.get('maxCount')); + }), date: Ember.computed.alias('filter.dateList'), @@ -43,8 +54,10 @@ if(event.button === 0) { isMouseDown = true; - var element = parseInt(Ember.$(this).attr('id')); - if(!_.inRange(element, self.get('range')[0], self.get('range')[1]+1)) { + var $elem = Ember.$(this); + var element = parseInt($elem.attr('id')); + var range = self.get('rangeArray'); + if(!$elem.hasClass('highlighted') && !_.inRange(element, range[0], range[1]+1)) { return false; } var elements = [element]; diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/components/visu-langues.js --- a/cms/app-client/app/components/visu-langues.js Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/components/visu-langues.js Tue Nov 15 17:42:57 2016 +0100 @@ -10,6 +10,14 @@ filter: Ember.inject.service(), colors: Ember.inject.service(), + scale: Ember.computed('maxCount', 'minCount', function() { + let maxCount = this.get('maxCount'); + let minCount = this.get('minCount'); + return this.get('colors').getScaleLinear(minCount, maxCount); + }), + maxCount: 0, + minCount: 0, + filterObserver: Ember.observer('filter.language', function() { Ember.$('.node').removeClass("selected"); Ember.$('.node[data-id="' + this.get('filter').get('language') + '"]').addClass("selected"); @@ -142,10 +150,14 @@ 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; })); + self.setProperties({minCount: dMin, maxCount: dMax}); + var scale = self.get('scale'); + var backgroundColor = function(_d) { return scale(_d.count);}; + var colorClass = function(_d) { return (self.get('colors').getPerceptiveLuminance(backgroundColor(_d)) >= 0.5)?'light-color':'dark-color'; }; - node.attr("class", function(d) { return "node" + ( d.id === self.get('filter').get('language') ? " selected" : "" ); }) + node.attr("class", function(_d) { return "node " + colorClass(_d) + ( _d.id === self.get('filter').get('language') ? " selected" : "" ); }) .call(position) - .style("background-color", function(d) { return self.get('colors').shadeLinear(d.count,dMin,dMax); }) + .style("background-color", backgroundColor) .on("click", selectHandler); node.filter(function(d) { return d._children; }) diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/helpers/.gitkeep diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/helpers/color-gradient-style.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/app/helpers/color-gradient-style.js Tue Nov 15 17:42:57 2016 +0100 @@ -0,0 +1,7 @@ +import Ember from 'ember'; + +export function colorGradientStyle(color) { + return Ember.String.htmlSafe(`background-color: ${color}`); +} + +export default Ember.Helper.helper(colorGradientStyle); diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/models/dateminmax.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/app/models/dateminmax.js Tue Nov 15 17:42:57 2016 +0100 @@ -0,0 +1,4 @@ +import DS from 'ember-data'; + +export default DS.Model.extend({ +}); diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/routes/tabs/chrono.js --- a/cms/app-client/app/routes/tabs/chrono.js Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/routes/tabs/chrono.js Tue Nov 15 17:42:57 2016 +0100 @@ -8,7 +8,7 @@ model: function() { return RSVP.hash({ - range: [1948, 2015], // TODO: make it dynamic + range: this.get('store').query('dateminmax', {}), datestats: this.get('store').query('datestat', this.get('filter').get('queryParamsValues')) }); }, diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/serializers/dateminmax.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/app/serializers/dateminmax.js Tue Nov 15 17:42:57 2016 +0100 @@ -0,0 +1,18 @@ +import DS from 'ember-data'; + +export default DS.Serializer.extend({ + + normalizeResponse: function(store, primaryModelClass, payload) { + var data = []; + payload['dateminmax'].forEach(function(key) { + data.push({ + 'id': key, + 'type': 'dateminmax' + }); + }); + return { + 'data': data + }; + } + +}); diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/services/colors.js --- a/cms/app-client/app/services/colors.js Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/services/colors.js Tue Nov 15 17:42:57 2016 +0100 @@ -4,8 +4,12 @@ export const LINEAR_COLOR_START = "#777777"; export const LINEAR_COLOR_END = "#333333"; +export function getScaleLinear(vmin, vmax) { + return chroma.scale([LINEAR_COLOR_START, LINEAR_COLOR_END]).mode('lab').domain([vmin,vmax]); +} + export function shadeLinear(v, vmin, vmax) { - var s = chroma.scale([LINEAR_COLOR_START, LINEAR_COLOR_END]).mode('lab').domain([vmin,vmax]); + var s = getScaleLinear(vmin, vmax); return s(v).hex(); } @@ -37,6 +41,7 @@ } export default Ember.Service.extend({ + getScaleLinear: getScaleLinear, shadeLinear: shadeLinear, getComplement: getComplement, getPerceptiveLuminance: getPerceptiveLuminance, diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/styles/app.scss --- a/cms/app-client/app/styles/app.scss Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/styles/app.scss Tue Nov 15 17:42:57 2016 +0100 @@ -60,6 +60,7 @@ @import 'components/toolbar-component'; @import 'components/notice-component'; @import 'components/transcript-component'; +@import 'components/color-gradient'; h1, h2, h3, h4, h5, h6 { @@ -122,7 +123,7 @@ .corpus-app-wrapper { background-color: $corpus-light-grey; - border-left: 1px solid $corpus-black; + border-left: 1px solid $corpus-black; position: relative; } diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/styles/components/color-gradient.scss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/app/styles/components/color-gradient.scss Tue Nov 15 17:42:57 2016 +0100 @@ -0,0 +1,37 @@ +.color-gradient { + width: 85%; + white-space: nowrap; + position: relative; + display: inline-block; + top: 4px; + padding-bottom: 1.2em; +} + +.color-gradient .grad-step { + display: inline-block; + height: 1.5em; + width: 1%; +} + +.color-gradient .domain-min { + position: absolute; + left: 0; + font-size: 0.8em; + bottom: 3px; +} + +.color-gradient .domain-med { + position: absolute; + right: 25%; + left: 25%; + text-align: center; + font-size: 0.8em; + bottom: 3px; +} + +.color-gradient .domain-max { + position: absolute; + right: 0; + font-size: 0.8em; + bottom: 3px; +} diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/styles/components/notice-component.scss --- a/cms/app-client/app/styles/components/notice-component.scss Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/styles/components/notice-component.scss Tue Nov 15 17:42:57 2016 +0100 @@ -22,7 +22,7 @@ color: $corpus-grey; padding-right: 0.5em; padding-left: 0.5em; - + text-decoration: none; } body.videoscreen .notice-component { diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/styles/tabs/chrono.scss --- a/cms/app-client/app/styles/tabs/chrono.scss Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/styles/tabs/chrono.scss Tue Nov 15 17:42:57 2016 +0100 @@ -1,7 +1,7 @@ #tabs-chrono p { padding: 0px 20px; text-align: center; - margin: 25px 0px 50px 0px; + margin: 25px 0px 25px 0px; line-height: 22px; color: $corpus-black; } @@ -46,12 +46,18 @@ #chrono-table li.disabled { cursor: default; color: $corpus-grey; + pointer-events: none; +} + +#chrono-table .color-gradient { + width: 150px; } #chrono-table li.highlighted { font-weight: bold; color: $corpus-white; background-color: $corpus-blue; + pointer-events: initial; } #chrono-table li.light-color { diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/styles/tabs/langues.scss --- a/cms/app-client/app/styles/tabs/langues.scss Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/styles/tabs/langues.scss Tue Nov 15 17:42:57 2016 +0100 @@ -71,4 +71,26 @@ #tabs-langues .node .count { font-weight: bold; -} \ No newline at end of file +} + +#tabs-langues .light-color { + color: $corpus-white; +} + +#tabs-langues .dark-color { + color: $corpus-black; +} + +#tabs-langues .color-gradient-wrapper { + position: absolute; + width: 100px; + top: 1px; + right: 5px; +} + +#tabs-langues .color-gradient-wrapper .color-gradient { + position: relative; + width: 100%; + height: 1.75em; + font-size: 0.75em; +} diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/templates/components/color-gradient.hbs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/app/templates/components/color-gradient.hbs Tue Nov 15 17:42:57 2016 +0100 @@ -0,0 +1,4 @@ +{{#each colorList as |c index|}}{{/each}} +{{domainStart}} +{{domainMed}} +{{domainEnd}} \ No newline at end of file diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/templates/components/visu-chrono.hbs --- a/cms/app-client/app/templates/components/visu-chrono.hbs Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/templates/components/visu-chrono.hbs Tue Nov 15 17:42:57 2016 +0100 @@ -1,9 +1,10 @@ +
{{ color-gradient domainStart=minCount domainEnd=maxCount scale=colorScale }}
{{#each decades as |decade| }}
{{input type="checkbox" checked=(is-checked date decade) indeterminate=(is-indeterminate date decade) click=(action 'selectDecade' decade)}}
diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/templates/components/visu-langues.hbs --- a/cms/app-client/app/templates/components/visu-langues.hbs Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/templates/components/visu-langues.hbs Tue Nov 15 17:42:57 2016 +0100 @@ -0,0 +1,3 @@ +
+{{ color-gradient domainStart=minCount domainEnd=maxCount scale=scale }} +
\ No newline at end of file diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/app/templates/tabs/chrono.hbs --- a/cms/app-client/app/templates/tabs/chrono.hbs Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/app/templates/tabs/chrono.hbs Tue Nov 15 17:42:57 2016 +0100 @@ -1,4 +1,4 @@
-

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.

+

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.

{{ visu-chrono range=model.range rawdatestats=model.datestats }}
diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/mirage/config.js --- a/cms/app-client/mirage/config.js Mon Nov 14 17:23:43 2016 +0100 +++ b/cms/app-client/mirage/config.js Tue Nov 15 17:42:57 2016 +0100 @@ -40,6 +40,8 @@ this.get('/stats/datestats', 'datestats'); + this.get('/stats/dateminmax', 'dateminmax'); + this.get('/resolvers/lexvo/:ids', ({lexvos}, request) => { var langIds = decodeURIComponent(request.params.ids); var resMap = _.reduce(langIds.split(','), function(res, id) { diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/mirage/fixtures/dateminmax.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/mirage/fixtures/dateminmax.js Tue Nov 15 17:42:57 2016 +0100 @@ -0,0 +1,4 @@ +export default [ + { 'id': "1948" }, + { 'id': "2015" } +]; diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/mirage/models/dateminmax.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/mirage/models/dateminmax.js Tue Nov 15 17:42:57 2016 +0100 @@ -0,0 +1,4 @@ +import { Model } from 'ember-cli-mirage'; + +export default Model.extend({ +}); diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/mirage/serializers/dateminmax.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/mirage/serializers/dateminmax.js Tue Nov 15 17:42:57 2016 +0100 @@ -0,0 +1,9 @@ +import { JSONAPISerializer } from 'ember-cli-mirage'; + +import _ from 'lodash/lodash'; + +export default JSONAPISerializer.extend({ + serialize(response) { + return {'dateminmax': _(response.models).map((dateinfo) => { return parseInt(dateinfo.id);}).value()}; + } +}); diff -r 788971813bdc -r feb0d3e0fef9 cms/app-client/tests/integration/components/color-gradient-test.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/tests/integration/components/color-gradient-test.js Tue Nov 15 17:42:57 2016 +0100 @@ -0,0 +1,24 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('color-gradient', 'Integration | Component | color gradient', { + 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`{{color-gradient}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#color-gradient}} + template block text + {{/color-gradient}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff -r 788971813bdc -r feb0d3e0fef9 server/src/app/Http/Controllers/Api/DateStatsController.php --- a/server/src/app/Http/Controllers/Api/DateStatsController.php Mon Nov 14 17:23:43 2016 +0100 +++ b/server/src/app/Http/Controllers/Api/DateStatsController.php Tue Nov 15 17:42:57 2016 +0100 @@ -12,23 +12,8 @@ class DateStatsController extends Controller { - /** - * Display the specified resource. - * - * @return \Illuminate\Http\Response - */ - public function index(Request $request) - { - - - $filterManager = new CorpusFilterManager(); - $filters = $filterManager->prepareFilters($request); - unset($filters['dates']); - $qFilterParts = $filterManager->buildESFilters($filters); - - $query = $filterManager->buildQuery($qFilterParts); - - $esQuery = [ + private function getStatQuery($query) { + return [ 'index' => config('elasticsearch.index'), 'body' => [ "size" => 0, @@ -60,6 +45,70 @@ ] ] ]; + } + + private function getMinMaxQuery($query) { + return [ + 'index' => config('elasticsearch.index'), + 'body' => [ + "size" => 0, + "query" => $query, + "aggs" => [ + "datestats" => [ + "nested"=> [ + "path" => "creation_years" + ], + "aggs" => [ + "minyear" => [ + "min" => [ "field"=> "creation_years.year" ] + ], + "maxyear" => [ + "max" => [ "field"=> "creation_years.year" ] + ] + ] + ] + ] + ] + ]; + } + + private function getDocQuery(Request $request) { + $filterManager = new CorpusFilterManager(); + $filters = $filterManager->prepareFilters($request); + unset($filters['dates']); + $qFilterParts = $filterManager->buildESFilters($filters); + + return $filterManager->buildQuery($qFilterParts); + } + + /** + * Display the min max date stats + */ + public function minmax(Request $request) { + $query = $this->getDocQuery($request); + + $esQuery = $this->getMinMaxQuery($query); + $esRes = Es::search($esQuery); + + $datestats = []; + + $max = intval($esRes['aggregations']['datestats']['maxyear']['value']); + $min = intval($esRes['aggregations']['datestats']['maxyear']['value']); + + return response()->json(['dateminmax' => [ $min, $max ] ]); + } + + /** + * Display the dates stats + * + * @return \Illuminate\Http\Response + */ + public function index(Request $request) + { + + $query = $this->getDocQuery($request); + + $esQuery = $this->getStatQuery($query); $esRes = Es::search($esQuery); $datestats = []; diff -r 788971813bdc -r feb0d3e0fef9 server/src/routes/api.php --- a/server/src/routes/api.php Mon Nov 14 17:23:43 2016 +0100 +++ b/server/src/routes/api.php Tue Nov 15 17:42:57 2016 +0100 @@ -31,6 +31,7 @@ Route::get('themes', 'Api\ThemeController@index'); Route::get('discourses', 'Api\DiscourseController@index'); Route::get('datestats', 'Api\DateStatsController@index'); + Route::get('dateminmax', 'Api\DateStatsController@minmax'); Route::get('geostats', 'Api\GeoStatsController@index'); }); });