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

Change subject: Stats: Deletion count graph
......................................................................


Stats: Deletion count graph

We show it only for local wiki language.
Showing cumulative deletion stats for all wikis
is not possible as of now.

Bug: T90538
Change-Id: I8581d07c00dac6228ba5cc8b465acf431a1163e3
---
M api/ApiQueryContentTranslationLanguageTrend.php
M extension.json
M i18n/en.json
M i18n/qqq.json
M includes/Translation.php
M modules/stats/ext.cx.stats.js
6 files changed, 207 insertions(+), 119 deletions(-)

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



diff --git a/api/ApiQueryContentTranslationLanguageTrend.php 
b/api/ApiQueryContentTranslationLanguageTrend.php
index 8bbf549..a790c47 100644
--- a/api/ApiQueryContentTranslationLanguageTrend.php
+++ b/api/ApiQueryContentTranslationLanguageTrend.php
@@ -31,15 +31,80 @@
                        $target = $params['target'];
                }
                $interval = $params['interval'];
-               $result->addValue(
-                       array( 'query' ),
-                       'contenttranslationlangtrend',
-                       array(
-                               'translations' =>
-                                       Translation::getPublishTrend( $source, 
$target, $interval ),
-                               'drafts' => Translation::getDraftTrend( 
$source, $target, $interval )
-                       )
+
+               $data = array(
+                       'translations' => Translation::getPublishTrend( 
$source, $target, $interval ),
+                       'drafts' => Translation::getDraftTrend( $source, 
$target, $interval ),
                );
+
+               if ( $target !== null ) {
+                       // We can give deletion rates for only local wiki. We 
cannot give
+                       // deletion stats for all wikis.
+                       $data['deletions'] = Translation::getDeletionTrend( 
$interval );
+               }
+
+               $out = $this->addMissingDates( $data, $interval );
+               $result->addValue( array( 'query' ), 
'contenttranslationlangtrend', $out );
+       }
+
+       public function addMissingDates( $data, $interval ) {
+               $min = PHP_INT_MAX;
+               $max = 0;
+               foreach ( $data as $column ) {
+                       foreach ( array_keys( $column ) as $date ) {
+                               $min = min( $min, strtotime( $date ) );
+                               $max = max( $max, strtotime( $date ) );
+                       }
+               }
+
+               $counts = array();
+               foreach ( array_keys( $data ) as $type ) {
+                       $counts[$type] = 0;
+               }
+
+               $steps = $this->getSteps( $min, $max, $interval );
+
+               $out = array();
+               foreach ( $steps as $step ) {
+                       foreach ( $data as $type => $column ) {
+                               if ( isset( $column[$step] ) ) {
+                                       $column[$step]['date'] = $step;
+                                       $out[$type][] = $column[$step];
+                                       $counts[$type] = 
$column[$step]['count'];
+                               } else {
+                                       $out[$type][] = array(
+                                               'count' => $counts[$type],
+                                               'delta' => 0,
+                                               'date' => $step,
+                                       );
+                               }
+                       }
+               }
+
+               return $out;
+       }
+
+       protected function getSteps( $min, $max, $interval ) {
+               $steps = array();
+               while ( true ) {
+                       // Lets not overflow
+                       $min = min( $min, $max );
+                       if ( $interval === 'month' ) {
+                               $uniq = $label = date( 'Y-m', $min );
+                       } else {
+                               $uniq = date( 'Y-W', $min );
+                               $label = date( 'Y-m-d', $min );
+                       }
+
+                       $steps[$uniq] = $label;
+
+                       if ( $min === $max ) {
+                               break;
+                       }
+                       $min += 3600 * 24;
+               }
+
+               return $steps;
        }
 
        public function getAllowedParams() {
diff --git a/extension.json b/extension.json
index ac3afe5..5ed4bb8 100644
--- a/extension.json
+++ b/extension.json
@@ -853,6 +853,7 @@
                                "cx-stats-draft-translations-title",
                                "cx-stats-published-translators-title",
                                "cx-trend-all-translations",
+                               "cx-trend-deletions",
                                "cx-trend-translations-to",
                                "cx-stats-try-contenttranslation",
                                "cx-stats-published-target-source",
diff --git a/i18n/en.json b/i18n/en.json
index d8948db..bf13237 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -155,6 +155,7 @@
        "cx-campaign-contributionsmenu-might-be-available": "$1 might be 
already available in other languages",
        "cx-campaign-contributionsmenu-myuploads": "Uploaded media",
        "cx-trend-all-translations": "All translations",
+       "cx-trend-deletions": "Deleted translations",
        "cx-trend-translations-to": "Translations to $1",
        "cx-stats-try-contenttranslation": "Content Translation is a tool to 
create new pages by translating from other languages. [$1 Try Content 
Translation]",
        "cx-stats-published-target-source": "Translations to",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index a36fe83..45c4b4b 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -159,8 +159,9 @@
        "cx-campaign-contributionsmenu-translate-instead": "Menu item for menu 
shown while hovering the contributions link in personal toolbar while a new 
page is being created. Points to the Content Translation 
dashboard\n{{Identical|Translation}}",
        "cx-campaign-contributionsmenu-might-be-available": "Appears under 
{{msg-mw|cx-campaign-contributionsmenu-translate-instead}}. $1 is the title of 
the article being created, in quotation marks.",
        "cx-campaign-contributionsmenu-myuploads": "Menu item for menu shown 
while hovering the contributions link in personal toolbar. Points to the 
Special:MyUploads in commons",
-       "cx-trend-all-translations": "Label shown in the legend section Content 
translation trends(graph visualization)",
-       "cx-trend-translations-to": "Label shown in the legend section Content 
translation trends graph visualization.\n* $1 - language name",
+       "cx-trend-all-translations": "Label shown in the legend section of 
[[Special:CXStats]] trends graph visualization",
+       "cx-trend-deletions": "Label shown in the legend section of 
[[Special:CXStats]] trends graph visualization",
+       "cx-trend-translations-to": "Label shown in the legend section of 
[[Special:CXStats]] trends graph visualization.\n* $1 - language name",
        "cx-stats-try-contenttranslation": "A message shown in 
[[Special:CXStats]] for users not enabled Content Translation . \n$1 - link to 
enable Content Translation beta feature and go to Content Translation 
dashboard",
        "cx-stats-published-target-source": "A message shown in 
[[Special:CXStats]]",
        "cx-stats-published-source-target": "A message shown in 
[[Special:CXStats]]",
diff --git a/includes/Translation.php b/includes/Translation.php
index 0f54508..3a7ba17 100644
--- a/includes/Translation.php
+++ b/includes/Translation.php
@@ -278,12 +278,8 @@
                $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 ) ),
+                       $time = self::getResultTime( $row->date, $interval );
+                       $result[$time] = array(
                                'count' => $count,
                                'delta' => $count - $prev,
                        );
@@ -292,6 +288,68 @@
                }
 
                return $result;
+       }
+
+       /**
+        * Get time-wise cumulative number of deletions for given
+        * language pairs, with given interval.
+        */
+       public static function getDeletionTrend( $interval ) {
+               $dbr = wfGetDB( DB_SLAVE );
+
+               $conditions = array(
+                       'ct_tag' => 'contenttranslation',
+                       'ar_rev_id = ct_rev_id'
+               );
+               $groupBy = null;
+
+               if ( $interval === 'week' ) {
+                       $groupBy = array(
+                               'GROUP BY' => array(
+                                       'YEARWEEK(ar_timestamp)',
+                               ),
+                       );
+               } elseif ( $interval === 'month' ) {
+                       $groupBy = array(
+                               'GROUP BY' => array(
+                                       'YEAR(ar_timestamp), 
MONTH(ar_timestamp)',
+                               ),
+                       );
+               }
+
+               $rows = $dbr->select(
+                       array( 'change_tag', 'archive' ),
+                       array( 'ar_timestamp', 'count(ar_page_id) as count' ),
+                       $conditions,
+                       __METHOD__,
+                       $groupBy
+               );
+
+               $prev = 0;
+               $count = 0;
+               $result = array();
+               foreach ( $rows as $row ) {
+                       $count += (int)$row->count;
+                       $time = self::getResultTime( $row->ar_timestamp, 
$interval );
+                       $result[$time] = array(
+                               'count' => $count,
+                               'delta' => $count - $prev,
+                       );
+                       $prev = $count;
+               }
+
+               return $result;
+       }
+
+       protected static function getResultTime( $timestamp, $interval ) {
+               $unix = wfTimestamp( TS_UNIX, $timestamp );
+               if ( $interval === 'week' ) {
+                       $n = 7 - date( 'w', $unix );
+                       $unix = strtotime( "+$n days", $unix );
+                       return date( 'Y-m-d', $unix );
+               } else {
+                       return date( 'Y-m', $unix );
+               }
        }
 
        /**
@@ -356,12 +414,8 @@
                $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 ) ),
+                       $time = self::getResultTime( $row->date, $interval );
+                       $result[$time] = array(
                                'count' => $count,
                                'delta' => $count - $prev,
                        );
diff --git a/modules/stats/ext.cx.stats.js b/modules/stats/ext.cx.stats.js
index b6bb788..17ce811 100644
--- a/modules/stats/ext.cx.stats.js
+++ b/modules/stats/ext.cx.stats.js
@@ -65,12 +65,11 @@
                        this.getCXTrends( mw.config.get( 'wgContentLanguage' ) )
                ).done( function ( totalTrend, languageTrend ) {
                        self.totalTranslationTrend = totalTrend.translations;
-                       self.languageTranslationTrend = 
languageTrend.translations;
-                       self.languageTranslationTrend = mergeAndFill( 
self.totalTranslationTrend, self.languageTranslationTrend );
+                       self.totalDraftTrend = totalTrend.drafts;
 
-                       self.totalDraftTrend = mergeAndFill( 
self.totalTranslationTrend, totalTrend.drafts );
-                       self.languageDraftTrend = mergeAndFill( 
self.languageTranslationTrend, languageTrend.drafts );
-                       self.languageDraftTrend = mergeAndFill( 
self.totalDraftTrend, self.languageDraftTrend );
+                       self.languageTranslationTrend = 
languageTrend.translations;
+                       self.languageDraftTrend = languageTrend.drafts;
+                       self.languageDeletionTrend = languageTrend.deletions;
                        self.renderHighlights();
                        self.drawCumulativeGraph( 'count' );
                        self.drawLanguageCumulativeGraph( 'count' );
@@ -88,49 +87,41 @@
         * Render the boxes at the top with the most interesting recent data.
         */
        CXStats.prototype.renderHighlights = function () {
-               var weekTrend, weekLangTrend, totalTrendLength, 
langTrendLength, localLanguage, total,
-                       lastWeekTotal, prevWeekTotal, lastWeekTranslations, 
prevWeekTranslations,
-                       langTotal, lastWeekLangTotal, prevWeekLangTotal,
-                       lastWeekLangTranslations, prevWeekLangTranslations,
+               var getTrend, info, infoLanguage, localLanguage,
                        $total, $weeklyStats,
                        weekLangTrendText, weekTrendText, weekTrendClass,
                        $parenthesizedTrend, $trendInLanguage,
                        fmt = mw.language.convertNumber; // Shortcut
 
-               if ( this.totalTranslationTrend.length < 4 ) {
-                       // Trend calculation works only if we have enough data
+               getTrend = function( data ) {
+                       var total, trend, thisWeek;
+
+                       if ( data.length < 3 ) {
+                               return;
+                       }
+
+                       thisWeek = data.length - 1;
+
+                       total = data[ thisWeek ].count;
+                       trend =
+                       ( data[ thisWeek - 1 ].delta - data[ thisWeek - 2 
].delta ) /
+                       data[ thisWeek - 2 ].delta * 100;
+                       trend = parseInt( trend );
+
+                       return {
+                               total: total,
+                               trend: trend,
+                               lastWeek: data[ thisWeek - 1 ].delta
+                       };
+               };
+
+               localLanguage = $.uls.data.getAutonym( mw.config.get( 
'wgContentLanguage' ) );
+               info = getTrend( this.totalTranslationTrend );
+               infoLanguage = getTrend( this.languageTranslationTrend );
+
+               if ( !info || !infoLanguage ) {
                        return;
                }
-
-               weekTrend = 0;
-               weekLangTrend = 0;
-               totalTrendLength = this.totalTranslationTrend.length;
-               langTrendLength = this.languageTranslationTrend.length;
-               localLanguage = $.uls.data.getAutonym( mw.config.get( 
'wgContentLanguage' ) );
-               total = this.totalTranslationTrend[ totalTrendLength - 1 
].count;
-
-               lastWeekTotal = this.totalTranslationTrend[ totalTrendLength - 
2 ].count;
-               prevWeekTotal = this.totalTranslationTrend[ totalTrendLength - 
3 ].count;
-               lastWeekTranslations = lastWeekTotal - prevWeekTotal;
-               prevWeekTranslations = prevWeekTotal -
-                       this.totalTranslationTrend[ totalTrendLength - 4 
].count;
-               if ( prevWeekTranslations ) {
-                       weekTrend = ( lastWeekTranslations - 
prevWeekTranslations ) /
-                               prevWeekTranslations * 100;
-               }
-               weekTrend = parseInt( weekTrend );
-
-               langTotal = this.languageTranslationTrend[ langTrendLength - 1 
].count;
-               lastWeekLangTotal = this.languageTranslationTrend[ 
langTrendLength - 2 ].count;
-               prevWeekLangTotal = this.languageTranslationTrend[ 
langTrendLength - 3 ].count;
-               lastWeekLangTranslations = lastWeekLangTotal - 
prevWeekLangTotal;
-               prevWeekLangTranslations = prevWeekLangTotal -
-                       this.languageTranslationTrend[ langTrendLength - 4 
].count;
-               if ( prevWeekLangTranslations ) {
-                       weekLangTrend = ( lastWeekLangTranslations - 
prevWeekLangTranslations ) /
-                               prevWeekLangTranslations * 100;
-               }
-               weekLangTrend = parseInt( weekLangTrend );
 
                $total = $( '<div>' )
                        .addClass( 'cx-stats-box' )
@@ -140,24 +131,24 @@
                                        .text( mw.msg( 
'cx-stats-total-published' ) ),
                                $( '<div>' )
                                        .addClass( 'cx-stats-box__total' )
-                                       .text( fmt( total ) ),
+                                       .text( fmt( info.total ) ),
                                $( '<div>' )
                                        .addClass( 'cx-stats-box__localtotal' )
                                        .text( mw.msg(
                                                
'cx-stats-local-published-number',
-                                               fmt( langTotal ),
+                                               fmt( infoLanguage.total ),
                                                fmt( localLanguage )
                                        ) )
                        );
 
-               weekLangTrendText = mw.msg( 'percent', fmt( weekLangTrend ) );
-               if ( weekLangTrend >= 0 ) {
+               weekLangTrendText = mw.msg( 'percent', fmt( infoLanguage.trend 
) );
+               if ( infoLanguage.trend >= 0 ) {
                        // Add the plus sign to make clear that it's an increase
                        weekLangTrendText = '+' + weekLangTrendText;
                }
 
-               weekTrendText = mw.msg( 'percent', fmt( weekTrend ) );
-               if ( weekTrend >= 0 ) {
+               weekTrendText = mw.msg( 'percent', fmt( info.trend ) );
+               if ( info.trend >= 0 ) {
                        // Add the plus sign to make clear that it's an increase
                        weekTrendText = '+' + weekTrendText;
                        weekTrendClass = 'increase';
@@ -173,7 +164,7 @@
                        .addClass( 'cx-stats-box__localtotal' )
                        .text( mw.msg(
                                'cx-stats-local-published',
-                               fmt( lastWeekLangTranslations ),
+                               fmt( infoLanguage.lastWeek ),
                                localLanguage,
                                '$3'
                        ) );
@@ -191,7 +182,7 @@
                                $( '<div>' ).append(
                                        $( '<span>' )
                                                .addClass( 
'cx-stats-box__total' )
-                                               .text( fmt( 
lastWeekTranslations ) ),
+                                               .text( fmt( info.lastWeek ) ),
                                        // nbsp is needed for separation 
between the numbers.
                                        // Without it the numbers appear in the 
wrong order in RTL environments.
                                        $( '<span>' )
@@ -509,10 +500,32 @@
                ctx = this.$languageCumulativeGraph[ 0 ].getContext( '2d' );
 
                data = {
-                       labels: $.map( this.totalTranslationTrend, function ( 
data ) {
+                       labels: $.map( this.languageTranslationTrend, function 
( data ) {
                                return data.date;
                        } ),
                        datasets: [
+                               {
+                                       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 ];
+                                       } )
+                               },
+                               {
+                                       label: mw.msg( 'cx-trend-deletions' ),
+                                       strokeColor: '#FF0000',
+                                       pointColor: '#FF0000',
+                                       pointStrokeColor: '#fff',
+                                       pointHighlightFill: '#fff',
+                                       pointHighlightStroke: '#FF0000',
+                                       data: $.map( 
this.languageDeletionTrend, function ( data ) {
+                                               return data[ type ];
+                                       } )
+                               },
                                {
                                        label: mw.message(
                                                'cx-trend-translations-to',
@@ -524,17 +537,6 @@
                                        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 ];
                                        } )
                                }
@@ -634,42 +636,6 @@
                }
                // a must be equal to b
                return 0;
-       }
-
-       /**
-        * Fill the data in languageData to match with totalData length.
-        * @param {[Object]} totalData Array of total translation trend data
-        * @param {[Object]} totalData Array of translations to a particular 
language
-        * @return {[Object]} Array of translations to a particular language, 
after padding
-        */
-       function mergeAndFill( totalData, languageData ) {
-               var i;
-
-               if ( totalData.length === languageData.length ) {
-                       return languageData;
-               }
-
-               // Fill at the beginning if languageData is not starting
-               // when totalData starts
-               for ( i = 0; i < totalData.length; i++ ) {
-                       if ( !languageData || languageData.length === 0 ) {
-                               break;
-                       }
-                       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
-                               } );
-                       }
-                       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;
        }
 
        $( function () {

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I8581d07c00dac6228ba5cc8b465acf431a1163e3
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/extensions/ContentTranslation
Gerrit-Branch: master
Gerrit-Owner: Santhosh <santhosh.thottin...@gmail.com>
Gerrit-Reviewer: Amire80 <amir.ahar...@mail.huji.ac.il>
Gerrit-Reviewer: KartikMistry <kartik.mis...@gmail.com>
Gerrit-Reviewer: Nikerabbit <niklas.laxst...@gmail.com>
Gerrit-Reviewer: Santhosh <santhosh.thottin...@gmail.com>
Gerrit-Reviewer: Siebrand <siebr...@kitano.nl>
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