| <?php |
| /** |
| * File containing the ezcGraphBarChart class |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| * @package Graph |
| * @version //autogentag// |
| * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 |
| */ |
| /** |
| * 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(); |
| } |
| } |
| ?> |