protected JFreeChart createPie3DChart() throws JRException { JFreeChart jfreeChart = super.createPie3DChart(); PiePlot3D piePlot3D = (PiePlot3D) jfreeChart.getPlot(); if (piePlot3D.getLabelGenerator() != null) { piePlot3D.setLabelBackgroundPaint(ChartThemesConstants.TRANSPARENT_PAINT); piePlot3D.setLabelShadowPaint(ChartThemesConstants.TRANSPARENT_PAINT); piePlot3D.setLabelOutlinePaint(ChartThemesConstants.TRANSPARENT_PAINT); } piePlot3D.setDarkerSides(true); piePlot3D.setDepthFactor(0.07); // does not work for 3D // piePlot3D.setShadowXOffset(5); // piePlot3D.setShadowYOffset(10); // piePlot3D.setShadowPaint(new GradientPaint( // 0, // getChart().getHeight() / 2, // new Color(41, 120, 162), // 0, // getChart().getHeight(), // Color.white) // ); PieDataset pieDataset = piePlot3D.getDataset(); if (pieDataset != null) { for (int i = 0; i < pieDataset.getItemCount(); i++) { piePlot3D.setSectionOutlinePaint( pieDataset.getKey(i), ChartThemesConstants.TRANSPARENT_PAINT); } } piePlot3D.setCircular(true); return jfreeChart; }
private static Collection getAllStatisticKeys(PieDataset pieDataset) { final List statisticKeys = newArrayList(); final List segmentKeys = pieDataset.getKeys(); for (final Object segmentKey : segmentKeys) { if (segmentKey instanceof PieSegment) { statisticKeys.add(((PieSegment) segmentKey).getKey()); } } return statisticKeys; }
/** Set colors for traffic light colors properly. */ @SuppressWarnings("unchecked") private void setColors(PiePlot plot, PieDataset dataSet) { List<Comparable<?>> keys = dataSet.getKeys(); for (Comparable<?> key : keys) { if (key instanceof ETrafficLightColor) { plot.setSectionPaint(key, AssessmentColorizer.determineColor((ETrafficLightColor) key)); } } }
protected JFreeChart createPieChart() throws JRException { JFreeChart jfreeChart = super.createPieChart(); PiePlot piePlot = (PiePlot) jfreeChart.getPlot(); if (piePlot.getLabelGenerator() != null) { piePlot.setLabelBackgroundPaint(ChartThemesConstants.TRANSPARENT_PAINT); piePlot.setLabelShadowPaint(ChartThemesConstants.TRANSPARENT_PAINT); piePlot.setLabelOutlinePaint(ChartThemesConstants.TRANSPARENT_PAINT); } piePlot.setShadowXOffset(0); piePlot.setShadowYOffset(0); PieDataset pieDataset = piePlot.getDataset(); if (pieDataset != null) { for (int i = 0; i < pieDataset.getItemCount(); i++) { piePlot.setSectionOutlinePaint( pieDataset.getKey(i), ChartThemesConstants.TRANSPARENT_PAINT); // makes pie colors darker // piePlot.setSectionPaint(pieDataset.getKey(i), GRADIENT_PAINTS[i]); } } piePlot.setCircular(true); return jfreeChart; }
/** * Draws the plot on a Java 2D graphics device (such as the screen or a printer). * * @param g2 the graphics device. * @param area the area within which the plot should be drawn. * @param anchor the anchor point (<code>null</code> permitted). * @param parentState the state from the parent plot, if there is one. * @param info collects info about the drawing. */ public void draw( Graphics2D g2, Rectangle2D area, Point2D anchor, PlotState parentState, PlotRenderingInfo info) { // adjust the drawing area for the plot insets (if any)... RectangleInsets insets = getInsets(); insets.trim(area); drawBackground(g2, area); drawOutline(g2, area); // check that there is some data to display... if (DatasetUtilities.isEmptyOrNull(getDataset())) { drawNoDataMessage(g2, area); return; } int pieCount = 0; if (getDataExtractOrder() == TableOrder.BY_ROW) { pieCount = getDataset().getRowCount(); } else { pieCount = getDataset().getColumnCount(); } // the columns variable is always >= rows int displayCols = (int) Math.ceil(Math.sqrt(pieCount)); int displayRows = (int) Math.ceil((double) pieCount / (double) displayCols); // swap rows and columns to match plotArea shape if (displayCols > displayRows && area.getWidth() < area.getHeight()) { int temp = displayCols; displayCols = displayRows; displayRows = temp; } prefetchSectionPaints(); int x = (int) area.getX(); int y = (int) area.getY(); int width = ((int) area.getWidth()) / displayCols; int height = ((int) area.getHeight()) / displayRows; int row = 0; int column = 0; int diff = (displayRows * displayCols) - pieCount; int xoffset = 0; Rectangle rect = new Rectangle(); for (int pieIndex = 0; pieIndex < pieCount; pieIndex++) { rect.setBounds(x + xoffset + (width * column), y + (height * row), width, height); String title = null; if (getDataExtractOrder() == TableOrder.BY_ROW) { title = getDataset().getRowKey(pieIndex).toString(); } else { title = getDataset().getColumnKey(pieIndex).toString(); } getPieChart().setTitle(title); PieDataset piedataset = null; PieDataset dd = new CategoryToPieDataset(getDataset(), getDataExtractOrder(), pieIndex); if (getLimit() > 0.0) { piedataset = DatasetUtilities.createConsolidatedPieDataset(dd, getAggregatedItemsKey(), getLimit()); } else { piedataset = dd; } PiePlot piePlot = (PiePlot) getPieChart().getPlot(); piePlot.setDataset(piedataset); piePlot.setPieIndex(pieIndex); // update the section colors to match the global colors... for (int i = 0; i < piedataset.getItemCount(); i++) { Comparable key = piedataset.getKey(i); Paint p; if (key.equals(getAggregatedItemsKey())) { p = getAggregatedItemsPaint(); } else { p = (Paint) this.sectionPaints.get(key); } piePlot.setSectionPaint(key, p); } ChartRenderingInfo subinfo = null; if (info != null) { subinfo = new ChartRenderingInfo(); } getPieChart().draw(g2, rect, subinfo); if (info != null) { info.getOwner().getEntityCollection().addAll(subinfo.getEntityCollection()); info.addSubplotInfo(subinfo.getPlotInfo()); } ++column; if (column == displayCols) { column = 0; ++row; if (row == displayRows - 1 && diff != 0) { xoffset = (diff * width) / 2; } } } }
/** * Draws a single data item. * * @param g2 the graphics device (<code>null</code> not permitted). * @param section the section index. * @param dataArea the data plot area. * @param state state information for one chart. * @param currentPass the current pass index. */ protected void drawItem( Graphics2D g2, int section, Rectangle2D dataArea, PiePlotState state, int currentPass) { PieDataset dataset = getDataset(); Number n = dataset.getValue(section); if (n == null) { return; } double value = n.doubleValue(); double angle1 = 0.0; double angle2 = 0.0; Rotation direction = getDirection(); if (direction == Rotation.CLOCKWISE) { angle1 = state.getLatestAngle(); angle2 = angle1 - value / state.getTotal() * 360.0; } else if (direction == Rotation.ANTICLOCKWISE) { angle1 = state.getLatestAngle(); angle2 = angle1 + value / state.getTotal() * 360.0; } else { throw new IllegalStateException("Rotation type not recognised."); } double angle = (angle2 - angle1); if (Math.abs(angle) > getMinimumArcAngleToDraw()) { double ep = 0.0; double mep = getMaximumExplodePercent(); if (mep > 0.0) { ep = getExplodePercent(section) / mep; } Rectangle2D arcBounds = getArcBounds(state.getPieArea(), state.getExplodedPieArea(), angle1, angle, ep); Arc2D.Double arc = new Arc2D.Double(arcBounds, angle1, angle, Arc2D.OPEN); // create the bounds for the inner arc RectangleInsets s = new RectangleInsets( UnitType.RELATIVE, sectionDepth, sectionDepth, sectionDepth, sectionDepth); Rectangle2D innerArcBounds = new Rectangle2D.Double(); innerArcBounds.setRect(arcBounds); s.trim(innerArcBounds); // calculate inner arc in reverse direction, for later // GeneralPath construction Arc2D.Double arc2 = new Arc2D.Double(innerArcBounds, angle1 + angle, -angle, Arc2D.OPEN); GeneralPath path = new GeneralPath(); path.moveTo((float) arc.getStartPoint().getX(), (float) arc.getStartPoint().getY()); path.append(arc.getPathIterator(null), false); path.append(arc2.getPathIterator(null), true); path.closePath(); Line2D separator = new Line2D.Double(arc2.getEndPoint(), arc.getStartPoint()); if (currentPass == 0) { Paint shadowPaint = getShadowPaint(); double shadowXOffset = getShadowXOffset(); double shadowYOffset = getShadowYOffset(); if (shadowPaint != null) { Shape shadowArc = ShapeUtilities.createTranslatedShape( path, (float) shadowXOffset, (float) shadowYOffset); g2.setPaint(shadowPaint); g2.fill(shadowArc); } } else if (currentPass == 1) { Paint paint = getSectionPaint(section); g2.setPaint(paint); g2.fill(path); Paint outlinePaint = getSectionOutlinePaint(section); Stroke outlineStroke = getSectionOutlineStroke(section); if (getSectionOutlinesVisible()) { g2.setPaint(outlinePaint); g2.setStroke(outlineStroke); g2.draw(path); } // add an entity for the pie section if (state.getInfo() != null) { EntityCollection entities = state.getEntityCollection(); if (entities != null) { Comparable key = dataset.getKey(section); String tip = null; PieToolTipGenerator toolTipGenerator = getToolTipGenerator(); if (toolTipGenerator != null) { tip = toolTipGenerator.generateToolTip(dataset, key); } String url = null; PieURLGenerator urlGenerator = getURLGenerator(); if (urlGenerator != null) { url = urlGenerator.generateURL(dataset, key, getPieIndex()); } PieSectionEntity entity = new PieSectionEntity(path, dataset, getPieIndex(), section, key, tip, url); entities.add(entity); } } } else if (currentPass == 2) { // if there were 3 passes... if (this.sectionSeparatorsVisible) { Line2D extendedSeparator = extendLine(separator, this.innerSeparatorExtension, this.outerSeparatorExtension); g2.setStroke(this.separatorStroke); g2.setPaint(this.separatorPaint); g2.draw(extendedSeparator); } } } state.setLatestAngle(angle2); }
/** * Generates an attributed label for the specified series, or <code>null</code> if no attributed * label is available (in which case, the string returned by {@link * #generateSectionLabel(PieDataset, Comparable)} will provide the fallback). Only certain * attributes are recognised by the code that ultimately displays the labels: * * <ul> * <li>{@link TextAttribute#FONT}: will set the font; * <li>{@link TextAttribute#POSTURE}: a value of {@link TextAttribute#POSTURE_OBLIQUE} will add * {@link Font#ITALIC} to the current font; * <li>{@link TextAttribute#WEIGHT}: a value of {@link TextAttribute#WEIGHT_BOLD} will add * {@link Font#BOLD} to the current font; * <li>{@link TextAttribute#FOREGROUND}: this will set the {@link Paint} for the current * <li>{@link TextAttribute#SUPERSCRIPT}: the values {@link TextAttribute#SUPERSCRIPT_SUB} and * {@link TextAttribute#SUPERSCRIPT_SUPER} are recognised. * </ul> * * @param dataset the dataset (<code>null</code> not permitted). * @param key the key. * @return An attributed label (possibly <code>null</code>). */ @Override public AttributedString generateAttributedSectionLabel(PieDataset dataset, Comparable key) { return getAttributedLabel(dataset.getIndex(key)); }