/* =========================================================== * JFreeChart : a free chart library for the Java(tm) platform * =========================================================== * * (C) Copyright 2000-2011, by Object Refinery Limited and Contributors. * * Project Info: http://www.jfree.org/jfreechart/index.html * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library 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. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. * * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. * Other names may be trademarks of their respective owners.] * * ------------------------- * LineAndShapeRenderer.java * ------------------------- * (C) Copyright 2001-2009, by Object Refinery Limited and Contributors. * * Original Author: David Gilbert (for Object Refinery Limited); * Contributor(s): Mark Watson (www.markwatson.com); * Jeremy Bowman; * Richard Atkinson; * Christian W. Zuckschwerdt; * Peter Kolb (patch 2497611); * * Changes * ------- * 23-Oct-2001 : Version 1 (DG); * 15-Nov-2001 : Modified to allow for null data values (DG); * 16-Jan-2002 : Renamed HorizontalCategoryItemRenderer.java * --> CategoryItemRenderer.java (DG); * 05-Feb-2002 : Changed return type of the drawCategoryItem method from void * to Shape, as part of the tooltips implementation (DG); * 11-May-2002 : Support for value label drawing (JB); * 29-May-2002 : Now extends AbstractCategoryItemRenderer (DG); * 25-Jun-2002 : Removed redundant import (DG); * 05-Aug-2002 : Small modification to drawCategoryItem method to support URLs * for HTML image maps (RA); * 26-Sep-2002 : Fixed errors reported by Checkstyle (DG); * 11-Oct-2002 : Added new constructor to incorporate tool tip and URL * generators (DG); * 24-Oct-2002 : Amendments for changes in CategoryDataset interface and * CategoryToolTipGenerator interface (DG); * 05-Nov-2002 : Base dataset is now TableDataset not CategoryDataset (DG); * 06-Nov-2002 : Renamed drawCategoryItem() --> drawItem() and now using axis * for category spacing (DG); * 17-Jan-2003 : Moved plot classes to a separate package (DG); * 10-Apr-2003 : Changed CategoryDataset to KeyedValues2DDataset in drawItem() * method (DG); * 12-May-2003 : Modified to take into account the plot orientation (DG); * 29-Jul-2003 : Amended code that doesn't compile with JDK 1.2.2 (DG); * 30-Jul-2003 : Modified entity constructor (CZ); * 22-Sep-2003 : Fixed cloning (DG); * 10-Feb-2004 : Small change to drawItem() method to make cut-and-paste * override easier (DG); * 16-Jun-2004 : Fixed bug (id=972454) with label positioning on horizontal * charts (DG); * 15-Oct-2004 : Updated equals() method (DG); * 05-Nov-2004 : Modified drawItem() signature (DG); * 11-Nov-2004 : Now uses ShapeUtilities class to translate shapes (DG); * 27-Jan-2005 : Changed attribute names, modified constructor and removed * constants (DG); * 01-Feb-2005 : Removed unnecessary constants (DG); * 15-Mar-2005 : Fixed bug 1163897, concerning outlines for shapes (DG); * 13-Apr-2005 : Check flags that control series visibility (DG); * 20-Apr-2005 : Use generators for legend labels, tooltips and URLs (DG); * 09-Jun-2005 : Use addItemEntity() method (DG); * ------------- JFREECHART 1.0.x --------------------------------------------- * 25-May-2006 : Added check to drawItem() to detect when both the line and * the shape are not visible (DG); * 20-Apr-2007 : Updated getLegendItem() for renderer change (DG); * 17-May-2007 : Set datasetIndex and seriesIndex in getLegendItem() (DG); * 18-May-2007 : Set dataset and seriesKey for LegendItem (DG); * 24-Sep-2007 : Deprecated redundant fields/methods (DG); * 27-Sep-2007 : Added option to offset series x-position within category (DG); * 17-Jun-2008 : Apply legend shape, font and paint attributes (DG); * 26-Jun-2008 : Added crosshair support (DG); * 14-Jan-2009 : Added support for seriesVisible flags (PK); * */ package open.dolphin.impl.lbtest; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.entity.EntityCollection; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.CategoryItemRendererState; import org.jfree.chart.renderer.category.LineAndShapeRenderer; import org.jfree.data.category.CategoryDataset; import org.jfree.util.ShapeUtilities; /** * IgnoreNullLineRenderer * * @author masuda, Masuda Naika */ public class IgnoreNullLineRenderer extends LineAndShapeRenderer { /** * Draw a single data item. * * @param g2 the graphics device. * @param state the renderer state. * @param dataArea the area in which the data is drawn. * @param plot the plot. * @param domainAxis the domain axis. * @param rangeAxis the range axis. * @param dataset the dataset. * @param row the row index (zero-based). * @param column the column index (zero-based). * @param pass the pass index. */ @Override public void drawItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, int pass) { // do nothing if item is not visible if (!getItemVisible(row, column)) { return; } // do nothing if both the line and shape are not visible if (!getItemLineVisible(row, column) && !getItemShapeVisible(row, column)) { return; } // nothing is drawn for null... Number v = dataset.getValue(row, column); if (v == null) { return; } int visibleRow = state.getVisibleSeriesIndex(row); if (visibleRow < 0) { return; } int visibleRowCount = state.getVisibleSeriesCount(); PlotOrientation orientation = plot.getOrientation(); // current data point... double x1; if (getUseSeriesOffset()) { x1 = domainAxis.getCategorySeriesMiddle(column, dataset.getColumnCount(), visibleRow, visibleRowCount, getItemMargin(), dataArea, plot.getDomainAxisEdge()); } else { x1 = domainAxis.getCategoryMiddle(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); } double value = v.doubleValue(); double y1 = rangeAxis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge()); if (pass == 0 && getItemLineVisible(row, column)) { if (column != 0) { int prevColumn = getPreviousNotNullColumn(dataset, row, column - 1); Number previousValue = (prevColumn != -1) ? dataset.getValue(row, prevColumn) : null; if (previousValue != null) { // previous data point... double previous = previousValue.doubleValue(); double x0; if (getUseSeriesOffset()) { x0 = domainAxis.getCategorySeriesMiddle( prevColumn, dataset.getColumnCount(), visibleRow, visibleRowCount, getItemMargin(), dataArea, plot.getDomainAxisEdge()); } else { x0 = domainAxis.getCategoryMiddle(prevColumn, getColumnCount(), dataArea, plot.getDomainAxisEdge()); } double y0 = rangeAxis.valueToJava2D(previous, dataArea, plot.getRangeAxisEdge()); Line2D line = null; if (orientation == PlotOrientation.HORIZONTAL) { line = new Line2D.Double(y0, x0, y1, x1); } else if (orientation == PlotOrientation.VERTICAL) { line = new Line2D.Double(x0, y0, x1, y1); } g2.setPaint(getItemPaint(row, column)); g2.setStroke(getItemStroke(row, column)); g2.draw(line); } } } if (pass == 1) { Shape shape = getItemShape(row, column); if (orientation == PlotOrientation.HORIZONTAL) { shape = ShapeUtilities.createTranslatedShape(shape, y1, x1); } else if (orientation == PlotOrientation.VERTICAL) { shape = ShapeUtilities.createTranslatedShape(shape, x1, y1); } if (getItemShapeVisible(row, column)) { if (getItemShapeFilled(row, column)) { if (getUseFillPaint()) { g2.setPaint(getItemFillPaint(row, column)); } else { g2.setPaint(getItemPaint(row, column)); } g2.fill(shape); } if (getDrawOutlines()) { if (getUseOutlinePaint()) { g2.setPaint(getItemOutlinePaint(row, column)); } else { g2.setPaint(getItemPaint(row, column)); } g2.setStroke(getItemOutlineStroke(row, column)); g2.draw(shape); } } // draw the item label if there is one... if (isItemLabelVisible(row, column)) { if (orientation == PlotOrientation.HORIZONTAL) { drawItemLabel(g2, orientation, dataset, row, column, y1, x1, (value < 0.0)); } else if (orientation == PlotOrientation.VERTICAL) { drawItemLabel(g2, orientation, dataset, row, column, x1, y1, (value < 0.0)); } } // submit the current data point as a crosshair candidate int datasetIndex = plot.indexOf(dataset); updateCrosshairValues(state.getCrosshairState(), dataset.getRowKey(row), dataset.getColumnKey(column), value, datasetIndex, x1, y1, orientation); // add an item entity, if this information is being collected EntityCollection entities = state.getEntityCollection(); if (entities != null) { addItemEntity(entities, dataset, row, column, shape); } } } // 非Nullのカラムを探す private int getPreviousNotNullColumn(CategoryDataset dataset, int row, int col) { for (int i = col; i >= 0; --i) { Number prevNum = dataset.getValue(row, i); if (prevNum != null) { return i; } } return -1; } }