jenkins-bot has submitted this change and it was merged.

Change subject: Stats: Separate total and language graph, and show draft count 
in graph
......................................................................


Stats: Separate total and language graph, and show draft count in graph

This is in preparation for showing deletion stats and weekly trend
graphs.

Showing both total and language specific stats is difficult to
understand because the difference is widening fast. So separated them.

ApiQueryContentTranslationLanguageTrend now return cumulative count
for translations in progress as well. Soon it should retun
cumulative deleted stats too.

Bug: T105192
Bug: T90538
Change-Id: Ifd4bd0e3a92ac022428edf3915552ea99142dbfb
---
M api/ApiQueryContentTranslationLanguageTrend.php
M includes/Translation.php
M modules/stats/ext.cx.stats.js
M modules/stats/styles/ext.cx.stats.less
4 files changed, 230 insertions(+), 73 deletions(-)

Approvals:
  Nikerabbit: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/api/ApiQueryContentTranslationLanguageTrend.php 
b/api/ApiQueryContentTranslationLanguageTrend.php
index cd5bf33..8bbf549 100644
--- a/api/ApiQueryContentTranslationLanguageTrend.php
+++ b/api/ApiQueryContentTranslationLanguageTrend.php
@@ -12,6 +12,8 @@
  *
  * @ingroup API ContentTranslationAPI
  */
+use ContentTranslation\Translation;
+
 class ApiQueryContentTranslationLanguageTrend extends ApiQueryBase {
 
        public function __construct( $query, $moduleName ) {
@@ -32,7 +34,11 @@
                $result->addValue(
                        array( 'query' ),
                        'contenttranslationlangtrend',
-                       ContentTranslation\Translation::getTrend( $source, 
$target, $interval )
+                       array(
+                               'translations' =>
+                                       Translation::getPublishTrend( $source, 
$target, $interval ),
+                               'drafts' => Translation::getDraftTrend( 
$source, $target, $interval )
+                       )
                );
        }
 
diff --git a/includes/Translation.php b/includes/Translation.php
index c0a7c98..0f54508 100644
--- a/includes/Translation.php
+++ b/includes/Translation.php
@@ -211,10 +211,94 @@
        }
 
        /**
+        * Get time-wise cumulative number of drafts for given
+        * language pairs, with given interval.
+        * @param string $source Source language code
+        * @param string $target Target language code
+        * @param string $interval 'weekly' or 'monthly' trend
+        * @return array
+        */
+       public static function getDraftTrend( $source, $target, $interval ) {
+               $dbr = Database::getConnection( DB_SLAVE );
+
+               $draftCondition = $dbr->makeList(
+                       array(
+                               'translation_status' => 'draft',
+                               'translation_target_url IS NULL'
+                       ),
+                       LIST_AND
+               );
+
+               $conditions = array();
+               $conditions[] = $draftCondition;
+               if ( $source !== null ) {
+                       $conditions['translation_source_language'] = $source;
+               }
+               if ( $target !== null ) {
+                       $conditions['translation_target_language'] = $target;
+               }
+
+               $options = null;
+               if ( $interval === 'week' ) {
+                        $options = array(
+                               'GROUP BY' => array(
+                                       
'YEARWEEK(translation_last_updated_timestamp)',
+                               ),
+                       );
+               } elseif ( $interval === 'month' ) {
+                        $options = array(
+                               'GROUP BY' => array(
+                                       
'YEAR(translation_last_updated_timestamp), 
MONTH(translation_last_updated_timestamp)',
+                               ),
+                       );
+               }
+
+               $subQuery = $dbr->selectSQLText(
+                       'cx_translations',
+                       'count(*)',
+                       $dbr->makeList( array(
+                               'translation_last_updated_timestamp <= 
MAX(translations.translation_last_updated_timestamp)',
+                               $dbr->makeList( $conditions, LIST_AND ),
+                       ),
+                       LIST_AND )
+               );
+
+               $rows = $dbr->select(
+                       array( 'translations' => 'cx_translations' ),
+                       array(
+                               
"translations.translation_last_updated_timestamp AS date",
+                               '(' . $subQuery . ') translatons_count',
+                       ),
+                       $dbr->makeList( $conditions, LIST_AND ),
+                       __METHOD__,
+                       $options
+               );
+
+               $prev = 0;
+               $result = array();
+               foreach ( $rows as $row ) {
+                       $count = (int)$row->translatons_count;
+                       $result[] = array(
+                               'date' => $interval === 'week' ?
+                                       // Week end date
+                                       date( 'Y-m-d', strtotime( $row->date . 
' + ' .
+                                               ( 6 - date( 'w', strtotime( 
$row->date ) ) ) . ' days' ) ) :
+                                       date( 'Y-m', strtotime( $row->date ) ),
+                               'count' => $count,
+                               'delta' => $count - $prev,
+                       );
+
+                       $prev = $count;
+               }
+
+               return $result;
+       }
+
+       /**
         * Get time-wise cumulative number of translations for given
         * language pairs, with given interval.
         */
-       public static function getTrend( $source, $target, $interval ) {
+       public static function getPublishTrend( $source, $target, $interval ) {
                $dbr = Database::getConnection( DB_SLAVE );
 
                $publishedCondition = $dbr->makeList(
@@ -224,50 +308,48 @@
                        ),
                        LIST_OR
                );
+               $conditions = array();
+               $conditions[] = $publishedCondition;
+               if ( $source !== null ) {
+                       $conditions['translation_source_language'] = $source;
+               }
+               if ( $target !== null ) {
+                       $conditions['translation_target_language'] = $target;
+               }
 
-               $groupBy = null;
-
+               $options = null;
                if ( $interval === 'week' ) {
-                       $groupBy = array(
+                       $options = array(
                                'GROUP BY' => array(
                                        
'YEARWEEK(translation_last_updated_timestamp)',
                                ),
                        );
                } elseif ( $interval === 'month' ) {
-                       $groupBy = array(
+                       $options = array(
                                'GROUP BY' => array(
                                        
'YEAR(translation_last_updated_timestamp), 
MONTH(translation_last_updated_timestamp)',
                                ),
                        );
                }
 
-               $conditions = array( $publishedCondition );
-
-               if ( $source !== null ) {
-                       $conditions['translation_source_language'] = $source;
-               }
-
-               if ( $target !== null ) {
-                       $conditions['translation_target_language'] = $target;
-               }
-
+               $subQuery = $dbr->selectSQLText(
+                       'cx_translations',
+                       'count(*)',
+                       $dbr->makeList( array(
+                               'translation_last_updated_timestamp <= 
MAX(translations.translation_last_updated_timestamp)',
+                               $dbr->makeList( $conditions, LIST_AND ),
+                       ),
+                       LIST_AND )
+               );
                $rows = $dbr->select(
                        array( 'translations' => 'cx_translations' ),
                        array(
-                               "DATE_FORMAT( 
translations.translation_last_updated_timestamp, '%Y-%m-%d' ) AS date",
-                               '(' . $dbr->selectSQLText(
-                                       'cx_translations',
-                                       'count(*)',
-                                       $dbr->makeList( array(
-                                               
'translation_last_updated_timestamp <= 
MAX(translations.translation_last_updated_timestamp)',
-                                               $dbr->makeList( $conditions, 
LIST_AND ),
-                                       ),
-                                       LIST_AND )
-                               ) . ') translatons_count',
+                               
"translations.translation_last_updated_timestamp AS date",
+                               '(' . $subQuery . ') translatons_count',
                        ),
                        $dbr->makeList( $conditions, LIST_AND ),
                        __METHOD__,
-                       $groupBy
+                       $options
                );
 
                $prev = 0;
@@ -323,7 +405,7 @@
         * @param string $to Target language code
         * @param int $limit Number of records to fetch atmost
         * @param in $offset Offset from which at most $limit records to fetch
-        * @return array[]
+        * @return array
         */
        public static function getAllPublishedTranslations( $from, $to, $limit, 
$offset ) {
                $dbr = Database::getConnection( DB_SLAVE );
diff --git a/modules/stats/ext.cx.stats.js b/modules/stats/ext.cx.stats.js
index 15bd6fc..b0a0245 100644
--- a/modules/stats/ext.cx.stats.js
+++ b/modules/stats/ext.cx.stats.js
@@ -32,8 +32,14 @@
                                $( '<div>' ).addClass( 'bounce3' )
                        );
                this.$highlights = $( '<div>' ).addClass( 'cx-stats-highlights' 
);
-               this.$graph = $( '<canvas>' ).attr( {
-                       id: 'cxtrend',
+               this.$cumlativeGraph = $( '<canvas>' ).attr( {
+                       id: 'cxcumulative',
+                       width: this.$container.width() - 200, // Leave a 200px 
margin buffer to avoid overflow
+                       height: 400
+               } );
+
+               this.$languageCumulativeGraph = $( '<canvas>' ).attr( {
+                       id: 'cxlangcumulative',
                        width: this.$container.width() - 200, // Leave a 200px 
margin buffer to avoid overflow
                        height: 400
                } );
@@ -42,18 +48,32 @@
                        $spinner,
                        this.$highlights,
                        $( '<h2>' ).text( mw.msg( 
'cx-stats-published-translations-title' ) ),
-                       $( '<div>' ).addClass( 'cx-stats-trend' ).append( 
this.$graph )
+                       $( '<div>' )
+                               .addClass( 'cx-stats-graph 
cx-stats-cumulative-total' )
+                               .append( this.$cumlativeGraph ),
+                       $( '<h2>' ).text( mw.message(
+                               'cx-trend-translations-to',
+                               $.uls.data.getAutonym( mw.config.get( 
'wgContentLanguage' ) )
+                       ).escaped() ),
+                       $( '<div>' )
+                               .addClass( 'cx-stats-graph 
cx-stats-cumulative-lang' )
+                               .append( this.$languageCumulativeGraph )
                );
 
                $.when(
                        this.getCXTrends(),
                        this.getCXTrends( mw.config.get( 'wgContentLanguage' ) )
                ).done( function ( totalTrend, languageTrend ) {
-                       self.totalTranslationTrend = totalTrend;
-                       self.languageTranslationTrend = languageTrend;
-                       self.languageTranslationTrend = mergeAndFill( 
totalTrend, languageTrend );
+                       self.totalTranslationTrend = totalTrend.translations;
+                       self.languageTranslationTrend = 
languageTrend.translations;
+                       self.languageTranslationTrend = mergeAndFill( 
self.totalTranslationTrend, self.languageTranslationTrend );
+
+                       self.totalDraftTrend = mergeAndFill( 
self.totalTranslationTrend, totalTrend.drafts );
+                       self.languageDraftTrend = mergeAndFill( 
self.languageTranslationTrend, languageTrend.drafts );
+                       self.languageDraftTrend = mergeAndFill( 
self.totalDraftTrend, self.languageDraftTrend );
                        self.renderHighlights();
-                       self.drawGraph( 'count' );
+                       self.drawCumulativeGraph( 'count' );
+                       self.drawLanguageCumulativeGraph( 'count' );
                } );
                this.getCXStats().then( function ( data ) {
                        if ( !data || !data.query ) {
@@ -127,8 +147,7 @@
                                                
'cx-stats-local-published-number',
                                                fmt( langTotal ),
                                                fmt( localLanguage )
-                                       )
-                               )
+                                       ) )
                        );
 
                weekLangTrendText = mw.msg( 'percent', fmt( weekLangTrend ) );
@@ -368,7 +387,9 @@
                                $total = $( '<a>' )
                                        .addClass( 'cx-stats-chart__total' )
                                        .prop( 'href', 
mw.cx.siteMapper.getPageUrl(
-                                               model[ i ].language, 
'Special:NewPages', { tagfilter: 'contenttranslation' }
+                                               model[ i ].language, 
'Special:NewPages', {
+                                                       tagfilter: 
'contenttranslation'
+                                               }
                                        ) )
                                        .text( fmt( model[ i ][ property ] ) );
                        } else {
@@ -424,10 +445,10 @@
                } );
        };
 
-       CXStats.prototype.drawGraph = function ( type ) {
-               var data, cxTrendGraph, ctx;
+       CXStats.prototype.drawCumulativeGraph = function ( type ) {
+               var data, cxCumulativeGraph, ctx;
 
-               ctx = this.$graph[ 0 ].getContext( '2d' );
+               ctx = this.$cumlativeGraph[ 0 ].getContext( '2d' );
 
                data = {
                        labels: $.map( this.totalTranslationTrend, function ( 
data ) {
@@ -435,34 +456,88 @@
                        } ),
                        datasets: [
                                {
-                                       label: mw.message( 
'cx-trend-all-translations' ).escaped(),
-                                       strokeColor: '#FD6E8A',
-                                       pointColor: '#FD6E8A',
+                                       label: mw.msg( 
'cx-trend-all-translations' ),
+                                       fillColor: '#347BFF',
+                                       strokeColor: '#347BFF',
+                                       pointColor: '#347BFF',
+                                       pointStrokeColor: '#fff',
+                                       pointHighlightFill: '#fff',
+                                       pointHighlightStroke: '#347BFF',
                                        data: $.map( 
this.totalTranslationTrend, function ( data ) {
-                                               return data[type];
+                                               return data[ type ];
                                        } )
                                },
                                {
-                                       label: mw.message(
-                                               'cx-trend-translations-to',
-                                               $.uls.data.getAutonym( 
mw.config.get( 'wgContentLanguage' ) )
-                                       ).escaped(),
-                                       strokeColor: '#80B3FF',
-                                       pointColor: '#80B3FF',
-                                       data: $.map( 
this.languageTranslationTrend, function ( data ) {
-                                               return data[type];
+                                       label:  mw.msg( 
'cx-stats-draft-translations-title' ),
+                                       fillColor: '#777',
+                                       strokeColor: '#777',
+                                       pointColor: '#777',
+                                       pointStrokeColor: '#fff',
+                                       pointHighlightFill: '#fff',
+                                       pointHighlightStroke: '#777',
+                                       data: $.map( this.totalDraftTrend, 
function ( data ) {
+                                               return data[ type ];
                                        } )
                                }
                        ]
                };
 
                /*global Chart:false */
-               cxTrendGraph = new Chart( ctx ).Line( data, {
+               cxCumulativeGraph = new Chart( ctx ).Line( data, {
+                       responsive: true,
                        datasetFill: false,
                        legendTemplate: '<ul><% for (var i=0; 
i<datasets.length; i++){%><li 
style=\"color:<%=datasets[i].strokeColor%>\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'
                } );
 
-               this.$container.find( '.cx-stats-trend' ).append( 
cxTrendGraph.generateLegend() );
+               this.$container.find( '.cx-stats-cumulative-total' ).append( 
cxCumulativeGraph.generateLegend() );
+       };
+
+       CXStats.prototype.drawLanguageCumulativeGraph = function ( type ) {
+               var data, cxCumulativeGraph, ctx;
+
+               ctx = this.$languageCumulativeGraph[ 0 ].getContext( '2d' );
+
+               data = {
+                       labels: $.map( this.totalTranslationTrend, function ( 
data ) {
+                               return data.date;
+                       } ),
+                       datasets: [
+                               {
+                                       label: mw.message(
+                                               'cx-trend-translations-to',
+                                               $.uls.data.getAutonym( 
mw.config.get( 'wgContentLanguage' ) )
+                                       ).escaped(),
+                                       strokeColor: '#347BFF',
+                                       pointColor: '#347BFF',
+                                       pointStrokeColor: '#fff',
+                                       pointHighlightFill: '#fff',
+                                       pointHighlightStroke: '#347BFF',
+                                       data: $.map( 
this.languageTranslationTrend, function ( data ) {
+                                               return data[ type ];
+                                       } )
+                               },
+                               {
+                                       label:  mw.msg( 
'cx-stats-draft-translations-title' ),
+                                       strokeColor: '#777',
+                                       pointColor: '#777',
+                                       pointStrokeColor: '#fff',
+                                       pointHighlightFill: '#fff',
+                                       pointHighlightStroke: '#777',
+                                       data: $.map( this.languageDraftTrend, 
function ( data ) {
+                                               return data[ type ];
+                                       } )
+                               }
+                       ]
+               };
+
+               /*global Chart:false */
+               cxCumulativeGraph = new Chart( ctx ).Line( data, {
+                       datasetFill: false,
+                       responsive: true,
+                       legendTemplate: '<ul><% for (var i=0; 
i<datasets.length; i++){%><li 
style=\"color:<%=datasets[i].strokeColor%>\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'
+               } );
+
+               this.$container.find( '.cx-stats-cumulative-lang' ).append( 
cxCumulativeGraph.generateLegend() );
        };
 
        CXStats.prototype.transformJsonToModel = function ( records ) {
@@ -557,8 +632,7 @@
         * @return {[Object]} Array of translations to a particular language, 
after padding
         */
        function mergeAndFill( totalData, languageData ) {
-               var i,
-                       padding = [];
+               var i;
 
                if ( totalData.length === languageData.length ) {
                        return languageData;
@@ -570,23 +644,18 @@
                        if ( !languageData || languageData.length === 0 ) {
                                break;
                        }
-
-                       if ( totalData[ i ].date === languageData[ 0 ].date ) {
-                               languageData = padding.concat( languageData );
-                       } else {
-                               padding.push( {
-                                       date: totalData[ i ].date,
-                                       count: 0
+                       if ( languageData[ i ] && new Date( totalData[ i ].date 
) > new Date( languageData[ i ].date ) ) {
+                               totalData.splice( i, 0, {
+                                       date: languageData[ i ].date,
+                                       count: totalData[ i - 1 ] ? totalData[ 
i - 1 ].count : 0
                                } );
                        }
-               }
-
-               // Fill at the end if languageData is shorter than totalData
-               for ( i = languageData.length; i < totalData.length; i++ ) {
-                       languageData.push( {
-                               date: totalData[ i ].date,
-                               count: languageData.length ? languageData[ i - 
1 ].count : 0
-                       } );
+                       if ( !languageData[ i ] || new Date( totalData[ i 
].date ) < new Date( languageData[ i ].date ) ) {
+                               languageData.splice( i, 0, {
+                                       date: totalData[ i ].date,
+                                       count: languageData[ i - 1 ] ? 
languageData[ i - 1 ].count : 0
+                               } );
+                       }
                }
 
                return languageData;
diff --git a/modules/stats/styles/ext.cx.stats.less 
b/modules/stats/styles/ext.cx.stats.less
index c5ef8b9..02b43fb 100644
--- a/modules/stats/styles/ext.cx.stats.less
+++ b/modules/stats/styles/ext.cx.stats.less
@@ -150,7 +150,7 @@
        text-align: left;
 }
 
-.cx-stats-trend {
+.cx-stats-graph {
        background-color: #fff;
 }
 

-- 
To view, visit https://gerrit.wikimedia.org/r/236529
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ifd4bd0e3a92ac022428edf3915552ea99142dbfb
Gerrit-PatchSet: 4
Gerrit-Project: mediawiki/extensions/ContentTranslation
Gerrit-Branch: master
Gerrit-Owner: Santhosh <santhosh.thottin...@gmail.com>
Gerrit-Reviewer: Nikerabbit <niklas.laxst...@gmail.com>
Gerrit-Reviewer: Santhosh <santhosh.thottin...@gmail.com>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to