/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright 2009 Pentaho Corporation. All rights reserved. */ package org.pentaho.platform.plugin.action.openflashchart.factory; import java.util.ArrayList; import java.util.List; import ofc4j.model.Tooltip; import ofc4j.model.axis.Axis; import ofc4j.model.elements.BarChart; import ofc4j.model.elements.Element; import ofc4j.model.elements.HorizontalBarChart; import ofc4j.model.elements.SketchBarChart; import ofc4j.model.elements.StackedBarChart; import ofc4j.model.elements.BarChart.Style; import ofc4j.model.elements.StackedBarChart.Stack; import ofc4j.model.elements.StackedBarChart.StackKey; import ofc4j.model.elements.StackedBarChart.StackValue; import org.dom4j.Node; public class BarChartFactory extends AbstractChartFactory { // bar related elements private static final String HEIGHT_3D_NODE_LOC = "height-3d"; //$NON-NLS-1$ private static final String FUN_FACTOR_NODE_LOC = "fun-factor"; //$NON-NLS-1$ private static final String IS3D_NODE_LOC = "is-3D"; //$NON-NLS-1$ private static final String ISGLASS_NODE_LOC = "is-glass"; //$NON-NLS-1$ private static final String ISSKETCH_NODE_LOC = "is-sketch"; //$NON-NLS-1$ private static final String ISSTACKED_NODE_LOC = "is-stacked"; //$NON-NLS-1$ private static final String OUTLINE_COLOR_PALETTE_NODE_LOC = "outline-color-palette"; //$NON-NLS-1$ // defaults private static final Style BARCHART_STYLE_DEFAULT = BarChart.Style.NORMAL; private static final int SKETCH_FUNFACTOR_DEFAULT = 5; // bar related members private ArrayList<String> outlineColors = new ArrayList<String>(); private BarChart.Style barchartstyle; private boolean issketch; private Integer sketchBarFunFactor; private Integer threedheight; private StackedBarChart sbc; protected boolean isstacked; @Override public MinMax getRangeMinMax() { if (isstacked) { return new MinMax(0, getStackedMaxRange()); } else { MinMax minmax = super.getRangeMinMax(); if (minmax.min > 0) { minmax.min = 0; } return minmax; } } public Axis setupDomain() { Axis axis = super.setupDomain(); axis.setOffset(true); return axis; } @SuppressWarnings("unchecked") public int getStackedMaxRange() { int maxRange = 0; for (int i = 0; i < sbc.getStackCount(); i++) { int currRange = 0; List<Object> vals = (List<Object>)sbc.getValues().get(i); for (Object val : vals) { currRange += ((StackValue)val).getValue().intValue(); } if (currRange > maxRange) { maxRange = currRange; } } return maxRange; } @Override public void setupStyles() { super.setupStyles(); barchartstyle = BARCHART_STYLE_DEFAULT; // 3d Node temp = chartNode.selectSingleNode(IS3D_NODE_LOC); if (getValue(temp) != null && "true".equals(getValue(temp))) { //$NON-NLS-1$ barchartstyle = BarChart.Style.THREED; // also load 3d height temp = chartNode.selectSingleNode(HEIGHT_3D_NODE_LOC); if (getValue(temp) != null) { threedheight = Integer.parseInt(getValue(temp)); } } // Glass temp = chartNode.selectSingleNode(ISGLASS_NODE_LOC); if (getValue(temp) != null && "true".equals(getValue(temp))) { //$NON-NLS-1$ barchartstyle = BarChart.Style.GLASS; } // Sketch temp = chartNode.selectSingleNode(ISSKETCH_NODE_LOC); if (getValue(temp) != null && "true".equals(getValue(temp))) { //$NON-NLS-1$ issketch = true; // Also load fun factor temp = chartNode.selectSingleNode(FUN_FACTOR_NODE_LOC); if (getValue(temp) != null) { sketchBarFunFactor = Integer.parseInt(getValue(temp)); } else { sketchBarFunFactor = SKETCH_FUNFACTOR_DEFAULT; } } else { issketch = false; } // Stacked temp = chartNode.selectSingleNode(ISSTACKED_NODE_LOC); if (getValue(temp) != null) { isstacked = "true".equals(getValue(temp)); //$NON-NLS-1$ } temp = chartNode.selectSingleNode(OUTLINE_COLOR_PALETTE_NODE_LOC); if (temp != null) { Object[] colorNodes = temp.selectNodes(COLOR_NODE_LOC).toArray(); for (int j = 0; j < colorNodes.length; j++) { outlineColors.add(getValue((Node) colorNodes[j])); } } else { for (int i = 0; i < COLORS_DEFAULT.length; i++) { outlineColors.add(COLORS_DEFAULT[i]); } } } @Override public void createElements() { if (CATEGORY_TYPE.equals(datasetType)) { int columnCount = getColumnCount(); for (int col = 0; col < columnCount; col++) { Element e = null; if (VERTICAL_ORIENTATION.equals(orientation)) { e = getVerticalBarChartFromColumn(col); } else if (HORIZONTAL_ORIENTATION.equals(orientation)) { e = getHorizontalBarChartFromColumn(col); // Fix for BISERVER-3027, incorrect hover tip placement on hbar chart.setTooltip(new Tooltip()); } else { // we've got an invalid orientation // TODO: Log error message } elements.add(e); } } else { // TOOD: Support XY in the future? } } public Element getStackedBarChartFromColumn(int col) { if (sbc == null) { sbc = new StackedBarChart(); // set the onclick event to the base url template if (null != baseURLTemplate) { sbc.setOn_click(baseURLTemplate); } if (alpha != null) { sbc.setAlpha(alpha); } } StackKey key = new StackKey(); String text = getColumnHeader(col); key.setText(text); key.setColour(getColor(col)); sbc.addKeys(key); for (int row = 0; row < getRowCount(); row++) { Stack stack = null; if (sbc.getStackCount() > row) { stack = sbc.stack(row); } else { stack = sbc.newStack(); } double d = ((Number) getValueAt(row, col)).doubleValue(); stack.addStackValues(new StackValue(d, getColor(col))); } return sbc; } public Element getVerticalBarChartFromColumn(int col) { if (isstacked) { return getStackedBarChartFromColumn(col); } else { BarChart bc; if (issketch) { bc = new SketchBarChart(); ((SketchBarChart) bc).setFunFactor(sketchBarFunFactor); ((SketchBarChart) bc).setOutlineColour(getOutlineColor(col)); } else { bc = new BarChart(this.barchartstyle); if (this.barchartstyle == Style.THREED && threedheight != null) { chart.getXAxis().set3D(threedheight); } } for (int row = 0; row < getRowCount(); row++) { double d = ((Number) getValueAt(row, col)).doubleValue(); bc.addBars(new BarChart.Bar(d)); } bc.setColour(getColor(col)); if (tooltipText != null) { bc.setTooltip(tooltipText); } // set the title for this series bc.setText(getColumnHeader(col)); // set the onclick event to the base url template if (null != baseURLTemplate) { bc.setOn_click(baseURLTemplate); } if (alpha != null) { bc.setAlpha(alpha); } return bc; } } public Element getHorizontalBarChartFromColumn(int col) { HorizontalBarChart hbc = new HorizontalBarChart(); for (int row = 0; row < getRowCount(); row++) { double d = ((Number) getValueAt(row, col)).doubleValue(); hbc.addBars(new HorizontalBarChart.Bar(d)); } hbc.setColour(getColor(col)); if (tooltipText != null) { hbc.setTooltip(tooltipText); } // set the title for this series hbc.setText(getColumnHeader(col)); // set the onclick event to the base url template if (null != baseURLTemplate) { hbc.setOn_click(baseURLTemplate); } if (alpha != null) { hbc.setAlpha(alpha); } return hbc; } // Utility Methods public String getOutlineColor(int i) { return outlineColors.get(i % outlineColors.size()); } }