diff --git a/webapp/core/bower.json b/webapp/core/bower.json index 5ada3de631..cfa58aa1fb 100644 --- a/webapp/core/bower.json +++ b/webapp/core/bower.json @@ -54,6 +54,7 @@ "datatables.net-fixedcolumns-bs": "3.2.2", "hp-autonomy-about-page": "0.3.0", "bootstrap": "3.3.7", + "Flot": "flot#~0.8.3", "moment-timezone": "0.5.11" }, "devDependencies": { diff --git a/webapp/core/src/main/less/app-include.less b/webapp/core/src/main/less/app-include.less index 5e0d931cc5..c4ed6ac848 100644 --- a/webapp/core/src/main/less/app-include.less +++ b/webapp/core/src/main/less/app-include.less @@ -1599,12 +1599,18 @@ input.find-input { width: @custom3; } -.parametric-value-count { +.parametric-value-graph-cell { + width: @custom3; + text-align: right; +} + +.parametric-value-count,.parametric-value-graph { &:extend(.text-right); } .parametric-value-name, -.parametric-value-count { +.parametric-value-count, +.parametric-value-graph{ white-space: nowrap; } @@ -2238,19 +2244,23 @@ h4.similar-dates-message { } @media @smHeightScreen { - .entity-topic-map { + .entity-topic-map, .dategraph-content { height: @custom4; } } @media @mHeightScreen { - .entity-topic-map { + .entity-topic-map, .dategraph-content { height: 500px; } } @media @lgHeightScreen { - .entity-topic-map { + .entity-topic-map, .dategraph-content { height: @lgHeightScreenTopicMapHeight; } } + +.dategraph-content { + clear: both; +} \ No newline at end of file diff --git a/webapp/core/src/main/public/static/js/find/app/page/search/filter-view.js b/webapp/core/src/main/public/static/js/find/app/page/search/filter-view.js index e648e7e19e..b3a29962d9 100644 --- a/webapp/core/src/main/public/static/js/find/app/page/search/filter-view.js +++ b/webapp/core/src/main/public/static/js/find/app/page/search/filter-view.js @@ -35,8 +35,10 @@ define([ const IndexesView = options.IndexesView; this.collapsed = {}; + const config = configuration(); + const views = [{ - shown: configuration().enableMetaFilter, + shown: config.enableMetaFilter, initialize: function () { //Initializing the text with empty string to stop IE11 issue with triggering input event on render this.filterModel = new Backbone.Model({text: ''}); @@ -175,7 +177,8 @@ define([ inputTemplate: NumericParametricFieldView.dateInputTemplate, formatting: NumericParametricFieldView.dateFormatting, indexesCollection: options.indexesCollection, - filteredParametricCollection: filteredParametricCollection + filteredParametricCollection: filteredParametricCollection, + showGraphButtons: _.contains(config.resultViewOrder, 'dategraph') }); }.bind(this), get$els: function () { diff --git a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-field-view.js b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-field-view.js index 80cc71a38b..dfaaaa186c 100644 --- a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-field-view.js +++ b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-field-view.js @@ -42,7 +42,8 @@ define([ queryModel: this.queryModel, parametricFieldsCollection: this.parametricFieldsCollection, selectedParametricValues: this.selectedParametricValues, - indexesCollection: this.indexesCollection + indexesCollection: this.indexesCollection, + showGraphButtons: this.showGraphButtons }); } }, @@ -52,6 +53,7 @@ define([ this.indexesCollection = options.indexesCollection; this.parametricFieldsCollection = options.parametricFieldsCollection; this.queryModel = options.queryModel; + this.showGraphButtons = options.showGraphButtons; this.listView = new ListView({ collection: this.collection, @@ -61,6 +63,7 @@ define([ tagName: 'tbody', itemOptions: { selectedValuesCollection: options.selectedValuesCollection, + showGraphButtons: options.showGraphButtons } }); }, @@ -109,7 +112,8 @@ define([ parametricFieldsCollection: this.parametricFieldsCollection, queryModel: this.queryModel, selectedParametricValues: this.selectedParametricValues, - indexesCollection: this.indexesCollection + indexesCollection: this.indexesCollection, + showGraphButtons: options.showGraphButtons }) }); diff --git a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-item-view.js b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-item-view.js index 15b28097a6..04158c9467 100644 --- a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-item-view.js +++ b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-item-view.js @@ -15,12 +15,17 @@ define([ tagName: 'li', template: _.template(template), + initialize: function(options) { + this.showGraphButtons = options.showGraphButtons; + }, + render: function() { this.$el .html(this.template({ count: this.model.get('count') || 0, value: this.model.get('value'), - displayValue: this.model.get('displayValue') + displayValue: this.model.get('displayValue'), + showGraphButtons: this.showGraphButtons })) .iCheck({checkboxClass: 'icheckbox-hp'}); diff --git a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-list-view.js b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-list-view.js index 7e75f1ff9e..f17d04fc9e 100644 --- a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-list-view.js +++ b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-list-view.js @@ -42,6 +42,9 @@ define([ ItemView: ItemView, collectionChangeEvents: { selected: 'updateSelected' + }, + itemOptions: { + showGraphButtons: options.showGraphButtons } }); diff --git a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-view.js b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-view.js index 8d2241a634..3c2f094443 100644 --- a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-view.js +++ b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal-view.js @@ -57,7 +57,10 @@ define([ return { id: fieldModel.id, displayName: fieldModel.get('displayName'), - view: new ParametricSelectModalListView({paginator: paginator}) + view: new ParametricSelectModalListView({ + showGraphButtons: options.showGraphButtons, + paginator: paginator + }) }; }.bind(this)); @@ -102,6 +105,10 @@ define([ }); }, + getSelectedField: function(){ + return this.fieldSelectionModel.get('field'); + }, + remove: function () { this.fieldData.forEach(function (data) { data.view.remove(); diff --git a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal.js b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal.js index 3165a79daa..deeddae903 100644 --- a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal.js +++ b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-select-modal.js @@ -26,6 +26,10 @@ define([ 'shown.bs.modal': function() { // The content view will be visible now, so check if we need to load parametric values this.parametricSelectView.checkScroll(); + }, + 'click .parametric-value-graph': function(e){ + var $checkboxEl = $(e.currentTarget).prev() + this.externalSelectedValues.trigger('graph', this.parametricSelectView.getSelectedField(), $checkboxEl.data('value')); } }, Modal.prototype.events), @@ -40,7 +44,8 @@ define([ indexesCollection: options.indexesCollection, queryModel: options.queryModel, parametricFieldsCollection: options.parametricFieldsCollection, - selectedParametricValues: this.selectedParametricValues + selectedParametricValues: this.selectedParametricValues, + showGraphButtons: options.showGraphButtons }); Modal.prototype.initialize.call(this, { diff --git a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-value-view.js b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-value-view.js index 8a3a9b2cc0..69a4736350 100644 --- a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-value-view.js +++ b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-value-view.js @@ -11,6 +11,7 @@ define([ initialize: function (options) { this.selectedValuesCollection = options.selectedValuesCollection; + this.showGraphButtons = options.showGraphButtons; this.$el.attr('data-value', this.model.get('value')); this.$el.attr('data-display-value', this.model.get('displayValue')); @@ -21,6 +22,10 @@ define([ render: function () { this.$el.html(template); + if (!this.showGraphButtons) { + this.$('.parametric-value-graph-cell').addClass('hide'); + } + this.$text = this.$('.parametric-value-text'); this.$name = this.$('.parametric-value-name'); this.$count = this.$('.parametric-value-count'); diff --git a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-view.js b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-view.js index 20012d6cf1..3f1d3759dd 100644 --- a/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-view.js +++ b/webapp/core/src/main/public/static/js/find/app/page/search/filters/parametric/parametric-view.js @@ -41,7 +41,9 @@ define([ type: 'Parametric' }; - if (this.selectedParametricValues.get(attributes)) { + if ($(e.target).closest('.parametric-value-graph-cell').length) { + this.selectedParametricValues.trigger('graph', attributes.field, attributes.value); + } else if (this.selectedParametricValues.get(attributes)) { this.selectedParametricValues.remove(attributes); } else { this.selectedParametricValues.add(attributes); @@ -54,6 +56,7 @@ define([ this.filteredParametricCollection = options.filteredParametricCollection; this.selectedParametricValues = options.queryState.selectedParametricValues; this.filterModel = options.filterModel; + this.showGraphButtons = options.showGraphButtons; this.initializeProcessingBehaviour(); @@ -96,7 +99,8 @@ define([ parametricFieldsCollection: options.parametricFieldsCollection, filteredParametricCollection: this.filteredParametricCollection, selectedParametricValues: this.selectedParametricValues, - filterModel: this.filterModel + filterModel: this.filterModel, + showGraphButtons: options.showGraphButtons }, numericViewItemOptions: { inputTemplate: options.inputTemplate, @@ -110,7 +114,8 @@ define([ zoomEnabled: options.zoomEnabled, buttonsEnabled: options.buttonsEnabled, coordinatesEnabled: options.coordinatesEnabled, - collapsed: isCollapsed + collapsed: isCollapsed, + showGraphButtons: options.showGraphButtons } } }); diff --git a/webapp/core/src/main/public/static/js/find/app/page/search/results/dategraph/dategraph-view.js b/webapp/core/src/main/public/static/js/find/app/page/search/results/dategraph/dategraph-view.js new file mode 100644 index 0000000000..7637d6ed31 --- /dev/null +++ b/webapp/core/src/main/public/static/js/find/app/page/search/results/dategraph/dategraph-view.js @@ -0,0 +1,324 @@ +/* + * Copyright 2015 Hewlett-Packard Development Company, L.P. + * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. + */ +define([ + 'backbone', + 'underscore', + 'd3', + 'find/app/util/topic-map-view', + 'find/app/model/entity-collection', + 'i18n!find/nls/bundle', + 'find/app/configuration', + 'find/app/page/search/filters/parametric/calibrate-buckets', + 'find/app/page/search/results/field-selection-view', + 'find/app/model/bucketed-parametric-collection', + 'parametric-refinement/to-field-text-node', + 'find/app/util/generate-error-support-message', + 'text!find/templates/app/page/search/results/dategraph/dategraph-view.html', + 'text!find/templates/app/page/loading-spinner.html', + 'iCheck', + 'slider/bootstrap-slider', + 'flot.time' +], function(Backbone, _, d3, TopicMapView, EntityCollection, i18n, configuration, calibrateBuckets, FieldSelectionView, + BucketedParametricCollection, toFieldTextNode, generateErrorHtml, template, + loadingTemplate) { + 'use strict'; + + var loadingHtml = _.template(loadingTemplate)({i18n: i18n, large: true}); + + var category10 = d3.scale.category10(); + + function rangeModelMatching(fieldName, dataType) { + var upperCase = fieldName.toUpperCase(); + + return function(model) { + return model.get('field').toUpperCase() === upperCase && model.get('range') && model.get('type') === dataType; + }; + } + + function dateModelMatching(fieldName, dataType) { + var upperCase = fieldName.toUpperCase(); + + return function(model) { + return model.id.toUpperCase() === upperCase && model.get('type') === dataType; + }; + } + + return Backbone.View.extend({ + template: _.template(template), + + events: { + 'click .dategraph-view-pptx': function(evt){ + evt.preventDefault(); + + var modelBuckets = this.bucketModel.get('values'); + var rows = []; + var multiAxes = !this.hideMainPlot && this.plots.length > 1; + + if (!this.hideMainPlot) { + rows.push({ + color: '#00B388', + label: i18n['search.resultsView.dategraph.defaultSeriesLabel'], + secondaryAxis: false, + values: _.pluck(modelBuckets, 'count') + }) + } + + _.each(this.plots, function(plot){ + var label = plot.field.replace(/^.*\//, '').replace(/_/g, '\u00A0') + ': ' + plot.value; + + rows.push({ + color: category10(label), + label: label, + secondaryAxis: multiAxes, + values: _.pluck(plot.model.get('values'), 'count') + }) + }) + + var data = { + rows: rows, + timestamps: _.map(modelBuckets, function(a) { + return Math.round(0.5*(a.min+a.max)); + }) + } + + var $form = $('
'); + $form[0].data.value = JSON.stringify(data) + $form.appendTo(document.body).submit().remove() + } + }, + + initialize: function(options) { + this.queryState = options.queryState; + + this.queryModel = options.queryModel; + this.pixelsPerBucket = options.pixelsPerBucket || 20; + + this.fieldName = 'autn_date'; + this.dataType = 'NumericDate'; + + this.bucketModel = new BucketedParametricCollection.Model({id: this.fieldName}); + this.selectedParametricValues = options.queryState.selectedParametricValues; + this.parametricFieldsCollection = options.parametricFieldsCollection; + + this.listenTo(this.queryModel, 'change', this.fetchBuckets); + + this.listenTo(this.bucketModel, 'change:values request sync error', this.updateGraph); + + this.listenTo(this.selectedParametricValues, 'graph', this.graphRequest) + + this.plots = [] + }, + + graphRequest: function(field, value){ + if (!_.where(this.plots, { field: field, value: value }).length) { + var model = new BucketedParametricCollection.Model({id: this.fieldName}); + var subPlot = { field: field, value: value, model: model }; + this.plots.push(subPlot); + this.listenTo(model, 'change:values', this.updateGraph) + this.lastOtherSelectedValues && this.fetchSubPlot(subPlot) + } + }, + + update: function() { + if(this.$el.is(':visible')) { + this.updateGraph(); + } + }, + + updateGraph: function() { + if (this.$tooltip) { + this.$tooltip.hide() + } + + var hadError = this.bucketModel.error; + var fetching = this.bucketModel.fetching; + var modelBuckets = this.bucketModel.get('values'); + var noValues = !modelBuckets || !modelBuckets.length; + + this.$('.dategraph-view-error-message').toggleClass('hide', !hadError); + this.$('.dategraph-view-empty-text').toggleClass('hide', hadError || !noValues || fetching); + + var hideLoadingIndicator = hadError || !fetching; + this.$('.dategraph-loading').toggleClass('hide', hideLoadingIndicator); + + + var $contentEl = this.$('.dategraph-content'); + var width = $contentEl.width(); + + function transform(values) { + return values.map(function (a) { + return [0.5e3 * (a.min + a.max), a.count, a.min, a.max] + }) + } + + if(!hadError && !noValues && hideLoadingIndicator && width > 0) { + var multiAxes = !this.hideMainPlot && this.plots.length > 1; + + var data = (this.hideMainPlot ? [] : [{ + color: '#00B388', + label: i18n['search.resultsView.dategraph.defaultSeriesLabel'], + data: transform(modelBuckets) + }]).concat(_.map(this.plots, function(plot, idx, plots){ + var label = plot.field.replace(/^.*\//, '').replace(/_/g, '\u00A0') + ': ' + plot.value; + return { + color: category10(label), + label: label, + data: transform(plot.model.get('values')), + yaxis: multiAxes ? 2 : 1 + } + })) + + var yaxes = [{ minTickSize: 1 }]; + + if (multiAxes) { + yaxes.push({ minTickSize: 1, position: 'right' }); + } + + $.plot($contentEl[0], data, { + grid: { hoverable: true }, + xaxis: {mode: 'time'}, + yaxes: yaxes + }) + + this.$('.dategraph-view-pptx').removeClass('disabled'); + } + else { + $contentEl.empty(); + this.$('.dategraph-view-pptx').addClass('disabled'); + } + }, + + fetchBuckets: function() { + // We now use the width of the closest visible ancestor, even if this tab itself is currently hidden, + // since the filters may change when we're not looking at the screen; which gives zero width for + // the SVG if it's not on the screen, but we still need data. + var width = this.$('.dategraph-content').closest(':visible').width(); + + // If the SVG has no width or there are no values, there is no point fetching new data + // if(width !== 0 && this.model.get('totalValues') !== 0) { + if(width) { + var rangeFilter = this.selectedParametricValues.find(rangeModelMatching(this.fieldName, this.dataType)); + + var otherSelectedValues = this.selectedParametricValues + .map(function(model) { + return model.toJSON(); + }); + + var dateRange = rangeFilter && rangeFilter.get('range'); + + var minDate = this.queryModel.getIsoDate('minDate'); + var maxDate = this.queryModel.getIsoDate('maxDate'); + + var dateField = this.parametricFieldsCollection.find(dateModelMatching(this.fieldName, this.dataType)); + + var baseParams = { + queryText: this.queryModel.get('queryText'), + fieldText: toFieldTextNode(otherSelectedValues), + minDate: minDate, + maxDate: maxDate, + minScore: this.queryModel.get('minScore'), + databases: this.queryModel.get('indexes'), + targetNumberOfBuckets: Math.floor(width / this.pixelsPerBucket), + bucketMin: dateRange ? dateRange[0] : dateField ? dateField.get('min') : Math.floor((new Date().getTime() - 86400e3*365)/1000), + bucketMax: dateRange ? dateRange[1] : dateField ? dateField.get('max') : Math.floor(new Date().getTime()/1000) + }; + + this.lastBaseParams = baseParams; + this.lastOtherSelectedValues = otherSelectedValues; + + this.hideMainPlot = false; + + this.bucketModel.fetch({ + data: baseParams + }); + + _.each(this.plots, this.fetchSubPlot, this) + } + }, + + fetchSubPlot: function(plot){ + var newFieldText = toFieldTextNode([{field: plot.field, value: plot.value}]) + var plotSelectedValues = toFieldTextNode(this.lastOtherSelectedValues); + + plot.model.set([]) + plot.model.fetch({ + data: _.defaults({ + fieldText: plotSelectedValues ? '(' + plotSelectedValues + ') AND (' + newFieldText + ')': newFieldText + }, this.lastBaseParams) + }) + }, + + render: function() { + this.$el.html(this.template({ + i18n: i18n, + errorTemplate: this.errorTemplate, + loadingHtml: loadingHtml, + cid: this.cid + })); + + this.$('.dategraph-content').on('click .legendColorBox', _.bind(function(evt){ + var idx = $(evt.target).closest('tr').index(), removed + + if (idx >= 0) { + if (this.hideMainPlot) { + removed = this.plots.splice(idx, 1) + this.stopListening(removed[0].model) + + if (!this.plots.length) { + this.hideMainPlot = false; + } + + this.updateGraph(); + } + else if (idx) { + removed = this.plots.splice(idx - 1, 1) + this.stopListening(removed[0].model) + + this.updateGraph(); + } + else if (this.plots.length) { + this.hideMainPlot = true; + this.updateGraph(); + } + } + }, this)).on('plothover', _.bind(function(evt, pos, item){ + function lPad2(num) { + return num < 10 ? '0' + num : num; + } + + function formatDate(epochSeconds){ + var date = new Date(1000 * epochSeconds); + return [ + [date.getFullYear(), lPad2(date.getMonth() + 1), lPad2(date.getDate())].join('-'), + [lPad2(date.getHours()), lPad2(date.getMinutes())].join(':') + ] + } + + if (item) { + if (!this.$tooltip) { + this.$tooltip = $('').appendTo(this.$el) + } + var origPt = item.series.data[item.dataIndex] + var minStr = formatDate(origPt[2]), maxStr = formatDate(origPt[3]) + + var timeStr = minStr[0] === maxStr[0] ? maxStr[0] + ' ' + minStr[1] + ' to ' + maxStr[1] : minStr[0] + ' to ' + maxStr[0]; + + this.$tooltip.find('.tooltip-inner').html(timeStr + '
' + _.escape(item.series.label) + ': ' + item.datapoint[1]) + this.$tooltip.show() + .css({ top: item.pageY - 20 - this.$tooltip.height(), left: item.pageX - 0.5 * this.$tooltip.width(), opacity: 1 }) + } + else if (this.$tooltip) { + this.$tooltip.hide() + } + }, this)).on('mouseout', _.bind(function(){ + if (this.$tooltip) { + this.$tooltip.hide() + } + }, this)) + + this.fetchBuckets(); + } + }); +}); diff --git a/webapp/core/src/main/public/static/js/find/app/page/search/service-view.js b/webapp/core/src/main/public/static/js/find/app/page/search/service-view.js index 976c5c7160..10da8e7b8b 100644 --- a/webapp/core/src/main/public/static/js/find/app/page/search/service-view.js +++ b/webapp/core/src/main/public/static/js/find/app/page/search/service-view.js @@ -25,6 +25,7 @@ define([ 'find/app/page/search/results/entity-topic-map-view', 'find/app/page/search/results/sunburst-view', 'find/app/page/search/results/map-results-view', + 'find/app/page/search/results/dategraph/dategraph-view', 'find/app/page/search/results/table/table-view', 'find/app/page/search/time-bar-view', 'find/app/configuration', @@ -34,7 +35,7 @@ define([ ParametricCollection, ParametricFieldsCollection, queryStrategy, stateTokenStrategy, ResultsViewContainer, ResultsViewSelection, RelatedConceptsView, addChangeListener, SavedSearchControlView, TopicMapView, - SunburstView, MapResultsView, TableView, TimeBarView, configuration, i18n, templateString) { + SunburstView, MapResultsView, DateGraphView, TableView, TimeBarView, configuration, i18n, templateString) { 'use strict'; const $window = $(window); @@ -257,6 +258,17 @@ define([ displayNameKey: 'table', icon: 'hp-table' } + }, + dategraph: { + Constructor: DateGraphView, + constructorArguments: _.extend({ + timeBarModel: this.timeBarModel + }, subViewArguments), + shown: hasBiRole, + selector: { + displayNameKey: 'dategraph', + icon: 'hp-analytics' + } } }; @@ -282,6 +294,10 @@ define([ views: this.resultsViews, model: this.resultsViewSelectionModel }); + + this.listenTo(this.queryModel.queryState.selectedParametricValues, 'graph', function(){ + this.resultsViewSelection.switchTab('dategraph') + }) } this.resultsViewContainer = new ResultsViewContainer({ diff --git a/webapp/core/src/main/public/static/js/find/nls/root/bundle.js b/webapp/core/src/main/public/static/js/find/nls/root/bundle.js index 93649f2973..b7bee486ac 100644 --- a/webapp/core/src/main/public/static/js/find/nls/root/bundle.js +++ b/webapp/core/src/main/public/static/js/find/nls/root/bundle.js @@ -207,6 +207,10 @@ define([ 'search.resultsView.amount.shown': 'Showing {0} to {1} of {2} results', 'search.resultsView.amount.shown.no.increment': 'Showing the top {0} results of {1}', 'search.resultsView.amount.shown.no.results': 'There are no results with the location field selected', + 'search.resultsView.dategraph': 'Date', + 'search.resultsView.dategraph.defaultSeriesLabel': 'Documents', + 'search.resultsView.dategraph.error': 'Failed to load data', + 'search.resultsView.dategraph.noValues': 'No values', 'search.answeredQuestion': 'Answered question', 'search.answeredQuestion.systemName': 'Answered by {0}', 'search.promoted': 'Promoted', diff --git a/webapp/core/src/main/public/static/js/find/templates/app/page/search/filters/parametric/parametric-select-modal-item-view.html b/webapp/core/src/main/public/static/js/find/templates/app/page/search/filters/parametric/parametric-select-modal-item-view.html index 3861a8adf6..7e84e166c8 100644 --- a/webapp/core/src/main/public/static/js/find/templates/app/page/search/filters/parametric/parametric-select-modal-item-view.html +++ b/webapp/core/src/main/public/static/js/find/templates/app/page/search/filters/parametric/parametric-select-modal-item-view.html @@ -1,4 +1,7 @@ \ No newline at end of file + +<% if (showGraphButtons) { %> + +<% } %> \ No newline at end of file diff --git a/webapp/core/src/main/public/static/js/find/templates/app/page/search/filters/parametric/parametric-value-view.html b/webapp/core/src/main/public/static/js/find/templates/app/page/search/filters/parametric/parametric-value-view.html index cb449082bd..e7c9dff453 100644 --- a/webapp/core/src/main/public/static/js/find/templates/app/page/search/filters/parametric/parametric-value-view.html +++ b/webapp/core/src/main/public/static/js/find/templates/app/page/search/filters/parametric/parametric-value-view.html @@ -5,3 +5,6 @@ + + + diff --git a/webapp/core/src/main/public/static/js/find/templates/app/page/search/results/dategraph/dategraph-view.html b/webapp/core/src/main/public/static/js/find/templates/app/page/search/results/dategraph/dategraph-view.html new file mode 100644 index 0000000000..f7d6bf9d3b --- /dev/null +++ b/webapp/core/src/main/public/static/js/find/templates/app/page/search/results/dategraph/dategraph-view.html @@ -0,0 +1,8 @@ +
+ PPTX +
+
<%- i18n['search.resultsView.dategraph.noValues'] %>
+
<%- i18n['search.resultsView.dategraph.error'] %>
+
<%= loadingHtml %>
+
+
\ No newline at end of file diff --git a/webapp/core/src/main/public/static/js/require-config.js b/webapp/core/src/main/public/static/js/require-config.js index fd202c9fc4..0914ddeeb9 100644 --- a/webapp/core/src/main/public/static/js/require-config.js +++ b/webapp/core/src/main/public/static/js/require-config.js @@ -39,7 +39,9 @@ require.config({ sunburst: '../bower_components/hp-autonomy-sunburst/src', topicmap: '../bower_components/hp-autonomy-topic-map/src', underscore: '../bower_components/underscore/underscore', - typeahead: '../bower_components/corejs-typeahead/dist/typeahead.jquery' + typeahead: '../bower_components/corejs-typeahead/dist/typeahead.jquery', + 'flot': '../bower_components/Flot/jquery.flot', + 'flot.time': '../bower_components/Flot/jquery.flot.time' }, shim: { 'backbone': { @@ -59,6 +61,8 @@ require.config({ exports: '_' }, 'Leaflet.awesome-markers': ['leaflet'], - 'leaflet.markercluster': ['leaflet'] + 'leaflet.markercluster': ['leaflet'], + 'flot': ['jquery'], + 'flot.time': ['flot'] } }); diff --git a/webapp/idol/src/main/resources/defaultIdolConfigFile.json b/webapp/idol/src/main/resources/defaultIdolConfigFile.json index f309c35364..dddfb2354e 100644 --- a/webapp/idol/src/main/resources/defaultIdolConfigFile.json +++ b/webapp/idol/src/main/resources/defaultIdolConfigFile.json @@ -126,7 +126,8 @@ "list", "sunburst", "table", - "map" + "map", + "dategraph" ], "user": [ "list"