/** * Calculates the total of all the values in a {@link PieDataset}. If * the dataset contains negative or <code>null</code> values, they are * ignored. * * @param dataset the dataset (<code>null</code> not permitted). * * @return The total. */ public static double calculatePieDatasetTotal(PieDataset dataset) { ParamChecks.nullNotPermitted(dataset, "dataset"); List keys = dataset.getKeys(); double totalValue = 0; Iterator iterator = keys.iterator(); while (iterator.hasNext()) { Comparable current = (Comparable) iterator.next(); if (current != null) { Number value = dataset.getValue(current); double v = 0.0; if (value != null) { v = value.doubleValue(); } if (v > 0) { totalValue = totalValue + v; } } } return totalValue; }
/** * Removes a subplot from the combined chart and sends a * {@link PlotChangeEvent} to all registered listeners. * * @param subplot the subplot (<code>null</code> not permitted). */ public void remove(XYPlot subplot) { ParamChecks.nullNotPermitted(subplot, "subplot"); int position = -1; int size = this.subplots.size(); int i = 0; while (position == -1 && i < size) { if (this.subplots.get(i) == subplot) { position = i; } i++; } if (position != -1) { this.subplots.remove(position); subplot.setParent(null); subplot.removeChangeListener(this); ValueAxis domain = getDomainAxis(); if (domain != null) { domain.configure(); } fireChangeEvent(); } }
/** * Removes a marker for a specific dataset/renderer and sends a * {@link PlotChangeEvent} to all registered listeners. * * @param index the dataset/renderer index. * @param marker the marker. * @param layer the layer (foreground or background). * @param notify notify listeners. * * @return A boolean indicating whether or not the marker was actually * removed. * * @since 1.0.10 * * @see #addRangeMarker(int, Marker, Layer, boolean) */ public boolean removeRangeMarker(int index, Marker marker, Layer layer, boolean notify) { ParamChecks.nullNotPermitted(marker, "marker"); ArrayList markers; if (layer == Layer.FOREGROUND) { markers = (ArrayList) this.foregroundRangeMarkers.get(new Integer( index)); } else { markers = (ArrayList) this.backgroundRangeMarkers.get(new Integer( index)); } if (markers == null) { return false; } boolean removed = markers.remove(marker); if (removed && notify) { fireChangeEvent(); } return removed; }
/** * Creates a line chart (based on an {@link XYDataset}) with default * settings. * * @param title the chart title (<code>null</code> permitted). * @param xAxisLabel a label for the X-axis (<code>null</code> permitted). * @param yAxisLabel a label for the Y-axis (<code>null</code> permitted). * @param dataset the dataset for the chart (<code>null</code> permitted). * @param orientation the plot orientation (horizontal or vertical) * (<code>null</code> NOT permitted). * @param legend a flag specifying whether or not a legend is required. * @param tooltips configure chart to generate tool tips? * @param urls configure chart to generate URLs? * * @return The chart. */ public static JFreeChart createXYLineChart(String title, String xAxisLabel, String yAxisLabel, XYDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) { ParamChecks.nullNotPermitted(orientation, "orientation"); NumberAxis xAxis = new NumberAxis(xAxisLabel); xAxis.setAutoRangeIncludesZero(false); NumberAxis yAxis = new NumberAxis(yAxisLabel); XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false); XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer); plot.setOrientation(orientation); if (tooltips) { renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); } if (urls) { renderer.setURLGenerator(new StandardXYURLGenerator()); } JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend); currentTheme.apply(chart); return chart; }
/** * Creates a new annotation that draws a line between (category1, value1) * and (category2, value2). * * @param category1 the category (<code>null</code> not permitted). * @param value1 the value. * @param category2 the category (<code>null</code> not permitted). * @param value2 the value. * @param paint the line color (<code>null</code> not permitted). * @param stroke the line stroke (<code>null</code> not permitted). */ public CategoryLineAnnotation(Comparable category1, double value1, Comparable category2, double value2, Paint paint, Stroke stroke) { super(); ParamChecks.nullNotPermitted(category1, "category1"); ParamChecks.nullNotPermitted(category2, "category2"); ParamChecks.nullNotPermitted(paint, "paint"); ParamChecks.nullNotPermitted(stroke, "stroke"); this.category1 = category1; this.value1 = value1; this.category2 = category2; this.value2 = value2; this.paint = paint; this.stroke = stroke; }
/** * Creates a label generator with the specified date formatter. * * @param labelFormat the label format string (<code>null</code> not * permitted). * @param formatter the date formatter (<code>null</code> not permitted). */ protected AbstractCategoryItemLabelGenerator(String labelFormat, DateFormat formatter) { ParamChecks.nullNotPermitted(labelFormat, "labelFormat"); ParamChecks.nullNotPermitted(formatter, "formatter"); this.labelFormat = labelFormat; this.numberFormat = null; this.percentFormat = NumberFormat.getPercentInstance(); this.dateFormat = formatter; this.nullValueString = "-"; }
/** * Calculates the range of values for a dataset where each item is the * running total of the items for the current series. * * @param dataset the dataset (<code>null</code> not permitted). * * @return The range. * * @see #findRangeBounds(CategoryDataset) */ public static Range findCumulativeRangeBounds(CategoryDataset dataset) { ParamChecks.nullNotPermitted(dataset, "dataset"); boolean allItemsNull = true; // we'll set this to false if there is at // least one non-null data item... double minimum = 0.0; double maximum = 0.0; for (int row = 0; row < dataset.getRowCount(); row++) { double runningTotal = 0.0; for (int column = 0; column <= dataset.getColumnCount() - 1; column++) { Number n = dataset.getValue(row, column); if (n != null) { allItemsNull = false; double value = n.doubleValue(); if (!Double.isNaN(value)) { runningTotal = runningTotal + value; minimum = Math.min(minimum, runningTotal); maximum = Math.max(maximum, runningTotal); } } } } if (!allItemsNull) { return new Range(minimum, maximum); } else { return null; } }
/** * Creates a new {@link XYDataset} containing the moving averages of each * series in the <code>source</code> dataset. * * @param source the source dataset. * @param suffix the string to append to source series names to create * target series names. * @param period the averaging period. * @param skip the length of the initial skip period. * * @return The dataset. */ public static XYDataset createMovingAverage(XYDataset source, String suffix, double period, double skip) { ParamChecks.nullNotPermitted(source, "source"); XYSeriesCollection result = new XYSeriesCollection(); for (int i = 0; i < source.getSeriesCount(); i++) { XYSeries s = createMovingAverage(source, i, source.getSeriesKey(i) + suffix, period, skip); result.addSeries(s); } return result; }
/** * Sets the last time period in the axis range and sends an * {@link AxisChangeEvent} to all registered listeners. * * @param last the time period (<code>null</code> not permitted). */ public void setLast(RegularTimePeriod last) { ParamChecks.nullNotPermitted(last, "last"); this.last = last; this.last.peg(this.calendar); fireChangeEvent(); }
/** * Adds a data item to the series and sends a {@link SeriesChangeEvent} to * all registered listeners. * * @param item the item (<code>null</code> not permitted). */ public void add(TimePeriodValue item) { ParamChecks.nullNotPermitted(item, "item"); this.data.add(item); updateBounds(item.getPeriod(), this.data.size() - 1); fireSeriesChanged(); }
/** * Sets the maximum date visible on the axis and sends an * {@link AxisChangeEvent} to all registered listeners. If * <code>maximumDate</code> is on or before the current minimum date for * the axis, the minimum date will be shifted to preserve the current * length of the axis. * * @param maximumDate the date (<code>null</code> not permitted). * * @see #getMinimumDate() * @see #setMinimumDate(Date) */ public void setMaximumDate(Date maximumDate) { ParamChecks.nullNotPermitted(maximumDate, "maximumDate"); // check the new maximum date relative to the current minimum date Date minDate = getMinimumDate(); long minMillis = minDate.getTime(); long newMaxMillis = maximumDate.getTime(); if (minMillis >= newMaxMillis) { Date oldMax = getMaximumDate(); long length = oldMax.getTime() - minMillis; minDate = new Date(newMaxMillis - length); } setRange(new DateRange(minDate, maximumDate), true, false); fireChangeEvent(); }
/** * Returns the subplot (if any) that contains the (x, y) point (specified * in Java2D space). * * @param info the chart rendering info (<code>null</code> not permitted). * @param source the source point (<code>null</code> not permitted). * * @return A subplot (possibly <code>null</code>). */ public XYPlot findSubplot(PlotRenderingInfo info, Point2D source) { ParamChecks.nullNotPermitted(info, "info"); ParamChecks.nullNotPermitted(source, "source"); XYPlot result = null; int subplotIndex = info.getSubplotIndex(source); if (subplotIndex >= 0) { result = (XYPlot) this.subplots.get(subplotIndex); } return result; }
/** * Finds the slope of a regression line using least squares. * * @param xData the x-values ({@code null} not permitted). * @param yData the y-values ({@code null} not permitted). * * @return The slope. */ public static double getSlope(Number[] xData, Number[] yData) { ParamChecks.nullNotPermitted(xData, "xData"); ParamChecks.nullNotPermitted(yData, "yData"); if (xData.length != yData.length) { throw new IllegalArgumentException("Array lengths must be equal."); } // ********* stat function for linear slope ******** // y = a + bx // a = ybar - b * xbar // sum(x * y) - (sum (x) * sum(y)) / n // b = ------------------------------------ // sum (x^2) - (sum(x)^2 / n // ************************************************* // sum of x, x^2, x * y, y double sx = 0.0, sxx = 0.0, sxy = 0.0, sy = 0.0; int counter; for (counter = 0; counter < xData.length; counter++) { sx = sx + xData[counter].doubleValue(); sxx = sxx + Math.pow(xData[counter].doubleValue(), 2); sxy = sxy + yData[counter].doubleValue() * xData[counter].doubleValue(); sy = sy + yData[counter].doubleValue(); } return (sxy - (sx * sy) / counter) / (sxx - (sx * sx) / counter); }
/** * Creates a new spider web plot with the given dataset. * * @param dataset the dataset. * @param extract controls how data is extracted ({@link TableOrder#BY_ROW} * or {@link TableOrder#BY_COLUMN}). */ public SpiderWebPlot(CategoryDataset dataset, TableOrder extract) { super(); ParamChecks.nullNotPermitted(extract, "extract"); this.dataset = dataset; if (dataset != null) { dataset.addChangeListener(this); } this.dataExtractOrder = extract; this.headPercent = DEFAULT_HEAD; this.axisLabelGap = DEFAULT_AXIS_LABEL_GAP; this.axisLinePaint = Color.black; this.axisLineStroke = new BasicStroke(1.0f); this.interiorGap = DEFAULT_INTERIOR_GAP; this.startAngle = DEFAULT_START_ANGLE; this.direction = Rotation.CLOCKWISE; this.maxValue = DEFAULT_MAX_VALUE; this.seriesPaint = null; this.seriesPaintList = new PaintList(); this.baseSeriesPaint = null; this.seriesOutlinePaint = null; this.seriesOutlinePaintList = new PaintList(); this.baseSeriesOutlinePaint = DEFAULT_OUTLINE_PAINT; this.seriesOutlineStroke = null; this.seriesOutlineStrokeList = new StrokeList(); this.baseSeriesOutlineStroke = DEFAULT_OUTLINE_STROKE; this.labelFont = DEFAULT_LABEL_FONT; this.labelPaint = DEFAULT_LABEL_PAINT; this.labelGenerator = new StandardCategoryItemLabelGenerator(); this.legendItemShape = DEFAULT_LEGEND_ITEM_CIRCLE; }
/** * Sets the vertical alignment for the title, and notifies any registered * listeners of the change. * * @param alignment the new vertical alignment (TOP, MIDDLE or BOTTOM, * <code>null</code> not permitted). */ public void setVerticalAlignment(VerticalAlignment alignment) { ParamChecks.nullNotPermitted(alignment, "alignment"); if (this.verticalAlignment != alignment) { this.verticalAlignment = alignment; notifyListeners(new TitleChangeEvent(this)); } }
/** * Creates a new histogram dataset. Note that the * <code>adjustForBinSize</code> flag defaults to <code>true</code>. * * @param key the series key (<code>null</code> not permitted). */ public SimpleHistogramDataset(Comparable key) { ParamChecks.nullNotPermitted(key, "key"); this.key = key; this.bins = new ArrayList(); this.adjustForBinSize = true; }
/** * Returns the domain axis for a dataset. You can change the axis for a * dataset using the {@link #mapDatasetToDomainAxis(int, int)} method. * * @param index the dataset index (must be >= 0). * * @return The domain axis. * * @see #mapDatasetToDomainAxis(int, int) */ public CategoryAxis getDomainAxisForDataset(int index) { ParamChecks.requireNonNegative(index, "index"); CategoryAxis axis; List axisIndices = (List) this.datasetToDomainAxesMap.get( new Integer(index)); if (axisIndices != null) { // the first axis in the list is used for data <--> Java2D Integer axisIndex = (Integer) axisIndices.get(0); axis = getDomainAxis(axisIndex.intValue()); } else { axis = getDomainAxis(0); } return axis; }
/** * Returns the group that a key is mapped to. * * @param key the key (<code>null</code> not permitted). * * @return The group (never <code>null</code>, returns the default group if * there is no mapping for the specified key). */ public Comparable getGroup(Comparable key) { ParamChecks.nullNotPermitted(key, "key"); Comparable result = this.defaultGroup; Comparable group = (Comparable) this.keyToGroupMap.get(key); if (group != null) { result = group; } return result; }
/** * Returns the row index for a given key. * * @param key the key (<code>null</code> not permitted). * * @return The row index. * * @see #getRowKey(int) * @see #getColumnIndex(Comparable) */ @Override public int getRowIndex(Comparable key) { ParamChecks.nullNotPermitted(key, "key"); if (this.sortRowKeys) { return Collections.binarySearch(this.rowKeys, key); } else { return this.rowKeys.indexOf(key); } }
/** * Returns the range of z-values in the specified dataset for the * data items belonging to the visible series and with x-values in the * given range. * * @param dataset the dataset (<code>null</code> not permitted). * @param visibleSeriesKeys the visible series keys (<code>null</code> not * permitted). * @param xRange the x-range (<code>null</code> not permitted). * @param includeInterval a flag that determines whether or not the * z-interval for the dataset is included (this only applies if the * dataset has an interval, which is currently not supported). * * @return The y-range (possibly <code>null</code>). */ public static Range iterateToFindZBounds(XYZDataset dataset, List visibleSeriesKeys, Range xRange, boolean includeInterval) { ParamChecks.nullNotPermitted(dataset, "dataset"); ParamChecks.nullNotPermitted(visibleSeriesKeys, "visibleSeriesKeys"); ParamChecks.nullNotPermitted(xRange, "xRange"); double minimum = Double.POSITIVE_INFINITY; double maximum = Double.NEGATIVE_INFINITY; Iterator iterator = visibleSeriesKeys.iterator(); while (iterator.hasNext()) { Comparable seriesKey = (Comparable) iterator.next(); int series = dataset.indexOf(seriesKey); int itemCount = dataset.getItemCount(series); for (int item = 0; item < itemCount; item++) { double x = dataset.getXValue(series, item); double z = dataset.getZValue(series, item); if (xRange.contains(x)) { if (!Double.isNaN(z)) { minimum = Math.min(minimum, z); maximum = Math.max(maximum, z); } } } } if (minimum == Double.POSITIVE_INFINITY) { return null; } else { return new Range(minimum, maximum); } }
/** * Returns the range of values in the range for the dataset. * * @param dataset the dataset (<code>null</code> not permitted). * @param includeInterval a flag that determines whether or not the * y-interval is taken into account. * * @return The range (possibly <code>null</code>). */ public static Range findRangeBounds(CategoryDataset dataset, boolean includeInterval) { ParamChecks.nullNotPermitted(dataset, "dataset"); Range result; if (dataset instanceof RangeInfo) { RangeInfo info = (RangeInfo) dataset; result = info.getRangeBounds(includeInterval); } else { result = iterateRangeBounds(dataset, includeInterval); } return result; }
/** * Returns the mean of a collection of {@code Number} objects. * * @param values the values ({@code null} not permitted). * @param includeNullAndNaN a flag that controls whether or not * {@code null} and {@code Double.NaN} values are included * in the calculation (if either is present in the array, the result is * {@link Double#NaN}). * * @return The mean. * * @since 1.0.3 */ public static double calculateMean(Collection values, boolean includeNullAndNaN) { ParamChecks.nullNotPermitted(values, "values"); int count = 0; double total = 0.0; Iterator iterator = values.iterator(); while (iterator.hasNext()) { Object object = iterator.next(); if (object == null) { if (includeNullAndNaN) { return Double.NaN; } } else { if (object instanceof Number) { Number number = (Number) object; double value = number.doubleValue(); if (Double.isNaN(value)) { if (includeNullAndNaN) { return Double.NaN; } } else { total = total + number.doubleValue(); count = count + 1; } } } } return total / count; }
/** * Fills the specified area with the background paint. If the background * paint is an instance of <code>GradientPaint</code>, the gradient will * run in the direction suggested by the plot's orientation. * * @param g2 the graphics target. * @param area the plot area. * @param orientation the plot orientation (<code>null</code> not * permitted). * * @since 1.0.6 */ protected void fillBackground(Graphics2D g2, Rectangle2D area, PlotOrientation orientation) { ParamChecks.nullNotPermitted(orientation, "orientation"); if (this.backgroundPaint == null) { return; } Paint p = this.backgroundPaint; if (p instanceof GradientPaint) { GradientPaint gp = (GradientPaint) p; if (orientation == PlotOrientation.VERTICAL) { p = new GradientPaint((float) area.getCenterX(), (float) area.getMaxY(), gp.getColor1(), (float) area.getCenterX(), (float) area.getMinY(), gp.getColor2()); } else if (orientation == PlotOrientation.HORIZONTAL) { p = new GradientPaint((float) area.getMinX(), (float) area.getCenterY(), gp.getColor1(), (float) area.getMaxX(), (float) area.getCenterY(), gp.getColor2()); } } Composite originalComposite = g2.getComposite(); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, this.backgroundAlpha)); g2.setPaint(p); g2.fill(area); g2.setComposite(originalComposite); }
/** * Constructs a new Hour. * * @param hour the hour (in the range 0 to 23). * @param day the day (<code>null</code> not permitted). */ public Hour(int hour, Day day) { ParamChecks.nullNotPermitted(day, "day"); this.hour = (byte) hour; this.day = day; peg(Calendar.getInstance()); }
/** * Creates a stacked bar chart with default settings. The chart object * returned by this method uses a {@link CategoryPlot} instance as the * plot, with a {@link CategoryAxis} for the domain axis, a * {@link NumberAxis} as the range axis, and a {@link StackedBarRenderer} * as the renderer. * * @param title the chart title (<code>null</code> permitted). * @param domainAxisLabel the label for the category axis * (<code>null</code> permitted). * @param rangeAxisLabel the label for the value axis * (<code>null</code> permitted). * @param dataset the dataset for the chart (<code>null</code> permitted). * @param orientation the orientation of the chart (horizontal or * vertical) (<code>null</code> not permitted). * @param legend a flag specifying whether or not a legend is required. * @param tooltips configure chart to generate tool tips? * @param urls configure chart to generate URLs? * * @return A stacked bar chart. */ public static JFreeChart createStackedBarChart(String title, String domainAxisLabel, String rangeAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) { ParamChecks.nullNotPermitted(orientation, "orientation"); CategoryAxis categoryAxis = new CategoryAxis(domainAxisLabel); ValueAxis valueAxis = new NumberAxis(rangeAxisLabel); StackedBarRenderer renderer = new StackedBarRenderer(); if (tooltips) { renderer.setBaseToolTipGenerator( new StandardCategoryToolTipGenerator()); } if (urls) { renderer.setBaseItemURLGenerator( new StandardCategoryURLGenerator()); } CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer); plot.setOrientation(orientation); JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend); currentTheme.apply(chart); return chart; }
/** * Sets the minimum date visible on the axis and sends an * {@link AxisChangeEvent} to all registered listeners. If * <code>date</code> is on or after the current maximum date for * the axis, the maximum date will be shifted to preserve the current * length of the axis. * * @param date the date (<code>null</code> not permitted). * * @see #getMinimumDate() * @see #setMaximumDate(Date) */ public void setMinimumDate(Date date) { ParamChecks.nullNotPermitted(date, "date"); // check the new minimum date relative to the current maximum date Date maxDate = getMaximumDate(); long maxMillis = maxDate.getTime(); long newMinMillis = date.getTime(); if (maxMillis <= newMinMillis) { Date oldMin = getMinimumDate(); long length = maxMillis - oldMin.getTime(); maxDate = new Date(newMinMillis + length); } setRange(new DateRange(date, maxDate), true, false); fireChangeEvent(); }
/** * Returns the total of the values in one row of the supplied data * table. * * @param data the table of values (<code>null</code> not permitted). * @param row the row index (zero-based). * * @return The total of the values in the specified row. */ public static double calculateRowTotal(Values2D data, int row) { ParamChecks.nullNotPermitted(data, "data"); double total = 0.0; int columnCount = data.getColumnCount(); for (int c = 0; c < columnCount; c++) { Number n = data.getValue(row, c); if (n != null) { total += n.doubleValue(); } } return total; }
/** * Creates a new border with the specified color. * * @param paint the color ({@code null} not permitted). * @param stroke the border stroke ({@code null} not permitted). * @param insets the insets ({@code null} not permitted). */ public LineBorder(Paint paint, Stroke stroke, RectangleInsets insets) { ParamChecks.nullNotPermitted(paint, "paint"); ParamChecks.nullNotPermitted(stroke, "stroke"); ParamChecks.nullNotPermitted(insets, "insets"); this.paint = paint; this.stroke = stroke; this.insets = insets; }
/** * Returns the minimum range value for the specified dataset. This is * easy if the dataset implements the {@link RangeInfo} interface (a good * idea if there is an efficient way to determine the minimum value). * Otherwise, it involves iterating over the entire data-set. Returns * <code>null</code> if all the data values in the dataset are * <code>null</code>. * * @param dataset the dataset (<code>null</code> not permitted). * * @return The minimum value (possibly <code>null</code>). */ public static Number findMinimumRangeValue(CategoryDataset dataset) { ParamChecks.nullNotPermitted(dataset, "dataset"); if (dataset instanceof RangeInfo) { RangeInfo info = (RangeInfo) dataset; return new Double(info.getRangeLowerBound(true)); } // hasn't implemented RangeInfo, so we'll have to iterate... else { double minimum = Double.POSITIVE_INFINITY; int seriesCount = dataset.getRowCount(); int itemCount = dataset.getColumnCount(); for (int series = 0; series < seriesCount; series++) { for (int item = 0; item < itemCount; item++) { Number value; if (dataset instanceof IntervalCategoryDataset) { IntervalCategoryDataset icd = (IntervalCategoryDataset) dataset; value = icd.getStartValue(series, item); } else { value = dataset.getValue(series, item); } if (value != null) { minimum = Math.min(minimum, value.doubleValue()); } } } if (minimum == Double.POSITIVE_INFINITY) { return null; } else { return new Double(minimum); } } }
/** * Adds a series to the collection and sends a {@link DatasetChangeEvent} * to all registered listeners. * * @param series the series (<code>null</code> not permitted). */ public void addSeries(XIntervalSeries series) { ParamChecks.nullNotPermitted(series, "series"); this.data.add(series); series.addChangeListener(this); fireDatasetChanged(); }
/** * Returns the maximum value in the dataset range, assuming that values in * each category are "stacked". * * @param dataset the dataset (<code>null</code> not permitted). * * @return The maximum value (possibly <code>null</code>). * * @see #findMinimumStackedRangeValue(CategoryDataset) */ public static Number findMaximumStackedRangeValue(CategoryDataset dataset) { ParamChecks.nullNotPermitted(dataset, "dataset"); Number result = null; boolean hasValidData = false; double maximum = 0.0; int categoryCount = dataset.getColumnCount(); for (int item = 0; item < categoryCount; item++) { double total = 0.0; int seriesCount = dataset.getRowCount(); for (int series = 0; series < seriesCount; series++) { Number number = dataset.getValue(series, item); if (number != null) { hasValidData = true; double value = number.doubleValue(); if (value > 0.0) { total = total + value; } } } maximum = Math.max(maximum, total); } if (hasValidData) { result = new Double(maximum); } return result; }
/** * Creates a new renderer. * * @param positivePaint the highlight color for positive differences * (<code>null</code> not permitted). * @param negativePaint the highlight color for negative differences * (<code>null</code> not permitted). * @param shapes draw shapes? */ public XYDifferenceRenderer(Paint positivePaint, Paint negativePaint, boolean shapes) { ParamChecks.nullNotPermitted(positivePaint, "positivePaint"); ParamChecks.nullNotPermitted(negativePaint, "negativePaint"); this.positivePaint = positivePaint; this.negativePaint = negativePaint; this.shapesVisible = shapes; this.legendLine = new Line2D.Double(-7.0, 0.0, 7.0, 0.0); this.roundXCoordinates = false; }
/** * Creates a new default instance. * * @param name the name of the theme (<code>null</code> not permitted). * @param shadow a flag that controls whether a shadow generator is * included. * * @since 1.0.14 */ public StandardChartTheme(String name, boolean shadow) { ParamChecks.nullNotPermitted(name, "name"); this.name = name; this.extraLargeFont = new Font("Tahoma", Font.BOLD, 20); this.largeFont = new Font("Tahoma", Font.BOLD, 14); this.regularFont = new Font("Tahoma", Font.PLAIN, 12); this.smallFont = new Font("Tahoma", Font.PLAIN, 10); this.titlePaint = Color.black; this.subtitlePaint = Color.black; this.legendBackgroundPaint = Color.white; this.legendItemPaint = Color.darkGray; this.chartBackgroundPaint = Color.white; this.drawingSupplier = new DefaultDrawingSupplier(); this.plotBackgroundPaint = Color.lightGray; this.plotOutlinePaint = Color.black; this.labelLinkPaint = Color.black; this.labelLinkStyle = PieLabelLinkStyle.CUBIC_CURVE; this.axisOffset = new RectangleInsets(4, 4, 4, 4); this.domainGridlinePaint = Color.white; this.rangeGridlinePaint = Color.white; this.baselinePaint = Color.black; this.crosshairPaint = Color.blue; this.axisLabelPaint = Color.darkGray; this.tickLabelPaint = Color.darkGray; this.barPainter = new GradientBarPainter(); this.xyBarPainter = new GradientXYBarPainter(); this.shadowVisible = false; this.shadowPaint = Color.gray; this.itemLabelPaint = Color.black; this.thermometerPaint = Color.white; this.wallPaint = BarRenderer3D.DEFAULT_WALL_PAINT; this.errorIndicatorPaint = Color.black; this.shadowGenerator = shadow ? new DefaultShadowGenerator() : null; }
/** * Creates a new annotation. The array of polygon coordinates must * contain an even number of coordinates (each pair is an (x, y) location * on the plot) and the last point is automatically joined back to the * first point. * * @param polygon the coordinates of the polygon's vertices * (<code>null</code> not permitted). * @param stroke the shape stroke (<code>null</code> permitted). * @param outlinePaint the shape color (<code>null</code> permitted). * @param fillPaint the paint used to fill the shape (<code>null</code> * permitted). */ public XYPolygonAnnotation(double[] polygon, Stroke stroke, Paint outlinePaint, Paint fillPaint) { super(); ParamChecks.nullNotPermitted(polygon, "polygon"); if (polygon.length % 2 != 0) { throw new IllegalArgumentException("The 'polygon' array must " + "contain an even number of items."); } this.polygon = (double[]) polygon.clone(); this.stroke = stroke; this.outlinePaint = outlinePaint; this.fillPaint = fillPaint; }
/** * Sets the item paint. * * @param paint the paint (<code>null</code> not permitted). */ public void setItemPaint(Paint paint) { ParamChecks.nullNotPermitted(paint, "paint"); this.itemPaint = paint; notifyListeners(new TitleChangeEvent(this)); }
/** * Resolves a range axis location for a given plot orientation. * * @param location the location (<code>null</code> not permitted). * @param orientation the orientation (<code>null</code> not permitted). * * @return The edge (never <code>null</code>). */ public static RectangleEdge resolveRangeAxisLocation( AxisLocation location, PlotOrientation orientation) { ParamChecks.nullNotPermitted(location, "location"); ParamChecks.nullNotPermitted(orientation, "orientation"); RectangleEdge result = null; if (location == AxisLocation.TOP_OR_RIGHT) { if (orientation == PlotOrientation.HORIZONTAL) { result = RectangleEdge.TOP; } else if (orientation == PlotOrientation.VERTICAL) { result = RectangleEdge.RIGHT; } } else if (location == AxisLocation.TOP_OR_LEFT) { if (orientation == PlotOrientation.HORIZONTAL) { result = RectangleEdge.TOP; } else if (orientation == PlotOrientation.VERTICAL) { result = RectangleEdge.LEFT; } } else if (location == AxisLocation.BOTTOM_OR_RIGHT) { if (orientation == PlotOrientation.HORIZONTAL) { result = RectangleEdge.BOTTOM; } else if (orientation == PlotOrientation.VERTICAL) { result = RectangleEdge.RIGHT; } } else if (location == AxisLocation.BOTTOM_OR_LEFT) { if (orientation == PlotOrientation.HORIZONTAL) { result = RectangleEdge.BOTTOM; } else if (orientation == PlotOrientation.VERTICAL) { result = RectangleEdge.LEFT; } } // the above should cover all the options... if (result == null) { throw new IllegalStateException("resolveRangeAxisLocation()"); } return result; }
/** * Applies the attributes of this theme to a plot. * * @param plot the plot (<code>null</code>). */ protected void applyToPlot(Plot plot) { ParamChecks.nullNotPermitted(plot, "plot"); if (plot.getDrawingSupplier() != null) { plot.setDrawingSupplier(getDrawingSupplier()); } if (plot.getBackgroundPaint() != null) { plot.setBackgroundPaint(this.plotBackgroundPaint); } plot.setOutlinePaint(this.plotOutlinePaint); // now handle specific plot types (and yes, I know this is some // really ugly code that has to be manually updated any time a new // plot type is added - I should have written something much cooler, // but I didn't and neither did anyone else). if (plot instanceof PiePlot) { applyToPiePlot((PiePlot) plot); } else if (plot instanceof MultiplePiePlot) { applyToMultiplePiePlot((MultiplePiePlot) plot); } else if (plot instanceof CategoryPlot) { applyToCategoryPlot((CategoryPlot) plot); } else if (plot instanceof XYPlot) { applyToXYPlot((XYPlot) plot); } else if (plot instanceof FastScatterPlot) { applyToFastScatterPlot((FastScatterPlot) plot); } else if (plot instanceof MeterPlot) { applyToMeterPlot((MeterPlot) plot); } else if (plot instanceof ThermometerPlot) { applyToThermometerPlot((ThermometerPlot) plot); } else if (plot instanceof SpiderWebPlot) { applyToSpiderWebPlot((SpiderWebPlot) plot); } else if (plot instanceof PolarPlot) { applyToPolarPlot((PolarPlot) plot); } }
/** * Constructs a dataset based on the specified data array. The array * can contain multiple series, each series can contain multiple items, * and each item is as follows: * <ul> * <li><code>data[series][item][0]</code> - the date (either a * <code>Date</code> or a <code>Number</code> that is the milliseconds * since 1-Jan-1970);</li> * <li><code>data[series][item][1]</code> - the wind direction (1 - 12, * like the numbers on a clock face);</li> * <li><code>data[series][item][2]</code> - the wind force (1 - 12 on the * Beaufort scale)</li> * </ul> * * @param seriesKeys the names of the series (<code>null</code> not * permitted). * @param data the wind dataset (<code>null</code> not permitted). * * @throws IllegalArgumentException if <code>seriesKeys</code> is * <code>null</code>. * @throws IllegalArgumentException if the number of series keys does not * match the number of series in the array. * @throws NullPointerException if <code>data</code> is <code>null</code>. */ public DefaultWindDataset(List seriesKeys, Object[][][] data) { ParamChecks.nullNotPermitted(seriesKeys, "seriesKeys"); if (seriesKeys.size() != data.length) { throw new IllegalArgumentException("The number of series keys does " + "not match the number of series in the data array."); } this.seriesKeys = seriesKeys; int seriesCount = data.length; this.allSeriesData = new java.util.ArrayList(seriesCount); for (int seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++) { List oneSeriesData = new java.util.ArrayList(); int maxItemCount = data[seriesIndex].length; for (int itemIndex = 0; itemIndex < maxItemCount; itemIndex++) { Object xObject = data[seriesIndex][itemIndex][0]; if (xObject != null) { Number xNumber; if (xObject instanceof Number) { xNumber = (Number) xObject; } else { if (xObject instanceof Date) { Date xDate = (Date) xObject; xNumber = new Long(xDate.getTime()); } else { xNumber = new Integer(0); } } Number windDir = (Number) data[seriesIndex][itemIndex][1]; Number windForce = (Number) data[seriesIndex][itemIndex][2]; oneSeriesData.add(new WindDataItem(xNumber, windDir, windForce)); } } Collections.sort(oneSeriesData); this.allSeriesData.add(seriesIndex, oneSeriesData); } }