List of usage examples for org.jfree.chart.axis ValueAxis valueToJava2D
public abstract double valueToJava2D(double value, Rectangle2D area, RectangleEdge edge);
From source file:org.yccheok.jstock.gui.charting.ChartLayerUI.java
private boolean updateMainTraceInfo(Point2D point) { if (point == null) { return false; }//from www . j a va 2 s. c om final ChartPanel chartPanel = this.chartJDialog.getChartPanel(); // Top most plot. final XYPlot plot = this.chartJDialog.getPlot(); if (plot.getDataset() instanceof org.jfree.data.xy.DefaultHighLowDataset) { return this._updateMainTraceInfoForCandlestick(point); } final TimeSeriesCollection timeSeriesCollection = (TimeSeriesCollection) plot.getDataset(); // 0 are the main chart. 1, 2, 3... are TA. final TimeSeries timeSeries = timeSeriesCollection.getSeries(0); // I also not sure why. This is what are being done in Mouse Listener Demo 4. // // Don't use it. It will cause us to lose precision. //final Point2D p2 = chartPanel.translateScreenToJava2D((Point)point); /* Try to get correct main chart area. */ final Rectangle2D _plotArea = chartPanel.getChartRenderingInfo().getPlotInfo().getSubplotInfo(0) .getDataArea(); final ValueAxis domainAxis = plot.getDomainAxis(); final RectangleEdge domainAxisEdge = plot.getDomainAxisEdge(); final ValueAxis rangeAxis = plot.getRangeAxis(); final RectangleEdge rangeAxisEdge = plot.getRangeAxisEdge(); // Don't use it. It will cause us to lose precision. //final double coordinateX = domainAxis.java2DToValue(p2.getX(), _plotArea, // domainAxisEdge); final double coordinateX = domainAxis.java2DToValue(point.getX(), _plotArea, domainAxisEdge); //double coordinateY = rangeAxis.java2DToValue(mousePoint2.getY(), plotArea, // rangeAxisEdge); int low = 0; int high = timeSeries.getItemCount() - 1; Date date = new Date((long) coordinateX); final long time = date.getTime(); long bestDistance = Long.MAX_VALUE; int bestMid = 0; while (low <= high) { int mid = (low + high) >>> 1; final TimeSeriesDataItem timeSeriesDataItem = timeSeries.getDataItem(mid); final Day day = (Day) timeSeriesDataItem.getPeriod(); final long search = day.getFirstMillisecond(); final long cmp = search - time; if (cmp < 0) { low = mid + 1; } else if (cmp > 0) { high = mid - 1; } else { bestDistance = 0; bestMid = mid; break; } final long abs_cmp = Math.abs(cmp); if (abs_cmp < bestDistance) { bestDistance = abs_cmp; bestMid = mid; } } final TimeSeriesDataItem timeSeriesDataItem = timeSeries.getDataItem(bestMid); final double xValue = timeSeriesDataItem.getPeriod().getFirstMillisecond(); final double yValue = timeSeriesDataItem.getValue().doubleValue(); final double xJava2D = domainAxis.valueToJava2D(xValue, _plotArea, domainAxisEdge); final double yJava2D = rangeAxis.valueToJava2D(yValue, _plotArea, rangeAxisEdge); final int tmpIndex = bestMid; // translateJava2DToScreen will internally convert Point2D.Double to Point. final Point2D tmpPoint = chartPanel.translateJava2DToScreen(new Point2D.Double(xJava2D, yJava2D)); this.mainDrawArea.setRect(_plotArea); if (this.mainDrawArea.contains(tmpPoint)) { // 0 indicates main plot. this.mainTraceInfo = TraceInfo.newInstance(tmpPoint, 0, 0, tmpIndex); return true; } return false; }
From source file:aprofplot.jfreechart.SamplingXYLineAndShapeRenderer.java
/** * Draws the visual representation of a series as shapes. * * @param g2 the graphics device./*from w w w . j a v a2 s. co m*/ * @param state the renderer state. * @param dataArea the area within which the data is being drawn. * @param info collects information about the drawing. * @param plot the plot (can be used to obtain standard color * information etc). * @param domainAxis the domain axis. * @param rangeAxis the range axis. * @param dataset the dataset. * @param series the series index (zero-based). * @param crosshairState crosshair information for the plot * (<code>null</code> permitted). * @param pass the pass index. * @param drawShapes a flag indicating whether shapes should be drawn * @param createEntities a flag indicating whether entities should be * generated. */ protected void drawSeriesShapes(Graphics2D g2, State state, Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot, ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset, int series, CrosshairState crosshairState, int pass, boolean drawShapes, boolean createEntities) { if (!drawShapes && !createEntities) { return; } PlotOrientation orientation = plot.getOrientation(); RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); double x = 0.0; double y = 0.0; double transX = 0.0; double transY = 0.0; boolean itemShapeFilled = getItemShapeFilled(series, 0); boolean drawOutlines = getDrawOutlines(); Paint itemFillPaint = getUseFillPaint() ? getItemFillPaint(series, 0) : getItemPaint(series, 0); Paint itemOutlinePaint = getUseOutlinePaint() ? getItemOutlinePaint(series, 0) : getItemPaint(series, 0); Stroke itemOutlineStroke = getItemOutlineStroke(series, 0); Shape centeredShape = getItemShape(series, 0); /* if(centeredShape instanceof LinedShape){ itemOutlinePaint = itemFillPaint; drawOutlines = true; itemShapeFilled = false; } */ //draw items //and create entities EntityCollection entities = null; if (info != null) { entities = info.getOwner().getEntityCollection(); } int domainAxisIndex = plot.getDomainAxisIndex(domainAxis); int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis); for (int itemIndex = state.getFirstItemIndex(); itemIndex <= state.getLastItemIndex(); itemIndex++) { if (state.itemVisible(series, itemIndex)) { x = dataset.getXValue(series, itemIndex); y = dataset.getYValue(series, itemIndex); transX = domainAxis.valueToJava2D(x, dataArea, xAxisLocation); transY = rangeAxis.valueToJava2D(y, dataArea, yAxisLocation); if (orientation == PlotOrientation.HORIZONTAL) { double temp = transX; transX = transY; transY = temp; } updateCrosshairValues(crosshairState, x, y, domainAxisIndex, rangeAxisIndex, transX, transY, orientation); Shape shape = ShapeUtilities.createTranslatedShape(centeredShape, transX, transY); if (drawShapes) { if (itemShapeFilled) { g2.setPaint(itemFillPaint); g2.fill(shape); } if (drawOutlines) { g2.setPaint(itemOutlinePaint); g2.setStroke(itemOutlineStroke); g2.draw(shape); } } if (createEntities && entities != null) { addEntity(entities, shape, dataset, series, itemIndex, transX, transY); } } } }
From source file:edu.dlnu.liuwenpeng.render.XYLineAndShapeRenderer.java
public void drawItem(Graphics2D g2, XYItemRendererState state, Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot, ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset, int series, int item, CrosshairState crosshairState, int pass) { ls.add(dataset.getYValue(0, item));//from ww w.j a va 2 s.c om // do nothing if item is not visible if (!getItemVisible(series, item)) { return; } // first pass draws the background (lines, for instance) if (isLinePass(pass)) { if (item == 0) { if (this.drawSeriesLineAsPath) { State s = (State) state; s.seriesPath.reset(); s.lastPointGood = false; } } if (getItemLineVisible(series, item)) { if (this.drawSeriesLineAsPath) { drawPrimaryLineAsPath(state, g2, plot, dataset, pass, series, item, domainAxis, rangeAxis, dataArea); } else { drawPrimaryLine(state, g2, plot, dataset, pass, series, item, domainAxis, rangeAxis, dataArea); } } } // second pass adds shapes where the items are .. else if (isItemPass(pass)) { // setup for collecting optional entity info... EntityCollection entities = null; if (info != null) { entities = info.getOwner().getEntityCollection(); } drawSecondaryPass(g2, plot, dataset, pass, series, item, domainAxis, dataArea, rangeAxis, crosshairState, entities); } if (i == dataset.getItemCount(0) - 1) { Double average = GetAverage.getAverage(ls); double averangeline = rangeAxis.valueToJava2D(average, dataArea, plot.getRangeAxisEdge()); double x = rangeAxis.valueToJava2D(dataset.getItemCount(0), dataArea, plot.getDomainAxisEdge()); Line2D line2d = new Line2D.Double(0, averangeline, x, averangeline); g2.setPaint(Color.white); g2.draw(line2d); ls.clear(); i = 0; } i++; }
From source file:extern.NpairsBoxAndWhiskerRenderer.java
/** * Draws the visual representation of a single data item when the plot has * a vertical orientation.//from ww w .ja v a 2s . com * * @param g2 the graphics device. * @param state the renderer state. * @param dataArea the area within which the plot is being drawn. * @param plot the plot (can be used to obtain standard color information * etc). * @param domainAxis the domain axis. * @param rangeAxis the range axis. * @param dataset the dataset (must be an instance of * {@link BoxAndWhiskerCategoryDataset}). * @param row the row index (zero-based). * @param column the column index (zero-based). */ public void drawVerticalItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column) { BoxAndWhiskerCategoryDataset bawDataset = (BoxAndWhiskerCategoryDataset) dataset; double categoryEnd = domainAxis.getCategoryEnd(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); double categoryStart = domainAxis.getCategoryStart(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); double categoryWidth = categoryEnd - categoryStart; double xx = categoryStart; int seriesCount = getRowCount(); int categoryCount = getColumnCount(); double widthToUse = Math.min(state.getBarWidth(), dataArea.getWidth() / 15); if (seriesCount > 1) { double seriesGap = dataArea.getWidth() * getItemMargin() / (categoryCount * (seriesCount - 1)); double usedWidth = (widthToUse * seriesCount) + (seriesGap * (seriesCount - 1)); // offset the start of the boxes if the total width used is smaller // than the category width double offset = (categoryWidth - usedWidth) / 2; xx = xx + offset + (row * (widthToUse + seriesGap)); } else { // offset the start of the box if the box width is smaller than the // category width double offset = (categoryWidth - widthToUse) / 2; xx = xx + offset; } double yyAverage = 0.0; double yyOutlier; Paint itemPaint = getItemPaint(row, column); g2.setPaint(itemPaint); Stroke s = getItemStroke(row, column); g2.setStroke(s); double aRadius = 0; // average radius 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; double xxmid = xx + widthToUse / 2.0; 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); // draw the upper shadow... g2.draw(new Line2D.Double(xxmid, yyMax, xxmid, yyQ3)); g2.draw(new Line2D.Double(xx, yyMax, xx + widthToUse, yyMax)); // draw the lower shadow... g2.draw(new Line2D.Double(xxmid, yyMin, xxmid, yyQ1)); g2.draw(new Line2D.Double(xx, yyMin, xx + widthToUse, yyMin)); // draw the body... box = new Rectangle2D.Double(xx, Math.min(yyQ1, yyQ3), widthToUse, Math.abs(yyQ1 - yyQ3)); if (this.fillBox) { g2.fill(box); } g2.setStroke(getItemOutlineStroke(row, column)); g2.setPaint(getItemOutlinePaint(row, column)); g2.draw(box); } g2.setPaint(this.artifactPaint); // draw mean - SPECIAL AIMS REQUIREMENT... Number yMean = bawDataset.getMeanValue(row, column); if (yMean != null && !Double.isNaN(yMean.doubleValue())) { yyAverage = rangeAxis.valueToJava2D(yMean.doubleValue(), dataArea, location); // THIS IS WHAT WE CHANGED // aRadius = widthWeWannaUse / 4; aRadius = 4; // here we check that the average marker will in fact be visible // before drawing it... // WE HAD TO CHANGE THIS TOO I DON'T KNOW WHAT THEY WERE DOING if ((yyAverage > (dataArea.getMinY() - aRadius)) && (yyAverage < (dataArea.getMaxY() + aRadius))) { Ellipse2D.Double avgEllipse = new Ellipse2D.Double(xxmid - aRadius, yyAverage - aRadius, aRadius * 2, aRadius * 2); g2.fill(avgEllipse); g2.draw(avgEllipse); } } // draw median... Number yMedian = bawDataset.getMedianValue(row, column); if (yMedian != null && !Double.isNaN(yMedian.doubleValue())) { double yyMedian = rangeAxis.valueToJava2D(yMedian.doubleValue(), dataArea, location); g2.draw(new Line2D.Double(xx, yyMedian, xx + widthToUse, yyMedian)); // add a line to connect the means of the boxes if (prevX != -1.0 && prevY != -1.0) { g2.draw(new Line2D.Double(prevX, prevY, xxmid, yyMedian)); } prevX = xxmid; prevY = yyMedian; } // draw yOutliers... g2.setPaint(itemPaint); // draw outliers double oRadius = 4; // outlier radius List<Outlier> outliers = new ArrayList<Outlier>(); // From outlier array sort out which are outliers and put these into a // list If there are any farouts, set the flag on the // OutlierListCollection List<Number> yOutliers = bawDataset.getOutliers(row, column); if (yOutliers != null) { for (int i = 0; i < yOutliers.size(); i++) { double outlier = yOutliers.get(i).doubleValue(); yyOutlier = rangeAxis.valueToJava2D(outlier, dataArea, location); outliers.add(new Outlier(xxmid, yyOutlier, oRadius)); } // Process outliers. Each outlier is either added to the // appropriate outlier list or a new outlier list is made for (Outlier outlier : outliers) { Point2D point = outlier.getPoint(); drawEllipse(point, oRadius, g2); } // for (Iterator iterator = outlierListCollection.iterator(); // iterator.hasNext();) { // OutlierList list = (OutlierList) iterator.next(); // Outlier outlier = list.getAveragedOutlier(); // Point2D point = outlier.getPoint(); // // if (list.isMultiple()) { // drawMultipleEllipse(point, widthWeWannaUse, oRadius, // g2); // } // else { // drawEllipse(point, oRadius, g2); // } // } // // // draw farout indicators // if (outlierListCollection.isHighFarOut()) { // drawHighFarOut(aRadius / 2.0, g2, // xx + widthWeWannaUse / 2.0, maxAxisValue); // } // // if (outlierListCollection.isLowFarOut()) { // drawLowFarOut(aRadius / 2.0, g2, // xx + widthWeWannaUse / 2.0, minAxisValue); // } // } // // collect entity and tool tip information... // if (state.getInfo() != null && box != null) { // EntityCollection entities = state.getEntityCollection(); // if (entities != null) { // addItemEntity(entities, dataset, row, column, box); // } } }
From source file:com.stableapps.anglewraparounddemo.AngleWrapDemoMain.java
/** * Creates a sample chart./*from w w w. j av a 2 s. c o m*/ * * @return a sample chart. */ private JFreeChart createChart() { final XYDataset direction = createAngleDataset(600); final JFreeChart chart = ChartFactory.createTimeSeriesChart("Time", "Date", "Direction", direction, true, true, false); final XYPlot plot = chart.getXYPlot(); plot.getDomainAxis().setLowerMargin(0.0); plot.getDomainAxis().setUpperMargin(0.0); // configure the range axis to provide a fix set of TickUnits depending on size of chart NumberAxis rangeAxis = new NumberAxis() { /** * */ private static final long serialVersionUID = 1L; @Override public NumberTickUnit getTickUnit() { NumberTickUnit tickUnit = super.getTickUnit(); if (tickUnit.getSize() < 15) { return tickUnit; } else if (tickUnit.getSize() < 45) { return new NumberTickUnit(45); } else if (tickUnit.getSize() < 90) { return new NumberTickUnit(90); } else if (tickUnit.getSize() < 180) { return new NumberTickUnit(180); } else { return new NumberTickUnit(360); } } }; rangeAxis.setAutoRangeIncludesZero(false); plot.setRangeAxis(rangeAxis); final OverflowCondition overflowCondition = new OverflowCondition() { @Override public boolean isOverflow(double y0, double x0, double y1, double x1) { return Math.abs(y1 - y0) > 180; } }; XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, false) { /** * */ private static final long serialVersionUID = 1L; double min = 0; double max = 360; LinearInterpolator interpolator = new LinearInterpolator(); @Override protected void drawPrimaryLine(XYItemRendererState state, Graphics2D g2, XYPlot plot, XYDataset dataset, int pass, int series, int item, ValueAxis domainAxis, ValueAxis rangeAxis, Rectangle2D dataArea) { if (item == 0) { return; } // get the data point... double x1 = dataset.getXValue(series, item); double y1 = dataset.getYValue(series, item); if (Double.isNaN(y1) || Double.isNaN(x1)) { return; } double x0 = dataset.getXValue(series, item - 1); double y0 = dataset.getYValue(series, item - 1); if (Double.isNaN(y0) || Double.isNaN(x0)) { return; } if (overflowCondition.isOverflow(y0, x0, y1, x1)) { boolean overflowAtMax = y1 < y0; if (overflowAtMax) { LinearFunction lf = interpolator.interpolate(new double[] { y0, y1 + (max - min) }, new double[] { x0, x1 }); double xmid = lf.value(max); drawPrimaryLine(state, g2, plot, x0, y0, xmid, max, pass, series, item, domainAxis, rangeAxis, dataArea); drawPrimaryLine(state, g2, plot, xmid, min, x1, y1, pass, series, item, domainAxis, rangeAxis, dataArea); } else { LinearFunction lf = interpolator.interpolate(new double[] { y1 - (max - min), y0 }, new double[] { x1, x0 }); double xmid = lf.value(min); drawPrimaryLine(state, g2, plot, x0, y0, xmid, min, pass, series, item, domainAxis, rangeAxis, dataArea); drawPrimaryLine(state, g2, plot, xmid, max, x1, y1, pass, series, item, domainAxis, rangeAxis, dataArea); } } else { drawPrimaryLine(state, g2, plot, x0, y0, x1, y1, pass, series, item, domainAxis, rangeAxis, dataArea); } } private void drawPrimaryLine(XYItemRendererState state, Graphics2D g2, XYPlot plot, double x0, double y0, double x1, double y1, int pass, int series, int item, ValueAxis domainAxis, ValueAxis rangeAxis, Rectangle2D dataArea) { RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); double transX0 = domainAxis.valueToJava2D(x0, dataArea, xAxisLocation); double transY0 = rangeAxis.valueToJava2D(y0, dataArea, yAxisLocation); double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation); double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation); // only draw if we have good values if (Double.isNaN(transX0) || Double.isNaN(transY0) || Double.isNaN(transX1) || Double.isNaN(transY1)) { return; } PlotOrientation orientation = plot.getOrientation(); boolean visible; if (orientation == PlotOrientation.HORIZONTAL) { state.workingLine.setLine(transY0, transX0, transY1, transX1); } else if (orientation == PlotOrientation.VERTICAL) { state.workingLine.setLine(transX0, transY0, transX1, transY1); } visible = LineUtilities.clipLine(state.workingLine, dataArea); if (visible) { drawFirstPassShape(g2, pass, series, item, state.workingLine); } } @Override protected void drawPrimaryLineAsPath(XYItemRendererState state, Graphics2D g2, XYPlot plot, XYDataset dataset, int pass, int series, int item, ValueAxis domainAxis, ValueAxis rangeAxis, Rectangle2D dataArea) { // get the data point... State s = (State) state; try { double x1 = dataset.getXValue(series, item); double y1 = dataset.getYValue(series, item); if (Double.isNaN(x1) && Double.isNaN(y1)) { s.setLastPointGood(false); return; } if (!s.isLastPointGood()) { ImmutablePair<Float, Float> xy = translate(plot, domainAxis, rangeAxis, dataArea, x1, y1); s.seriesPath.moveTo(xy.getLeft(), xy.getRight()); s.setLastPointGood(true); return; } double x0 = dataset.getXValue(series, item - 1); double y0 = dataset.getYValue(series, item - 1); if (overflowCondition.isOverflow(y0, x0, y1, x1)) { boolean overflowAtMax = y1 < y0; if (overflowAtMax) { LinearFunction lf = interpolator.interpolate(new double[] { y0, y1 + (max - min) }, new double[] { x0, x1 }); double xmid = lf.value(max); ImmutablePair<Float, Float> xy = translate(plot, domainAxis, rangeAxis, dataArea, xmid, max); s.seriesPath.lineTo(xy.getLeft(), xy.getRight()); xy = translate(plot, domainAxis, rangeAxis, dataArea, xmid, min); s.seriesPath.moveTo(xy.getLeft(), xy.getRight()); xy = translate(plot, domainAxis, rangeAxis, dataArea, x1, y1); s.seriesPath.lineTo(xy.getLeft(), xy.getRight()); } else { LinearFunction lf = interpolator.interpolate(new double[] { y1 - (max - min), y0 }, new double[] { x1, x0 }); double xmid = lf.value(min); ImmutablePair<Float, Float> xy = translate(plot, domainAxis, rangeAxis, dataArea, xmid, min); s.seriesPath.lineTo(xy.getLeft(), xy.getRight()); xy = translate(plot, domainAxis, rangeAxis, dataArea, xmid, max); s.seriesPath.moveTo(xy.getLeft(), xy.getRight()); xy = translate(plot, domainAxis, rangeAxis, dataArea, x1, y1); s.seriesPath.lineTo(xy.getLeft(), xy.getRight()); } } else { ImmutablePair<Float, Float> xy = translate(plot, domainAxis, rangeAxis, dataArea, x1, y1); s.seriesPath.lineTo(xy.getLeft(), xy.getRight()); } s.setLastPointGood(true); } finally { // if this is the last item, draw the path ... if (item == s.getLastItemIndex()) { // draw path drawFirstPassShape(g2, pass, series, item, s.seriesPath); } } } private ImmutablePair<Float, Float> translate(XYPlot plot, ValueAxis domainAxis, ValueAxis rangeAxis, Rectangle2D dataArea, double x, double y) { RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); double transX1 = domainAxis.valueToJava2D(x, dataArea, xAxisLocation); double transY1 = rangeAxis.valueToJava2D(y, dataArea, yAxisLocation); // update path to reflect latest point float xtrans = (float) transX1; float ytrans = (float) transY1; PlotOrientation orientation = plot.getOrientation(); if (orientation == PlotOrientation.HORIZONTAL) { xtrans = (float) transY1; ytrans = (float) transX1; } return new ImmutablePair<>(xtrans, ytrans); } }; renderer.setDrawSeriesLineAsPath(true); plot.setRenderer(0, renderer); return chart; }
From source file:extern.NpairsBoxAndWhiskerRenderer.java
/** * Draws the visual representation of a single data item when the plot has * a horizontal orientation./*from www.j a v a 2 s . c om*/ * * @param g2 the graphics device. * @param state the renderer state. * @param dataArea the area within which the plot is being drawn. * @param plot the plot (can be used to obtain standard color * information etc). * @param domainAxis the domain axis. * @param rangeAxis the range axis. * @param dataset the dataset (must be an instance of * {@link BoxAndWhiskerCategoryDataset}). * @param row the row index (zero-based). * @param column the column index (zero-based). */ public void drawHorizontalItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column) { BoxAndWhiskerCategoryDataset bawDataset = (BoxAndWhiskerCategoryDataset) dataset; double categoryEnd = domainAxis.getCategoryEnd(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); double categoryStart = domainAxis.getCategoryStart(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); double categoryWidth = Math.abs(categoryEnd - categoryStart); double yy = categoryStart; int seriesCount = getRowCount(); int categoryCount = getColumnCount(); double widthWeWannaUse = Math.min(state.getBarWidth(), dataArea.getWidth() / 10); if (seriesCount > 1) { double seriesGap = dataArea.getHeight() * getItemMargin() / (categoryCount * (seriesCount - 1)); // double usedWidth = (state.getBarWidth() * seriesCount) // + (seriesGap * (seriesCount - 1)); double usedWidth = (widthWeWannaUse * seriesCount) + (seriesGap * (seriesCount - 1)); // offset the start of the boxes if the total width used is smaller // than the category width double offset = (categoryWidth - usedWidth) / 2; // yy = yy + offset + (row * (state.getBarWidth() + seriesGap)); yy = yy + offset + (row * (widthWeWannaUse + seriesGap)); } else { // offset the start of the box if the box width is smaller than // the category width // double offset = (categoryWidth - state.getBarWidth()) / 2; double offset = (categoryWidth - widthWeWannaUse) / 2; yy = yy + offset; } g2.setPaint(getItemPaint(row, column)); Stroke s = getItemStroke(row, column); g2.setStroke(s); RectangleEdge location = plot.getRangeAxisEdge(); Number xQ1 = bawDataset.getQ1Value(row, column); Number xQ3 = bawDataset.getQ3Value(row, column); Number xMax = bawDataset.getMaxRegularValue(row, column); Number xMin = bawDataset.getMinRegularValue(row, column); Shape box = null; if (xQ1 != null && xQ3 != null && xMax != null && xMin != null) { double xxQ1 = rangeAxis.valueToJava2D(xQ1.doubleValue(), dataArea, location); double xxQ3 = rangeAxis.valueToJava2D(xQ3.doubleValue(), dataArea, location); double xxMax = rangeAxis.valueToJava2D(xMax.doubleValue(), dataArea, location); double xxMin = rangeAxis.valueToJava2D(xMin.doubleValue(), dataArea, location); // double yymid = yy + state.getBarWidth() / 2.0; double yymid = yy + widthWeWannaUse / 2.0; // draw the upper shadow... g2.draw(new Line2D.Double(xxMax, yymid, xxQ3, yymid)); // g2.draw(new Line2D.Double(xxMax, yy, xxMax, // yy + state.getBarWidth())); g2.draw(new Line2D.Double(xxMax, yy, xxMax, yy + widthWeWannaUse)); // draw the lower shadow... g2.draw(new Line2D.Double(xxMin, yymid, xxQ1, yymid)); // g2.draw(new Line2D.Double(xxMin, yy, xxMin, // yy + state.getBarWidth())); g2.draw(new Line2D.Double(xxMin, yy, xxMin, yy + widthWeWannaUse)); // draw the box... // box = new Rectangle2D.Double(Math.min(xxQ1, xxQ3), yy, // Math.abs(xxQ1 - xxQ3), state.getBarWidth()); box = new Rectangle2D.Double(Math.min(xxQ1, xxQ3), yy, Math.abs(xxQ1 - xxQ3), widthWeWannaUse); if (this.fillBox) { g2.fill(box); } g2.setStroke(getItemOutlineStroke(row, column)); g2.setPaint(getItemOutlinePaint(row, column)); g2.draw(box); } g2.setPaint(this.artifactPaint); double aRadius = 0; // average radius // draw mean - SPECIAL AIMS REQUIREMENT... Number xMean = bawDataset.getMeanValue(row, column); if (xMean != null) { double xxMean = rangeAxis.valueToJava2D(xMean.doubleValue(), dataArea, location); // aRadius = state.getBarWidth() / 4; aRadius = widthWeWannaUse / 4; // here we check that the average marker will in fact be visible // before drawing it... if ((xxMean > (dataArea.getMinX() - aRadius)) && (xxMean < (dataArea.getMaxX() + aRadius))) { Ellipse2D.Double avgEllipse = new Ellipse2D.Double(xxMean - aRadius, yy + aRadius, aRadius * 2, aRadius * 2); g2.fill(avgEllipse); g2.draw(avgEllipse); } } // draw median... Number xMedian = bawDataset.getMedianValue(row, column); if (xMedian != null) { double xxMedian = rangeAxis.valueToJava2D(xMedian.doubleValue(), dataArea, location); // g2.draw(new Line2D.Double(xxMedian, yy, xxMedian, // yy + state.getBarWidth())); g2.draw(new Line2D.Double(xxMedian, yy, xxMedian, yy + widthWeWannaUse)); } // collect entity and tool tip information... if (state.getInfo() != null && box != null) { EntityCollection entities = state.getEntityCollection(); if (entities != null) { addItemEntity(entities, dataset, row, column, box); } } }
From source file:extern.PlotBySplitClassRenderer.java
/** * Draws the visual representation of a single data item when the plot has * a vertical orientation./*from www .jav a2 s. c o m*/ * * @param g2 the graphics device. * @param state the renderer state. * @param dataArea the area within which the plot is being drawn. * @param plot the plot (can be used to obtain standard color information * etc). * @param domainAxis the domain axis. * @param rangeAxis the range axis. * @param dataset the dataset (must be an instance of * {@link BoxAndWhiskerCategoryDataset}). * @param row the row index (zero-based). * @param column the column index (zero-based). */ public void drawVerticalItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column) { if (lastSplitObj != column) { lastSplitObj = column; prevX = -1; prevY = -1; } BoxAndWhiskerCategoryDataset bawDataset = (BoxAndWhiskerCategoryDataset) dataset; double categoryEnd = domainAxis.getCategoryEnd(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); double categoryStart = domainAxis.getCategoryStart(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); double categoryWidth = categoryEnd - categoryStart; double xx = categoryStart; int seriesCount = getRowCount(); int categoryCount = getColumnCount(); double widthToUse = Math.min(state.getBarWidth(), dataArea.getWidth() / 15); if (seriesCount > 1) { double seriesGap = dataArea.getWidth() * getItemMargin() / (categoryCount * (seriesCount - 1)); double usedWidth = (widthToUse * seriesCount) + (seriesGap * (seriesCount - 1)); // offset the start of the boxes if the total width used is smaller // than the category width double offset = (categoryWidth - usedWidth) / 2; xx = xx + offset + (row * (widthToUse + seriesGap)); } else { // offset the start of the box if the box width is smaller than the // category width double offset = (categoryWidth - widthToUse) / 2; xx = xx + offset; } double yyAverage = 0.0; double yyOutlier; Paint itemPaint = getItemPaint(row, column); g2.setPaint(itemPaint); Stroke s = getItemStroke(row, column); g2.setStroke(s); double aRadius = 0; // average radius 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; double xxmid = xx + widthToUse / 2.0; double yyQ1 = 0; double yyQ3 = 0; if (yQ1 != null && yQ3 != null && yMax != null && yMin != null) { yyQ1 = rangeAxis.valueToJava2D(yQ1.doubleValue(), dataArea, location); yyQ3 = rangeAxis.valueToJava2D(yQ3.doubleValue(), dataArea, location); double yyMax = rangeAxis.valueToJava2D(yMax.doubleValue(), dataArea, location); double yyMin = rangeAxis.valueToJava2D(yMin.doubleValue(), dataArea, location); // draw the upper shadow... g2.draw(new Line2D.Double(xxmid, yyMax, xxmid, yyQ3)); g2.draw(new Line2D.Double(xx, yyMax, xx + widthToUse, yyMax)); // draw the lower shadow... g2.draw(new Line2D.Double(xxmid, yyMin, xxmid, yyQ1)); g2.draw(new Line2D.Double(xx, yyMin, xx + widthToUse, yyMin)); // draw the body... box = new Rectangle2D.Double(xx, Math.min(yyQ1, yyQ3), widthToUse, Math.abs(yyQ1 - yyQ3)); if (this.fillBox) { g2.fill(box); } g2.setStroke(getItemOutlineStroke(row, column)); g2.setPaint(getItemOutlinePaint(row, column)); g2.draw(box); } g2.setPaint(this.artifactPaint); // draw mean - SPECIAL AIMS REQUIREMENT... Number yMean = bawDataset.getMeanValue(row, column); if (yMean != null && !Double.isNaN(yMean.doubleValue())) { yyAverage = rangeAxis.valueToJava2D(yMean.doubleValue(), dataArea, location); // THIS IS WHAT WE CHANGED // aRadius = widthWeWannaUse / 4; aRadius = 4; // here we check that the average marker will in fact be visible // before drawing it... // WE HAD TO CHANGE THIS TOO I DON'T KNOW WHAT THEY WERE DOING if ((yyAverage > (dataArea.getMinY() - aRadius)) && (yyAverage < (dataArea.getMaxY() + aRadius))) { Ellipse2D.Double avgEllipse = new Ellipse2D.Double(xxmid - aRadius, yyAverage - aRadius, aRadius * 2, aRadius * 2); //If this is a single point only, then draw this point with //the color of its class. if (yQ1 != null && yQ3 != null) { if (aRadius / 2 > Math.abs(yyQ3 - yyQ1)) { g2.setPaint(itemPaint); } } g2.fill(avgEllipse); g2.draw(avgEllipse); } } // draw median... Number yMedian = bawDataset.getMedianValue(row, column); if (yMedian != null && !Double.isNaN(yMedian.doubleValue())) { double yyMedian = rangeAxis.valueToJava2D(yMedian.doubleValue(), dataArea, location); g2.draw(new Line2D.Double(xx, yyMedian, xx + widthToUse, yyMedian)); // add a line to connect the means of the boxes if (prevX != -1 && prevY != -1) { g2.setPaint(artifactPaint); g2.draw(new Line2D.Double(prevX, prevY, xxmid, yyMedian)); } prevX = xxmid; prevY = yyMedian; } // draw yOutliers... g2.setPaint(itemPaint); // draw outliers double oRadius = 4; // outlier radius List<Outlier> outliers = new ArrayList<Outlier>(); // From outlier array sort out which are outliers and put these into a // list If there are any farouts, set the flag on the // OutlierListCollection List<Number> yOutliers = bawDataset.getOutliers(row, column); if (yOutliers != null) { for (int i = 0; i < yOutliers.size(); i++) { double outlier = yOutliers.get(i).doubleValue(); yyOutlier = rangeAxis.valueToJava2D(outlier, dataArea, location); outliers.add(new Outlier(xxmid, yyOutlier, oRadius)); } // Process outliers. Each outlier is either added to the // appropriate outlier list or a new outlier list is made for (Outlier outlier : outliers) { Point2D point = outlier.getPoint(); drawEllipse(point, oRadius, g2); } } }
From source file:aprofplot.jfreechart.SamplingXYLineAndShapeRenderer.java
protected void drawSeriesLine(Graphics2D g2, XYItemRendererState state, Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot, ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset, int series, CrosshairState crosshairState, int pass) { State s = (State) state; PlotOrientation orientation = plot.getOrientation(); RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); double lowestVisibleX = domainAxis.getLowerBound(); double highestVisibleX = domainAxis.getUpperBound(); double width = (orientation == PlotOrientation.HORIZONTAL) ? dataArea.getHeight() : dataArea.getWidth(); double dX = (highestVisibleX - lowestVisibleX) / width * lineWidth; double lowestVisibleY = rangeAxis.getLowerBound(); double highestVisibleY = rangeAxis.getUpperBound(); double lastX = Double.NEGATIVE_INFINITY; double lastY = 0.0; double highY = 0.0; double lowY = 0.0; double closeY = 0.0; boolean lastIntervalDone = false; boolean currentPointVisible = false; boolean lastPointVisible = false; boolean lastPointGood = false; boolean lastPointInInterval = false; int intervalCount = 0; int badPoints = 0; for (int itemIndex = state.getFirstItemIndex(); itemIndex <= state.getLastItemIndex(); itemIndex++) { double x = dataset.getXValue(series, itemIndex); double y = dataset.getYValue(series, itemIndex); if (!Double.isNaN(x) && !Double.isNaN(y)) { if ((Math.abs(x - lastX) > dX)) { //System.out.println("Breakpoint 1: leaving interval"); //in any case, add the interval that we are about to leave to the intervalPath float intervalStartX = 0.0f; float intervalEndX = 0.0f; float intervalStartY = 0.0f; float intervalEndY = 0.0f; float currentX = 0.0f; float currentY = 0.0f; float lastFX = 0.0f; float lastFY = 0.0f; //first set some variables if (orientation == PlotOrientation.VERTICAL) { intervalStartX = (float) domainAxis.valueToJava2D(lastX, dataArea, xAxisLocation); intervalEndX = (float) domainAxis.valueToJava2D(lastX, dataArea, xAxisLocation); intervalStartY = (float) rangeAxis.valueToJava2D(lowY, dataArea, yAxisLocation); intervalEndY = (float) rangeAxis.valueToJava2D(highY, dataArea, yAxisLocation); currentX = (float) domainAxis.valueToJava2D(x, dataArea, xAxisLocation); lastFX = (float) domainAxis.valueToJava2D(lastX, dataArea, xAxisLocation); currentY = (float) rangeAxis.valueToJava2D(y, dataArea, yAxisLocation); lastFY = (float) rangeAxis.valueToJava2D(closeY, dataArea, yAxisLocation); } else { intervalStartX = (float) rangeAxis.valueToJava2D(lowY, dataArea, yAxisLocation); intervalEndX = (float) rangeAxis.valueToJava2D(highY, dataArea, yAxisLocation); intervalStartY = (float) domainAxis.valueToJava2D(lastX, dataArea, xAxisLocation); intervalEndY = (float) domainAxis.valueToJava2D(lastX, dataArea, xAxisLocation); currentX = (float) rangeAxis.valueToJava2D(y, dataArea, yAxisLocation); lastFX = (float) rangeAxis.valueToJava2D(closeY, dataArea, yAxisLocation); currentY = (float) domainAxis.valueToJava2D(x, dataArea, xAxisLocation); lastFY = (float) domainAxis.valueToJava2D(lastX, dataArea, xAxisLocation); }/* w w w . j av a 2 s. c om*/ if ((lowY - highY) < 1) { //System.out.println("Breakpoint 2: setting lastPointInInterval"); lastPointInInterval = false; } //System.out.println("Breakpoint 3: lastPointInInterval: " +lastPointInInterval); if ((lowY < highY)) { intervalCount++; //System.out.println("Breakpoint 4: adding segment to interval path:" ); //System.out.println("xStart" + intervalStartX + ", yStart " + intervalStartY + ", xEnd " + intervalEndX + ", yEnd " + intervalEndY); s.intervalPath.moveTo(intervalStartX, intervalStartY); s.intervalPath.lineTo(intervalEndX, intervalEndY); lastIntervalDone = true; } //now the series path currentPointVisible = ((x >= lowestVisibleX) && (x <= highestVisibleX) && (y >= lowestVisibleY) && (y <= highestVisibleY)); if (!lastPointGood) {//last point not valid -- badPoints++; if (currentPointVisible) {//--> if the current position is visible move seriesPath cursor to the current position s.seriesPath.moveTo(currentX, currentY); } } else {//last point valid //if the last point was visible and not part of an interval, //we have already moved the seriesPath cursor to the last point, either with or without drawingh a line //thus we only need to draw a line to the current position if (lastPointVisible && !lastPointInInterval) { s.seriesPath.lineTo(currentX, currentY); } //if the last point was not visible or part of an interval, we have just stored the y values of the last point //and not yet moved the seriesPath cursor. Thus, we need to move the cursor to the last point without drawing //and draw a line to the current position. else { s.seriesPath.moveTo(lastFX, lastFY); s.seriesPath.lineTo(currentX, currentY); } } lastPointVisible = currentPointVisible; lastX = x; lastY = y; highY = y; lowY = y; closeY = y; lastPointInInterval = false; } else { lastIntervalDone = false; lastPointInInterval = true; highY = Math.max(highY, y); lowY = Math.min(lowY, y); closeY = y; } lastPointGood = true; } else { lastPointGood = false; } } // if this is the last item, draw the path ... // draw path, but first check whether we need to complete an interval if (!lastIntervalDone) { if (lowY < highY) { float intervalStartX = 0.0f; float intervalEndX = 0.0f; float intervalStartY = 0.0f; float intervalEndY = 0.0f; if (orientation == PlotOrientation.VERTICAL) { intervalStartX = (float) domainAxis.valueToJava2D(lastX, dataArea, xAxisLocation); intervalEndX = (float) domainAxis.valueToJava2D(lastX, dataArea, xAxisLocation); intervalStartY = (float) rangeAxis.valueToJava2D(lowY, dataArea, yAxisLocation); intervalEndY = (float) rangeAxis.valueToJava2D(highY, dataArea, yAxisLocation); } else { intervalStartX = (float) rangeAxis.valueToJava2D(lowY, dataArea, yAxisLocation); intervalEndX = (float) rangeAxis.valueToJava2D(highY, dataArea, yAxisLocation); intervalStartY = (float) domainAxis.valueToJava2D(lastX, dataArea, xAxisLocation); intervalEndY = (float) domainAxis.valueToJava2D(lastX, dataArea, xAxisLocation); } intervalCount++; s.intervalPath.moveTo(intervalStartX, intervalStartY); s.intervalPath.lineTo(intervalEndX, intervalEndY); } } PathIterator pi = s.seriesPath.getPathIterator(null); g2.setStroke(getItemStroke(series, 0)); g2.setPaint(getItemPaint(series, 0)); g2.draw(s.seriesPath); g2.draw(s.intervalPath); //System.out.println("Interval count " + intervalCount); //System.out.println("Bad points " + badPoints); }
From source file:gov.nih.nci.caintegrator.application.graphing.BoxAndWhiskerDotsRenderer.java
/** * Draws the visual representation of a single data item when the plot has * a vertical orientation./*from w w w . j a v a2s. c om*/ * * @param g2 the graphics device. * @param state the renderer state. * @param dataArea the area within which the plot is being drawn. * @param plot the plot (can be used to obtain standard color information * etc). * @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). */ public void drawVerticalItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column) { BoxAndWhiskerCategoryDataset bawDataset = (BoxAndWhiskerCategoryDataset) dataset; double categoryEnd = domainAxis.getCategoryEnd(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); double categoryStart = domainAxis.getCategoryStart(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); double categoryWidth = (categoryEnd - categoryStart); double xx = categoryStart; int seriesCount = getRowCount(); int categoryCount = getColumnCount(); if (seriesCount > 1) { double seriesGap = dataArea.getWidth() * getItemMargin() / (categoryCount * (seriesCount - 1)); double usedWidth = (state.getBarWidth() * seriesCount) + (seriesGap * (seriesCount - 1)); // offset the start of the boxes if the total width used is smaller // than the category width double offset = (categoryWidth - usedWidth) / 2; xx = xx + offset + (row * (state.getBarWidth() + seriesGap)); } else { // offset the start of the box if the box width is smaller than the // category width double offset = (categoryWidth - state.getBarWidth()) / 2; xx = xx + offset; } double yyAverage = 0.0; double yyOutlier; //bar colors are determined by the Paint p obtained here in a rotational //manner (from a Color array). By switching the column and raw values, //you can get a different color pattern for the bar: In the method //getItemPaint(), only the first argument counts for the color. The original //code Paint p = getItemPaint(row, column); is commented out for a difference. //Paint p = getItemPaint(row, column); Paint p = getItemPaint(column, row); // <-- this is wrong, dont know who put this here // Paint p = PaintUtilities.stringToColor("red"); // coin plot should all be one color if (p != null) { g2.setPaint(p); } Stroke s = getItemStroke(row, column); g2.setStroke(s); double aRadius = 0; // average radius 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 (this.fillBox) { g2.fill(box); } //The following draw the boxes where mean and media are located. g2.draw(box); } g2.setPaint(this.artifactPaint); // draw median... Number yMedian = bawDataset.getMedianValue(row, column); if (yMedian != null) { double yyMedian = rangeAxis.valueToJava2D(yMedian.doubleValue(), dataArea, location); g2.draw(new Line2D.Double(xx, yyMedian, xx + state.getBarWidth(), yyMedian)); } //caIntegrator: The outLiner is no longer needed to be here. // draw the rawData around the box... /////////////////////////////////caIntegrator: Begin of drawing dots around the box double maxAxisValue = rangeAxis.valueToJava2D(rangeAxis.getUpperBound(), dataArea, location) + aRadius; double minAxisValue = rangeAxis.valueToJava2D(rangeAxis.getLowerBound(), dataArea, location) - aRadius; g2.setPaint(p); //caIntegrator: oRadius is the radius of the outlier circles. It was used to be 3. double oRadius = state.getBarWidth() / 10; // outlier radius List outliers = new ArrayList(); //Get the raw item data for a given row/column pair for plotting. //getRawItemData() method is added to bawDataset object for //this purpose. //List yOutliers = bawDataset.getRawItemData(row, column); List yOutliers = this.caintegOutliers.get(String.valueOf(row) + "_" + String.valueOf(column)); if (yOutliers != null) { for (int i = 0; i < yOutliers.size(); i++) { double outlier = ((Number) yOutliers.get(i)).doubleValue(); yyOutlier = rangeAxis.valueToJava2D(outlier, dataArea, location); outliers.add(new Outlier(xx + state.getBarWidth() / 2.0, yyOutlier, oRadius)); Collections.sort(outliers); } //Sort the raw data according to its Y axis first as groups. //Grouping of these raw data is based on a single standard: //if any number of data, when plotted on a vertical line, overlap //with one another, they belong to the same group. In this case, //the grouping is largely determined by the diameter of the dot, that //represents each raw data. boolean firstOutlier = true; double topY = 0; double bottomY = 0; List groupList = new ArrayList(); List tempList = null; double diameter = 2 * oRadius; double difference = 0; for (Iterator iterator = outliers.iterator(); iterator.hasNext();) { Outlier outlier = (Outlier) iterator.next(); //Set the smallest outlier as the base bottom line if (firstOutlier) { firstOutlier = false; bottomY = outlier.getY(); tempList = new ArrayList(); tempList.add(outlier); continue; } topY = outlier.getY(); //If this one and the one before it is overlapping, //Then put them in the same group, so we can spread them //horizontally difference = topY - bottomY; if (difference < diameter) { tempList.add(outlier); } //They do not overlap, they belong to the different groups. else { bottomY = topY; groupList.add(tempList); tempList = new ArrayList(); tempList.add(outlier); } } //caIntegrator - x axis cloud //Process each outlier's x coordinates boolean isOdd = true; double offSet = 0; int listSize = 0; for (int m = 0; m < groupList.size(); m++) { List list = (List) groupList.get(m); if (list != null && list.size() > 1) { listSize = list.size(); isOdd = (listSize % 2 == 1) ? true : false; if (isOdd) { offSet = diameter * (listSize / 2); } else { offSet = diameter * (listSize / 2) - oRadius; } Random r = new Random(); offSet = (Math.abs(r.nextInt()) % 3) * 3; offSet = 0; for (int n = 0; n < list.size(); n++) { Outlier outlier = (Outlier) list.get(n); outlier.setPoint(new Point2D.Double(outlier.getX() - offSet, outlier.getY())); offSet = offSet - diameter; r = new Random(); int randInt = Math.abs(r.nextInt()) % 3; offSet = randInt * 2; } } } //Draw these dots on the graph. for (Iterator iterator = groupList.iterator(); iterator.hasNext();) { List list = (List) iterator.next(); for (int i = 0; i < list.size(); i++) { Outlier outlier = (Outlier) list.get(i); Point2D point = outlier.getPoint(); drawEllipse(point, oRadius, g2); } } } }
From source file:gov.nih.nci.caintegrator.ui.graphing.chart.plot.BoxAndWhiskerCoinPlotRenderer.java
/** * Draws the visual representation of a single data item when the plot has * a vertical orientation.//from ww w . j a v a 2 s . c o m * * @param g2 the graphics device. * @param state the renderer state. * @param dataArea the area within which the plot is being drawn. * @param plot the plot (can be used to obtain standard color information * etc). * @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). */ public void drawVerticalItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column) { BoxAndWhiskerCategoryDataset bawDataset = (BoxAndWhiskerCategoryDataset) dataset; double categoryEnd = domainAxis.getCategoryEnd(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); double categoryStart = domainAxis.getCategoryStart(column, getColumnCount(), dataArea, plot.getDomainAxisEdge()); double categoryWidth = categoryEnd - categoryStart; double xx = categoryStart; int seriesCount = getRowCount(); int categoryCount = getColumnCount(); if (seriesCount > 1) { double seriesGap = dataArea.getWidth() * getItemMargin() / (categoryCount * (seriesCount - 1)); double usedWidth = (state.getBarWidth() * seriesCount) + (seriesGap * (seriesCount - 1)); // offset the start of the boxes if the total width used is smaller // than the category width double offset = (categoryWidth - usedWidth) / 2; xx = xx + offset + (row * (state.getBarWidth() + seriesGap)); } else { // offset the start of the box if the box width is smaller than the // category width double offset = (categoryWidth - state.getBarWidth()) / 2; xx = xx + offset; } double yyAverage = 0.0; double yyOutlier; // bar colors are determined by the Paint p obtained here in a rotational //manner (from a Color array). By switching the column and raw values, //you can get a different color pattern for the bar: In the method //getItemPaint(), only the first argument counts for the color. The original //code Paint p = getItemPaint(row, column); is commented out for a difference. Paint p = null; if (this.getPlotColor() != null) { p = PaintUtilities.stringToColor(getPlotColor()); // coin plot should all be one color } else { p = getItemPaint(row, column); } // Paint p = PaintUtilities.stringToColor("red"); if (p != null) { g2.setPaint(p); } Stroke s = getItemStroke(row, column); g2.setStroke(s); double aRadius = 0; // average radius 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); } g2.setPaint(getArtifactPaint()); if (this.isDisplayMean()) { // draw mean - SPECIAL AIMS REQUIREMENT... Number yMean = bawDataset.getMeanValue(row, column); if (yMean != null) { yyAverage = rangeAxis.valueToJava2D(yMean.doubleValue(), dataArea, location); aRadius = state.getBarWidth() / 4; Ellipse2D.Double avgEllipse = new Ellipse2D.Double(xx + aRadius, yyAverage - aRadius, aRadius * 2, aRadius * 2); g2.fill(avgEllipse); g2.draw(avgEllipse); } } if (this.isDisplayMedian()) { // draw median... Number yMedian = bawDataset.getMedianValue(row, column); if (yMedian != null) { double yyMedian = rangeAxis.valueToJava2D(yMedian.doubleValue(), dataArea, location); g2.draw(new Line2D.Double(xx, yyMedian, xx + state.getBarWidth(), yyMedian)); } } // draw yOutliers... double maxAxisValue = rangeAxis.valueToJava2D(rangeAxis.getUpperBound(), dataArea, location) + aRadius; double minAxisValue = rangeAxis.valueToJava2D(rangeAxis.getLowerBound(), dataArea, location) - aRadius; g2.setPaint(p); if (this.isDisplayCoinCloud()) { //draw coin clouds drawCoinCloud(g2, state, dataArea, location, rangeAxis, xx, row, column, bawDataset); } //caIntegrator: oRadius is the radius of the outlier circles. It was used to be 3. // draw outliers double oRadius = state.getBarWidth() / this.outlierRadiusDenominator; // outlier radius List outliers = new ArrayList(); OutlierListCollection outlierListCollection = new OutlierListCollection(); List yOutliers = bawDataset.getOutliers(row, column); if (yOutliers != null) { for (int i = 0; i < yOutliers.size(); i++) { double outlier = ((Number) yOutliers.get(i)).doubleValue(); Number minOutlier = bawDataset.getMinOutlier(row, column); Number maxOutlier = bawDataset.getMaxOutlier(row, column); Number minRegular = bawDataset.getMinRegularValue(row, column); Number maxRegular = bawDataset.getMaxRegularValue(row, column); if (outlier > maxOutlier.doubleValue()) { outlierListCollection.setHighFarOut(true); } else if (outlier < minOutlier.doubleValue()) { outlierListCollection.setLowFarOut(true); } else if (outlier > maxRegular.doubleValue()) { yyOutlier = rangeAxis.valueToJava2D(outlier, dataArea, location); outliers.add(new Outlier(xx + state.getBarWidth() / 2.0, yyOutlier, oRadius)); } else if (outlier < minRegular.doubleValue()) { yyOutlier = rangeAxis.valueToJava2D(outlier, dataArea, location); outliers.add(new Outlier(xx + state.getBarWidth() / 2.0, yyOutlier, oRadius)); } Collections.sort(outliers); } //display farouts as JFreeChart Implemetation if (!displayAllOutliers) { // Process outliers. Each outlier is either added to the // appropriate outlier list or a new outlier list is made for (int i = 0; i < yOutliers.size(); i++) { Number minRegular = bawDataset.getMinRegularValue(row, column); Number maxRegular = bawDataset.getMaxRegularValue(row, column); double outlier = ((Number) yOutliers.get(i)).doubleValue(); if (outlier < minRegular.doubleValue() || outlier > maxRegular.doubleValue()) { yyOutlier = rangeAxis.valueToJava2D(outlier, dataArea, location); outliers.add(new Outlier(xx + state.getBarWidth() / 2.0, yyOutlier, oRadius)); } } for (Iterator iterator = outliers.iterator(); iterator.hasNext();) { Outlier outlier = (Outlier) iterator.next(); outlierListCollection.add(outlier); } for (Iterator iterator = outlierListCollection.iterator(); iterator.hasNext();) { OutlierList list = (OutlierList) iterator.next(); Outlier outlier = list.getAveragedOutlier(); Point2D point = outlier.getPoint(); if (list.isMultiple()) { drawMultipleEllipse(point, state.getBarWidth(), oRadius, g2); } else { drawEllipse(point, oRadius, g2); } } // draw farout indicators if (outlierListCollection.isHighFarOut()) { drawHighFarOut(aRadius / 2.0, g2, xx + state.getBarWidth() / 2.0, maxAxisValue); } if (outlierListCollection.isLowFarOut()) { drawLowFarOut(aRadius / 2.0, g2, xx + state.getBarWidth() / 2.0, minAxisValue); } } else { for (int i = 0; i < yOutliers.size(); i++) { Number minRegular = bawDataset.getMinRegularValue(row, column); Number maxRegular = bawDataset.getMaxRegularValue(row, column); double outlier = ((Number) yOutliers.get(i)).doubleValue(); if (outlier < minRegular.doubleValue() || outlier > maxRegular.doubleValue()) { yyOutlier = rangeAxis.valueToJava2D(outlier, dataArea, location); outliers.add(new Outlier(xx + state.getBarWidth() / 2.0, yyOutlier, oRadius)); } } Collections.sort(outliers); for (Iterator iterator = outliers.iterator(); iterator.hasNext();) { Outlier outlier = (Outlier) iterator.next(); Point2D point = outlier.getPoint(); drawEllipse(point, oRadius, g2); } } } // collect entity and tool tip information... if (state.getInfo() != null) { EntityCollection entities = state.getEntityCollection(); if (entities != null) { String tip = null; CategoryToolTipGenerator tipster = getToolTipGenerator(row, column); if (tipster != null) { tip = tipster.generateToolTip(dataset, row, column); } String url = null; if (getItemURLGenerator(row, column) != null) { url = getItemURLGenerator(row, column).generateURL(dataset, row, column); } CategoryItemEntity entity = new CategoryItemEntity(box, tip, url, dataset, row, dataset.getColumnKey(column), column); entities.add(entity); } } }