summaryrefslogtreecommitdiffstats
path: root/src/charts
diff options
context:
space:
mode:
authorKore Nordmann <github@kore-nordmann.de>2009-07-14 14:13:45 +0000
committerKore Nordmann <github@kore-nordmann.de>2009-07-14 14:13:45 +0000
commit11e6744455cadf222f828a437e095205da53da7a (patch)
treed85b763feeb930ebc2f29394475241bab0931561 /src/charts
parent8262fb03d006afdc4ea1ea6c21be991178510137 (diff)
downloadzetacomponents-graph-11e6744455cadf222f828a437e095205da53da7a.zip
zetacomponents-graph-11e6744455cadf222f828a437e095205da53da7a.tar.gz
- Implemented: #13341: Vertical Bar Charts
Diffstat (limited to 'src/charts')
-rw-r--r--src/charts/horizontal_bar.php292
-rw-r--r--src/charts/line.php74
2 files changed, 334 insertions, 32 deletions
diff --git a/src/charts/horizontal_bar.php b/src/charts/horizontal_bar.php
new file mode 100644
index 0000000..7e4e4a0
--- /dev/null
+++ b/src/charts/horizontal_bar.php
@@ -0,0 +1,292 @@
+<?php
+/**
+ * File containing the ezcGraphBarChart class
+ *
+ * @package Graph
+ * @version //autogentag//
+ * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
+ * @license http://ez.no/licenses/new_bsd New BSD License
+ */
+/**
+ * Class for bar charts. Can make use of an unlimited amount of datasets and
+ * will display them as bars by default.
+ * X axis:
+ * - Labeled axis
+ * - Boxed axis label renderer
+ * Y axis:
+ * - Numeric axis
+ * - Exact axis label renderer
+ *
+ * <code>
+ * // Create a new horizontal bar chart
+ * $chart = new ezcGraphHorizontalBarChart();
+ *
+ * // Add data to line chart
+ * $chart->data['sample dataset'] = new ezcGraphArrayDataSet(
+ * array(
+ * '100' => 1.2,
+ * '200' => 43.2,
+ * '300' => -34.14,
+ * '350' => 65,
+ * '400' => 123,
+ * )
+ * );
+ *
+ * // Render chart with the special designated renderer and default SVG driver
+ * $chart->renderer = new ezcGraphHorizontalRenderer();
+ * $chart->render( 500, 200, 'bar_chart.svg' );
+ * </code>
+ *
+ * Each chart consists of several chart elements which represents logical
+ * parts of the chart and can be formatted independently. The bar chart
+ * consists of:
+ * - title ( {@link ezcGraphChartElementText} )
+ * - legend ( {@link ezcGraphChartElementLegend} )
+ * - background ( {@link ezcGraphChartElementBackground} )
+ * - xAxis ( {@link ezcGraphChartElementLabeledAxis} )
+ * - yAxis ( {@link ezcGraphChartElementNumericAxis} )
+ *
+ * The type of the axis may be changed and all elements can be configured by
+ * accessing them as properties of the chart:
+ *
+ * <code>
+ * $chart->legend->position = ezcGraph::RIGHT;
+ * </code>
+ *
+ * The chart itself also offers several options to configure the appearance. As
+ * bar charts extend line charts the the extended configure options are
+ * available in {@link ezcGraphLineChartOptions} extending the
+ * {@link ezcGraphChartOptions}.
+ *
+ * @property ezcGraphLineChartOptions $options
+ * Chart options class
+ *
+ * @version //autogentag//
+ * @package Graph
+ * @mainclass
+ */
+class ezcGraphHorizontalBarChart extends ezcGraphBarChart
+{
+ /**
+ * Constructor
+ *
+ * @param array $options Default option array
+ * @return void
+ * @ignore
+ */
+ public function __construct( array $options = array() )
+ {
+ parent::__construct();
+
+ $this->addElement( 'xAxis', new ezcGraphChartElementNumericAxis() );
+ $this->elements['xAxis']->axisLabelRenderer = new ezcGraphAxisCenteredLabelRenderer();
+ $this->elements['xAxis']->position = ezcGraph::LEFT;
+
+ $this->addElement( 'yAxis', new ezcGraphChartElementLabeledAxis() );
+ $this->elements['yAxis']->axisLabelRenderer = new ezcGraphAxisBoxedLabelRenderer();
+ $this->elements['yAxis']->position = ezcGraph::BOTTOM;
+
+ $this->renderer = new ezcGraphHorizontalRenderer();
+ }
+
+ /**
+ * Render the assigned data
+ *
+ * Will renderer all charts data in the remaining boundings after drawing
+ * all other chart elements. The data will be rendered depending on the
+ * settings in the dataset.
+ *
+ * @param ezcGraphRenderer $renderer Renderer
+ * @param ezcGraphBoundings $boundings Remaining boundings
+ * @return void
+ */
+ protected function renderData( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings, ezcGraphBoundings $innerBoundings )
+ {
+ // Use inner boundings for drawning chart data
+ $boundings = $innerBoundings;
+
+ $yAxisNullPosition = $this->elements['xAxis']->getCoordinate( false );
+
+ // Initialize counters
+ $nr = array();
+ $count = array();
+
+ foreach ( $this->data as $data )
+ {
+ if ( !isset( $nr[$data->displayType->default] ) )
+ {
+ $nr[$data->displayType->default] = 0;
+ $count[$data->displayType->default] = 0;
+ }
+
+ $nr[$data->displayType->default]++;
+ $count[$data->displayType->default]++;
+ }
+
+ $checkedRegularSteps = false;
+
+ // Display data
+ foreach ( $this->data as $datasetName => $data )
+ {
+ --$nr[$data->displayType->default];
+
+ // Check which axis should be used
+ $xAxis = ( $data->xAxis->default ? $data->xAxis->default: $this->elements['xAxis'] );
+ $yAxis = ( $data->yAxis->default ? $data->yAxis->default: $this->elements['yAxis'] );
+
+ // Determine fill color for dataset
+ if ( $this->options->fillLines !== false )
+ {
+ $fillColor = clone $data->color->default;
+ $fillColor->alpha = (int) round( ( 255 - $fillColor->alpha ) * ( $this->options->fillLines / 255 ) );
+ }
+ else
+ {
+ $fillColor = null;
+ }
+
+ // Ensure regular steps on axis when used with bar charts and
+ // precalculate some values use to render bar charts
+ //
+ // Called only once and only when bars should be rendered
+ if ( ( $checkedRegularSteps === false ) &&
+ ( $data->displayType->default === ezcGraph::BAR ) )
+ {
+ $height = $this->calculateStepWidth( $yAxis, $xAxis, $boundings->height )->y;
+ }
+
+ // Draw lines for dataset
+ $lastPoint = false;
+ foreach ( $data as $key => $value )
+ {
+ // Calculate point in chart
+ $point = $xAxis->axisLabelRenderer->modifyChartDataPosition(
+ $yAxis->axisLabelRenderer->modifyChartDataPosition(
+ new ezcGraphCoordinate(
+ $xAxis->getCoordinate( $value ),
+ $yAxis->getCoordinate( $key )
+ )
+ )
+ );
+
+ // Render depending on display type of dataset
+ switch ( true )
+ {
+ case $data->displayType->default === ezcGraph::BAR:
+ $renderer->drawHorizontalBar(
+ $boundings,
+ new ezcGraphContext( $datasetName, $key, $data->url[$key] ),
+ $data->color[$key],
+ $point,
+ $height,
+ $nr[$data->displayType->default],
+ $count[$data->displayType->default],
+ $data->symbol[$key],
+ $yAxisNullPosition
+ );
+
+ // Render highlight string if requested
+ if ( $data->highlight[$key] )
+ {
+ $renderer->drawDataHighlightText(
+ $boundings,
+ new ezcGraphContext( $datasetName, $key, $data->url[$key] ),
+ $point,
+ $yAxisNullPosition,
+ $nr[$data->displayType->default],
+ $count[$data->displayType->default],
+ $this->options->highlightFont,
+ ( $data->highlightValue[$key] ? $data->highlightValue[$key] : $value ),
+ $this->options->highlightSize + $this->options->highlightFont->padding * 2,
+ ( $this->options->highlightLines ? $data->color[$key] : null ),
+ ( $this->options->highlightXOffset ? $this->options->highlightXOffset : 0 ),
+ ( $this->options->highlightYOffset ? $this->options->highlightYOffset : 0 ),
+ $height,
+ $data->displayType->default
+ );
+ }
+ break;
+ default:
+ throw new ezcGraphInvalidDisplayTypeException( $data->displayType->default );
+ break;
+ }
+
+ // Store last point, used to connect lines in line chart.
+ $lastPoint = $point;
+ }
+ }
+ }
+
+ /**
+ * Aggregate and calculate value boundings on axis.
+ *
+ * This function is nearly the same as in ezcGraphLineChart, but reverses
+ * the usage of keys and values for the axis.
+ *
+ * @return void
+ */
+ protected function setAxisValues()
+ {
+ // Virtual data set build for agrregated values sums for bar charts
+ $virtualBarSumDataSet = array( array(), array() );
+
+ // Calculate axis scaling and labeling
+ foreach ( $this->data as $dataset )
+ {
+ $nr = 0;
+ $labels = array();
+ $values = array();
+ foreach ( $dataset as $label => $value )
+ {
+ $labels[] = $label;
+ $values[] = $value;
+
+ // Build sum of all bars
+ if ( $this->options->stackBars &&
+ ( $dataset->displayType->default === ezcGraph::BAR ) )
+ {
+ if ( !isset( $virtualBarSumDataSet[(int) $value >= 0][$nr] ) )
+ {
+ $virtualBarSumDataSet[(int) $value >= 0][$nr++] = $value;
+ }
+ else
+ {
+ $virtualBarSumDataSet[(int) $value >= 0][$nr++] += $value;
+ }
+ }
+ }
+
+ // Check if data has been associated with another custom axis, use
+ // default axis otherwise.
+ if ( $dataset->xAxis->default )
+ {
+ $dataset->xAxis->default->addData( $values );
+ }
+ else
+ {
+ $this->elements['xAxis']->addData( $values );
+ }
+
+ if ( $dataset->yAxis->default )
+ {
+ $dataset->yAxis->default->addData( array_reverse( $labels ) );
+ }
+ else
+ {
+ $this->elements['yAxis']->addData( array_reverse( $labels ) );
+ }
+ }
+
+ // There should always be something assigned to the main x and y axis.
+ if ( !$this->elements['xAxis']->initialized ||
+ !$this->elements['yAxis']->initialized )
+ {
+ throw new ezcGraphNoDataException();
+ }
+
+ // Calculate boundings from assigned data
+ $this->elements['xAxis']->calculateAxisBoundings();
+ $this->elements['yAxis']->calculateAxisBoundings();
+ }
+}
+?>
diff --git a/src/charts/line.php b/src/charts/line.php
index 3348920..4c0ba14 100644
--- a/src/charts/line.php
+++ b/src/charts/line.php
@@ -174,6 +174,47 @@ class ezcGraphLineChart extends ezcGraphChart
}
/**
+ * Calculate bar chart step width
+ *
+ * @return void
+ */
+ protected function calculateStepWidth( ezcGraphChartElementAxis $mainAxis, ezcGraphChartElementAxis $secondAxis, $width )
+ {
+ $steps = $mainAxis->getSteps();
+
+ $stepWidth = null;
+ foreach ( $steps as $step )
+ {
+ if ( $stepWidth === null )
+ {
+ $stepWidth = $step->width;
+ }
+ elseif ( $step->width !== $stepWidth )
+ {
+ throw new ezcGraphUnregularStepsException();
+ }
+ }
+
+ $step = reset( $steps );
+ if ( count( $step->childs ) )
+ {
+ // Keep this for BC reasons
+ $barCount = ( $mainAxis->getMajorStepCount() + 1 ) * ( $mainAxis->getMinorStepCount() - 1 );
+ $stepWidth = 1 / $barCount;
+ }
+
+ $checkedRegularSteps = true;
+ return $mainAxis->axisLabelRenderer->modifyChartDataPosition(
+ $secondAxis->axisLabelRenderer->modifyChartDataPosition(
+ new ezcGraphCoordinate(
+ $width * $stepWidth,
+ $width * $stepWidth
+ )
+ )
+ );
+ }
+
+ /**
* Render the assigned data
*
* Will renderer all charts data in the remaining boundings after drawing
@@ -236,38 +277,7 @@ class ezcGraphLineChart extends ezcGraphChart
if ( ( $checkedRegularSteps === false ) &&
( $data->displayType->default === ezcGraph::BAR ) )
{
- $steps = $xAxis->getSteps();
-
- $stepWidth = null;
- foreach ( $steps as $step )
- {
- if ( $stepWidth === null )
- {
- $stepWidth = $step->width;
- }
- elseif ( $step->width !== $stepWidth )
- {
- throw new ezcGraphUnregularStepsException();
- }
- }
-
- $step = reset( $steps );
- if ( count( $step->childs ) )
- {
- // Keep this for BC reasons
- $barCount = ( $xAxis->getMajorStepCount() + 1 ) * ( $xAxis->getMinorStepCount() - 1 );
- $stepWidth = 1 / $barCount;
- }
-
- $checkedRegularSteps = true;
- $width = $xAxis->axisLabelRenderer->modifyChartDataPosition(
- $yAxis->axisLabelRenderer->modifyChartDataPosition(
- new ezcGraphCoordinate(
- ( $boundings->x1 - $boundings->x0 ) * $stepWidth,
- 0
- )
- )
- )->x;
+ $width = $this->calculateStepWidth( $xAxis, $yAxis, $boundings->width )->x;
}
// Draw lines for dataset
OpenPOWER on IntegriCloud