@Override public void drawItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, int pass) { super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis,dataset,row, column,pass); //Draw label if (dataset.getRowCount() - 1 == row) { //last row Number value = dataset.getValue(row, column); double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); double y1 = rangeAxis.valueToJava2D(value.doubleValue(), dataArea, plot.getRangeAxisEdge()); g2.setFont(new Font("SansSerif", Font.BOLD, 14)); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); String name = dataset.getColumnKey(column).toString(); int width = g2.getFontMetrics().stringWidth(name); g2.drawString(name, (int) y1 - width, (int) x1 - 12); } }
/** * Draws the bar with its standard deviation line range for a single (series, category) data item. * * @param g2 the graphics device. * @param state the renderer state. * @param dataArea the data area. * @param plot the plot. * @param domainAxis the domain axis. * @param rangeAxis the range axis. * @param data the data. * @param row the row index (zero-based). * @param column the column index (zero-based). * @param pass the pass index. */ @Override public void drawItem(final Graphics2D g2, final CategoryItemRendererState state, final Rectangle2D dataArea, final CategoryPlot plot, final CategoryAxis domainAxis, final ValueAxis rangeAxis, final CategoryDataset data, final int row, final int column, final int pass) { // defensive check if (!(data instanceof StatisticalCategoryDataset)) { throw new IllegalArgumentException("Requires StatisticalCategoryDataset."); } final StatisticalCategoryDataset statData = (StatisticalCategoryDataset) data; final PlotOrientation orientation = plot.getOrientation(); if (orientation == PlotOrientation.HORIZONTAL) { drawHorizontalItem(g2, state, dataArea, plot, domainAxis, rangeAxis, statData, row, column); } else if (orientation == PlotOrientation.VERTICAL) { drawVerticalItem(g2, state, dataArea, plot, domainAxis, rangeAxis, statData, row, column); } }
/** * Draws the tasks/subtasks for one item. * * @param g2 the graphics device. * @param state the renderer state. * @param dataArea the data plot area. * @param plot the plot. * @param domainAxis the domain axis. * @param rangeAxis the range axis. * @param dataset the data. * @param row the row index (zero-based). * @param column the column index (zero-based). */ protected void drawTasks (Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, TrackTaskSeriesCollection dataset, int row, int column, int pass) { int count = dataset.getSubIntervalCount (row, column); if (count == 0) { drawTask (g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, pass); } // rendering for subtasks is actually obsolete since we have a tree structure and // do not use subtasks in the class Task (JFreechart Task) else{ // just in case... we let the superclass handle it... super.drawTasks (g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column); } }
@Override public void drawItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, int pass) { super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, pass); double barW0 = calculateBarW0(plot, plot.getOrientation(), dataArea, domainAxis, state, state.getVisibleSeriesIndex(row), column); Number dataValue = dataset.getValue(row, column); if (dataValue == null) { return; } final double value = dataValue.doubleValue(); if(rangeAxis instanceof PartitionedNumberAxis) { Range r = new Range(0, value); ((PartitionedNumberAxis)rangeAxis).drawPatitionBoundaries( g2, r, dataArea, state.getBarWidth(), barW0); } }
@Override public void drawItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, int pass) { if(column == 0) { Shape shape = createShape(state, dataArea, plot, domainAxis, rangeAxis, dataset, row); if(shape != null) { if(pass == 0) { // render all drop shadows first (pass 0) Graphics2D g0 = (Graphics2D)g2.create(); g0.translate(2, 2); g0.setPaint(Color.darkGray); g0.fill(shape); g0.dispose(); } else if(pass == 1) { g2.setPaint(getSeriesPaint(row)); g2.fill(shape); } } } }
@Override public void drawItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, int pass) { drawItemInternal(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, pass); // System.out.println(String.format("row %s, column %s, pass %s", row, column, pass)); if((pass == 0) && (row == 1)&& (column == 3)) { // Workaround: because the dataArea sits on the the Axis the 0% gridline gets drawn // over the category axis making it gray. To fix this as we draw another black line // to restore the black axis. g2.setColor(Color.black); g2.setStroke(new BasicStroke(2)); g2.drawLine((int)dataArea.getMinX(), (int)dataArea.getMaxY(), (int)dataArea.getMaxX(), (int)dataArea.getMaxY()); g2.drawLine((int)dataArea.getMinX(), (int)dataArea.getMinY(), (int)dataArea.getMinX(), (int)dataArea.getMaxY()); } }
private double drawMean(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, ValueAxis rangeAxis, int row, int column, BoxAndWhiskerCategoryDataset bawDataset, double xx, double aRadius, RectangleEdge location) { double yyAverage; double newARadius = aRadius; // draw mean - SPECIAL AIMS REQUIREMENT... Number yMean = bawDataset.getMeanValue(row, column); if (yMean != null) { yyAverage = rangeAxis.valueToJava2D(yMean.doubleValue(), dataArea, location); newARadius = state.getBarWidth() / 4; Ellipse2D.Double avgEllipse = new Ellipse2D.Double(xx + aRadius, yyAverage - aRadius, aRadius * 2, aRadius * 2); g2.fill(avgEllipse); g2.draw(avgEllipse); } return newARadius; }
/** * Draws the bar for a single (series, category) data item. * * @param g2 the graphics device. * @param state the renderer state. * @param dataArea the data area. * @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). */ @Override public void drawItem (Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, int pass) { if (dataset instanceof TrackTaskSeriesCollection) { log.debug ("Drawing Item in TrackTaskSeriesCollection."); TrackTaskSeriesCollection ttsc = (TrackTaskSeriesCollection) dataset; drawTasks (g2, state, dataArea, plot, domainAxis, rangeAxis, ttsc, row, column, pass); } else { // let the superclass handle it... log.debug ("Drawing item in CategoryDataset."); super.drawItem (g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, 0); } }
@Override protected void calculateBarWidth(CategoryPlot plot, Rectangle2D dataArea, int rendererIndex, CategoryItemRendererState state) { CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex); double usedArea = dataArea.getWidth() * (1 - domainAxis.getLowerMargin() - domainAxis.getUpperMargin() - domainAxis.getCategoryMargin()); double barWidth = usedArea / plot.getDataset(rendererIndex).getColumnCount(); state.setBarWidth(barWidth); }
/** * Perform a select for the item(s) at the specified (x, y) coordinates * in Java2D space. * * @param x the x-coordinate. * @param y the y-coordinate. * @param dataArea the data area. * @param source the rendering source. * * @since 1.2.0 */ public void select(double x, double y, Rectangle2D dataArea, RenderingSource source) { int datasetCount = this.datasets.size(); for (int d = 0; d < datasetCount; d++) { CategoryDataset dataset = (CategoryDataset) this.datasets.get(d); if (dataset == null) { continue; } CategoryDatasetSelectionState state = findSelectionStateForDataset( dataset, source); if (state == null) { continue; } Graphics2D g2 = source.createGraphics2D(); CategoryItemRenderer renderer = getRendererForDataset(dataset); CategoryItemRendererState rs = renderer.initialise(g2, dataArea, this, dataset, null); int rowCount = dataset.getRowCount(); int columnCount = dataset.getColumnCount(); for (int r = 0; r < rowCount; r++) { for (int c = 0; c < columnCount; c++) { if (renderer.hitTest(x, y, null, dataArea, this, getDomainAxisForDataset(d), getRangeAxisForDataset(d), dataset, r, c, false, rs)) { state.setSelected(r, c, !state.isSelected(r, c)); } } } } }
@Override protected void calculateBarWidth(CategoryPlot plot, Rectangle2D dataArea, int rendererIndex, CategoryItemRendererState state) { CategoryAxis xAxis = plot.getDomainAxisForDataset(rendererIndex); if(xAxis instanceof AutoSubCategoryAxis) { state.setBarWidth(((AutoSubCategoryAxis)xAxis).calculateCategorySize(dataArea)); } else { super.calculateBarWidth(plot, dataArea, rendererIndex, state); } }
@Override protected double calculateBarW0(CategoryPlot plot, PlotOrientation orientation, Rectangle2D dataArea, CategoryAxis domainAxis, CategoryItemRendererState state, int row, int column) { return domainAxis.getCategoryMiddle(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()) - state.getBarWidth() / 2.0; }
public void drawItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, int pass) { super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, pass); _drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, pass); // draw the legend last and only if the chart contains the subtidal series (row == 1) if((row == 1) && (pass == 1) && (column == dataset.getColumnCount()-1)) { drawLegend(g2, dataArea); } }
private List<Point2D> getPoints(int row, Rectangle2D dataArea, CategoryDataset dataset, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryItemRendererState state) { List<Point2D> points = Lists.newArrayList(); for(int column = 0; true; column++) { Number v = null; try { v = dataset.getValue(row, column); } catch(Exception e) {} if (v == null) { break; } int visibleRow = state.getVisibleSeriesIndex(row); if (visibleRow < 0) { break; } int visibleRowCount = state.getVisibleSeriesCount(); double x1; if (this.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()); points.add(new Point2D.Double(x1, y1)); } return points; }
/** * 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 data. * @param row the row index (zero-based). * @param column the column index (zero-based). * @param pass the pass index. */ public void drawItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, int pass) { if (!(dataset instanceof BoxAndWhiskerCategoryDataset)) { throw new IllegalArgumentException( "BoxAndWhiskerRenderer.drawItem() : the data should be of type " + "BoxAndWhiskerCategoryDataset only." ); } PlotOrientation orientation = plot.getOrientation(); if (orientation == PlotOrientation.HORIZONTAL) { drawHorizontalItem( g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column ); } else if (orientation == PlotOrientation.VERTICAL) { drawVerticalItem( g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column ); } }
/** * Calculates the bar width and stores it in the renderer state. * * @param plot * the plot. * @param dataArea * the data area. * @param rendererIndex * the renderer index. * @param state * the renderer state. */ @Override protected void calculateBarWidth(CategoryPlot plot, Rectangle2D dataArea, int rendererIndex, CategoryItemRendererState state) { // calculate the bar width - this calculation differs from the // BarRenderer calculation because the bars are layered on top of one // another, so there is effectively only one bar per category for // the purpose of the bar width calculation CategoryAxis domainAxis = this.getDomainAxis(plot, rendererIndex); CategoryDataset dataset = plot.getDataset(rendererIndex); if (dataset != null) { int columns = dataset.getColumnCount(); int rows = dataset.getRowCount(); double space = dataArea.getWidth(); double maxWidth = space * this.getMaximumBarWidth(); double categoryMargin = 0.0; if (columns > 1) { categoryMargin = domainAxis.getCategoryMargin(); } double used = space * (1 - domainAxis.getLowerMargin() - domainAxis.getUpperMargin() - categoryMargin); if ((rows * columns) > 0) { state.setBarWidth(Math.min(used / (dataset.getColumnCount()), maxWidth)); } else { state.setBarWidth(Math.min(used, maxWidth)); } } }
/** * {@inheritDoc} */ @Override public CategoryItemRendererState initialise(Graphics2D g2, Rectangle2D dataArea, CategoryPlot plot, int rendererIndex, PlotRenderingInfo info) { CategoryItemRendererState state = super.initialise(g2, dataArea, plot, rendererIndex, info); if (state.getBarWidth() > maxBarWidth) { state.setBarWidth(maxBarWidth); } return state; }
private RectangleEdge drawRectangles(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, ValueAxis rangeAxis, int row, int column, BoxAndWhiskerCategoryDataset bawDataset, double xx) { RectangleEdge location = plot.getRangeAxisEdge(); Number yQ1 = bawDataset.getQ1Value(row, column); Number yQ3 = bawDataset.getQ3Value(row, column); Number yMax = bawDataset.getMaxRegularValue(row, column); Number yMin = bawDataset.getMinRegularValue(row, column); Shape box = null; if (yQ1 != null && yQ3 != null && yMax != null && yMin != null) { double yyQ1 = rangeAxis.valueToJava2D(yQ1.doubleValue(), dataArea, location); double yyQ3 = rangeAxis.valueToJava2D(yQ3.doubleValue(), dataArea, location); double yyMax = rangeAxis.valueToJava2D(yMax.doubleValue(), dataArea, location); double yyMin = rangeAxis.valueToJava2D(yMin.doubleValue(), dataArea, location); double xxmid = xx + state.getBarWidth() / 2.0; // draw the upper shadow... g2.draw(new Line2D.Double(xxmid, yyMax, xxmid, yyQ3)); g2.draw(new Line2D.Double(xx, yyMax, xx + state.getBarWidth(), yyMax)); // draw the lower shadow... g2.draw(new Line2D.Double(xxmid, yyMin, xxmid, yyQ1)); g2.draw(new Line2D.Double(xx, yyMin, xx + state.getBarWidth(), yyMin)); // draw the body... box = new Rectangle2D.Double(xx, Math.min(yyQ1, yyQ3), state.getBarWidth(), Math.abs(yyQ1 - yyQ3)); if (getFillBox()) { g2.fill(box); } g2.draw(box); } return location; }
/** * This function is taken directly from JFreeChart with adjustments to draw differently colored * items. * * When updating JFreeChart this function must probably be adapted. * */ @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; } int visibleRow = state.getVisibleSeriesIndex(row); if (visibleRow < 0) { return; } int visibleRowCount = state.getVisibleSeriesCount(); PlotOrientation orientation = plot.getOrientation(); ValueSourceToMultiValueCategoryDatasetAdapter dataSet = (ValueSourceToMultiValueCategoryDatasetAdapter) dataset; List values = dataSet.getValues(row, column); if (values == null) { return; } int valueCount = values.size(); for (int i = 0; i < valueCount; i++) { // 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()); } Number n = (Number) values.get(i); int idx = dataSet.getValueIndex(row, column, i); double value = n.doubleValue(); double y1 = rangeAxis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge()); Shape shape = getItemShape(row, idx); if (orientation == PlotOrientation.HORIZONTAL) { shape = ShapeUtilities.createTranslatedShape(shape, y1, x1); } else if (orientation == PlotOrientation.VERTICAL) { shape = ShapeUtilities.createTranslatedShape(shape, x1, y1); } if (getItemShapeFilled(row, column)) { if (getUseFillPaint()) { g2.setPaint(getItemFillPaint(row, column)); } else { g2.setPaint(getItemPaint(row, idx)); } g2.fill(shape); } if (getDrawOutlines()) { if (getUseOutlinePaint()) { g2.setPaint(getItemOutlinePaint(row, column)); } else { g2.setPaint(getItemPaint(row, idx)); } g2.setStroke(getItemOutlineStroke(row, column)); g2.draw(shape); } } }
/** * Draws a representation of a dataset within the dataArea region using the appropriate * renderer. * * @param g2 the graphics device. * @param dataArea the region in which the data is to be drawn. * @param index the dataset and renderer index. * @param info an optional object for collection dimension information. * * @return A boolean that indicates whether or not real data was found. */ public boolean render(Graphics2D g2, Rectangle2D dataArea, int index, PlotRenderingInfo info) { boolean foundData = false; CategoryDataset currentDataset = getDataset(index); CategoryItemRenderer renderer = getRenderer(index); CategoryAxis domainAxis = getDomainAxisForDataset(index); ValueAxis rangeAxis = getRangeAxisForDataset(index); if (!DatasetUtilities.isEmptyOrNull(currentDataset) && renderer != null) { foundData = true; CategoryItemRendererState state = renderer.initialise(g2, dataArea, this, index, info); int columnCount = currentDataset.getColumnCount(); int rowCount = currentDataset.getRowCount(); if (this.columnRenderingOrder == SortOrder.ASCENDING) { for (int column = 0; column < columnCount; column++) { if (this.rowRenderingOrder == SortOrder.ASCENDING) { for (int row = 0; row < rowCount; row++) { renderer.drawItem( g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column ); } } else { for (int row = rowCount - 1; row >= 0; row--) { renderer.drawItem( g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column ); } } } } else { for (int column = columnCount - 1; column >= 0; column--) { if (this.rowRenderingOrder == SortOrder.ASCENDING) { for (int row = 0; row < rowCount; row++) { renderer.drawItem( g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column ); } } else { for (int row = rowCount - 1; row >= 0; row--) { renderer.drawItem( g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column ); } } } } } return foundData; }
/** * Draws a representation of a dataset within the dataArea region using the * appropriate renderer. * * @param g2 the graphics device. * @param dataArea the region in which the data is to be drawn. * @param index the dataset and renderer index. * @param info an optional object for collection dimension information. * * @return A boolean that indicates whether or not real data was found. */ public boolean render(Graphics2D g2, Rectangle2D dataArea, int index, PlotRenderingInfo info) { boolean foundData = false; CategoryDataset currentDataset = getDataset(index); CategoryItemRenderer renderer = getRenderer(index); CategoryAxis domainAxis = getDomainAxisForDataset(index); ValueAxis rangeAxis = getRangeAxisForDataset(index); boolean hasData = !DatasetUtilities.isEmptyOrNull(currentDataset); if (hasData && renderer != null) { foundData = true; CategoryItemRendererState state = renderer.initialise(g2, dataArea, this, index, info); int columnCount = currentDataset.getColumnCount(); int rowCount = currentDataset.getRowCount(); int passCount = renderer.getPassCount(); for (int pass = 0; pass < passCount; pass++) { if (this.columnRenderingOrder == SortOrder.ASCENDING) { for (int column = 0; column < columnCount; column++) { if (this.rowRenderingOrder == SortOrder.ASCENDING) { for (int row = 0; row < rowCount; row++) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } else { for (int row = rowCount - 1; row >= 0; row--) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } } } else { for (int column = columnCount - 1; column >= 0; column--) { if (this.rowRenderingOrder == SortOrder.ASCENDING) { for (int row = 0; row < rowCount; row++) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } else { for (int row = rowCount - 1; row >= 0; row--) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } } } } } return foundData; }
/** * Draws a representation of a dataset within the dataArea region using the * appropriate renderer. * * @param g2 the graphics device. * @param dataArea the region in which the data is to be drawn. * @param index the dataset and renderer index. * @param info an optional object for collection dimension information. * @param crosshairState a state object for tracking crosshair info * (<code>null</code> permitted). * * @return A boolean that indicates whether or not real data was found. * * @since 1.0.11 */ public boolean render(Graphics2D g2, Rectangle2D dataArea, int index, PlotRenderingInfo info, CategoryCrosshairState crosshairState) { boolean foundData = false; CategoryDataset currentDataset = getDataset(index); CategoryItemRenderer renderer = getRenderer(index); CategoryAxis domainAxis = getDomainAxisForDataset(index); ValueAxis rangeAxis = getRangeAxisForDataset(index); boolean hasData = !DatasetUtilities.isEmptyOrNull(currentDataset); if (hasData && renderer != null) { foundData = true; CategoryItemRendererState state = renderer.initialise(g2, dataArea, this, index, info); state.setCrosshairState(crosshairState); int columnCount = currentDataset.getColumnCount(); int rowCount = currentDataset.getRowCount(); int passCount = renderer.getPassCount(); for (int pass = 0; pass < passCount; pass++) { if (this.columnRenderingOrder == SortOrder.ASCENDING) { for (int column = 0; column < columnCount; column++) { if (this.rowRenderingOrder == SortOrder.ASCENDING) { for (int row = 0; row < rowCount; row++) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } else { for (int row = rowCount - 1; row >= 0; row--) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } } } else { for (int column = columnCount - 1; column >= 0; column--) { if (this.rowRenderingOrder == SortOrder.ASCENDING) { for (int row = 0; row < rowCount; row++) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } else { for (int row = rowCount - 1; row >= 0; row--) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } } } } } return foundData; }
/** * Draws a representation of a dataset within the dataArea region using the * appropriate renderer. * * @param g2 the graphics device. * @param dataArea the region in which the data is to be drawn. * @param index the dataset and renderer index. * @param info an optional object for collection dimension information. * @param crosshairState a state object for tracking crosshair info * ({@code null} permitted). * * @return A boolean that indicates whether or not real data was found. * * @since 1.0.11 */ public boolean render(Graphics2D g2, Rectangle2D dataArea, int index, PlotRenderingInfo info, CategoryCrosshairState crosshairState) { boolean foundData = false; CategoryDataset currentDataset = getDataset(index); CategoryItemRenderer renderer = getRenderer(index); CategoryAxis domainAxis = getDomainAxisForDataset(index); ValueAxis rangeAxis = getRangeAxisForDataset(index); boolean hasData = !DatasetUtils.isEmptyOrNull(currentDataset); if (hasData && renderer != null) { foundData = true; CategoryItemRendererState state = renderer.initialise(g2, dataArea, this, index, info); state.setCrosshairState(crosshairState); int columnCount = currentDataset.getColumnCount(); int rowCount = currentDataset.getRowCount(); int passCount = renderer.getPassCount(); for (int pass = 0; pass < passCount; pass++) { if (this.columnRenderingOrder == SortOrder.ASCENDING) { for (int column = 0; column < columnCount; column++) { if (this.rowRenderingOrder == SortOrder.ASCENDING) { for (int row = 0; row < rowCount; row++) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } else { for (int row = rowCount - 1; row >= 0; row--) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } } } else { for (int column = columnCount - 1; column >= 0; column--) { if (this.rowRenderingOrder == SortOrder.ASCENDING) { for (int row = 0; row < rowCount; row++) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } else { for (int row = rowCount - 1; row >= 0; row--) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } } } } } return foundData; }
/** * This function is taken directly from JFreeChart with adjustments to draw differently colored * items. * * When updating JFreeChart this function must probably be adapted. * */ @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; } int visibleRow = state.getVisibleSeriesIndex(row); if (visibleRow < 0) { return; } int visibleRowCount = state.getVisibleSeriesCount(); PlotOrientation orientation = plot.getOrientation(); ValueSourceToMultiValueCategoryDatasetAdapter dataSet = (ValueSourceToMultiValueCategoryDatasetAdapter) dataset; List<Double> values = dataSet.getValues(row, column); if (values == null) { return; } int valueCount = values.size(); for (int i = 0; i < valueCount; i++) { // 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()); } Number n = values.get(i); int idx = dataSet.getValueIndex(row, column, i); double value = n.doubleValue(); double y1 = rangeAxis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge()); Shape shape = getItemShape(row, idx); if (orientation == PlotOrientation.HORIZONTAL) { shape = ShapeUtilities.createTranslatedShape(shape, y1, x1); } else if (orientation == PlotOrientation.VERTICAL) { shape = ShapeUtilities.createTranslatedShape(shape, x1, y1); } if (getItemShapeFilled(row, column)) { if (getUseFillPaint()) { g2.setPaint(getItemFillPaint(row, column)); } else { g2.setPaint(getItemPaint(row, idx)); } g2.fill(shape); } if (getDrawOutlines()) { if (getUseOutlinePaint()) { g2.setPaint(getItemOutlinePaint(row, column)); } else { g2.setPaint(getItemPaint(row, idx)); } g2.setStroke(getItemOutlineStroke(row, column)); g2.draw(shape); } } }
/** * Draws a representation of a dataset within the dataArea region using the * appropriate renderer. * * @param g2 the graphics device. * @param dataArea the region in which the data is to be drawn. * @param index the dataset and renderer index. * @param info an optional object for collection dimension information. * * @return A boolean that indicates whether or not real data was found. */ public boolean render(Graphics2D g2, Rectangle2D dataArea, int index, PlotRenderingInfo info) { boolean foundData = false; CategoryDataset currentDataset = getDataset(index); CategoryItemRenderer renderer = getRenderer(index); CategoryAxis domainAxis = getDomainAxisForDataset(index); ValueAxis rangeAxis = getRangeAxisForDataset(index); boolean hasData = !DatasetUtilities.isEmptyOrNull(currentDataset); if (hasData && renderer != null) { foundData = true; CategoryItemRendererState state = renderer.initialise( g2, dataArea, this, index, info ); int columnCount = currentDataset.getColumnCount(); int rowCount = currentDataset.getRowCount(); int passCount = renderer.getPassCount(); for (int pass = 0; pass < passCount; pass++) { if (this.columnRenderingOrder == SortOrder.ASCENDING) { for (int column = 0; column < columnCount; column++) { if (this.rowRenderingOrder == SortOrder.ASCENDING) { for (int row = 0; row < rowCount; row++) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } else { for (int row = rowCount - 1; row >= 0; row--) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } } } else { for (int column = columnCount - 1; column >= 0; column--) { if (this.rowRenderingOrder == SortOrder.ASCENDING) { for (int row = 0; row < rowCount; row++) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } else { for (int row = rowCount - 1; row >= 0; row--) { renderer.drawItem(g2, state, dataArea, this, domainAxis, rangeAxis, currentDataset, row, column, pass); } } } } } } return foundData; }
/** * This function is taken directly from JFreeChart with adjustments to draw * differently colored items. * * When updating JFreeChart this function must probably be adapted. * */ @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; } int visibleRow = state.getVisibleSeriesIndex(row); if (visibleRow < 0) { return; } int visibleRowCount = state.getVisibleSeriesCount(); PlotOrientation orientation = plot.getOrientation(); ValueSourceToMultiValueCategoryDatasetAdapter dataSet = (ValueSourceToMultiValueCategoryDatasetAdapter)dataset; List values = dataSet.getValues(row, column); if (values == null) { return; } int valueCount = values.size(); for (int i = 0; i < valueCount; i++) { // 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()); } Number n = (Number)values.get(i); int idx = dataSet.getValueIndex(row, column, i); double value = n.doubleValue(); double y1 = rangeAxis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge()); Shape shape = getItemShape(row, idx); if (orientation == PlotOrientation.HORIZONTAL) { shape = ShapeUtilities.createTranslatedShape(shape, y1, x1); } else if (orientation == PlotOrientation.VERTICAL) { shape = ShapeUtilities.createTranslatedShape(shape, x1, y1); } if (getItemShapeFilled(row, column)) { if (getUseFillPaint()) { g2.setPaint(getItemFillPaint(row, column)); } else { g2.setPaint(getItemPaint(row, idx)); } g2.fill(shape); } if (getDrawOutlines()) { if (getUseOutlinePaint()) { g2.setPaint(getItemOutlinePaint(row, column)); } else { g2.setPaint(getItemPaint(row, idx)); } g2.setStroke(getItemOutlineStroke(row, column)); g2.draw(shape); } } }
private void _drawItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, int pass) { StatisticalCategoryDataset statDataset = (StatisticalCategoryDataset) dataset; int visibleRow = state.getVisibleSeriesIndex(row); 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()); } Number meanValue = statDataset.getMeanValue(row, column); if (meanValue == null) { return; } double y1 = rangeAxis.valueToJava2D(meanValue.doubleValue(), dataArea, plot.getRangeAxisEdge()); if (pass == 0 && getItemLineVisible(row, column)) { if (column != 0) { Number previousValue = statDataset.getValue(row, column - 1); if(previousValue != null) { // ignore this case here because the call to super.drawItem(...) took care if it. return; } else { // previous data point... Integer pIdx = findPreviousIndex(statDataset, row, column); if(pIdx == null) { return; } previousValue = statDataset.getValue(row, pIdx.intValue()); double previous = previousValue.doubleValue(); double x0; if (getUseSeriesOffset()) { x0 = domainAxis.getCategorySeriesMiddle( pIdx.intValue(), dataset.getColumnCount(), visibleRow, visibleRowCount, getItemMargin(), dataArea, plot.getDomainAxisEdge()); } else { x0 = domainAxis.getCategoryMiddle(pIdx.intValue(), 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); } } } }
@Override public void drawItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, int pass) { super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, pass); // after the stacked bar is completely rendered draw the glow text into it. if((pass == 2) && isSeriesComplete(dataset, row) && renderBarLabel(dataset, row, column)) { GraphUtils g = new GraphUtils(g2); String rowKey = dataset.getRowKey(row).toString(); String colKey = dataset.getColumnKey(column).toString(); String label = String.format("%s %s", colKey, getSeries(rowKey)); double barW0 = calculateBarW0(plot, plot.getOrientation(), dataArea, domainAxis, state, row, column); // centre the label double labelx = barW0 + state.getBarWidth()/2; double labely = (dataArea.getMinY()+dataArea.getHeight() / 2) - (g.getBounds(label).getWidth() / 2); AffineTransform saveT = g2.getTransform(); AffineTransform transform = new AffineTransform(); // jfree chart seem to be using the transform on the Graphics2D object // for scaling when the window gets very small or large // therefore we can not just overwrite the transform but have to factor it into // our rotation and translation transformations. transform.concatenate(saveT); transform.concatenate(AffineTransform.getRotateInstance(-Math.PI/2, labelx, labely)); g2.setTransform(transform); g2.setFont(LEGEND_FONT); g2.setColor(Color.black); g.drawGlowString(label, Color.white, 6, (int)labelx, (int)labely); g2.setTransform(saveT); } if((pass == 2) && isLastRow(dataset, row)) { // Workaround: because the dataArea sits on the the Axis the 0% gridline gets drawn // over the category axis making it gray. To fix this as we draw another black line // to restore the black axis. g2.setColor(Color.black); g2.setStroke(new BasicStroke(2)); g2.drawLine((int)dataArea.getMinX(), (int)dataArea.getMaxY(), (int)dataArea.getMaxX(), (int)dataArea.getMaxY()); g2.drawLine((int)dataArea.getMinX(), (int)dataArea.getMinY(), (int)dataArea.getMinX(), (int)dataArea.getMaxY()); } }
/** * Initialises the renderer. This method gets called once at the start of * the process of drawing a chart. * * @param g2 the graphics device. * @param dataArea the area in which the data is to be plotted. * @param plot the plot. * @param rendererIndex the renderer index. * @param info collects chart rendering information for return to caller. * * @return The renderer state. */ public CategoryItemRendererState initialise(Graphics2D g2, Rectangle2D dataArea, CategoryPlot plot, int rendererIndex, PlotRenderingInfo info) { CategoryItemRendererState state = super.initialise( g2, dataArea, plot, rendererIndex, info ); // calculate the box width CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex); CategoryDataset dataset = plot.getDataset(rendererIndex); if (dataset != null) { int columns = dataset.getColumnCount(); int rows = dataset.getRowCount(); double space = 0.0; PlotOrientation orientation = plot.getOrientation(); if (orientation == PlotOrientation.HORIZONTAL) { space = dataArea.getHeight(); } else if (orientation == PlotOrientation.VERTICAL) { space = dataArea.getWidth(); } double categoryMargin = 0.0; double currentItemMargin = 0.0; if (columns > 1) { categoryMargin = domainAxis.getCategoryMargin(); } if (rows > 1) { currentItemMargin = getItemMargin(); } double used = space * (1 - domainAxis.getLowerMargin() - domainAxis.getUpperMargin() - categoryMargin - currentItemMargin); if ((rows * columns) > 0) { state.setBarWidth( used / (dataset.getColumnCount() * dataset.getRowCount()) ); } else { state.setBarWidth(used); } } if (state.getBarWidth() > maxBarWidth) state.setBarWidth(maxBarWidth); return state; }