public function execute( $par ) { global $wgRequest, $wgOut, $wgLang, $wgAutoloadClasses; $this->setHeaders(); $this->outputHeader(); if ( !class_exists( 'PHPlot' ) && !isset($wgAutoloadClasses['PHPlot'] ) ) { $wgOut->addWikiMsg( 'uos-warn' ); return; } $par = trim(strtolower($par)); foreach ( $this->blacklist as $b ) { if ( $b === $par ) { $par = false; break; } } if ( !$par ) { $opts = array(); $hiddenoptions = $this->getHiddenOptions(); $name = SpecialPage::getTitleFor( 'UserOptionStats' )->getPrefixedText(); foreach ( $this->getOptions() as $k ) { if( in_array( $k, $hiddenoptions ) ) { continue; # List hidden options separately (see below) } $opts[] = "[[$name/$k|$k]]"; } $wgOut->addWikiMsg( 'uos-choose', $wgLang->commaList( $opts ) ); if ( count( $hiddenoptions ) > 0 ) { $hiddenopts = array(); foreach ( $hiddenoptions as $hk ) { $hiddenopts[] = "[[$name/$hk|$hk]]"; } $wgOut->addWikiMsg( 'uos-choose-hidden', $wgLang->commaList( $hiddenopts ) ); } return; } $dbr = wfGetDB( DB_SLAVE ); $users = $dbr->select( 'user', '*', '', __METHOD__ ); $data = array(); $optionName = $par; foreach ( $users as $u ) { // New from row doesn't load user_properties, hence this is slow! $obj = User::newFromRow( $u ); $opt = $obj->getOption( $optionName, wfMsg( 'uos-unknown' ) ); if ( !isset($data[$opt]) ) $data[$opt] = 0; $data[$opt]++; } $realdata = array(); $labels = array(); // Most popular first, barring other arsort( $data ); // After more than 7 the default colors start to loop :( // So use the last free color for "other" which includes the rest $max = 7; $rest = array_slice( $data, $max ); $data = array_slice( $data, 0, $max ); foreach ( $data as $k => $d ) { $labels[] = "$k ($d)"; $realdata[] = array( $k, $d ); } if ( count($rest) ) { $other = 0; foreach ( $rest as $v ) $other += $v; $labels[] = wfMsg( 'uos-other' ) . " ($other)"; $realdata[] = array( 'other', $other ); } $title = $wgRequest->getText( 'pietitle', wfMsg( 'uos-title', $optionName ) ); $width = $wgRequest->getInt( 'width', 700 ); $height = $wgRequest->getInt( 'height', 500 ); $width = max( 200, min( 1000, $width ) ); $height = max( 200, min( 1000, $height ) ); $shading = $wgRequest->getInt( 'shading', 10 ); $height = max( 0, min( 1000, $height ) ); // Define the object $plot = new PHPlot( $width, $height ); $plot->SetDataType('text-data-single'); $plot->setDataValues( $realdata ); $plot->SetPlotType('pie'); $plot->SetLegend($labels); $plot->SetShading( $shading ); $plot->SetLabelScalePosition(0.3); $plot->SetTitle( $title ); // Better fonts $realFunction = array( 'FCFontFinder', 'find' ); if ( is_callable( $realFunction ) ) { $font = FCFontFinder::find( $wgLang->getCode() ); if ( $font ) { $plot->SetDefaultTTFont( $font ); } } global $wgOut; $wgOut->disable(); $plot->DrawGraph(); }
/** * Adds raw image data of the graph to the output. * @param $opts FormOptions */ public function draw( FormOptions $opts ) { global $wgTranslatePHPlotFont, $wgLang; $width = $opts->getValue( 'width' ); $height = $opts->getValue( 'height' ); // Define the object $plot = new PHPlot( $width, $height ); list( $legend, $resData ) = $this->getData( $opts ); $count = count( $resData ); $skip = intval( $count / ( $width / 60 ) - 1 ); $i = $count; foreach ( $resData as $date => $edits ) { if ( $skip > 0 ) { if ( ( $count - $i ) % $skip !== 0 ) $date = ''; } if ( strpos( $date, ';' ) !== false ) { list( , $date ) = explode( ';', $date, 2 ); } array_unshift( $edits, $date ); $data[] = $edits; $i--; } $font = FCFontFinder::find( $wgLang->getCode() ); if ( $font ) { $plot->SetDefaultTTFont( $font ); } else { $plot->SetDefaultTTFont( $wgTranslatePHPlotFont ); } $plot->SetDataValues( $data ); if ( $legend !== null ) { $plot->SetLegend( $legend ); } $numberFont = FCFontFinder::find( 'en' ); $plot->setFont( 'x_label', $numberFont, 8 ); $plot->setFont( 'y_label', $numberFont, 8 ); $yTitle = wfMsg( 'translate-stats-' . $opts['count'] ); // Turn off X axis ticks and labels because they get in the way: $plot->SetYTitle( $yTitle ); $plot->SetXTickLabelPos( 'none' ); $plot->SetXTickPos( 'none' ); $plot->SetXLabelAngle( 45 ); $max = max( array_map( 'max', $resData ) ); $max = self::roundToSignificant( $max, 1 ); $max = round( $max, intval( -log( $max, 10 ) ) ); $yTick = 10; while ( $max / $yTick > $height / 20 ) { $yTick *= 2; } // If we have very small case, ensure that there is at least one tick $yTick = min( $max, $yTick ); $yTick = self::roundToSignificant( $yTick ); $plot->SetYTickIncrement( $yTick ); $plot->SetPlotAreaWorld( null, 0, null, $max ); $plot->SetTransparentColor( 'white' ); $plot->SetBackgroundColor( 'white' ); // Draw it $plot->DrawGraph(); }