Ejegg has uploaded a new change for review. https://gerrit.wikimedia.org/r/198821
Change subject: Use C3 binding in all widgets ...................................................................... Use C3 binding in all widgets Update C3 binding to delete chart on update with falsy value. Would be nice to detect when we need to do this based on which options have changed (e.g., not just data) Modal IDs still need de-duplication to allow multiple instances of the same widget type on one board. Bug: T92430 Change-Id: I1e5b94d91efd2772a85b11fbceccc4688065e14f --- M src/app/bindings.js M src/components/widgets/distance-to-goal-chart/distance-to-goal-chart.html M src/components/widgets/distance-to-goal-chart/distance-to-goal-chart.js M src/components/widgets/fraud-gauge/fraud-gauge.html M src/components/widgets/fraud-gauge/fraud-gauge.js M src/components/widgets/totals-earned-chart/totals-earned-chart.html M src/components/widgets/totals-earned-chart/totals-earned-chart.js M src/components/widgets/x-by-y/x-by-y.html M src/components/widgets/x-by-y/x-by-y.js 9 files changed, 169 insertions(+), 159 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/dash refs/changes/21/198821/1 diff --git a/src/app/bindings.js b/src/app/bindings.js index b74f752..92fb601 100644 --- a/src/app/bindings.js +++ b/src/app/bindings.js @@ -19,6 +19,12 @@ var chart = ko.utils.domData.get( element, 'chart' ), options = ko.unwrap(valueAccessor()); if ( !options ) { + // Destroys existing chart if you pass a falsy value + // TODO: also reset when options outside of data have changed. + if ( chart ) { + chart.destroy(); + ko.utils.domData.set( element, 'chart', undefined ); + } return; } if ( chart ) { diff --git a/src/components/widgets/distance-to-goal-chart/distance-to-goal-chart.html b/src/components/widgets/distance-to-goal-chart/distance-to-goal-chart.html index 950b808..e158f9d 100644 --- a/src/components/widgets/distance-to-goal-chart/distance-to-goal-chart.html +++ b/src/components/widgets/distance-to-goal-chart/distance-to-goal-chart.html @@ -10,7 +10,7 @@ <p data-bind="visible: !hasData()">No data available. This widget requires a widget like Totals Earned to provide data.</p> <div class="row-fluid"> <div class="col-md-12"> - <div id="distanceToGoalChart" width='1000' height='450'></div> + <div id="distanceToGoalChart" width='1000' height='450' data-bind="c3: distanceToGoalChart"></div> </div> </div> </div> diff --git a/src/components/widgets/distance-to-goal-chart/distance-to-goal-chart.js b/src/components/widgets/distance-to-goal-chart/distance-to-goal-chart.js index 6e71c06..170df01 100644 --- a/src/components/widgets/distance-to-goal-chart/distance-to-goal-chart.js +++ b/src/components/widgets/distance-to-goal-chart/distance-to-goal-chart.js @@ -11,6 +11,7 @@ var self = this; WidgetBase.call( this, params ); self.hasData = ko.observable( false ); + self.distanceToGoalChart = ko.observable( false ); self.makeCharts = function() { if ( params.sharedContext.dailyDataArray.length < 2 ) { @@ -25,15 +26,7 @@ self.neededArray[d] = self.updatedGoal >= 0 ? self.updatedGoal : 0; } - if ( self.distanceToGoalChart ) { - self.distanceToGoalChart.load( { - columns: [ self.neededArray ] - } ); - return; - } - - self.distanceToGoalChart = c3.generate({ - bindto: '#distanceToGoalChart', + self.distanceToGoalChart({ size: { height: 250, width: window.width/2 diff --git a/src/components/widgets/fraud-gauge/fraud-gauge.html b/src/components/widgets/fraud-gauge/fraud-gauge.html index ce71883..d5a32be 100644 --- a/src/components/widgets/fraud-gauge/fraud-gauge.html +++ b/src/components/widgets/fraud-gauge/fraud-gauge.html @@ -20,11 +20,11 @@ <h3 class="text-center" data-bind="visible: configSet, text: selectedTimePeriod"></h3> </div> - <div class="row" id="specifiedFraudGauge" data-bind="visible: configSet"> - <div id="FraudRiskScoreGauge"></div> + <div class="row" id="specifiedFraudGauge" data-bind="if: configSet"> + <div id="FraudRiskScoreGauge" data-bind='c3: gauge'></div> </div> - <div class="row" id="unspecifiedFraudGauge" data-bind="visible: !configSet()"> + <div class="row" id="unspecifiedFraudGauge" data-bind="if: !configSet()"> <div class="col-md-12"> <div class="setupAsk"> <h3>This widget hasn't been set up yet.</h3> diff --git a/src/components/widgets/fraud-gauge/fraud-gauge.js b/src/components/widgets/fraud-gauge/fraud-gauge.js index b3fc217..49701cc 100644 --- a/src/components/widgets/fraud-gauge/fraud-gauge.js +++ b/src/components/widgets/fraud-gauge/fraud-gauge.js @@ -53,6 +53,7 @@ self.greenHighRange = ko.observable(17); self.redLowRange = ko.observable(68); self.configSet = ko.observable(Object.keys(self.config).length > 0); + self.gauge = ko.observable(false); self.populateChoices = function(){ return $.get( 'metadata/fraud-gauge', function(reqData){ @@ -120,8 +121,7 @@ }; self.makeChart = function(){ - self.gauge = c3.generate({ - bindto: '#FraudRiskScoreGauge', + self.gauge({ size: { height: 300, width: 390 diff --git a/src/components/widgets/totals-earned-chart/totals-earned-chart.html b/src/components/widgets/totals-earned-chart/totals-earned-chart.html index 5e763a9..3ea33e7 100644 --- a/src/components/widgets/totals-earned-chart/totals-earned-chart.html +++ b/src/components/widgets/totals-earned-chart/totals-earned-chart.html @@ -69,9 +69,13 @@ <div class="panel-heading"> <p data-bind="text: title"></p> </div> - <div class="panel-body"> - <!--Daily, Hourly, etc Totals Earned--> - <div id='totalsEarnedChart'></div> + <div class="panel-body" data-bind="visible: showChart() === 'daily'"> + <!--Daily Totals Earned--> + <div data-bind="c3: dailyChart"></div> + </div> + <div class="panel-body" data-bind="visible: showChart() === 'hourly'"> + <!--Hourly Totals Earned--> + <div data-bind="c3: hourlyChart"></div> </div> </div> </div> diff --git a/src/components/widgets/totals-earned-chart/totals-earned-chart.js b/src/components/widgets/totals-earned-chart/totals-earned-chart.js index d37ffe8..27c7710 100644 --- a/src/components/widgets/totals-earned-chart/totals-earned-chart.js +++ b/src/components/widgets/totals-earned-chart/totals-earned-chart.js @@ -25,6 +25,9 @@ // Get the date self.displayDate = ko.observable( moment().format( timeFormat ) ); + self.showChart = ko.observable( '' ); + self.hourlyChart = ko.observable( false ); + self.dailyChart = ko.observable( false ); self.goal = params.sharedContext.goal = ko.observable( self.config.goal || 20000000 ); params.sharedContext.goal.subscribe( function() { @@ -119,155 +122,158 @@ if (params.sharedContext.dailyDataArray.length < 2) { return; } - self.hourlyChart = function(d,i){ - var hourlyData = params.sharedContext.dayObj[d.x + 1 ], - hourlyCountArray = ['Hourly Count'], - hourlyTotalArray = ['Hourly Total']; - for(var j=1; j<25; j++){ - hourlyCountArray.push(hourlyData[j].count); - hourlyTotalArray.push(hourlyData[j].total); - } - return { - bindto: '#totalsEarnedChart', - size: { - height: 450, - width: window.width - }, - zoom: { enabled: true }, - data: { - columns: [ hourlyTotalArray, hourlyCountArray ], - type: 'bar', - colors: { 'Hourly Total': 'rgb(92,184,92)', 'Hourly Count': '#f0ad4e' }, - onclick: function (d, i) { - self.totalsEarnedChart.destroy(); - self.totalsEarnedChart = c3.generate(self.dailyChart()); - }, - axes: { - 'Hourly Total': 'y', - 'Hourly Count': 'y2' - } - }, - grid: { - x: { - show: true - }, - y: { - show: true - } - }, - axis: { - x: { - label: { - text: 'December ' + ( d.x + 1 ), - position: 'outer-left' - }, - tick: { - format: function(x){ return x + ':00'; } - } - }, - y: { - tick: { - format: function(x){ return numeral(x).format('$0,0'); } - } - }, - y2: { - tick: { - format: function(x){ return numeral(x).format('0,0'); } - }, - show: true - } - }, - tooltip: { - format: { - title: function (d) { return 'Hour ' + d; }, - value: function (value, ratio, id) { - var display; - if(id === 'Hourly Total'){ - display = numeral(value).format('$0,0'); - } else { - display = numeral(value).format('0,0'); - } - return display; - } - } - }, - bar: { - width: { - ratio: 0.5 - } - } - }; - }; + self.showChart( '' ); + self.dailyChart( self.makeDailyChart() ); + self.showChart( 'daily' ); + } - self.dailyChart = function(d,i){ - return { - bindto: '#totalsEarnedChart', - size: { - height: 450, - width: window.width + self.makeHourlyChart = function(d,i){ + var hourlyData = params.sharedContext.dayObj[d.x + 1 ], + hourlyCountArray = ['Hourly Count'], + hourlyTotalArray = ['Hourly Total']; + for(var j=1; j<25; j++){ + hourlyCountArray.push(hourlyData[j].count); + hourlyTotalArray.push(hourlyData[j].total); + } + return { + size: { + height: 450, + width: window.width + }, + zoom: { enabled: true }, + data: { + columns: [ hourlyTotalArray, hourlyCountArray ], + type: 'bar', + colors: { 'Hourly Total': 'rgb(92,184,92)', 'Hourly Count': '#f0ad4e' }, + onclick: function (d, i) { + self.showChart( '' ); + self.dailyChart( self.makeDailyChart() ); + self.showChart( 'daily' ); }, - zoom: { enabled: true }, - data: { - columns: [ params.sharedContext.dailyDataArray, params.sharedContext.dailyCountArray ], - type: 'bar', - colors: { 'Daily Total': 'rgb(49,176,213)', 'Daily Count': '#f0ad4e' }, - onclick: function (d, i) { - self.totalsEarnedChart.destroy(); - self.totalsEarnedChart = c3.generate(self.hourlyChart(d,i)); + axes: { + 'Hourly Total': 'y', + 'Hourly Count': 'y2' + } + }, + grid: { + x: { + show: true + }, + y: { + show: true + } + }, + axis: { + x: { + label: { + text: 'December ' + ( d.x + 1 ), + position: 'outer-left' }, - axes: { - 'Daily Total': 'y', - 'Daily Count': 'y2' + tick: { + format: function(x){ return x + ':00'; } } }, - grid: { - x: { - show: true - }, - y: { - show: true + y: { + tick: { + format: function(x){ return numeral(x).format('$0,0'); } } }, - axis: { - x: { - tick: { - format: function(x){ return 'Dec ' + (x+1); } + y2: { + tick: { + format: function(x){ return numeral(x).format('0,0'); } + }, + show: true + } + }, + tooltip: { + format: { + title: function (d) { return 'Hour ' + d; }, + value: function (value, ratio, id) { + var display; + if(id === 'Hourly Total'){ + display = numeral(value).format('$0,0'); + } else { + display = numeral(value).format('0,0'); } - }, - y: { - tick: { - format: function(x){ return numeral(x).format('$0,0'); } - } - }, - y2: { - tick: { - format: function(x){ return numeral(x).format('0,0'); } - }, - show: true - } - }, - tooltip: { - format: { - title: function (d) { return 'Day ' + (d+1); }, - value: function (value, ratio, id) { - var display; - if(id === 'Daily Total'){ - display = numeral(value).format('$0,0'); - } else { - display = numeral(value).format('0,0'); - } - return display; - } - } - }, - bar: { - width: { - ratio: 0.5 + return display; } } - }; + }, + bar: { + width: { + ratio: 0.5 + } + } }; - self.totalsEarnedChart = c3.generate(self.dailyChart()); + }; + + self.makeDailyChart = function(d,i){ + return { + size: { + height: 450, + width: window.width + }, + zoom: { enabled: true }, + data: { + columns: [ params.sharedContext.dailyDataArray, params.sharedContext.dailyCountArray ], + type: 'bar', + colors: { 'Daily Total': 'rgb(49,176,213)', 'Daily Count': '#f0ad4e' }, + onclick: function ( d, i ) { + self.showChart( '' ); + self.hourlyChart( self.makeHourlyChart( d, i ) ); + self.showChart( 'hourly' ); + }, + axes: { + 'Daily Total': 'y', + 'Daily Count': 'y2' + } + }, + grid: { + x: { + show: true + }, + y: { + show: true + } + }, + axis: { + x: { + tick: { + format: function(x){ return 'Dec ' + (x+1); } + } + }, + y: { + tick: { + format: function(x){ return numeral(x).format('$0,0'); } + } + }, + y2: { + tick: { + format: function(x){ return numeral(x).format('0,0'); } + }, + show: true + } + }, + tooltip: { + format: { + title: function (d) { return 'Day ' + (d+1); }, + value: function (value, ratio, id) { + var display; + if(id === 'Daily Total'){ + display = numeral(value).format('$0,0'); + } else { + display = numeral(value).format('0,0'); + } + return display; + } + } + }, + bar: { + width: { + ratio: 0.5 + } + } + }; }; self.makeCharts(); } diff --git a/src/components/widgets/x-by-y/x-by-y.html b/src/components/widgets/x-by-y/x-by-y.html index fa3b62a..163cb9a 100644 --- a/src/components/widgets/x-by-y/x-by-y.html +++ b/src/components/widgets/x-by-y/x-by-y.html @@ -106,7 +106,7 @@ </span> </h4> </div> - <div id='x-by-yChart' data-bind="attr: { width: chartWidth, height: chartHeight }"></div> + <div data-bind="{ c3: xByYChart, attr: { width: chartWidth, height: chartHeight } }"></div> </div> <!-- <div class="col-md-2 pull-right"> diff --git a/src/components/widgets/x-by-y/x-by-y.js b/src/components/widgets/x-by-y/x-by-y.js index 01eaeac..7191519 100644 --- a/src/components/widgets/x-by-y/x-by-y.js +++ b/src/components/widgets/x-by-y/x-by-y.js @@ -22,6 +22,7 @@ self.queryString = ''; self.chosenFilters = ko.observableArray(); self.subChoices = ko.observableArray(); + self.xByYChart = ko.observable( false ); self.chartWidth(950); self.title = ko.computed( function(){ @@ -55,8 +56,8 @@ axes[data.totals[0]] = 'y'; axes[data.counts[0]] = 'y2'; - self.xByYChart = c3.generate( { - bindto: '#x-by-yChart', //need to update this to allow multiples + self.xByYChart( false ); + self.xByYChart( { size: { height: 450, width: window.width -- To view, visit https://gerrit.wikimedia.org/r/198821 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1e5b94d91efd2772a85b11fbceccc4688065e14f Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/dash Gerrit-Branch: master Gerrit-Owner: Ejegg <eeggles...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits