[Piwik-svn] r208 - in trunk: libs libs/sparkline libs/sparkline/lib modules modules/ViewDataTable plugins/Home plugins/Home/templates plugins/VisitsSummary
svnmaster at piwik.org
svnmaster at piwik.org
Sun Jan 20 07:57:21 CET 2008
Author: matt
Date: 2008-01-20 07:57:20 +0100 (Sun, 20 Jan 2008)
New Revision: 208
Added:
trunk/libs/sparkline/
trunk/libs/sparkline/CHANGES
trunk/libs/sparkline/DESIGN
trunk/libs/sparkline/LICENSE
trunk/libs/sparkline/README
trunk/libs/sparkline/lib/
trunk/libs/sparkline/lib/Object.php
trunk/libs/sparkline/lib/Sparkline.php
trunk/libs/sparkline/lib/Sparkline_Bar.php
trunk/libs/sparkline/lib/Sparkline_Line.php
trunk/modules/ViewDataTable/Sparkline.php
Modified:
trunk/modules/ViewDataTable.php
trunk/modules/ViewDataTable/GenerateGraphData.php
trunk/modules/ViewDataTable/Graph.php
trunk/plugins/Home/Controller.php
trunk/plugins/Home/templates/datatable.css
trunk/plugins/Home/templates/index.tpl
trunk/plugins/VisitsSummary/API.php
Log:
- adding sparklines: http://piwik.org/demo/
first shot still lot of work
Added: trunk/libs/sparkline/CHANGES
===================================================================
--- trunk/libs/sparkline/CHANGES (rev 0)
+++ trunk/libs/sparkline/CHANGES 2008-01-20 06:57:20 UTC (rev 208)
@@ -0,0 +1,22 @@
+#
+# Sparkline PHP Graphing Library
+# Copyright 2004 James Byers <jbyers at users.sf.net>
+# http://sparkline.org
+#
+# Sparkline is distributed under a BSD License. See LICENSE for details.
+#
+# $Id: CHANGES,v 1.2 2005/06/02 20:57:51 jbyers Exp $
+#
+
+2005-06-02 James Byers <jbyers at users.sf.net>
+
+ * Version 0.2 released
+ * Corrected line chart behavior for small data sets [1096890]
+ * Library will create log file if possible [1163412]
+ * Fixed error message on bad log file [1096895]
+ * Corrected bitmask on DEBUG_ALL
+ * Revised structure of SetFeature
+
+2004-11-08 James Byers <jbyers at users.sf.net>
+
+ * Version 0.1 released
Added: trunk/libs/sparkline/DESIGN
===================================================================
--- trunk/libs/sparkline/DESIGN (rev 0)
+++ trunk/libs/sparkline/DESIGN 2008-01-20 06:57:20 UTC (rev 208)
@@ -0,0 +1,27 @@
+#
+# Sparkline PHP Graphing Library
+# Copyright 2004 James Byers <jbyers at users.sf.net>
+# http://sparkline.org
+#
+# Sparkline is distributed under a BSD License. See LICENSE for details.
+#
+# $Id: DESIGN,v 1.3 2004/11/09 07:10:42 jbyers Exp $
+#
+
+Not much to see. It's 0.1, after all.
+
+Flow
+------------------------------------------------------------------------------
+
+Instantiate appropriate Sparkline subclass
+Load data, set parameters, all Set* calls
+Render
+ convert coordinates
+ calculate image size
+ create image handle
+ set colors
+ fill background
+ draw graph
+ draw features
+Optionally call Draw* functions
+Output / OutputFile
Added: trunk/libs/sparkline/LICENSE
===================================================================
--- trunk/libs/sparkline/LICENSE (rev 0)
+++ trunk/libs/sparkline/LICENSE 2008-01-20 06:57:20 UTC (rev 208)
@@ -0,0 +1,29 @@
+Copyright (c) 2004 James Byers <jbyers at users.sf.net>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of James Byers nor the names of its contributors
+ may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Added: trunk/libs/sparkline/README
===================================================================
--- trunk/libs/sparkline/README (rev 0)
+++ trunk/libs/sparkline/README 2008-01-20 06:57:20 UTC (rev 208)
@@ -0,0 +1,37 @@
+#
+# Sparkline PHP Graphing Library
+# Copyright 2004 James Byers <jbyers at users.sf.net>
+# http://sparkline.org
+#
+# Sparkline is distributed under a BSD License. See LICENSE for details.
+#
+# $Id: README,v 1.2 2004/11/09 07:10:42 jbyers Exp $
+#
+
+Installation:
+-------------
+
+Sparkline does not have any installation requirements. See the
+samples directory for usage ideas.
+
+Requirements:
+-------------
+
+Sparkline requires PHP 4.0.6 or newer and GD 2.0 built as a PHP
+module.
+
+Troubleshooting and Support:
+----------------------------
+
+See http://sparkline.org for troubleshooting advice and support.
+
+Bugs, Features:
+---------------
+
+Please submit bugs to the bug tracker:
+
+ http://sourceforge.net/tracker/?group_id=122936&atid=694962
+
+Please submit feature requests to the RFE tracker:
+
+ http://sourceforge.net/tracker/?group_id=122936&atid=694965
Added: trunk/libs/sparkline/lib/Object.php
===================================================================
--- trunk/libs/sparkline/lib/Object.php (rev 0)
+++ trunk/libs/sparkline/lib/Object.php 2008-01-20 06:57:20 UTC (rev 208)
@@ -0,0 +1,158 @@
+<?php
+/*
+ * Sparkline PHP Graphing Library
+ * Copyright 2004 James Byers <jbyers at users.sf.net>
+ * http://sparkline.org
+ *
+ * Sparkline is distributed under a BSD License. See LICENSE for details.
+ *
+ * $Id: Object.php,v 1.8 2005/06/02 21:01:42 jbyers Exp $
+ *
+ */
+
+define('DEBUG_NONE', 0); // nothing
+define('DEBUG_ERROR', 1); // major errors
+define('DEBUG_WARNING', 2); // warnings
+define('DEBUG_STATS', 4); // dataset, rendering statistics
+define('DEBUG_CALLS', 8); // major function calls
+define('DEBUG_SET', 16); // all Set methods
+define('DEBUG_DRAW', 32); // all Draw methods
+define('DEBUG_ALL', 2047); // everything
+
+function error_handler($errno, $errstr, $errfile, $errline) {
+ switch ($errno) {
+ case E_ERROR:
+ $message = "ERROR: ";
+ break;
+ case E_WARNING:
+ $message = "WARNING: ";
+ break;
+ case E_PARSE:
+ $message = "PARSE: ";
+ break;
+ case E_NOTICE:
+ $message = "NOTICE: ";
+ break;
+ case E_USER_ERROR:
+ $message = "UERROR: ";
+ break;
+ case E_USER_WARNING:
+ $message = "UWARNING: ";
+ break;
+ case E_USER_NOTICE:
+ $message = "UNOTICE: ";
+ break;
+ default:
+ $message = "UNKNOWN: ";
+ break;
+ } // switch
+
+ $message .= "$errstr in $errfile at line $errline\n";
+
+ if (($errno != E_NOTICE) && // suppress notices
+ (error_reporting() != 0)) { // respect supressed errors (@)
+ log_write($message, 'PHP');
+ }
+} // function error_handler
+
+function log_write($string, $type = '', $date = false) {
+ global $LOGFILE;
+
+ if (isset($LOGFILE)) {
+ if ($date == false) {
+ $date = time();
+ }
+
+ $message = date('d/m/Y:H:i:s', $date) . " $type: $string \n";
+ error_log($message, 3, $LOGFILE);
+ }
+} // function log_write
+
+class Object {
+
+ var $isError;
+ var $logFile;
+ var $errorList;
+ var $debugList;
+ var $debugLevel;
+ var $startTime;
+
+ ////////////////////////////////////////////////////////////////////////////
+ // constructor
+ //
+ function Object($catch_errors = true) {
+ $this->isError = false;
+ $this->logFile = null;
+ $this->logDate = '';
+ $this->errorList = array();
+ $this->debugList = array();
+ $this->debugLevel = DEBUG_NONE;
+ $this->startTime = $this->microTimer();
+
+ // if ($catch_errors) {
+ set_error_handler('error_handler');
+ //}
+ } // function Object
+
+ ////////////////////////////////////////////////////////////////////////////
+ // utility
+ //
+ function microTimer() {
+ list($usec, $sec) = explode(" ", microtime());
+ return ((float)$usec + (float)$sec);
+ } // function microTimer
+
+ ////////////////////////////////////////////////////////////////////////////
+ // error handling
+ //
+ function SetDebugLevel($level, $file = null) {
+ global $LOGFILE;
+
+ if ($level >= DEBUG_NONE &&
+ $level <= DEBUG_ALL) {
+ $this->debugLevel = $level;
+ }
+
+ if ($file != null) {
+ if ((!file_exists($file) && !touch($file)) ||
+ !is_writable($file)) {
+ die("error log file '$file' is not writable to the web server user");
+ } else {
+ $this->logFile = $file;
+ $LOGFILE = $file;
+ }
+ }
+ } // function SetDebugLevel
+
+ function Debug($string, $level = DEBUG_WARNING) {
+ $this->debugList[] = $string;
+ if ($this->debugLevel & $level &&
+ $this->logFile != null) {
+ log_write($string, 'DEBUG');
+ }
+ } // function Debug
+
+ function Error($string) {
+ $this->isError = true;
+ $this->errorList[] = $string;
+ if ($this->debugLevel & DEBUG_ERROR &&
+ $this->logFile != null) {
+ log_write($string, 'ERROR');
+ }
+ } // function Error
+
+ function GetDebug() {
+ return $this->debugList;
+ } // function GetDebug
+
+ function GetError() {
+ return $this->errorList;
+ } // function GetError
+
+ function IsError() {
+ return $this->isError;
+ } // function IsError
+
+} // class Object
+
+?>
Added: trunk/libs/sparkline/lib/Sparkline.php
===================================================================
--- trunk/libs/sparkline/lib/Sparkline.php (rev 0)
+++ trunk/libs/sparkline/lib/Sparkline.php 2008-01-20 06:57:20 UTC (rev 208)
@@ -0,0 +1,496 @@
+<?php
+/*
+ * Sparkline PHP Graphing Library
+ * Copyright 2004 James Byers <jbyers at users.sf.net>
+ * http://sparkline.org
+ *
+ * Sparkline is distributed under a BSD License. See LICENSE for details.
+ *
+ * $Id: Sparkline.php,v 1.8 2005/05/02 20:25:47 jbyers Exp $
+ *
+ */
+
+define('TEXT_TOP', 1);
+define('TEXT_RIGHT', 2);
+define('TEXT_BOTTOM', 3);
+define('TEXT_LEFT', 4);
+
+define('FONT_1', 1);
+define('FONT_2', 2);
+define('FONT_3', 3);
+define('FONT_4', 4);
+define('FONT_5', 5);
+
+require_once('Object.php');
+
+class Sparkline extends Object {
+
+ var $imageX;
+ var $imageY;
+ var $imageHandle;
+ var $graphAreaPx;
+ var $graphAreaPt;
+ var $colorList;
+ var $colorBackground;
+ var $lineSize;
+
+ ////////////////////////////////////////////////////////////////////////////
+ // constructor
+ //
+ function Sparkline($catch_errors = true) {
+ parent::Object($catch_errors);
+
+ $this->colorList = array();
+ $this->colorBackground = 'white';
+ $this->lineSize = 1;
+ $this->graphAreaPx = array(array(0, 0), array(0, 0)); // px(L, B), px(R, T)
+ } // function Sparkline
+
+ ////////////////////////////////////////////////////////////////////////////
+ // init
+ //
+ function Init($x, $y) {
+ $this->Debug("Sparkline :: Init($x, $y)", DEBUG_CALLS);
+
+ $this->imageX = $x;
+ $this->imageY = $y;
+
+ // Set functions may have already set graphAreaPx offsets; add image dimensions
+ //
+ $this->graphAreaPx = array(array($this->graphAreaPx[0][0],
+ $this->graphAreaPx[0][1]),
+ array($this->graphAreaPx[1][0] + $x - 1,
+ $this->graphAreaPx[1][1] + $y - 1));
+
+ $this->imageHandle = $this->CreateImageHandle($x, $y);
+
+ // load default colors; set all color handles
+ //
+ $this->SetColorDefaults();
+ while (list($k, $v) = each($this->colorList)) {
+ $this->SetColorHandle($k, $this->DrawColorAllocate($k, $this->imageHandle));
+ }
+ reset($this->colorList);
+
+ if ($this->IsError()) {
+ return false;
+ } else {
+ return true;
+ }
+ } // function Init
+
+ ////////////////////////////////////////////////////////////////////////////
+ // color, drawing setup functions
+ //
+ function SetColor($name, $r, $g, $b) {
+ $this->Debug("Sparkline :: SetColor('$name', $r, $g, $b)", DEBUG_SET);
+ $name = strtolower($name);
+ $this->colorList[$name] = array('rgb' => array($r, $g, $b));
+ } // function SetDecColor
+
+ function SetColorHandle($name, $handle) {
+ $this->Debug("Sparkline :: SetColorHandle('$name', $handle)", DEBUG_SET);
+ $name = strtolower($name);
+ if (array_key_exists($name, $this->colorList)) {
+ $this->colorList[$name]['handle'] = $handle;
+ return true;
+ } else {
+ return false;
+ }
+ } // function SetColorHandle
+
+ function SetColorHex($name, $r, $g, $b) {
+ $this->Debug("Sparkline :: SetColorHex('$name', $r, $g, $b)", DEBUG_SET);
+ $this->SetColor($name, hexdec($r), hexdec($g), hexdec($b));
+ } // function SetHexColor
+
+ function SetColorHtml($name, $rgb) {
+ $this->Debug("Sparkline :: SetColorHtml('$name', '$rgb')", DEBUG_SET);
+ $rgb = trim($rgb, '#');
+ $this->SetColor($name, hexdec(substr($rgb, 0, 2)), hexdec(substr($rgb, 2, 2)), hexdec(substr($rgb, 4, 2)));
+ } // function SetHexColor
+
+ function SetColorBackground($name) {
+ $this->Debug("Sparkline :: SetColorBackground('$name')", DEBUG_SET);
+ $this->colorBackground = $name;
+ } // function SetColorBackground
+
+ function GetColor($name) {
+ if (array_key_exists($name, $this->colorList)) {
+ return $this->colorList[$name]['rgb'];
+ } else {
+ return false;
+ }
+ } // function GetColor
+
+ function GetColorHandle($name) {
+ $name = strtolower($name);
+ if (array_key_exists($name, $this->colorList)) {
+ return $this->colorList[$name]['handle'];
+ } else {
+ $this->Debug("Sparkline :: GetColorHandle color '$name' not set", DEBUG_WARNING);
+ return false;
+ }
+ } // function GetColorHandle
+
+ function SetColorDefaults() {
+ $this->Debug("Sparkline :: SetColorDefaults()", DEBUG_SET);
+ $colorDefaults = array(array('aqua', '#00FFFF'),
+ array('black', '#010101'), // TODO failure if 000000?
+ array('blue', '#0000FF'),
+ array('fuscia', '#FF00FF'),
+ array('gray', '#808080'),
+ array('grey', '#808080'),
+ array('green', '#008000'),
+ array('lime', '#00FF00'),
+ array('maroon', '#800000'),
+ array('navy', '#000080'),
+ array('olive', '#808000'),
+ array('purple', '#800080'),
+ array('red', '#FF0000'),
+ array('silver', '#C0C0C0'),
+ array('teal', '#008080'),
+ array('white', '#FFFFFF'),
+ array('yellow', '#FFFF00'));
+ while (list(, $v) = each($colorDefaults)) {
+ if (!array_key_exists($v[0], $this->colorList)) {
+ $this->SetColorHtml($v[0], $v[1]);
+ }
+ }
+ } // function SetColorDefaults
+
+ function SetLineSize($size) {
+ $this->Debug("Sparkline :: SetLineSize($size)", DEBUG_CALLS);
+
+ $this->lineSize = $size;
+ } // function SetLineSize
+
+ function GetLineSize() {
+ return($this->lineSize);
+ } // function GetLineSize
+
+ function SetPadding($T, $R = null, $B = null, $L = null) {
+ $this->Debug("Sparkline :: SetPadding($T, $R, $B, $L)", DEBUG_CALLS);
+
+ if (null == $R &&
+ null == $B &&
+ null == $L) {
+ $this->graphAreaPx = array(array($this->graphAreaPx[0][0] + $T,
+ $this->graphAreaPx[0][1] + $T),
+ array($this->graphAreaPx[1][0] - $T,
+ $this->graphAreaPx[1][1] - $T));
+ } else {
+ $this->graphAreaPx = array(array($this->graphAreaPx[0][0] + $L,
+ $this->graphAreaPx[0][1] + $B),
+ array($this->graphAreaPx[1][0] - $R,
+ $this->graphAreaPx[1][1] - $T));
+ }
+ } // function SetPadding
+
+ ////////////////////////////////////////////////////////////////////////////
+ // canvas setup
+ //
+ function CreateImageHandle($x, $y) {
+ $this->Debug("Sparkline :: CreateImageHandle($x, $y)", DEBUG_CALLS);
+
+ $handle = @imagecreatetruecolor($x, $y);
+ if (!is_resource($handle)) {
+ $handle = imagecreate($x, $y);
+ $this->Debug('imagecreatetruecolor unavailable', DEBUG_WARNING);
+ }
+
+ if (!is_resource($handle)) {
+ $this->Debug('imagecreate unavailable', DEBUG_WARNING);
+ $this->Error('could not create image; GD imagecreate functions unavailable');
+ }
+
+ return $handle;
+ } // function CreateImageHandle
+
+ ////////////////////////////////////////////////////////////////////////////
+ // drawing primitives
+ //
+ // NB: all drawing primitives use the coordinate system where (0,0)
+ // corresponds to the bottom left of the image, unlike y-inverted
+ // PHP gd functions
+ //
+ function DrawBackground($handle = false) {
+ $this->Debug("Sparkline :: DrawBackground()", DEBUG_DRAW);
+
+ if (!$this->IsError()) {
+ if ($handle === false) $handle = $this->imageHandle;
+ return $this->DrawRectangleFilled(0,
+ 0,
+ imagesx($handle) - 1,
+ imagesy($handle) - 1,
+ $this->colorBackground,
+ $handle);
+ }
+ } // function DrawBackground
+
+ function DrawColorAllocate($color, $handle = false) {
+ $this->Debug("Sparkline :: DrawColorAllocate('$color')", DEBUG_DRAW);
+
+ if (!$this->IsError() &&
+ $colorRGB = $this->GetColor($color)) {
+ if ($handle === false) $handle = $this->imageHandle;
+ return imagecolorallocate($handle,
+ $colorRGB[0],
+ $colorRGB[1],
+ $colorRGB[2]);
+ }
+ } // function DrawColorAllocate
+
+ function DrawFill($x, $y, $color, $handle = false) {
+ $this->Debug("Sparkline :: DrawFill($x, $y, '$color')", DEBUG_DRAW);
+
+ if (!$this->IsError() &&
+ $colorHandle = $this->GetColorHandle($color)) {
+ if ($handle === false) $handle = $this->imageHandle;
+ return imagefill($handle,
+ $x,
+ $this->TxGDYToSLY($y, $handle),
+ $colorHandle);
+ }
+ } // function DrawFill
+
+ function DrawLine($x1, $y1, $x2, $y2, $color, $thickness = 1, $handle = false) {
+ $this->Debug("Sparkline :: DrawLine($x1, $y1, $x2, $y2, '$color', $thickness)", DEBUG_DRAW);
+
+ if (!$this->IsError() &&
+ $colorHandle = $this->GetColorHandle($color)) {
+ if ($handle === false) $handle = $this->imageHandle;
+
+ imagesetthickness($handle, $thickness);
+ $result = imageline($handle,
+ $x1,
+ $this->TxGDYToSLY($y1, $handle),
+ $x2,
+ $this->TxGDYToSLY($y2, $handle),
+ $colorHandle);
+ imagesetthickness($handle, 1);
+ return $result;
+ }
+ } // function DrawLine
+
+ function DrawPoint($x, $y, $color, $handle = false) {
+ $this->Debug("Sparkline :: DrawPoint($x, $y, '$color')", DEBUG_DRAW);
+
+ if (!$this->IsError() &&
+ $colorHandle = $this->GetColorHandle($color)) {
+ if ($handle === false) $handle = $this->imageHandle;
+ return imagesetpixel($handle,
+ $x,
+ $this->TxGDYToSLY($y, $handle),
+ $colorHandle);
+ }
+ } // function DrawPoint
+
+ function DrawRectangle($x1, $y1, $x2, $y2, $color, $handle = false) {
+ $this->Debug("Sparkline :: DrawRectangle($x1, $y1, $x2, $y2 '$color')", DEBUG_DRAW);
+
+ if (!$this->IsError() &&
+ $colorHandle = $this->GetColorHandle($color)) {
+ if ($handle === false) $handle = $this->imageHandle;
+ return imagerectangle($handle,
+ $x1,
+ $this->TxGDYToSLY($y1, $handle),
+ $x2,
+ $this->TxGDYToSLY($y2, $handle),
+ $colorHandle);
+ }
+ } // function DrawRectangle
+
+ function DrawRectangleFilled($x1, $y1, $x2, $y2, $color, $handle = false) {
+ $this->Debug("Sparkline :: DrawRectangleFilled($x1, $y1, $x2, $y2 '$color')", DEBUG_DRAW);
+
+ if (!$this->IsError() &&
+ $colorHandle = $this->GetColorHandle($color)) {
+ // NB: switch y1, y2 post conversion
+ //
+ if ($y1 < $y2) {
+ $yt = $y1;
+ $y1 = $y2;
+ $y2 = $yt;
+ }
+
+ if ($handle === false) $handle = $this->imageHandle;
+ return imagefilledrectangle($handle,
+ $x1,
+ $this->TxGDYToSLY($y1, $handle),
+ $x2,
+ $this->TxGDYToSLY($y2, $handle),
+ $colorHandle);
+ }
+ } // function DrawRectangleFilled
+
+ function DrawCircleFilled($x, $y, $diameter, $color, $handle = false) {
+ $this->Debug("Sparkline :: DrawCircleFilled($x, $y, $diameter, '$color')", DEBUG_DRAW);
+
+ if (!$this->IsError() &&
+ $colorHandle = $this->GetColorHandle($color)) {
+ if ($handle === false) $handle = $this->imageHandle;
+ return imagefilledellipse($handle,
+ $x,
+ $this->TxGDYToSLY($y, $handle),
+ $diameter,
+ $diameter,
+ $colorHandle);
+ }
+ } // function DrawCircleFilled
+
+ function DrawText($string, $x, $y, $color, $font = FONT_1, $handle = false) {
+ $this->Debug("Sparkline :: DrawText('$string', $x, $y, '$color', $font)", DEBUG_DRAW);
+
+ if (!$this->IsError() &&
+ $colorHandle = $this->GetColorHandle($color)) {
+ // adjust for font height so x,y corresponds to bottom left of font
+ //
+ if ($handle === false) $handle = $this->imageHandle;
+ return imagestring($handle,
+ $font,
+ $x,
+ $this->TxGDYToSLY($y + imagefontheight($font), $handle),
+ $string,
+ $colorHandle);
+ }
+ } // function DrawText
+
+ function DrawTextRelative($string, $x, $y, $color, $position, $padding = 2, $font = FONT_1, $handle = false) {
+ $this->Debug("Sparkline :: DrawTextRelative('$string', $x, $y, '$color', $position, $font, $padding)", DEBUG_DRAW);
+
+ if (!$this->IsError() &&
+ $colorHandle = $this->GetColorHandle($color)) {
+ if ($handle === false) $handle = $this->imageHandle;
+
+ // rendered text width, height
+ //
+ $textHeight = imagefontheight($font);
+ $textWidth = imagefontwidth($font) * strlen($string);
+
+ // set (pxX, pxY) based on position and point
+ //
+ switch($position) {
+ case TEXT_TOP:
+ $x = $x - round($textWidth / 2);
+ $y = $y + $padding;
+ break;
+
+ case TEXT_RIGHT:
+ $x = $x + $padding;
+ $y = $y - round($textHeight / 2);
+ break;
+
+ case TEXT_BOTTOM:
+ $x = $x - round($textWidth / 2);
+ $y = $y - $padding - $textHeight;
+ break;
+
+ case TEXT_LEFT:
+ default:
+ $x = $x - $padding - $textWidth;
+ $y = $y - round($textHeight / 2);
+ break;
+ }
+
+ // truncate bounds based on string size in pixels, image bounds
+ // order: TRBL
+ //
+ $y = min($y, $this->GetImageHeight() - $textHeight);
+ $x = min($x, $this->GetImageWidth() - $textWidth);
+ $y = max($y, 0);
+ $x = max($x, 0);
+
+ return $this->DrawText($string,
+ $x,
+ $y,
+ $color,
+ $font,
+ $handle);
+ }
+ } // function DrawTextRelative
+
+ function DrawImageCopyResampled($dhandle, $shandle, $dx, $dy, $sx, $sy, $dw, $dh, $sw, $sh) {
+ $this->Debug("Sparkline :: DrawImageCopyResampled($dhhandle, $shandle, $dx, $dy, $sx, $sy, $dw, $dh, $sw, $sh)", DEBUG_DRAW);
+ if (!$this->IsError()) {
+ return imagecopyresampled($dhandle, // dest handle
+ $shandle, // src handle
+ $dx, $dy, // dest x, y
+ $sx, $sy, // src x, y
+ $dw, $dh, // dest w, h
+ $sw, $sh); // src w, h
+ }
+ } // function DrawImageCopyResampled
+
+ ////////////////////////////////////////////////////////////////////////////
+ // coordinate system functions
+ // world coordinates are referenced as points or pt
+ // graph coordinates are referenced as pixels or px
+ // sparkline inverts GD Y pixel coordinates; the bottom left of the
+ // image rendering area is px(0,0)
+ // all coordinate transformation functions are prefixed with Tx
+ // all coordinate transformation functions depend on a valid image handle
+ // and will only return valid results after all Set* calls are performed
+ //
+ function TxGDYToSLY($gdY, $handle) {
+ return imagesy($handle) - 1 - $gdY;
+ } // function TxGDYToSLY
+
+ function TxPxToPt($pxX, $pxY, $handle) {
+ // TODO; must occur after data series conversion
+ } // function TxPxToPt
+
+ function TxPtToPx($ptX, $ptY, $handle) {
+ // TODO; must occur after data series conversion
+ } // function TxPtToPx
+
+ function GetGraphWidth() {
+ return $this->graphAreaPx[1][0] - $this->graphAreaPx[0][0];
+ } // function GetGraphWidth
+
+ function GetGraphHeight() {
+ return $this->graphAreaPx[1][1] - $this->graphAreaPx[0][1];
+ } // function GetGraphHeight
+
+ function GetImageWidth() {
+ return $this->imageX;
+ } // function GetImageWidth
+
+ function GetImageHeight() {
+ return $this->imageY;
+ } // function GetImageHeight
+
+ ////////////////////////////////////////////////////////////////////////////
+ // image output
+ //
+ function Output($file = '') {
+
+ $this->Debug("Sparkline :: Output($file)", DEBUG_CALLS);
+
+ if ($this->IsError()) {
+ $colorError = imagecolorallocate($this->imageHandle, 0xFF, 0x00, 0x00);
+ imagestring($this->imageHandle,
+ 1,
+ ($this->imageX / 2) - (5 * imagefontwidth(1) / 2),
+ ($this->imageY / 2) - (imagefontheight(1) / 2),
+ "ERROR",
+ $colorError);
+ }
+
+ if ($file == '') {
+ header('Content-type: image/png');
+ imagepng($this->imageHandle);
+ } else {
+ imagepng($this->imageHandle, $file);
+ }
+
+ $this->Debug('Sparkline :: Output - total execution time: ' . round($this->microTimer() - $this->startTime, 4) . ' seconds', DEBUG_STATS);
+ } // function Output
+
+ function OutputToFile($file) {
+ $this->Output($file);
+ } // function OutputToFile
+
+} // class Sparkline
+
+?>
Added: trunk/libs/sparkline/lib/Sparkline_Bar.php
===================================================================
--- trunk/libs/sparkline/lib/Sparkline_Bar.php (rev 0)
+++ trunk/libs/sparkline/lib/Sparkline_Bar.php 2008-01-20 06:57:20 UTC (rev 208)
@@ -0,0 +1,191 @@
+<?php
+/*
+ * Sparkline PHP Graphing Library
+ * Copyright 2004 James Byers <jbyers at users.sf.net>
+ * http://sparkline.org
+ *
+ * Sparkline is distributed under a BSD License. See LICENSE for details.
+ *
+ * $Id: Sparkline_Bar.php,v 1.2 2004/11/09 06:18:52 jbyers Exp $
+ *
+ */
+
+require_once('Sparkline.php');
+
+class Sparkline_Bar extends Sparkline {
+
+ var $dataSeries;
+ var $dataSeriesStats;
+ var $dataSeriesConverted;
+ var $yMin;
+ var $yMax;
+ var $barWidth;
+ var $barSpacing;
+ var $barColorDefault;
+ var $barColorUnderscoreDefault;
+
+ ////////////////////////////////////////////////////////////////////////////
+ // constructor
+ //
+ function Sparkline_Bar($catch_errors = true) {
+ parent::Sparkline($catch_errors);
+
+ $this->dataSeries = array();
+ $this->dataSeriesStats = array();
+ $this->dataSeriesConverted = array();
+ $this->barWidth = 1;
+ $this->barSpacing = 1;
+ $this->barColorDefault = 'black';
+ $this->barColorUnderscoreDefault = 'black';
+ } // function Sparkline
+
+ ////////////////////////////////////////////////////////////////////////////
+ // color, image property setting
+ //
+ function SetBarWidth($value) {
+ $this->Debug("Sparkline_Bar :: SetBarWidth($value)", DEBUG_SET);
+ $this->barWidth = $value;
+ } // function SetBarWidth
+
+ function SetBarSpacing($value) {
+ $this->Debug("Sparkline_Bar :: SetBarSpacing($value)", DEBUG_SET);
+ $this->barSpacing = $value;
+ } // function SetBarSpacing
+
+ function SetBarColorDefault($value) {
+ $this->Debug("Sparkline_Bar :: SetBarColorDefault($value)", DEBUG_SET);
+ $this->barColorDefault = $value;
+ } // function SetBarColorDefault
+
+ function SetBarColorUnderscoreDefault($value) {
+ $this->Debug("Sparkline_Bar :: SetBarColorUnderscoreDefault($value)", DEBUG_SET);
+ $this->barColorUnderscoreDefault = $value;
+ } // function SetBarColorUnderscoreDefault
+
+ ////////////////////////////////////////////////////////////////////////////
+ // data setting
+ //
+ function SetData($x, $y, $color = null, $underscore = false, $series = 1) {
+ $x = trim($x);
+ $y = trim($y);
+
+ $this->Debug("Sparkline_Bar :: SetData($x, $y, $series)", DEBUG_SET);
+
+ if (!is_numeric($x) ||
+ !is_numeric($y)) {
+ $this->Debug("Sparkline_Bar :: SetData rejected values($x, $y) in series $series", DEBUG_WARNING);
+ return false;
+ } // if
+
+ if ($color == null) {
+ $color = $this->barColorDefault;
+ }
+
+ $this->dataSeries[$series][$x] = array('value' => $y,
+ 'color' => $color,
+ 'underscore' => $underscore);
+
+ if (!isset($this->dataSeriesStats[$series]['min']) ||
+ $y < $this->dataSeriesStats[$series]['min']) {
+ $this->dataSeriesStats[$series]['min'] = $y;
+ }
+
+ if (!isset($this->dataSeriesStats[$series]['max']) ||
+ abs($y) > $this->dataSeriesStats[$series]['max']) {
+ $this->dataSeriesStats[$series]['max'] = abs($y);
+ }
+ } // function SetData
+
+ function SetYMin($value) {
+ $this->Debug("Sparkline_Bar :: SetYMin($value)", DEBUG_SET);
+ $this->yMin = $value;
+ }
+
+ function SetYMax($value) {
+ $this->Debug("Sparkline_Bar :: SetYMax($value)", DEBUG_SET);
+ $this->yMax = $value;
+ }
+
+ function ConvertDataSeries($series, $xBound, $yBound) {
+ $this->Debug("Sparkline_Bar :: ConvertDataSeries($series, $xBound, $yBound)", DEBUG_CALLS);
+
+ if (!isset($this->yMin)) {
+ $this->yMin = $this->dataSeriesStats[$series]['min'];
+ }
+
+ if (!isset($this->yMax)) {
+ $this->yMax = $this->dataSeriesStats[$series]['max'];
+ }
+
+ while (list(, $v) = each($this->dataSeries[$series])) {
+ $y = floor($v['value'] * ($yBound / (abs($this->yMax) + abs($this->yMin))));
+ $this->dataSeriesConverted[$series][] = array('value' => $y,
+ 'color' => $v['color'],
+ 'underscore' => $v['underscore']);
+
+ if (!isset($this->dataSeriesStats[$series]['min_converted']) ||
+ $y < $this->dataSeriesStats[$series]['min_converted']) {
+ $this->dataSeriesStats[$series]['min_converted'] = $y;
+ }
+
+ if (!isset($this->dataSeriesStats[$series]['max_converted']) ||
+ abs($y) > $this->dataSeriesStats[$series]['max_converted']) {
+ $this->dataSeriesStats[$series]['max_converted'] = abs($y);
+ }
+ }
+ reset($this->dataSeries[$series]);
+
+ } // function ConvertDataSeries
+
+ function CalculateImageWidth() {
+ $this->Debug("Sparkline_Bar :: CalculateImageWidth()", DEBUG_CALLS);
+
+ $count = sizeof($this->dataSeries[1]);
+ return (($count - 1) * $this->barSpacing) + ($count * $this->barWidth);
+ } // function CalculateImageWidth
+
+ ////////////////////////////////////////////////////////////////////////////
+ // rendering
+ //
+ function Render($y) {
+ $this->Debug("Sparkline_Bar :: Render($y)", DEBUG_CALLS);
+
+ // calculate size based on sets for init
+ //
+ if (!parent::Init($this->CalculateImageWidth(), $y)) {
+ return false;
+ }
+
+ // convert based on actual canvas size
+ //
+ $this->ConvertDataSeries(1, $this->GetGraphWidth(), $this->GetGraphHeight());
+
+ // stats debugging
+ //
+ $this->Debug('Sparkline_Bar :: Draw' .
+ ' series: 1 min: ' . $this->dataSeriesStats[1]['min'] .
+ ' max: ' . $this->dataSeriesStats[1]['max'] .
+ ' height: ' . $this->GetGraphHeight() .
+ ' yfactor: ' . ($this->GetGraphHeight() / (abs($this->dataSeriesStats[1]['max']) + abs($this->dataSeriesStats[1]['min']))));
+
+ $this->DrawBackground();
+
+ $yAxis = abs(min($this->dataSeriesStats[1]['min_converted'], 0));
+ for ($i = 0; $i < sizeof($this->dataSeriesConverted[1]); $i++) {
+ $this->DrawRectangleFilled($i * ($this->barWidth + $this->barSpacing),
+ $yAxis,
+ $i * ($this->barWidth + $this->barSpacing) + $this->barWidth - 1,
+ $yAxis + $this->dataSeriesConverted[1][$i]['value'],
+ $this->dataSeriesConverted[1][$i]['color']);
+ if ($this->dataSeriesConverted[1][$i]['underscore']) {
+ $this->DrawLine(max(0, $i * ($this->barWidth + $this->barSpacing) - ($this->barSpacing / 2)),
+ $yAxis,
+ min($this->GetGraphWidth(), $i * ($this->barWidth + $this->barSpacing) + ($this->barSpacing / 2)),
+ $yAxis,
+ $this->barColorUnderscoreDefault);
+ }
+ }
+ } // function Render
+} // class Sparkline_Bar
+
+?>
Added: trunk/libs/sparkline/lib/Sparkline_Line.php
===================================================================
--- trunk/libs/sparkline/lib/Sparkline_Line.php (rev 0)
+++ trunk/libs/sparkline/lib/Sparkline_Line.php 2008-01-20 06:57:20 UTC (rev 208)
@@ -0,0 +1,279 @@
+<?php
+/*
+ * Sparkline PHP Graphing Library
+ * Copyright 2004 James Byers <jbyers at users.sf.net>
+ * http://sparkline.org
+ *
+ * Sparkline is distributed under a BSD License. See LICENSE for details.
+ *
+ * $Id: Sparkline_Line.php,v 1.7 2005/01/06 02:40:46 jbyers Exp $
+ *
+ */
+
+require_once('Sparkline.php');
+
+class Sparkline_Line extends Sparkline {
+
+ var $dataSeries;
+ var $dataSeriesStats;
+ var $dataSeriesConverted;
+ var $yMin;
+ var $yMax;
+ var $featurePoint;
+
+ ////////////////////////////////////////////////////////////////////////////
+ // constructor
+ //
+ function Sparkline_Line($catch_errors = true) {
+ parent::Sparkline($catch_errors);
+
+ $this->dataSeries = array();
+ $this->dataSeriesStats = array();
+ $this->dataSeriesConverted = array();
+
+ $this->featurePoint = array();
+ } // function Sparkline
+
+ ////////////////////////////////////////////////////////////////////////////
+ // data setting
+ //
+ function SetData($x, $y, $series = 1) {
+ $x = trim($x);
+ $y = trim($y);
+
+ $this->Debug("Sparkline_Line :: SetData($x, $y, $series)", DEBUG_SET);
+
+ if (!is_numeric($x) ||
+ !is_numeric($y)) {
+ $this->Debug("Sparkline_Line :: SetData rejected values($x, $y) in series $series", DEBUG_WARNING);
+ return false;
+ } // if
+
+ $this->dataSeries[$series][$x] = $y;
+
+ if (!isset($this->dataSeriesStats[$series]['yMin']) ||
+ $y < $this->dataSeriesStats[$series]['yMin']) {
+ $this->dataSeriesStats[$series]['yMin'] = $y;
+ }
+
+ if (!isset($this->dataSeriesStats[$series]['xMin']) ||
+ $x < $this->dataSeriesStats[$series]['xMin']) {
+ $this->dataSeriesStats[$series]['xMin'] = $x;
+ }
+
+ if (!isset($this->dataSeriesStats[$series]['yMax']) ||
+ $y > $this->dataSeriesStats[$series]['yMax']) {
+ $this->dataSeriesStats[$series]['yMax'] = $y;
+ }
+
+ if (!isset($this->dataSeriesStats[$series]['xMax']) ||
+ $x > $this->dataSeriesStats[$series]['xMax']) {
+ $this->dataSeriesStats[$series]['xMax'] = $x;
+ }
+ } // function SetData
+
+ function SetYMin($value) {
+ $this->Debug("Sparkline_Line :: SetYMin($value)", DEBUG_SET);
+ $this->yMin = $value;
+ } // function SetYMin
+
+ function SetYMax($value) {
+ $this->Debug("Sparkline_Line :: SetYMax($value)", DEBUG_SET);
+ $this->yMax = $value;
+ } // function SetYMin
+
+ function ConvertDataSeries($series, $xBound, $yBound) {
+ $this->Debug("Sparkline_Line :: ConvertDataSeries($series, $xBound, $yBound)", DEBUG_CALLS);
+
+ if (!isset($this->yMin)) {
+ $this->yMin = $this->dataSeriesStats[$series]['yMin'];
+ }
+
+ if (!isset($this->yMin)) {
+ $this->xMin = $this->dataSeriesStats[$series]['XMin'];
+ }
+
+ if (!isset($this->yMax)) {
+ $this->yMax = $this->dataSeriesStats[$series]['yMax'] + ($this->yMin * -1);
+ }
+
+ if (!isset($this->xMax)) {
+ $this->xMax = $this->dataSeriesStats[$series]['xMax'];
+ }
+
+ for ($i = 0; $i < sizeof($this->dataSeries[$series]); $i ++) {
+ $y = round(($this->dataSeries[$series][$i] + ($this->yMin * -1)) * ($yBound / $this->yMax));
+ $x = round($i * $xBound / sizeof($this->dataSeries[$series]));
+ $this->dataSeriesConverted[$series][] = array($x, $y);
+ $this->Debug("Sparkline :: ConvertDataSeries series $series value $i ($x, $y)", DEBUG_SET);
+ }
+ } // function ConvertDataSeries
+
+ ////////////////////////////////////////////////////////////////////////////
+ // features
+ //
+ function SetFeaturePoint($x, $y, $color, $diameter, $text = '', $position = TEXT_TOP, $font = FONT_1) {
+ $this->Debug("Sparkline_Line :: SetFeaturePoint($x, $y, '$color', $diameter, '$text')", DEBUG_CALLS);
+
+ $this->featurePoint[] = array('ptX' => $x,
+ 'ptY' => $y,
+ 'color' => $color,
+ 'diameter' => $diameter,
+ 'text' => $text,
+ 'textpos' => $position,
+ 'font' => $font);
+ } // function SetFeaturePoint
+
+ ////////////////////////////////////////////////////////////////////////////
+ // low quality rendering
+ //
+ function Render($x, $y) {
+ $this->Debug("Sparkline_Line :: Render($x, $y)", DEBUG_CALLS);
+
+ if (!parent::Init($x, $y)) {
+ return false;
+ }
+
+ // convert based on graphAreaPx bounds
+ //
+ $this->ConvertDataSeries(1, $this->GetGraphWidth(), $this->GetGraphHeight());
+
+ // stats debugging
+ //
+ $this->Debug('Sparkline_Line :: Draw' .
+ ' series: 1 min: ' . $this->dataSeriesStats[1]['yMin'] .
+ ' max: ' . $this->dataSeriesStats[1]['yMax'] .
+ ' offset: ' . ($this->dataSeriesStats[1]['yMin'] * -1) .
+ ' height: ' . $this->GetGraphHeight() + 1 .
+ ' yfactor: ' . ($this->GetGraphHeight() / ($this->dataSeriesStats[1]['yMax'] + ($this->dataSeriesStats[1]['yMin'] * -1))));
+ $this->Debug('Sparkline_Line :: Draw' .
+ ' drawing area:' .
+ ' (' . $this->graphAreaPx[0][0] . ',' . $this->graphAreaPx[0][1] . '), ' .
+ ' (' . $this->graphAreaPx[1][0] . ',' . $this->graphAreaPx[1][1] . ')');
+
+ $this->DrawBackground();
+
+ // draw graph
+ //
+ for ($i = 0; $i < sizeof($this->dataSeriesConverted[1]) - 1; $i++) {
+// $this->DrawLine($this->dataSeriesConverted[1][$i][0] + $this->graphAreaPx[0][0],
+// $this->dataSeriesConverted[1][$i][1] + $this->graphAreaPx[0][1],
+// $this->dataSeriesConverted[1][$i+1][0] + $this->graphAreaPx[0][0],
+// $this->dataSeriesConverted[1][$i+1][1] + $this->graphAreaPx[0][1],
+// 'black');
+ }
+
+ // draw features
+ //
+ while (list(, $v) = each($this->featurePoint)) {
+ $pxY = round(($v['ptY'] + ($this->yMin * -1)) * ($this->GetGraphHeight() / $this->yMax));
+ $pxX = round($v['ptX'] * $this->GetGraphWidth() / $this->dataSeriesStats[1]['xMax']);
+
+ $this->DrawCircleFilled($pxX + $this->graphAreaPx[0][0],
+ $pxY + $this->graphAreaPx[0][1],
+ $v['diameter'],
+ $v['color'],
+ $this->imageHandle);
+ $this->DrawTextRelative($v['text'],
+ $pxX + $this->graphAreaPx[0][0],
+ $pxY + $this->graphAreaPx[0][1],
+ $v['color'],
+ $v['textpos'],
+ round($v['diameter'] / 2),
+ $v['font'],
+ $this->imageHandle);
+ }
+ } // function Render
+
+ ////////////////////////////////////////////////////////////////////////////
+ // high quality rendering
+ //
+ function RenderResampled($x, $y, $colorLineName = 'black') {
+ $this->Debug("Sparkline_Line :: RenderResampled($x, $y)", DEBUG_CALLS);
+
+ if (!parent::Init($x, $y)) {
+ return false;
+ }
+
+ // draw background on standard image in case of resample blit miss
+ //
+ $this->DrawBackground($this->imageHandle);
+
+ // convert based on virtual canvas: x based on size of dataset, y scaled proportionately
+ // if size of data set is small, default to 4X target canvas size
+ //
+ $xVC = max(sizeof($this->dataSeries[1]), 4 * $x);
+ $yVC = floor($xVC * ($this->GetGraphHeight() / $this->GetGraphWidth()));
+ $this->ConvertDataSeries(1, $xVC, $yVC);
+
+ // stats debugging
+ //
+ $this->Debug('Sparkline_Line :: DrawResampled' .
+ ' series: 1 min: ' . $this->dataSeriesStats[1]['yMin'] .
+ ' max: ' . $this->dataSeriesStats[1]['yMax'] .
+ ' offset: ' . ($this->dataSeriesStats[1]['yMin'] * -1) .
+ ' height: ' . $this->GetGraphHeight() .
+ ' yfactor: ' . ($this->GetGraphHeight() / ($this->dataSeriesStats[1]['yMax'] + ($this->dataSeriesStats[1]['yMin'] * -1))), DEBUG_STATS);
+ $this->Debug('Sparkline_Line :: DrawResampled' .
+ ' drawing area:' .
+ ' (' . $this->graphAreaPx[0][0] . ',' . $this->graphAreaPx[0][1] . '), ' .
+ ' (' . $this->graphAreaPx[1][0] . ',' . $this->graphAreaPx[1][1] . ')');
+
+ // create virtual image
+ // allocate colors
+ // draw background, graph
+ // resample and blit onto original graph
+ //
+ $imageVCHandle = $this->CreateImageHandle($xVC, $yVC);
+
+ while (list($k, $v) = each($this->colorList)) {
+ $this->SetColorHandle($k, $this->DrawColorAllocate($k, $imageVCHandle));
+ }
+ reset($this->colorList);
+
+ $this->DrawBackground($imageVCHandle);
+
+ for ($i = 0; $i < sizeof($this->dataSeriesConverted[1]) - 1; $i++) {
+ $this->DrawLine($this->dataSeriesConverted[1][$i][0],
+ $this->dataSeriesConverted[1][$i][1],
+ $this->dataSeriesConverted[1][$i+1][0],
+ $this->dataSeriesConverted[1][$i+1][1],
+ $colorLineName,
+ $this->GetLineSize(),
+ $imageVCHandle);
+ }
+
+ $this->DrawImageCopyResampled($this->imageHandle,
+ $imageVCHandle,
+ $this->graphAreaPx[0][0], // dest x
+ $this->GetImageHeight() - $this->graphAreaPx[1][1], // dest y
+ 0, 0, // src x, y
+ $this->GetGraphWidth(), // dest width
+ $this->GetGraphHeight(), // dest height
+ $xVC, // src width
+ $yVC); // src height
+
+ // draw features
+ //
+ while (list(, $v) = each($this->featurePoint)) {
+ $pxY = round(($v['ptY'] + ($this->yMin * -1)) * ($this->GetGraphHeight() / $this->yMax));
+ $pxX = round($v['ptX'] * $this->GetGraphWidth() / $this->dataSeriesStats[1]['xMax']);
+
+ $this->DrawCircleFilled($pxX + $this->graphAreaPx[0][0],
+ $pxY + $this->graphAreaPx[0][1],
+ $v['diameter'],
+ $v['color'],
+ $this->imageHandle);
+ $this->DrawTextRelative($v['text'],
+ $pxX + $this->graphAreaPx[0][0],
+ $pxY + $this->graphAreaPx[0][1],
+ $v['color'],
+ $v['textpos'],
+ round($v['diameter'] / 2),
+ $v['font'],
+ $this->imageHandle);
+ }
+ } // function RenderResampled
+} // class Sparkline_Line
+
+?>
Modified: trunk/modules/ViewDataTable/GenerateGraphData.php
===================================================================
--- trunk/modules/ViewDataTable/GenerateGraphData.php 2008-01-20 04:19:48 UTC (rev 207)
+++ trunk/modules/ViewDataTable/GenerateGraphData.php 2008-01-20 06:57:20 UTC (rev 208)
@@ -110,29 +110,7 @@
protected function generateDataFromDataTable()
{
- // we have to fill a $data array with each row = array('label' => X, 'value' => y)
-
- $data = array();
- foreach($this->dataTable->getArray() as $keyName => $table)
- {
- $value = false;
-
- $onlyRow = $table->getRowFromId(0);
- if($onlyRow !== false)
- {
- $value = $onlyRow->getColumn('value');
- }
-
- if($value === false)
- {
- $value = 0;
- }
- $data[] = array(
- 'label' => $keyName,
- 'value' => $value
- );
- }
- return $data;
+ return $this->generateDataFromDataTableArray($this->dataTable);
}
}
/**
Modified: trunk/modules/ViewDataTable/Graph.php
===================================================================
--- trunk/modules/ViewDataTable/Graph.php 2008-01-20 04:19:48 UTC (rev 207)
+++ trunk/modules/ViewDataTable/Graph.php 2008-01-20 06:57:20 UTC (rev 208)
@@ -64,7 +64,7 @@
//TODO change $use_swfobject = true
public function getFlashInvocationCode(
$url = 'libs/open-flash-chart/data-files/nodata.txt',
- $use_swfobject = false )
+ $use_swfobject = true )
{
$width = $this->width;
$height = $this->height;
@@ -82,8 +82,7 @@
// I think we may use swfobject for all browsers, not JUST for IE...
//
//$ie = strstr(getenv('HTTP_USER_AGENT'), 'MSIE');
-
-
+
$return = '';
if( $use_swfobject )
{
@@ -91,7 +90,7 @@
$return .= '
<div id="'. $div_name .'"></div>
<script type="text/javascript">
- var so = new SWFObject("'.$pathToLibraryOpenChart.'open-flash-chart.swf", "chart", "'. $width . '", "' . $height . '", "9", "#FFFFFF");
+ var so = new SWFObject("'.$pathToLibraryOpenChart.'open-flash-chart.swf", "'.$obj_id.'_swf", "'. $width . '", "' . $height . '", "9", "#FFFFFF");
so.addVariable("data", "'. $url . '");
so.addParam("allowScriptAccess", "sameDomain");
so.write("'. $div_name .'");
Added: trunk/modules/ViewDataTable/Sparkline.php
===================================================================
--- trunk/modules/ViewDataTable/Sparkline.php (rev 0)
+++ trunk/modules/ViewDataTable/Sparkline.php 2008-01-20 06:57:20 UTC (rev 208)
@@ -0,0 +1,113 @@
+<?php
+class Piwik_ViewDataTable_Sparkline extends Piwik_ViewDataTable
+{
+
+ function init($currentControllerName,
+ $currentControllerAction,
+ $moduleNameAndMethod )
+ {
+ parent::init($currentControllerName,
+ $currentControllerAction,
+ $moduleNameAndMethod );
+ }
+ public function main()
+ {
+ if($this->mainAlreadyExecuted)
+ {
+ return;
+ }
+ $this->mainAlreadyExecuted = true;
+
+ // we load the data with the filters applied
+ $this->loadDataTableFromAPI();
+
+ $this->dataAvailable = $this->dataTable->getRowsCount() != 0;
+
+ if(!$this->dataAvailable)
+ {
+ $this->view->title("No data for this graph", '{font-size: 25px;}');
+ }
+ else
+ {
+ $data = $this->generateDataFromDataTableArray($this->dataTable);
+
+ $graph = new Piwik_Sparkline_Graph;
+ $graph->setData($data);
+ $graph->main();
+// var_dump($data);
+ $this->view = $graph;
+ }
+ }
+
+}
+
+require_once 'sparkline/lib/Sparkline_Line.php';
+
+class Piwik_Sparkline_Graph
+{
+ function setData($data)
+ {
+ $this->data = $data;
+ }
+
+ function main()
+ {
+ $data = $this->data;
+ $sparkline = new Sparkline_Line();
+
+// $sparkline->SetColorHtml('lineColor', '000000');
+ $sparkline->SetColor('lineColor', 0,0,0);
+ $sparkline->SetColorHtml('red', '#FF7F7F');
+ $sparkline->SetColorHtml('blue', '#55AAFF');
+ $sparkline->SetColorHtml('green', '#75BF7C');
+ $sparkline->SetDebugLevel(DEBUG_NONE);
+// $sparkline->SetDebugLevel(DEBUG_ERROR | DEBUG_WARNING | DEBUG_STATS | DEBUG_CALLS, '../log.txt');
+
+ $data = array_reverse($data);
+ $min = $max= $last = null;
+ $i = 0;
+ foreach($this->data as $row)
+ {
+
+ $value = $row['value'];
+ $sparkline->SetData($i, $value);
+ if( null == $min || $value <= $min[1])
+ {
+ $min = array($i, $value);
+ }
+
+ if(null == $max || $value >= $max[1])
+ {
+ $max = array($i, $value);
+ }
+
+ $last = array($i, $value);
+
+ $i++;
+ }
+
+ // set y-bound, min and max extent lines
+ //
+ $sparkline->SetYMin(0);
+ $sparkline->SetPadding(2); // setpadding is additive
+ $sparkline->SetPadding(imagefontheight(FONT_2),
+ imagefontwidth(FONT_2) * strlen(" $last[1]"),
+ 0, //imagefontheight(FONT_2),
+ 0);
+ $sparkline->SetFeaturePoint($min[0]-1,$min[1]+2,'red', 5, $min[1], TEXT_TOP,FONT_2);
+ $sparkline->SetFeaturePoint($max[0]-1,$max[1],'green', 5, $max[1], TEXT_TOP,FONT_2);
+ $sparkline->SetFeaturePoint($last[0]-1, $last[1], 'blue',5, " $last[1]", TEXT_RIGHT,FONT_2);
+
+ $sparkline->SetLineSize(3); // for renderresampled, linesize is on virtual image
+ $sparkline->RenderResampled(130, 30, 'black');
+
+ $this->sparkline = $sparkline;
+ }
+
+ function render()
+ {
+ $this->sparkline->Output();
+ }
+}
+
+?>
\ No newline at end of file
Modified: trunk/modules/ViewDataTable.php
===================================================================
--- trunk/modules/ViewDataTable.php 2008-01-20 04:19:48 UTC (rev 207)
+++ trunk/modules/ViewDataTable.php 2008-01-20 06:57:20 UTC (rev 208)
@@ -72,6 +72,11 @@
case 'graphEvolution':
require_once "ViewDataTable/Graph.php";
return new Piwik_ViewDataTable_Graph_ChartEvolution();
+ break;
+
+ case 'sparkline':
+ require_once "ViewDataTable/Sparkline.php";
+ return new Piwik_ViewDataTable_Sparkline();
break;
case 'generateDataChartVerticalBar':
@@ -133,6 +138,36 @@
*/
public function __call($function, $args)
{
+ }
+
+
+
+ // given a DataTable_Array made of DataTable_Simple
+ // returns PHP array containing rows of array( label => X, value => Y)
+ protected function generateDataFromDataTableArray( $dataTableArray)
+ {
+ // we have to fill a $data array with each row = array('label' => X, 'value' => y)
+ $data = array();
+ foreach($dataTableArray->getArray() as $keyName => $table)
+ {
+ $value = false;
+
+ $onlyRow = $table->getRowFromId(0);
+ if($onlyRow !== false)
+ {
+ $value = $onlyRow->getColumn('value');
+ }
+
+ if($value === false)
+ {
+ $value = 0;
+ }
+ $data[] = array(
+ 'label' => $keyName,
+ 'value' => $value
+ );
+ }
+ return $data;
}
public function getView()
Modified: trunk/plugins/Home/Controller.php
===================================================================
--- trunk/plugins/Home/Controller.php 2008-01-20 04:19:48 UTC (rev 207)
+++ trunk/plugins/Home/Controller.php 2008-01-20 06:57:20 UTC (rev 208)
@@ -41,6 +41,57 @@
echo $view->render();
}
+ function getUrlSparkline( $action )
+ {
+ $params = array('action' => $action, 'date' => 'last30', 'viewDataTable' => 'sparkline');
+ $url = Piwik_Url::getCurrentQueryStringWithParametersModified($params);
+ return $url;
+ }
+
+ function getLastUnitGraph($currentControllerAction, $apiMethod)
+ {
+ require_once "ViewDataTable/Graph.php";
+ $view = Piwik_ViewDataTable::factory(null, 'graphEvolution');
+ $view->init( $this->currentControllerName, $currentControllerAction, $apiMethod );
+ return $view;
+ }
+
+ function getLastVisitsGraph( $fetch = false )
+ {
+ $view = $this->getLastUnitGraph(__FUNCTION__, "VisitsSummary.getVisits");
+ return $this->renderView($view, $fetch);
+ }
+
+ function getLastUniqueVisitorsGraph( $fetch = false )
+ {
+ $view = $this->getLastUnitGraph(__FUNCTION__, "VisitsSummary.getUniqueVisitors");
+ return $this->renderView($view, $fetch);
+ }
+
+ function getLastActionsGraph( $fetch = false )
+ {
+ $view = $this->getLastUnitGraph(__FUNCTION__, "VisitsSummary.getActions");
+ return $this->renderView($view, $fetch);
+ }
+
+ function getLastSumVisitsLengthGraph( $fetch = false )
+ {
+ $view = $this->getLastUnitGraph(__FUNCTION__, "VisitsSummary.getSumVisitsLength");
+ return $this->renderView($view, $fetch);
+ }
+
+ function getLastMaxActionsGraph( $fetch = false )
+ {
+ $view = $this->getLastUnitGraph(__FUNCTION__, "VisitsSummary.getMaxActions");
+ return $this->renderView($view, $fetch);
+ }
+
+ function getLastBounceCountGraph( $fetch = false )
+ {
+ $view = $this->getLastUnitGraph(__FUNCTION__, "VisitsSummary.getBounceCount");
+ return $this->renderView($view, $fetch);
+ }
+
function index()
{
$view = new Piwik_View('Home/templates/index.tpl');
@@ -70,6 +121,14 @@
/* General visits */
$view->graphLastVisits = $this->getLastVisitsGraph( true );
+ $view->urlSparklineNbVisits = $this->getUrlSparkline( 'getLastVisitsGraph');
+ $view->urlSparklineNbUniqVisitors = $this->getUrlSparkline( 'getLastUniqueVisitorsGraph');
+ $view->urlSparklineNbActions = $this->getUrlSparkline( 'getLastActionsGraph');
+ $view->urlSparklineSumVisitLength = $this->getUrlSparkline( 'getLastSumVisitsLengthGraph');
+ $view->urlSparklineMaxActions = $this->getUrlSparkline( 'getLastMaxActionsGraph');
+ $view->urlSparklineBounceCount = $this->getUrlSparkline( 'getLastBounceCountGraph');
+
+
$dataTableVisit = $this->getVisitsSummary();
$view->nbUniqVisitors = $dataTableVisit->getColumn('nb_uniq_visitors');
$view->nbVisits = $dataTableVisit->getColumn('nb_visits');
@@ -312,14 +371,7 @@
$request = new Piwik_API_Request($requestString);
return $request->process();
}
-
- function getLastVisitsGraph( $fetch = false )
- {
- require_once "ViewDataTable/Graph.php";
- $view = Piwik_ViewDataTable::factory(null, 'graphEvolution');
- $view->init( $this->currentControllerName, __FUNCTION__, "VisitsSummary.getVisits" );
- return $this->renderView($view, $fetch);
- }
+
function getLastDistinctKeywordsGraph( $fetch = false )
{
require_once "ViewDataTable/Graph.php";
Modified: trunk/plugins/Home/templates/datatable.css
===================================================================
--- trunk/plugins/Home/templates/datatable.css 2008-01-20 04:19:48 UTC (rev 207)
+++ trunk/plugins/Home/templates/datatable.css 2008-01-20 06:57:20 UTC (rev 208)
@@ -193,7 +193,7 @@
#loadingDataTable {
font-size: 1em;
- font-decoration:bold;
+ font-weight:bold;
color:#193B6C;
padding:0.5em;
}
\ No newline at end of file
Modified: trunk/plugins/Home/templates/index.tpl
===================================================================
--- trunk/plugins/Home/templates/index.tpl 2008-01-20 04:19:48 UTC (rev 207)
+++ trunk/plugins/Home/templates/index.tpl 2008-01-20 06:57:20 UTC (rev 208)
@@ -206,14 +206,35 @@
{$graphLastVisits}
<h3>Report</h3>
- <p>{$nbUniqVisitors} unique visitors</p>
- <p>{$nbVisits} visits</p>
- <p>{$nbActions} actions (page views)</p>
- <p>{$sumVisitLength|sumtime} total time spent by the visitors</p>
- <p>{$maxActions} max actions</p>
- <p>{$bounceCount} visitors have bounced (left the site directly)</p>
+ {literal}
+<script type="text/javascript">
+ function findSWF(movieName) {
+ if (navigator.appName.indexOf("Microsoft")!= -1) {
+ return window[movieName];
+ } else {
+ return document[movieName];
+ }
+}
+function reload()
+{
+ tmp = findSWF("getLastVisitsGraphChart_swf");
+ x = tmp.reload();
+}
+
+</script>
+ {/literal}
+
+ <p><a href="javascript:reload();">test</a>
+ <p><img align="absmiddle" src="{$urlSparklineNbVisits}" /><strong>{$nbVisits} </strong>visits</p>
+ <p><img align="absmiddle" src="{$urlSparklineNbUniqVisitors}" /> <strong>{$nbUniqVisitors}</strong> unique visitors</p>
+ <p><img align="absmiddle" src="{$urlSparklineNbActions}" /> <strong>{$nbActions}</strong> actions (page views)</p>
+ <p><img align="absmiddle" src="{$urlSparklineSumVisitLength}" /> <strong>{$sumVisitLength|sumtime}</strong> total time spent by the visitors</p>
+ <p><img align="absmiddle" src="{$urlSparklineMaxActions}" /> <strong>{$maxActions}</strong> max actions</p>
+ <p><img align="absmiddle" src="{$urlSparklineBounceCount}" /> <strong>{$bounceCount} </strong>visitors have bounced (left the site directly)</p>
+
+
<br><br><br><hr width="300px" align="left">
<p><small>{$totalTimeGeneration} seconds {if $totalNumberOfQueries != 0}/ {$totalNumberOfQueries} queries{/if} to generate the page</p>
</div>
Modified: trunk/plugins/VisitsSummary/API.php
===================================================================
--- trunk/plugins/VisitsSummary/API.php 2008-01-20 04:19:48 UTC (rev 207)
+++ trunk/plugins/VisitsSummary/API.php 2008-01-20 06:57:20 UTC (rev 208)
@@ -60,10 +60,14 @@
{
return $this->getNumeric( $idSite, $period, $date, 'nb_visits');
}
- public function getUniquesVisitors( $idSite, $period, $date )
+ public function getUniqueVisitors( $idSite, $period, $date )
{
return $this->getNumeric( $idSite, $period, $date, 'nb_uniq_visitors');
}
+ public function getActions( $idSite, $period, $date )
+ {
+ return $this->getNumeric( $idSite, $period, $date, 'nb_actions');
+ }
public function getMaxActions( $idSite, $period, $date )
{
return $this->getNumeric( $idSite, $period, $date, 'max_actions');
More information about the Piwik-svn
mailing list