Mediawiki/Erweiterung/Gnuplot

Aus Mikiwiki
Version vom 8. Februar 2009, 21:17 Uhr von Michi (Diskussion | Beiträge)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

Die Mediawiki-Erweiterung Gnuplot (auch: GNUPlot) erlaubt die Erzeugung und Anzeige von grafischen Darstellungen. Dabei wird das Programm Gnuplot verwendet.

Installation

1. Voraussetzung ist die Installation des Pakets "gnuplot".

# apt-get install gnuplot

2. Anlegen der Datei "extensions/Gnuplot.php" und Einfügen des folgenden PHP-Codes (Stand: 8. Februar 2009).

<?php
/**
 * Parser hook extension adds a <gnuplot> tag and <dataset> tag to wiki markup for rendering gnuplot plots!
 * 
 * 
 * Usage is something like this:
 * <gnuplot>
 * set title "Text"
 * set yrange [0:60]
 * set xtics (0,1,2,3,4,5,6,7,8,9,10)
 * set xrange [0:10]
 * plot <dataset>0 1
 * 2 10
 * 3 15
 * </dataset> using 1:2 title "Burndown" with lines
 * </gnuplot>
 * 
 * Options should be heroicly wide open.. if you can wrap your head around all the possibilities listed in the
 * gnuplot documentation. 
 * 
 **/
 
// Make sure we are being called properly
if( !defined( 'MEDIAWIKI' ) ) {
	echo(" This file is an extension to the MediaWiki software and cannot be used standalone.\n" );
	die( -1 );
}
 
$wgExtensionFunctions[] = "wfGnuplotExtension";
 
/**
 * You should refer to the gnuplot documentation for the different output types
 * Honestly, only image types will work without some other changes
 */
$image_format = "png";
$gnuplot_path   = "/usr/bin/gnuplot";
 
/**
 * The function links its methods as
 * hooks for the Parser
 */
function wfGnuplotExtension() {
	global $wgParser;
	# register the extension with the WikiText parser
	# the first parameter is the name of the new tag.
	# the second parameter is the callback function for
	# processing the text between the tags
	$wgParser->setHook( "dataset", "saveDATA" );
	$wgParser->setHook( "gnuplot", "renderPLOT" );
}
 
 
/**
 * This method setups up the output of the plot script, which 
 * has a few things that we dont want to repeat EVERYTIME someone 
 * wants to make a graph
 *
 * @param String $plot_source - we have to have the full source to wrap
 * @param String $output_filename - we have to tell gnuplot where to output the graph
 * @return the script with output stuff wrapped in it
 */
function wrap_script($plot_source, $output_filename) {
	global $image_format;
	$something  = "set terminal ".$image_format."\n";
	$something .= "set output \"".$output_filename."\"\n";
	$something .= $plot_source;
	return $something;
}
 
/**
 * Caches the command script and calls the gnuplot executable to render the
 * graph image
 *
 * @param String $plot_script
 * @return Nothing.. we assume this all goes correctly.
 */
function renderGnuPlot(&$plot_script) {
	global
	$wgMathDirectory,
	$wgMathPath,
	$wgTmpDirectory,
	$image_format,
	$gnuplot_path;
 
 
	// hash our script
	$script_hash = md5($plot_script);
	// make the output of the command be in the math directory
	$filename = $wgMathDirectory."/plot-".$script_hash.".".$image_format;
 
	//fill in the extras our consumer doesn't care about
	$full_plot_script = wrap_script($plot_script,$filename);
 
	$current_dir = getcwd();
 
	chdir($wgTmpDirectory);
 
	// create temporary file for the plot script
	$winPath = $wgTmpDirectory."/".$script_hash.".plot";
	$fp = fopen($winPath,"a+");
	$w= fputs($fp,$full_plot_script);
	fclose($fp);
 
	// run gnuplot to create our file
	$command = $gnuplot_path." ".$script_hash.".plot ";
	//I had a problem with the status code always being false. so, stopped using it
	$status_code = exec($command);
 
	//delete the plot file
	unlink($wgTmpDirectory."/".$script_hash.".plot");
	chdir($current_dir);
}
 
 
/**
 * Determins if a graph file has already been rendered
 * if not, calls to render one and returns the root host url to the image. 
 *
 * @param String $plot_script
 * @return images/math/plot-.... file reference for the image tag
 */
function getPlotImageURL($plot_script) {
	global
	$wgMathDirectory,
	$wgMathPath,
	$image_format;
 
	//unique our script
	$formula_hash = md5($plot_script);
 
	$filename = 'plot-' . $formula_hash.".".$image_format;
	$full_path_filename = $wgMathDirectory."/".$filename;
 
	if (is_file($full_path_filename)) {
		//nothing to do
		//we've already made this image before
	} else {
		renderGnuPlot($plot_script);
	}
	return $wgMathPath."/".$filename;
}
 
/**
 * The callback function for converting the input text to HTML output
 *
 * @param String $input
 * @param Array<String> $argv
 * @param Parser $parser
 * @return HTML image tag to the graph itself
 */
function renderPLOT( &$input, $argv, &$parser ) {
	//get our parser to finish up its parse and recover the real data-set data (the UNIQ QINU problem)
	$input = $parser->recursiveTagParse( $input );
	$input = $parser->mStripState->unstripBoth($input);
	$url = getPlotImageURL($input);
 
	return "<img src='$url'>";
 
}
 
/**
 * This method takes in the raw tuple input of the dataset, and any arguments, and saves it to a random
 * file on the system. The return is the absolute path to the data file, so that it can be 
 * embedded into the plot command.
 *
 * @param String $input
 * @param Array<String> $argv
 * @param Parser $parser
 * @return unknown
 */
function saveDATA( $input, $argv, &$parser){
	global
	$wgMathDirectory,
	$wgMathPath,
	$wgTmpDirectory;
 
	//make a temp filename with a hash of the input
	$filename = md5($input);
	//we dont wanna create toooo many of these guys either
	if (!is_file($wgTmpDirectory."/".$filename.".dat")) {
		//know where we are
		$current_dir = getcwd();
		//than change it
		chdir($wgTmpDirectory);
 
		// saving this data set as a temporary RANDOM file
		$winPath = $wgTmpDirectory."/".$filename.".dat";
		$fp = fopen($winPath,"a+");
		$w=fputs($fp,$input);
		fclose($fp);
 
		chdir($current_dir);
	}		
	return "\"".$wgTmpDirectory."/".$filename.".dat\"";
}
 
?>

3. Anpassung der Rechte.

# chown wiki:wiki extensions/gnuplot.php

4. Pfad zu Gnuplot in der Datei "extensions/gnuplot.php" anpassen.

$gnuplot_path   = "/usr/bin/gnuplot";

5. Einfügen der folgenden Zeile in die Datei "LocalSettings.php".

## Extension: Gnuplot
require_once('extensions/gnuplot.php');

Die Standardeinstellungen in der Datei "gnuplot.php" sind die folgenden.

set terminal png color
set size 0.5,0.5

Passendere Einstellungen sind z. B.

set terminal png color
set size 1.5,1.0

Weblinks