/** * Returns a string containing the coordinates (x1, y1, x2, y2) for a given * rectangle. This string is intended for use in an image map. * * @param rectangle the rectangle ({@code null} not permitted). * * @return Upper left and lower right corner of a rectangle. */ private String getRectCoords(Rectangle2D rectangle) { Args.nullNotPermitted(rectangle, "rectangle"); int x1 = (int) rectangle.getX(); int y1 = (int) rectangle.getY(); int x2 = x1 + (int) rectangle.getWidth(); int y2 = y1 + (int) rectangle.getHeight(); // fix by rfuller if (x2 == x1) { x2++; } if (y2 == y1) { y2++; } // end fix by rfuller return x1 + "," + y1 + "," + x2 + "," + y2; }
/** * Inserts a new value at the specified position in the dataset or, if * there is an existing item with the specified key, updates the value * for that item and moves it to the specified position. * * @param position the position (in the range 0 to getItemCount()). * @param key the key ({@code null} not permitted). * @param value the value ({@code null} permitted). * * @since 1.0.6 */ public void insertValue(int position, Comparable key, Number value) { if (position < 0 || position > getItemCount()) { throw new IllegalArgumentException("'position' out of bounds."); } Args.nullNotPermitted(key, "key"); int pos = getIndex(key); if (pos == position) { this.keys.set(pos, key); this.values.set(pos, value); } else { if (pos >= 0) { this.keys.remove(pos); this.values.remove(pos); } this.keys.add(position, key); this.values.add(position, value); rebuildIndex(); } }
/** * Sets the range for the axis and, if requested, sends a change event to * all registered listeners. Furthermore, if {@code turnOffAutoRange} * is {@code true}, the auto-range flag is set to {@code false} * (normally when setting the axis range manually the caller expects that * range to remain in force). * * @param range the range ({@code null} not permitted). * @param turnOffAutoRange a flag that controls whether or not the auto * range is turned off. * @param notify a flag that controls whether or not listeners are * notified. * * @see #getRange() */ public void setRange(Range range, boolean turnOffAutoRange, boolean notify) { Args.nullNotPermitted(range, "range"); if (range.getLength() <= 0.0) { throw new IllegalArgumentException( "A positive range length is required: " + range); } if (turnOffAutoRange) { this.autoRange = false; } this.range = range; if (notify) { fireChangeEvent(); } }
/** * Creates a new instance. * * @param scale the scale ({@code null} not permitted). * @param axis the axis ({@code null} not permitted). */ public PaintScaleLegend(PaintScale scale, ValueAxis axis) { Args.nullNotPermitted(axis, "axis"); this.scale = scale; this.axis = axis; this.axis.addChangeListener(this); this.axisLocation = AxisLocation.BOTTOM_OR_LEFT; this.axisOffset = 0.0; this.axis.setRange(scale.getLowerBound(), scale.getUpperBound()); this.stripWidth = 15.0; this.stripOutlineVisible = true; this.stripOutlinePaint = Color.GRAY; this.stripOutlineStroke = new BasicStroke(0.5f); this.backgroundPaint = Color.WHITE; this.subdivisions = 100; }
/** * Creates a new position record. The item label anchor is a point * relative to the data item (dot, bar or other visual item) on a chart. * The item label is aligned by aligning the text anchor with the item * label anchor. * * @param categoryAnchor the category anchor ({@code null} not * permitted). * @param labelAnchor the label anchor ({@code null} not permitted). * @param rotationAnchor the rotation anchor ({@code null} not * permitted). * @param angle the rotation angle ({@code null} not permitted). * @param widthType the width type ({@code null} not permitted). * @param widthRatio the maximum label width as a percentage (of the * category space or the range space). */ public CategoryLabelPosition(RectangleAnchor categoryAnchor, TextBlockAnchor labelAnchor, TextAnchor rotationAnchor, double angle, CategoryLabelWidthType widthType, float widthRatio) { Args.nullNotPermitted(categoryAnchor, "categoryAnchor"); Args.nullNotPermitted(labelAnchor, "labelAnchor"); Args.nullNotPermitted(rotationAnchor, "rotationAnchor"); Args.nullNotPermitted(widthType, "widthType"); this.categoryAnchor = categoryAnchor; this.labelAnchor = labelAnchor; this.rotationAnchor = rotationAnchor; this.angle = angle; this.widthType = widthType; this.widthRatio = widthRatio; }
/** * Adds a series to the dataset and sends a * {@link org.jfree.data.general.DatasetChangeEvent} to all registered * listeners. * * @param series the series ({@code null} not permitted). */ public void add(TaskSeries series) { Args.nullNotPermitted(series, "series"); this.data.add(series); series.addChangeListener(this); // look for any keys that we don't already know about... Iterator iterator = series.getTasks().iterator(); while (iterator.hasNext()) { Task task = (Task) iterator.next(); String key = task.getDescription(); int index = this.keys.indexOf(key); if (index < 0) { this.keys.add(key); } } fireDatasetChanged(); }
/** * Maps a key to a group. * * @param key the key ({@code null} not permitted). * @param group the group ({@code null} permitted, clears any * existing mapping). */ public void mapKeyToGroup(Comparable key, Comparable group) { Args.nullNotPermitted(key, "key"); Comparable currentGroup = getGroup(key); if (!currentGroup.equals(this.defaultGroup)) { if (!currentGroup.equals(group)) { int count = getKeyCount(currentGroup); if (count == 1) { this.groups.remove(currentGroup); } } } if (group == null) { this.keyToGroupMap.remove(key); } else { if (!this.groups.contains(group)) { if (!this.defaultGroup.equals(group)) { this.groups.add(group); } } this.keyToGroupMap.put(key, group); } }
/** * Returns a constraint for the content of this block that will result in * the bounds of the block matching the specified constraint. * * @param c the outer constraint ({@code null} not permitted). * * @return The content constraint. */ protected RectangleConstraint toContentConstraint(RectangleConstraint c) { Args.nullNotPermitted(c, "c"); if (c.equals(RectangleConstraint.NONE)) { return c; } double w = c.getWidth(); Range wr = c.getWidthRange(); double h = c.getHeight(); Range hr = c.getHeightRange(); double ww = trimToContentWidth(w); double hh = trimToContentHeight(h); Range wwr = trimToContentWidth(wr); Range hhr = trimToContentHeight(hr); return new RectangleConstraint(ww, wwr, c.getWidthConstraintType(), hh, hhr, c.getHeightConstraintType()); }
/** * Adds a subplot with a particular weight (greater than or equal to one). * The weight determines how much space is allocated to the subplot * relative to all the other subplots. * <br><br> * You must ensure that the subplot has a non-null domain axis. The range * axis for the subplot will be set to {@code null}. * * @param subplot the subplot ({@code null} not permitted). * @param weight the weight (must be 1 or greater). */ public void add(XYPlot subplot, int weight) { Args.nullNotPermitted(subplot, "subplot"); if (weight <= 0) { String msg = "The 'weight' must be positive."; throw new IllegalArgumentException(msg); } // store the plot and its weight subplot.setParent(this); subplot.setWeight(weight); subplot.setInsets(new RectangleInsets(0.0, 0.0, 0.0, 0.0)); subplot.setRangeAxis(null); subplot.addChangeListener(this); this.subplots.add(subplot); configureRangeAxes(); fireChangeEvent(); }
/** * Creates a new unit. * * @param unitType the unit. * @param multiple the multiple. * @param rollUnitType the roll unit. * @param rollMultiple the roll multiple. * @param formatter the date formatter ({@code null} not permitted). * * @since 1.0.13 */ public DateTickUnit(DateTickUnitType unitType, int multiple, DateTickUnitType rollUnitType, int rollMultiple, DateFormat formatter) { super(DateTickUnit.getMillisecondCount(unitType, multiple)); Args.nullNotPermitted(formatter, "formatter"); if (multiple <= 0) { throw new IllegalArgumentException("Requires 'multiple' > 0."); } if (rollMultiple <= 0) { throw new IllegalArgumentException("Requires 'rollMultiple' > 0."); } this.unitType = unitType; this.count = multiple; this.rollUnitType = rollUnitType; this.rollCount = rollMultiple; this.formatter = formatter; }
/** * Add an overlay to the canvas. * * @param overlay the overlay ({@code null} not permitted). */ public void addOverlay(OverlayFX overlay) { Args.nullNotPermitted(overlay, "overlay"); this.overlays.add(overlay); overlay.addChangeListener(this); draw(); }
/** * Removes an overlay from the canvas. * * @param overlay the overlay to remove ({@code null} not permitted). */ public void removeOverlay(OverlayFX overlay) { Args.nullNotPermitted(overlay, "overlay"); boolean removed = this.overlays.remove(overlay); if (removed) { overlay.removeChangeListener(this); draw(); } }
/** * Constructs a new Minute, based on the supplied date/time and timezone. * * @param time the time ({@code null} not permitted). * @param zone the time zone ({@code null} not permitted). * @param locale the locale ({@code null} not permitted). * * @since 1.0.13 */ public Minute(Date time, TimeZone zone, Locale locale) { Args.nullNotPermitted(time, "time"); Args.nullNotPermitted(zone, "zone"); Args.nullNotPermitted(locale, "locale"); Calendar calendar = Calendar.getInstance(zone, locale); calendar.setTime(time); int min = calendar.get(Calendar.MINUTE); this.minute = (byte) min; this.hour = (byte) calendar.get(Calendar.HOUR_OF_DAY); this.day = new Day(time, zone, locale); peg(calendar); }
/** * Creates a label generator with the specified number formatter. * * @param labelFormat the label format string ({@code null} not * permitted). * @param formatter the number formatter ({@code null} not permitted). * @param percentFormatter the percent formatter ({@code null} not * permitted). * * @since 1.0.2 */ protected AbstractCategoryItemLabelGenerator(String labelFormat, NumberFormat formatter, NumberFormat percentFormatter) { Args.nullNotPermitted(labelFormat, "labelFormat"); Args.nullNotPermitted(formatter, "formatter"); Args.nullNotPermitted(percentFormatter, "percentFormatter"); this.labelFormat = labelFormat; this.numberFormat = formatter; this.percentFormat = percentFormatter; this.dateFormat = null; this.nullValueString = "-"; }
/** * Returns the index of the series with the specified key, or -1 if no * series has that key. * * @param key the key ({@code null} not permitted). * * @return The index. * * @since 1.0.14 */ public int getSeriesIndex(Comparable key) { Args.nullNotPermitted(key, "key"); int seriesCount = getSeriesCount(); for (int i = 0; i < seriesCount; i++) { XYSeries series = (XYSeries) this.data.get(i); if (key.equals(series.getKey())) { return i; } } return -1; }
/** * Creates a new range by adding margins to an existing range. * * @param range the range ({@code null} not permitted). * @param lowerMargin the lower margin (expressed as a percentage of the * range length). * @param upperMargin the upper margin (expressed as a percentage of the * range length). * * @return The expanded range. */ public static Range expand(Range range, double lowerMargin, double upperMargin) { Args.nullNotPermitted(range, "range"); double length = range.getLength(); double lower = range.getLowerBound() - length * lowerMargin; double upper = range.getUpperBound() + length * upperMargin; if (lower > upper) { lower = lower / 2.0 + upper / 2.0; upper = lower; } return new Range(lower, upper); }
/** * Returns the maximum value in the dataset range, assuming that values in * each category are "stacked". * * @param dataset the dataset ({@code null} not permitted). * * @return The maximum value (possibly {@code null}). * * @see #findMinimumStackedRangeValue(CategoryDataset) */ public static Number findMaximumStackedRangeValue(CategoryDataset dataset) { Args.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; }
/** * Returns a new instance based on an existing instance but with the left * position changed. * * @param base the base ({@code null} not permitted). * @param left the left position ({@code null} not permitted). * * @return A new instance (never {@code null}). */ public static CategoryLabelPositions replaceLeftPosition( CategoryLabelPositions base, CategoryLabelPosition left) { Args.nullNotPermitted(base, "base"); Args.nullNotPermitted(left, "left"); return new CategoryLabelPositions( base.getLabelPosition(RectangleEdge.TOP), base.getLabelPosition(RectangleEdge.BOTTOM), left, base.getLabelPosition(RectangleEdge.RIGHT)); }
/** * Returns the standard deviation of a set of numbers. * * @param data the data ({@code null} or zero length array not * permitted). * * @return The standard deviation of a set of numbers. */ public static double getStdDev(Number[] data) { Args.nullNotPermitted(data, "data"); if (data.length == 0) { throw new IllegalArgumentException("Zero length 'data' array."); } double avg = calculateMean(data); double sum = 0.0; for (int counter = 0; counter < data.length; counter++) { double diff = data[counter].doubleValue() - avg; sum = sum + diff * diff; } return Math.sqrt(sum / (data.length - 1)); }
/** * Sets the position for the title and sends a {@link TitleChangeEvent} to * all registered listeners. * * @param position the position ({@code null} not permitted). */ public void setPosition(RectangleEdge position) { Args.nullNotPermitted(position, "position"); if (this.position != position) { this.position = position; notifyListeners(new TitleChangeEvent(this)); } }
/** * Returns the group that a key is mapped to. * * @param key the key ({@code null} not permitted). * * @return The group (never {@code null}, returns the default group if * there is no mapping for the specified key). */ public Comparable getGroup(Comparable key) { Args.nullNotPermitted(key, "key"); Comparable result = this.defaultGroup; Comparable group = (Comparable) this.keyToGroupMap.get(key); if (group != null) { result = group; } return result; }
/** * Creates a label generator with the specified date formatter. * * @param labelFormat the label format string ({@code null} not * permitted). * @param formatter the date formatter ({@code null} not permitted). */ protected AbstractCategoryItemLabelGenerator(String labelFormat, DateFormat formatter) { Args.nullNotPermitted(labelFormat, "labelFormat"); Args.nullNotPermitted(formatter, "formatter"); this.labelFormat = labelFormat; this.numberFormat = null; this.percentFormat = NumberFormat.getPercentInstance(); this.dateFormat = formatter; this.nullValueString = "-"; }
/** * Sets the first time period in the axis range and sends an * {@link AxisChangeEvent} to all registered listeners. * * @param first the time period ({@code null} not permitted). */ public void setFirst(RegularTimePeriod first) { Args.nullNotPermitted(first, "first"); this.first = first; this.first.peg(this.calendar); fireChangeEvent(); }
/** * Returns a new instance based on an existing instance but with the top * position changed. * * @param base the base ({@code null} not permitted). * @param top the top position ({@code null} not permitted). * * @return A new instance (never {@code null}). */ public static CategoryLabelPositions replaceTopPosition( CategoryLabelPositions base, CategoryLabelPosition top) { Args.nullNotPermitted(base, "base"); Args.nullNotPermitted(top, "top"); return new CategoryLabelPositions(top, base.getLabelPosition(RectangleEdge.BOTTOM), base.getLabelPosition(RectangleEdge.LEFT), base.getLabelPosition(RectangleEdge.RIGHT)); }
/** * Sets the range axis for the plot and sends a {@link PlotChangeEvent} to * all registered listeners. * * @param axis the new axis ({@code null} not permitted). * * @see #getRangeAxis() */ public void setRangeAxis(ValueAxis axis) { Args.nullNotPermitted(axis, "axis"); // plot is registered as a listener with the existing axis... this.rangeAxis.removeChangeListener(this); axis.setPlot(this); axis.addChangeListener(this); this.rangeAxis = axis; fireChangeEvent(); }
/** * Creates a stacked area 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 StackedAreaRenderer} * as the renderer. * * @param title the chart title ({@code null} permitted). * @param categoryAxisLabel the label for the category axis * ({@code null} permitted). * @param valueAxisLabel the label for the value axis ({@code null} * permitted). * @param dataset the dataset for the chart ({@code null} permitted). * @param orientation the plot orientation (horizontal or vertical) * ({@code null} 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 area chart. */ public static JFreeChart createStackedAreaChart(String title, String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) { Args.nullNotPermitted(orientation, "orientation"); CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel); categoryAxis.setCategoryMargin(0.0); ValueAxis valueAxis = new NumberAxis(valueAxisLabel); StackedAreaRenderer renderer = new StackedAreaRenderer(); if (tooltips) { renderer.setDefaultToolTipGenerator( new StandardCategoryToolTipGenerator()); } if (urls) { renderer.setDefaultItemURLGenerator( 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; }
/** * Creates a bubble chart with default settings. The chart is composed of * an {@link XYPlot}, with a {@link NumberAxis} for the domain axis, * a {@link NumberAxis} for the range axis, and an {@link XYBubbleRenderer} * to draw the data items. * * @param title the chart title ({@code null} permitted). * @param xAxisLabel a label for the X-axis ({@code null} permitted). * @param yAxisLabel a label for the Y-axis ({@code null} permitted). * @param dataset the dataset for the chart ({@code null} permitted). * @param orientation the orientation (horizontal or vertical) * ({@code null} 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 bubble chart. */ public static JFreeChart createBubbleChart(String title, String xAxisLabel, String yAxisLabel, XYZDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) { Args.nullNotPermitted(orientation, "orientation"); NumberAxis xAxis = new NumberAxis(xAxisLabel); xAxis.setAutoRangeIncludesZero(false); NumberAxis yAxis = new NumberAxis(yAxisLabel); yAxis.setAutoRangeIncludesZero(false); XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null); XYItemRenderer renderer = new XYBubbleRenderer( XYBubbleRenderer.SCALE_ON_RANGE_AXIS); if (tooltips) { renderer.setDefaultToolTipGenerator(new StandardXYZToolTipGenerator()); } if (urls) { renderer.setURLGenerator(new StandardXYZURLGenerator()); } plot.setRenderer(renderer); plot.setOrientation(orientation); JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend); currentTheme.apply(chart); return chart; }
/** * Adds a subtitle at a particular position in the subtitle list, and sends * a {@link ChartChangeEvent} to all registered listeners. * * @param index the index (in the range 0 to {@link #getSubtitleCount()}). * @param subtitle the subtitle to add ({@code null} not permitted). * * @since 1.0.6 */ public void addSubtitle(int index, Title subtitle) { if (index < 0 || index > getSubtitleCount()) { throw new IllegalArgumentException( "The 'index' argument is out of range."); } Args.nullNotPermitted(subtitle, "subtitle"); this.subtitles.add(index, subtitle); subtitle.addChangeListener(this); fireChartChanged(); }
/** * Creates a new series with the specified key and description. * * @param key the series key ({@code null} NOT permitted). * @param description the series description ({@code null} permitted). */ protected Series(Comparable key, String description) { Args.nullNotPermitted(key, "key"); this.key = key; this.description = description; this.listeners = new EventListenerList(); this.propertyChangeSupport = new PropertyChangeSupport(this); this.vetoableChangeSupport = new VetoableChangeSupport(this); this.notify = true; }
/** * 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} not permitted). * * @return The range. * * @see #findRangeBounds(CategoryDataset) */ public static Range findCumulativeRangeBounds(CategoryDataset dataset) { Args.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 item. * * @param date the date ({@code null} not permitted). * @param open the open value. * @param high the high value. * @param low the low value. * @param close the close value. * @param volume the volume. */ public OHLCDataItem(Date date, double open, double high, double low, double close, double volume) { Args.nullNotPermitted(date, "date"); this.date = date; this.open = new Double(open); this.high = new Double(high); this.low = new Double(low); this.close = new Double(close); this.volume = new Double(volume); }
/** * Creates a new dataset with the given time zone and locale. * * @param zone the time zone to use ({@code null} not permitted). * @param locale the locale to use ({@code null} not permitted). */ public TimeTableXYDataset(TimeZone zone, Locale locale) { Args.nullNotPermitted(zone, "zone"); Args.nullNotPermitted(locale, "locale"); this.values = new DefaultKeyedValues2D(true); this.workingCalendar = Calendar.getInstance(zone, locale); this.xPosition = TimePeriodAnchor.START; }
/** * Returns a string containing the data in JSON format. The format is... * <br><br> * Note that this method can be used with instances of * {@link CategoryDataset}. * * @param data the data ({@code null} not permitted). * * @return A string in JSON format. */ public static String writeKeyedValues2D(KeyedValues2D data) { Args.nullNotPermitted(data, "data"); StringWriter sw = new StringWriter(); try { writeKeyedValues2D(data, sw); } catch (IOException ex) { throw new RuntimeException(ex); } return sw.toString(); }
/** * Creates a new dataset based on the supplied collection of tasks. * * @param tasks the underlying dataset ({@code null} not permitted). */ public XYTaskDataset(TaskSeriesCollection tasks) { Args.nullNotPermitted(tasks, "tasks"); this.underlying = tasks; this.seriesWidth = 0.8; this.underlying.addChangeListener(this); }
/** * Sets the chart that is used to draw the individual pie plots. The * chart's plot must be an instance of {@link PiePlot}. * * @param pieChart the pie chart ({@code null} not permitted). * * @see #getPieChart() */ public void setPieChart(JFreeChart pieChart) { Args.nullNotPermitted(pieChart, "pieChart"); if (!(pieChart.getPlot() instanceof PiePlot)) { throw new IllegalArgumentException("The 'pieChart' argument must " + "be a chart based on a PiePlot."); } this.pieChart = pieChart; fireChangeEvent(); }
/** * Sets the font for the tick label for the specified category and sends * an {@link AxisChangeEvent} to all registered listeners. * * @param category the category ({@code null} not permitted). * @param font the font ({@code null} permitted). * * @see #getTickLabelFont(Comparable) */ public void setTickLabelFont(Comparable category, Font font) { Args.nullNotPermitted(category, "category"); if (font == null) { this.tickLabelFontMap.remove(category); } else { this.tickLabelFontMap.put(category, font); } fireChangeEvent(); }
/** * Returns the maximum 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 maximum value). * Otherwise, it involves iterating over the entire data-set. Returns * {@code null} if all the data values are {@code null}. * * @param dataset the dataset ({@code null} not permitted). * * @return The maximum value (possibly {@code null}). */ public static Number findMaximumRangeValue(CategoryDataset dataset) { Args.nullNotPermitted(dataset, "dataset"); // work out the minimum value... if (dataset instanceof RangeInfo) { RangeInfo info = (RangeInfo) dataset; return new Double(info.getRangeUpperBound(true)); } // hasn't implemented RangeInfo, so we'll have to iterate... else { double maximum = Double.NEGATIVE_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.getEndValue(series, item); } else { value = dataset.getValue(series, item); } if (value != null) { maximum = Math.max(maximum, value.doubleValue()); } } } if (maximum == Double.NEGATIVE_INFINITY) { return null; } else { return new Double(maximum); } } }
/** * Finds the minimum domain (or X) value for the specified dataset. This * is easy if the dataset implements the {@link DomainInfo} interface (a * good idea if there is an efficient way to determine the minimum value). * Otherwise, it involves iterating over the entire data-set. * <p> * Returns {@code null} if all the data values in the dataset are * {@code null}. * * @param dataset the dataset ({@code null} not permitted). * * @return The minimum value (possibly {@code null}). */ public static Number findMinimumDomainValue(XYDataset dataset) { Args.nullNotPermitted(dataset, "dataset"); Number result; // if the dataset implements DomainInfo, life is easy if (dataset instanceof DomainInfo) { DomainInfo info = (DomainInfo) dataset; return new Double(info.getDomainLowerBound(true)); } else { double minimum = Double.POSITIVE_INFINITY; int seriesCount = dataset.getSeriesCount(); for (int series = 0; series < seriesCount; series++) { int itemCount = dataset.getItemCount(series); for (int item = 0; item < itemCount; item++) { double value; if (dataset instanceof IntervalXYDataset) { IntervalXYDataset intervalXYData = (IntervalXYDataset) dataset; value = intervalXYData.getStartXValue(series, item); } else { value = dataset.getXValue(series, item); } if (!Double.isNaN(value)) { minimum = Math.min(minimum, value); } } } if (minimum == Double.POSITIVE_INFINITY) { result = null; } else { result = new Double(minimum); } } return result; }
/** * Resolves a domain axis location for a given plot orientation. * * @param location the location ({@code null} not permitted). * @param orientation the orientation ({@code null} not permitted). * * @return The edge (never {@code null}). */ public static RectangleEdge resolveDomainAxisLocation( AxisLocation location, PlotOrientation orientation) { Args.nullNotPermitted(location, "location"); Args.nullNotPermitted(orientation, "orientation"); RectangleEdge result = null; if (location == AxisLocation.TOP_OR_RIGHT) { if (orientation == PlotOrientation.HORIZONTAL) { result = RectangleEdge.RIGHT; } else if (orientation == PlotOrientation.VERTICAL) { result = RectangleEdge.TOP; } } else if (location == AxisLocation.TOP_OR_LEFT) { if (orientation == PlotOrientation.HORIZONTAL) { result = RectangleEdge.LEFT; } else if (orientation == PlotOrientation.VERTICAL) { result = RectangleEdge.TOP; } } else if (location == AxisLocation.BOTTOM_OR_RIGHT) { if (orientation == PlotOrientation.HORIZONTAL) { result = RectangleEdge.RIGHT; } else if (orientation == PlotOrientation.VERTICAL) { result = RectangleEdge.BOTTOM; } } else if (location == AxisLocation.BOTTOM_OR_LEFT) { if (orientation == PlotOrientation.HORIZONTAL) { result = RectangleEdge.LEFT; } else if (orientation == PlotOrientation.VERTICAL) { result = RectangleEdge.BOTTOM; } } // the above should cover all the options... if (result == null) { throw new IllegalStateException("resolveDomainAxisLocation()"); } return result; }
/** * Creates a new instance. The modifier keys are used to select a * mouse handler to be the current "live" handler (when a handler is * used as an auxiliary handler, the modifier keys are not relevant). * * @param id the handler id ({@code null} not permitted). * @param altKey require ALT key modifier? * @param ctrlKey require ALT key modifier? * @param metaKey require ALT key modifier? * @param shiftKey require ALT key modifier? */ public AbstractMouseHandlerFX(String id, boolean altKey, boolean ctrlKey, boolean metaKey, boolean shiftKey) { Args.nullNotPermitted(id, "id"); this.id = id; this.enabled = true; this.altKey = altKey; this.ctrlKey = ctrlKey; this.metaKey = metaKey; this.shiftKey = shiftKey; }