Java tutorial
/******************************************************************************* * Copyright (c) 2010 Australian Nuclear Science and Technology Organisation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Norman Xiong (nxi@Bragg Institute) - initial API and implementation ******************************************************************************/ package org.gumtree.vis.plot1d; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Cursor; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Shape; import java.awt.Stroke; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import javax.swing.JFileChooser; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JRadioButtonMenuItem; import org.eclipse.swt.SWT; import org.gumtree.vis.awt.JChartPanel; import org.gumtree.vis.core.internal.StaticValues; import org.gumtree.vis.dataset.DatasetUtils; import org.gumtree.vis.dataset.DatasetUtils.ExportFormat; import org.gumtree.vis.interfaces.IDataset; import org.gumtree.vis.interfaces.IExporter; import org.gumtree.vis.interfaces.IHelpProvider; import org.gumtree.vis.interfaces.IPlot1D; import org.gumtree.vis.interfaces.IXYErrorDataset; import org.gumtree.vis.interfaces.IXYErrorSeries; import org.gumtree.vis.listener.XYChartMouseEvent; import org.gumtree.vis.mask.AbstractMask; import org.gumtree.vis.mask.ChartMaskingUtilities; import org.gumtree.vis.mask.RangeMask; import org.jfree.chart.ChartMouseListener; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.block.RectangleConstraint; import org.jfree.chart.entity.ChartEntity; import org.jfree.chart.entity.EntityCollection; import org.jfree.chart.entity.XYItemEntity; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYErrorRenderer; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.chart.title.LegendTitle; import org.jfree.data.Range; import org.jfree.data.xy.XYDataset; import org.jfree.ui.ExtensionFileFilter; import org.jfree.ui.RectangleEdge; import org.jfree.ui.Size2D; /** * @author nxi * */ public class Plot1DPanel extends JChartPanel implements IPlot1D { /** * */ public static final Color MASK_INCLUSIVE_COLOR = new Color(0, 220, 0, 30); public static final Color MASK_EXCLUSIVE_COLOR = new Color(0, 0, 220, 30); private static final long serialVersionUID = -5212815744540142881L; private static final String PROPERTY_INDEX_IN_TOOLTIP = "gumtree.plot.indexintooltip"; private static final String LEGEND_NONE_COMMAND = "legendNone"; private static final String LEGEND_INTERNAL_COMMAND = "legendInternal"; private static final String LEGEND_BOTTOM_COMMAND = "legendBottom"; private static final String LEGEND_RIGHT_COMMAND = "legendRight"; private static final Stroke DEFAULT_STROCK = new BasicStroke(1); private static final Stroke BOLD_STROCK = new BasicStroke(2f); private static final int seriesSelectionEventMask = InputEvent.CTRL_MASK; // private static final Cursor MOVE_CURSOR = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR); private static final Color axisTraceColor = Color.darkGray; private JMenu legendMenu; private JMenuItem legendNone; private JMenuItem legendBottom; private JMenuItem legendRight; private JMenuItem legendInternal; private int selectedSeriesIndex = -1; private double chartError; private boolean indexInTooltip; /** Remove the selected mask command. */ public static final String UNFOCUS_CURVE_COMMAND = "FOCUS_NONE"; public static final String FOCUS_ON_COMMAND = "FOCUS_ON"; private static int minMaskWidth = 4; private double maskPoint = Double.NaN; private Point2D legendPoint; private RangeMask currentMaskRectangle = null; // private List<RectangleMask> exclusiveMaskList; // private RangeMask selectedMask; private double maskMovePoint; // private JMenu maskManagementMenu; private JMenu curveManagementMenu; // private JMenuItem removeSelectedMaskMenuItem; private Rectangle2D internalLegendSetup; private boolean isInternalLegendEnabled; private boolean isInternalLegendSelected; private int mouseFollowerXPrecision; private int mouseFollowerYPrecision; private int itemIndex; private int seriesIndex; /** * @param chart */ public Plot1DPanel(JFreeChart chart) { this(chart, StaticValues.PANEL_WIDTH, StaticValues.PANEL_HEIGHT, StaticValues.PANEL_MINIMUM_DRAW_WIDTH, StaticValues.PANEL_MINIMUM_DRAW_HEIGHT, StaticValues.PANEL_MAXIMUM_DRAW_WIDTH, StaticValues.PANEL_MAXIMUM_DRAW_HEIGHT, true, true, // properties true, // save true, // print true, // zoom true // tooltips ); } /** * @param chart * @param useBuffer */ public Plot1DPanel(JFreeChart chart, boolean useBuffer) { this(chart, StaticValues.PANEL_WIDTH, StaticValues.PANEL_HEIGHT, StaticValues.PANEL_MINIMUM_DRAW_WIDTH, StaticValues.PANEL_MINIMUM_DRAW_HEIGHT, StaticValues.PANEL_MAXIMUM_DRAW_WIDTH, StaticValues.PANEL_MAXIMUM_DRAW_HEIGHT, useBuffer, true, // properties true, // save true, // print true, // zoom true // tooltips ); } /** * @param chart * @param properties * @param save * @param print * @param zoom * @param tooltips */ public Plot1DPanel(JFreeChart chart, boolean properties, boolean save, boolean print, boolean zoom, boolean tooltips) { this(chart, StaticValues.PANEL_WIDTH, StaticValues.PANEL_HEIGHT, StaticValues.PANEL_MINIMUM_DRAW_WIDTH, StaticValues.PANEL_MINIMUM_DRAW_HEIGHT, StaticValues.PANEL_MAXIMUM_DRAW_WIDTH, StaticValues.PANEL_MAXIMUM_DRAW_HEIGHT, true, properties, save, print, zoom, tooltips); } /** * @param chart * @param width * @param height * @param minimumDrawWidth * @param minimumDrawHeight * @param maximumDrawWidth * @param maximumDrawHeight * @param useBuffer * @param properties * @param save * @param print * @param zoom * @param tooltips */ public Plot1DPanel(JFreeChart chart, int width, int height, int minimumDrawWidth, int minimumDrawHeight, int maximumDrawWidth, int maximumDrawHeight, boolean useBuffer, boolean properties, boolean save, boolean print, boolean zoom, boolean tooltips) { this(chart, width, height, minimumDrawWidth, minimumDrawHeight, maximumDrawWidth, maximumDrawHeight, useBuffer, properties, true, save, print, zoom, tooltips); } /** * @param chart * @param width * @param height * @param minimumDrawWidth * @param minimumDrawHeight * @param maximumDrawWidth * @param maximumDrawHeight * @param useBuffer * @param properties * @param copy * @param save * @param print * @param zoom * @param tooltips */ public Plot1DPanel(JFreeChart chart, int width, int height, int minimumDrawWidth, int minimumDrawHeight, int maximumDrawWidth, int maximumDrawHeight, boolean useBuffer, boolean properties, boolean copy, boolean save, boolean print, boolean zoom, boolean tooltips) { super(chart, width, height, minimumDrawWidth, minimumDrawHeight, maximumDrawWidth, maximumDrawHeight, useBuffer, properties, copy, save, print, zoom, tooltips); createMaskColors(false); String horizontalMarginProperty = System.getProperty(StaticValues.HORIZONTAL_MARGIN_PROPERTY); if (horizontalMarginProperty != null) { float horizontalMargin = 0.05f; try { horizontalMargin = Float.valueOf(horizontalMarginProperty); getHorizontalAxis().setLowerMargin(horizontalMargin); getHorizontalAxis().setUpperMargin(horizontalMargin); } catch (Exception e) { } } internalLegendSetup = new Rectangle2D.Double(152, 20, 150, 20); isInternalLegendSelected = false; mouseFollowerXPrecision = 2; mouseFollowerYPrecision = 2; indexInTooltip = false; String indexInTooltipProperty = System.getProperty(PROPERTY_INDEX_IN_TOOLTIP); if (indexInTooltipProperty != null) { try { indexInTooltip = Boolean.valueOf(indexInTooltipProperty); } catch (Exception e) { } } } @Override public void paintComponent(Graphics g) { // TODO Auto-generated method stub super.paintComponent(g); if (isInternalLegendEnabled) { Graphics2D g2 = (Graphics2D) g.create(); drawInternalLegend(g2); } } // @Override // public void paintComponent(Graphics g) { //// long time = System.currentTimeMillis(); // super.paintComponent(g); // Graphics2D g2 = (Graphics2D) g.create(); //// ChartMaskingUtilities.drawDomainMask(g2, getScreenDataArea(), maskList, //// selectedMask, getChart()); // ChartMaskingUtilities.drawMasks(g2, getScreenDataArea(), getMasks(), // selectedMask, getChart()); // if (getHorizontalAxisTrace()) { // drawHorizontalAxisTrace(g2, horizontalTraceLocation); // } // if (getVerticalAxisTrace()) { // drawVerticalAxisTrace(g2, verticalTraceLocation); // } // if (isToolTipFollowerEnabled) { // drawToolTipFollower(g2, horizontalTraceLocation, verticalTraceLocation); // } //// System.out.println("refreshing cost " + (System.currentTimeMillis() - time) + " ms"); // } private void drawInternalLegend(Graphics2D g2) { // XYDataset dataset = getXYPlot().getDataset(); // int numSeries = dataset.getSeriesCount(); Rectangle2D screenArea = getScreenDataArea(); Rectangle2D lengendArea = new Rectangle2D.Double(screenArea.getMaxX() - internalLegendSetup.getMinX(), screenArea.getMinY() + internalLegendSetup.getMinY(), internalLegendSetup.getWidth(), internalLegendSetup.getHeight()); LegendTitle legend = new LegendTitle(getXYPlot()); RectangleConstraint rc = new RectangleConstraint(new Range(0, internalLegendSetup.getWidth()), new Range(0, internalLegendSetup.getHeight())); Size2D size = legend.arrange(g2, rc); getXYPlot().getLegendItems(); legend.draw(g2, lengendArea); Rectangle2D titleRect = new Rectangle2D.Double(lengendArea.getMinX(), lengendArea.getMinY(), size.width, size.height); internalLegendSetup.setRect(internalLegendSetup.getX(), internalLegendSetup.getY(), titleRect.getWidth(), titleRect.getHeight()); if (isInternalLegendSelected) { ChartMaskingUtilities.drawMaskBoarder(g2, titleRect); } else { g2.setColor(Color.GRAY); g2.draw(titleRect); } } @Override protected JPopupMenu createPopupMenu(boolean properties, boolean copy, boolean save, boolean print, boolean zoom) { JPopupMenu menu = super.createPopupMenu(properties, copy, save, print, zoom); menu.addSeparator(); legendMenu = new JMenu("Legend Position"); menu.add(legendMenu); legendNone = new JRadioButtonMenuItem("None"); legendNone.setActionCommand(LEGEND_NONE_COMMAND); legendNone.addActionListener(this); legendMenu.add(legendNone); legendInternal = new JRadioButtonMenuItem("Internal"); legendInternal.setActionCommand(LEGEND_INTERNAL_COMMAND); legendInternal.addActionListener(this); legendMenu.add(legendInternal); legendBottom = new JRadioButtonMenuItem("Bottom"); legendBottom.setActionCommand(LEGEND_BOTTOM_COMMAND); legendBottom.addActionListener(this); legendMenu.add(legendBottom); legendRight = new JRadioButtonMenuItem("Right"); legendRight.setActionCommand(LEGEND_RIGHT_COMMAND); legendRight.addActionListener(this); legendMenu.add(legendRight); menu.addSeparator(); curveManagementMenu = new JMenu("Focus on Curve"); menu.add(curveManagementMenu); // this.removeSelectedMaskMenuItem = new JMenuItem(); // this.removeSelectedMaskMenuItem.setActionCommand(REMOVE_SELECTED_MASK_COMMAND); // this.removeSelectedMaskMenuItem.addActionListener(this); // menu.addSeparator(); // menu.add(removeSelectedMaskMenuItem); // maskManagementMenu = new JMenu("Mask Management"); // menu.add(maskManagementMenu); return menu; } @Override protected void displayPopupMenu(int x, int y) { LegendTitle legend = getChart().getLegend(); if (legend != null) { boolean isVisable = legend.isVisible(); RectangleEdge location = legend.getPosition(); if (isVisable) { if (location.equals(RectangleEdge.BOTTOM)) { legendBottom.setSelected(true); legendNone.setSelected(false); legendInternal.setSelected(false); legendRight.setSelected(false); } else if (isVisable && location.equals(RectangleEdge.RIGHT)) { legendRight.setSelected(true); legendNone.setSelected(false); legendInternal.setSelected(false); legendBottom.setSelected(false); } } else { if (isInternalLegendEnabled) { legendNone.setSelected(false); legendInternal.setSelected(true); legendRight.setSelected(false); legendBottom.setSelected(false); } else { legendNone.setSelected(true); legendInternal.setSelected(false); legendRight.setSelected(false); legendBottom.setSelected(false); } } } XYDataset dataset = getChart().getXYPlot().getDataset(); curveManagementMenu.removeAll(); if (dataset.getSeriesCount() > 0) { curveManagementMenu.setEnabled(true); JMenuItem focusNoneCurveItem = new JRadioButtonMenuItem(); focusNoneCurveItem.setText("None"); focusNoneCurveItem.setActionCommand(UNFOCUS_CURVE_COMMAND); focusNoneCurveItem.addActionListener(this); curveManagementMenu.add(focusNoneCurveItem); boolean isCurveFocused = false; for (int i = 0; i < dataset.getSeriesCount(); i++) { String seriesKey = (String) dataset.getSeriesKey(i); JMenuItem focusOnCurveItem = new JRadioButtonMenuItem(); focusOnCurveItem.setText(seriesKey); focusOnCurveItem.setActionCommand(FOCUS_ON_COMMAND + "-" + seriesKey); focusOnCurveItem.addActionListener(this); curveManagementMenu.add(focusOnCurveItem); if (i == selectedSeriesIndex) { focusOnCurveItem.setSelected(true); isCurveFocused = true; } } if (!isCurveFocused) { focusNoneCurveItem.setSelected(true); } } else { curveManagementMenu.setEnabled(false); } // addMaskMenu(x, y); super.displayPopupMenu(x, y); } @Override public void actionPerformed(ActionEvent event) { String command = event.getActionCommand(); if (command.equals(LEGEND_NONE_COMMAND)) { getChart().getLegend().setVisible(false); isInternalLegendEnabled = false; repaint(); } else if (command.equals(LEGEND_INTERNAL_COMMAND)) { getChart().getLegend().setVisible(false); isInternalLegendEnabled = true; repaint(); } else if (command.equals(LEGEND_BOTTOM_COMMAND)) { getChart().getLegend().setVisible(true); getChart().getLegend().setPosition(RectangleEdge.BOTTOM); isInternalLegendEnabled = false; repaint(); } else if (command.startsWith(LEGEND_RIGHT_COMMAND)) { getChart().getLegend().setVisible(true); getChart().getLegend().setPosition(RectangleEdge.RIGHT); isInternalLegendEnabled = false; repaint(); } else if (command.equals(UNFOCUS_CURVE_COMMAND)) { selectSeries(-1); repaint(); } else if (command.startsWith(FOCUS_ON_COMMAND)) { String[] commands = command.split("-", 2); if (commands.length > 1) { selectSeries(commands[1]); repaint(); } } else { super.actionPerformed(event); } } @Override public void doEditChartProperties() { showPropertyEditor(0); } private void showPropertyEditor(int tabIndex) { XYDataset dataset = getChart().getXYPlot().getDataset(); if (selectedSeriesIndex >= 0 && selectedSeriesIndex < dataset.getSeriesCount()) { Plot1DChartEditor.setSuggestedSeriesKey((String) dataset.getSeriesKey(selectedSeriesIndex)); } Plot1DChartEditor editor = new Plot1DChartEditor(getChart(), this); editor.getTabs().setSelectedIndex(tabIndex); int result = JOptionPane.showConfirmDialog(this, editor, localizationResources.getString("Chart_Properties"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); if (result == JOptionPane.OK_OPTION) { editor.updateChart(getChart()); } } public void doEditMaskProperties() { showPropertyEditor(2); } /** * Receives notification of mouse clicks on the panel. These are * translated and passed on to any registered {@link ChartMouseListener}s. * * @param event Information about the mouse event. */ @Override public void mouseClicked(MouseEvent event) { Insets insets = getInsets(); int x = (int) ((event.getX() - insets.left) / getScaleX()); int y = (int) ((event.getY() - insets.top) / getScaleY()); setAnchor(new Point2D.Double(x, y)); if (getChart() == null) { return; } // getChart().setNotify(true); // force a redraw // new entity code... // if (listeners.length == 0) { // return; // } // if ((event.getModifiers() & maskingSelectionMask) != 0) { if (isInternalLegendEnabled) { Rectangle2D screenArea = getScreenDataArea(); Rectangle2D legendArea = new Rectangle2D.Double(screenArea.getMaxX() - internalLegendSetup.getMinX(), screenArea.getMinY() + internalLegendSetup.getMinY(), internalLegendSetup.getWidth(), internalLegendSetup.getHeight()); if (legendArea.contains(event.getPoint())) { selectInternalLegend(true); selectMask(Double.NaN, Double.NaN); repaint(); return; } else { selectInternalLegend(false); } } if (!isTextInputEnabled() && (event.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) { selectMask(ChartMaskingUtilities.translateScreenX(x, getScreenDataArea(), getChart()), Double.NaN); repaint(); } if ((event.getModifiers() & seriesSelectionEventMask) == 0) { if (getSelectedMask() != null && (event.getModifiers() & MouseEvent.BUTTON1_MASK) != 0 && !getSelectedMask().getRange() .contains(ChartMaskingUtilities.translateScreenX(x, getScreenDataArea(), getChart()))) { selectMask(Double.NaN, Double.NaN); } repaint(); } else if (!isTextInputEnabled()) { selectMask(ChartMaskingUtilities.translateScreenX(x, getScreenDataArea(), getChart()), Double.NaN); repaint(); } ChartEntity entity = null; if (getChartRenderingInfo() != null) { EntityCollection entities = getChartRenderingInfo().getEntityCollection(); if (entities != null) { entity = entities.getEntity(x, y); if (entity instanceof XYItemEntity) { XYItemEntity xyEntity = (XYItemEntity) entity; // XYDataset dataset = xyEntity.getDataset(); // int item = ((XYItemEntity) entity).getItem(); // chartX = dataset.getXValue(xyEntity.getSeriesIndex(), item); // chartY = dataset.getYValue(xyEntity.getSeriesIndex(), item); // Point2D screenPoint = ChartMaskingUtilities.translateChartPoint( // new Point2D.Double(chartX, chartY), getScreenDataArea(), getChart()); // if (getHorizontalAxisTrace()) { // horizontalTraceLocation = (int) screenPoint.getX(); // } // if (getVerticalAxisTrace()) { // verticalTraceLocation = (int) screenPoint.getY(); // } if ((event.getModifiers() & seriesSelectionEventMask) != 0 && (event.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) { selectSeries(xyEntity.getSeriesIndex()); return; } else if ((event.getModifiers() & maskingSelectionMask) == 0 && (event.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) { if (selectedSeriesIndex != xyEntity.getSeriesIndex()) { selectSeries(-1); return; } } } else { if (selectedSeriesIndex >= 0) { if ((event.getModifiers() & seriesSelectionEventMask) != 0 && (event.getModifiers() & maskingSelectionMask) == 0 && (event.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) { selectSeries(-1); return; } } } } } XYChartMouseEvent chartEvent = new XYChartMouseEvent(getChart(), event, entity); chartEvent.setXY(getChartX(), getChartY()); Object[] listeners = getListeners(ChartMouseListener.class); for (int i = listeners.length - 1; i >= 0; i -= 1) { ((ChartMouseListener) listeners[i]).chartMouseClicked(chartEvent); } super.mouseClicked(event); } @Override public void mouseMoved(MouseEvent e) { Insets insets = getInsets(); int x = (int) ((e.getX() - insets.left) / getScaleX()); int y = (int) ((e.getY() - insets.top) / getScaleY()); ChartEntity entity = null; if (getChartRenderingInfo() != null) { EntityCollection entities = getChartRenderingInfo().getEntityCollection(); if (entities != null) { entity = entities.getEntity(x, y); // boolean isDirty = false; int seriesIndex = -1; if (selectedSeriesIndex >= 0) { // double xInChart = ChartMaskingUtilities.translateScreenX(x, // getScreenDataArea(), getChart()); // XYDataset dataset = getChart().getXYPlot().getDataset(); // PatternDataset patternDataset = (PatternDataset) dataset; // int itemIndex = patternDataset.getItemFromX(selectedSeriesIndex, xInChart); // if (itemIndex < patternDataset.getItemCount(selectedSeriesIndex)) { // chartX = patternDataset.getXValue(selectedSeriesIndex, itemIndex); // chartY = patternDataset.getYValue(selectedSeriesIndex, itemIndex); // Point2D axisTrace = ChartMaskingUtilities.translateChartPoint( // new Point2D.Double(chartX, chartY), getScreenDataArea(), getChart()); // horizontalTraceLocation = (int) axisTrace.getX(); // verticalTraceLocation = (int) axisTrace.getY(); // if (getHorizontalAxisTrace() || getVerticalAxisTrace() || isToolTipFollowerEnabled) { // repaint(); // } // seriesIndex = selectedSeriesIndex; // isDirty = true; // } seriesIndex = followDomainTrace(selectedSeriesIndex, x); if (seriesIndex >= 0 && (getHorizontalAxisTrace() || getVerticalAxisTrace() || isToolTipFollowerEnabled())) { repaint(); } } else if (getChart().getXYPlot().getSeriesCount() == 1) { // int seriesIndex0 = 0; // double xInChart = ChartMaskingUtilities.translateScreenX(x, // getScreenDataArea(), getChart()); // XYDataset dataset = getChart().getXYPlot().getDataset(); // PatternDataset patternDataset = (PatternDataset) dataset; // int itemIndex = patternDataset.getItemFromX(seriesIndex0, xInChart); // if (itemIndex < patternDataset.getItemCount(seriesIndex0)) { // chartX = patternDataset.getXValue(seriesIndex0, itemIndex); // chartY = patternDataset.getYValue(seriesIndex0, itemIndex); // Point2D axisTrace = ChartMaskingUtilities.translateChartPoint( // new Point2D.Double(chartX, chartY), getScreenDataArea(), getChart()); //// if (getScreenDataArea().contains(axisTrace)) { // horizontalTraceLocation = (int) axisTrace.getX(); // verticalTraceLocation = (int) axisTrace.getY(); // if (getHorizontalAxisTrace() || getVerticalAxisTrace() || isToolTipFollowerEnabled) { // repaint(); // } // seriesIndex = seriesIndex0; // isDirty = true; //// } // } seriesIndex = followDomainTrace(0, x); if (seriesIndex >= 0 && (getHorizontalAxisTrace() || getVerticalAxisTrace() || isToolTipFollowerEnabled())) { repaint(); } } else if (entity instanceof XYItemEntity) { XYItemEntity xyEntity = (XYItemEntity) entity; XYDataset dataset = xyEntity.getDataset(); int item = ((XYItemEntity) entity).getItem(); seriesIndex = xyEntity.getSeriesIndex(); double chartX = dataset.getXValue(seriesIndex, item); double chartY = dataset.getYValue(seriesIndex, item); Point2D screenPoint = ChartMaskingUtilities.translateChartPoint( new Point2D.Double(chartX, chartY), getScreenDataArea(), getChart()); setChartX(chartX); setChartY(chartY); setSeriesIndex(seriesIndex); setItemIndex(item); if (dataset instanceof IXYErrorDataset) { setChartError(((IXYErrorDataset) dataset).getYError(seriesIndex, item)); } if (getHorizontalAxisTrace()) { setHorizontalTraceLocation((int) screenPoint.getX()); } if (getVerticalAxisTrace()) { setVerticalTraceLocation((int) screenPoint.getY()); } if (getHorizontalAxisTrace() || getVerticalAxisTrace() || isToolTipFollowerEnabled()) { repaint(); } // isDirty = true; } if (seriesIndex >= 0) { Object[] listeners = getListeners(ChartMouseListener.class); if (getChart() != null) { XYChartMouseEvent event = new XYChartMouseEvent(getChart(), e, entity); event.setXY(getChartX(), getChartY()); event.setSeriesIndex(seriesIndex); for (int i = listeners.length - 1; i >= 0; i -= 1) { ((ChartMouseListener) listeners[i]).chartMouseMoved(event); } } } } // getChart().handleClick(x, y, getChartRenderingInfo()); } if (isInternalLegendEnabled && isInternalLegendSelected) { int cursorType = findCursorOnSelectedItem(e.getX(), e.getY()); setCursor(Cursor.getPredefinedCursor(cursorType)); } else if (getCursor() != defaultCursor) { setCursor(defaultCursor); } super.mouseMoved(e); // we can only generate events if the panel's chart is not null // (see bug report 1556951) } @Override public void mousePressed(MouseEvent e) { int mods = e.getModifiers(); // if (isMaskingEnabled() && (mods & maskingKeyMask) != 0) { if (isInternalLegendEnabled && isInternalLegendSelected) { int cursorType = findCursorOnSelectedItem(e.getX(), e.getY()); if (cursorType == Cursor.DEFAULT_CURSOR) { Rectangle2D screenDataArea = getScreenDataArea(e.getX(), e.getY()); if (screenDataArea != null) { legendPoint = e.getPoint(); } else { legendPoint = null; } } else { if (cursorType == Cursor.MOVE_CURSOR) { legendPoint = e.getPoint(); } } } if (isMaskingEnabled()) { // Prepare masking service. int cursorType = findCursorOnSelectedItem(e.getX(), e.getY()); if (cursorType == Cursor.DEFAULT_CURSOR && (mods & maskingKeyMask) != 0) { Rectangle2D screenDataArea = getScreenDataArea(e.getX(), e.getY()); if (screenDataArea != null) { this.maskPoint = getPointInRectangle(e.getX(), e.getY(), screenDataArea).getX(); } else { this.maskPoint = Double.NaN; } } else { if (cursorType == Cursor.MOVE_CURSOR) { // this.maskMovePoint = translateScreenToChart( // translateScreenToJava2D(e.getPoint())).getX(); Insets insets = getInsets(); this.maskMovePoint = ChartMaskingUtilities.translateScreenX( (e.getX() - insets.left) / getScaleX(), getScreenDataArea(), getChart()); } setMaskDragIndicator(cursorType); } } if (getMaskDragIndicator() == Cursor.DEFAULT_CURSOR) { super.mousePressed(e); } } @Override public void mouseDragged(MouseEvent e) { Insets insets = getInsets(); int x = (int) ((e.getX() - insets.left) / getScaleX()); int y = (int) ((e.getY() - insets.top) / getScaleY()); ChartEntity entity = null; EntityCollection entities = null; if (getChartRenderingInfo() != null) { entities = getChartRenderingInfo().getEntityCollection(); if (entities != null) { entity = entities.getEntity(x, y); // boolean isDirty = false; int seriesIndex = -1; if (selectedSeriesIndex >= 0) { // double xInChart = ChartMaskingUtilities.translateScreenX(x, // getScreenDataArea(), getChart()); // XYDataset dataset = getChart().getXYPlot().getDataset(); // PatternDataset patternDataset = (PatternDataset) dataset; // int itemIndex = patternDataset.getItemFromX(selectedSeriesIndex, xInChart); // if (itemIndex < patternDataset.getItemCount(selectedSeriesIndex)) { // chartX = patternDataset.getXValue(selectedSeriesIndex, itemIndex); // chartY = patternDataset.getYValue(selectedSeriesIndex, itemIndex); // Point2D axisTrace = ChartMaskingUtilities.translateChartPoint( // new Point2D.Double(chartX, chartY), getScreenDataArea(), getChart()); // horizontalTraceLocation = (int) axisTrace.getX(); // verticalTraceLocation = (int) axisTrace.getY(); // seriesIndex = selectedSeriesIndex; // isDirty = true; // } seriesIndex = followDomainTrace(selectedSeriesIndex, x); } else if (getChart().getXYPlot().getSeriesCount() == 1) { // int seriesIndex0 = 0; // double xInChart = ChartMaskingUtilities.translateScreenX(x, // getScreenDataArea(), getChart()); // XYDataset dataset = getChart().getXYPlot().getDataset(); // PatternDataset patternDataset = (PatternDataset) dataset; // int itemIndex = patternDataset.getItemFromX(seriesIndex0, xInChart); // if (itemIndex < patternDataset.getItemCount(seriesIndex0)) { // chartX = patternDataset.getXValue(seriesIndex0, itemIndex); // chartY = patternDataset.getYValue(seriesIndex0, itemIndex); // Point2D axisTrace = ChartMaskingUtilities.translateChartPoint( // new Point2D.Double(chartX, chartY), getScreenDataArea(), getChart()); // horizontalTraceLocation = (int) axisTrace.getX(); // verticalTraceLocation = (int) axisTrace.getY(); // seriesIndex = seriesIndex0; // isDirty = true; // } seriesIndex = followDomainTrace(0, x); } else if (entity instanceof XYItemEntity) { XYItemEntity xyEntity = (XYItemEntity) entity; XYDataset dataset = xyEntity.getDataset(); int item = ((XYItemEntity) entity).getItem(); seriesIndex = xyEntity.getSeriesIndex(); double chartX = dataset.getXValue(seriesIndex, item); double chartY = dataset.getYValue(seriesIndex, item); Point2D screenPoint = ChartMaskingUtilities.translateChartPoint( new Point2D.Double(chartX, chartY), getScreenDataArea(), getChart()); setChartX(chartX); setChartY(chartY); setSeriesIndex(seriesIndex); setItemIndex(item); if (dataset instanceof IXYErrorDataset) { setChartError(((IXYErrorDataset) dataset).getYError(seriesIndex, item)); } if (getHorizontalAxisTrace()) { setHorizontalTraceLocation((int) screenPoint.getX()); } if (getVerticalAxisTrace()) { setVerticalTraceLocation((int) screenPoint.getY()); } // isDirty = true; } if (seriesIndex >= 0) { Object[] listeners = getListeners(ChartMouseListener.class); if (getChart() != null) { XYChartMouseEvent event = new XYChartMouseEvent(getChart(), e, entity); event.setXY(getChartX(), getChartY()); event.setSeriesIndex(seriesIndex); for (int i = listeners.length - 1; i >= 0; i -= 1) { ((ChartMouseListener) listeners[i]).chartMouseMoved(event); } } } } } // if (isMaskingEnabled() && (e.getModifiers() & maskingKeyMask) != 0) { if (isInternalLegendEnabled && isInternalLegendSelected) { int cursorType = findCursorOnSelectedItem(e.getX(), e.getY()); setCursor(Cursor.getPredefinedCursor(cursorType)); } else if (isMaskingEnabled() && (e.getModifiers() & maskingKeyMask) == 0) { int cursorType = findCursorOnSelectedItem(e.getX(), e.getY()); setCursor(Cursor.getPredefinedCursor(cursorType)); } else if (getCursor() != defaultCursor) { setCursor(defaultCursor); } if (isInternalLegendEnabled && isInternalLegendSelected && findCursorOnSelectedItem(e.getX(), e.getY()) != Cursor.DEFAULT_CURSOR && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) { changeInternalLegend(e); } else if (getMaskDragIndicator() != Cursor.DEFAULT_CURSOR && this.getSelectedMask() != null && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) { changeSelectedMask(e); } else if (isMaskingEnabled() && (e.getModifiers() & maskingKeyMask) != 0) { // Do masking service // if no initial masking point was set, ignore dragging... makeNewMask(e); } else { super.mouseDragged(e); } } private void changeSelectedMask(MouseEvent e) { // TODO Auto-generated method stub Point2D screenPoint = translateScreenToJava2D(e.getPoint()); //TODO: resize the mask Rectangle2D screenArea = getScreenDataArea(); if (screenArea.contains(screenPoint)) { // Point2D chartPoint = translateScreenToChart(screenPoint); changeSelectedMask( ChartMaskingUtilities.translateScreenX(screenPoint.getX(), getScreenDataArea(), getChart())); repaint(); } } private void changeInternalLegend(MouseEvent e) { // TODO Auto-generated method stub Point2D screenPoint = translateScreenToJava2D(e.getPoint()); //TODO: resize the mask Rectangle2D screenArea = getScreenDataArea(); if (screenArea.contains(screenPoint)) { // Point2D chartPoint = translateScreenToChart(screenPoint); // changeSelectedMask(ChartMaskingUtilities.translateScreenX( // screenPoint.getX(), getScreenDataArea(), getChart())); int cursorType = findCursorOnSelectedItem(e.getX(), e.getY()); switch (cursorType) { case Cursor.MOVE_CURSOR: moveLegend(e.getPoint()); break; case Cursor.W_RESIZE_CURSOR: changeLegendX(e.getPoint()); break; case Cursor.E_RESIZE_CURSOR: changeLegendWidth(e.getPoint()); break; default: break; } repaint(); } } private void moveLegend(Point2D point) { if (isInternalLegendEnabled && isInternalLegendSelected && legendPoint != null) { internalLegendSetup.setRect(internalLegendSetup.getX() + legendPoint.getX() - point.getX(), internalLegendSetup.getY() - legendPoint.getY() + point.getY(), internalLegendSetup.getWidth(), internalLegendSetup.getHeight()); legendPoint = point; } } private void changeLegendX(Point2D point) { if (isInternalLegendEnabled && isInternalLegendSelected && legendPoint != null) { Rectangle2D screenArea = getScreenDataArea(); if (point.getX() < screenArea.getMaxX()) { internalLegendSetup.setRect( screenArea.getMaxX() - point.getX(), internalLegendSetup.getY(), screenArea.getMaxX() - internalLegendSetup.getX() + internalLegendSetup.getWidth() - point.getX(), internalLegendSetup.getHeight()); } } } private void changeLegendWidth(Point2D point) { if (isInternalLegendEnabled && isInternalLegendSelected && legendPoint != null) { Rectangle2D screenArea = getScreenDataArea(); if (point.getX() < screenArea.getMaxX()) { internalLegendSetup.setRect(internalLegendSetup.getX(), internalLegendSetup.getY(), point.getX() - screenArea.getMaxX() + internalLegendSetup.getX(), internalLegendSetup.getHeight()); } } } private void makeNewMask(MouseEvent e) { Point2D screenPoint = translateScreenToJava2D(e.getPoint()); if (Double.isNaN(maskPoint) || Math.abs(screenPoint.getX() - maskPoint) < minMaskWidth) { return; } Graphics2D g2 = (Graphics2D) getGraphics(); // erase the previous zoom rectangle (if any). We only need to do // this is we are using XOR mode, which we do when we're not using // the buffer (if there is a buffer, then at the end of this method we // just trigger a repaint) if (!isDoubleBuffered()) { // drawZoomRectangle(g2, true); ChartMaskingUtilities.drawMasks(g2, getScreenDataArea(), getMaskMap(), getSelectedMask(), getChart()); } // boolean hZoom = false; // boolean vZoom = false; // if (this.orientation == PlotOrientation.HORIZONTAL) { // hZoom = this.rangeZoomable; // vZoom = this.domainZoomable; // } // else { // hZoom = this.domainZoomable; // vZoom = this.rangeZoomable; // } Rectangle2D scaledDataArea = getScreenDataArea(); // (int) this.maskPoint.getX(), (int) this.maskPoint.getY()); // Working on the current mask. Only create one new mask per drag-drawing. if (currentMaskRectangle == null) { boolean isInclusive = (e.getModifiers() & maskingExclusiveMask) == 0; currentMaskRectangle = new RangeMask(isInclusive); // currentMaskRectangle.setFillColor(getNextMaskColor(isInclusive)); // getMasks().add(currentMaskRectangle); addMask(currentMaskRectangle); } // selected rectangle shouldn't extend outside the data area... double xmax = Math.min(e.getX(), scaledDataArea.getMaxX()); // Update the current mask. Insets insets = getInsets(); double startX = ChartMaskingUtilities.translateScreenX((maskPoint - insets.left) / getScaleX(), getScreenDataArea(), getChart()); double endX = ChartMaskingUtilities.translateScreenX((xmax - insets.left) / getScaleX(), getScreenDataArea(), getChart()); updateCurrentDomainMask(startX, endX); // Draw the new zoom rectangle... if (isDoubleBuffered()) { repaint(); } else { // with no buffer, we use XOR to draw the rectangle "over" the // chart... ChartMaskingUtilities.drawMasks(g2, getScreenDataArea(), getMaskMap(), getSelectedMask(), getChart()); } g2.dispose(); } @Override public void mouseReleased(MouseEvent e) { if (currentMaskRectangle != null) { // reset masking service. maskPoint = Double.NaN; currentMaskRectangle = null; } else { super.mouseReleased(e); } setMaskDragIndicator(Cursor.DEFAULT_CURSOR); this.maskMovePoint = Double.NaN; } public void selectSeries(int seriesIndex) { if (selectedSeriesIndex != seriesIndex && seriesIndex >= 0) { XYItemRenderer renderer = getChart().getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { if (selectedSeriesIndex >= 0) { renderer.setSeriesStroke(selectedSeriesIndex, DEFAULT_STROCK); } renderer.setSeriesStroke(seriesIndex, BOLD_STROCK); selectedSeriesIndex = seriesIndex; } } else if (seriesIndex < 0 && selectedSeriesIndex >= 0) { XYItemRenderer renderer = getChart().getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { renderer.setSeriesStroke(selectedSeriesIndex, DEFAULT_STROCK); selectedSeriesIndex = -1; } } } public void selectSeries(String key) { if (key == null) { selectSeries(-1); return; } XYDataset dataset = getChart().getXYPlot().getDataset(); for (int i = 0; i < dataset.getSeriesCount(); i++) { if (dataset.getSeriesKey(i).equals(key)) { selectSeries(i); break; } } } public int getSelectedCurveIndex() { if (selectedSeriesIndex >= 0) { XYDataset dataset = getChart().getXYPlot().getDataset(); if (dataset.getSeriesCount() > selectedSeriesIndex) { return selectedSeriesIndex; } } return -1; } protected int findCursorOnSelectedItem(int x, int y) { if (isInternalLegendEnabled && isInternalLegendSelected) { Rectangle2D screenArea = getScreenDataArea(); Rectangle2D legendArea = new Rectangle2D.Double(screenArea.getMaxX() - internalLegendSetup.getMinX(), screenArea.getMinY() + internalLegendSetup.getMinY(), internalLegendSetup.getWidth(), internalLegendSetup.getHeight()); Rectangle2D intersect = screenArea.createIntersection(legendArea); Point2D point = new Point2D.Double(x, y); double minX = legendArea.getMinX(); double maxX = legendArea.getMaxX(); double minY = legendArea.getMinY(); double width = legendArea.getWidth(); double height = legendArea.getHeight(); if (!intersect.isEmpty() && screenArea.contains(point)) { if (width > 8) { Rectangle2D center = new Rectangle2D.Double(minX + 4, minY, width - 8, height); if (screenArea.createIntersection(center).contains(point)) { return Cursor.MOVE_CURSOR; } } Rectangle2D west = new Rectangle2D.Double(minX - 4, minY, width < 8 ? width / 2 + 4 : 8, height); if (screenArea.createIntersection(west).contains(point)) { return Cursor.W_RESIZE_CURSOR; } Rectangle2D east = new Rectangle2D.Double(maxX - (width < 8 ? width / 2 : 4), minY, width < 8 ? width / 2 + 4 : 8, height); if (screenArea.createIntersection(east).contains(point)) { return Cursor.E_RESIZE_CURSOR; } } } else if (getSelectedMask() != null && !getSelectedMask().isEmpty()) { Rectangle2D screenArea = getScreenDataArea(); Rectangle2D maskArea = ChartMaskingUtilities.getDomainMaskFrame(getSelectedMask(), getScreenDataArea(), getChart()); Rectangle2D intersect = screenArea.createIntersection(maskArea); Point2D point = new Point2D.Double(x, y); double minX = maskArea.getMinX(); double maxX = maskArea.getMaxX(); double minY = maskArea.getMinY(); double width = maskArea.getWidth(); double height = maskArea.getHeight(); if (!intersect.isEmpty() && screenArea.contains(point)) { if (width > 8) { Rectangle2D center = new Rectangle2D.Double(minX + 4, minY, width - 8, height); if (screenArea.createIntersection(center).contains(point)) { return Cursor.MOVE_CURSOR; } } Rectangle2D west = new Rectangle2D.Double(minX - 4, minY, width < 8 ? width / 2 + 4 : 8, height); if (screenArea.createIntersection(west).contains(point)) { return Cursor.W_RESIZE_CURSOR; } Rectangle2D east = new Rectangle2D.Double(maxX - (width < 8 ? width / 2 : 4), minY, width < 8 ? width / 2 + 4 : 8, height); if (screenArea.createIntersection(east).contains(point)) { return Cursor.E_RESIZE_CURSOR; } } } return Cursor.DEFAULT_CURSOR; } private void changeSelectedMask(double point) { switch (getMaskDragIndicator()) { case Cursor.MOVE_CURSOR: moveMask(point); break; case Cursor.W_RESIZE_CURSOR: if (((XYPlot) getChart().getPlot()).getDomainAxis().isInverted()) { changeMaskXMax(point); } else { changeMaskXMin(point); } break; case Cursor.E_RESIZE_CURSOR: if (((XYPlot) getChart().getPlot()).getDomainAxis().isInverted()) { changeMaskXMin(point); } else { changeMaskXMax(point); } break; default: break; } } private void moveMask(double point) { if (maskMovePoint != Double.NaN && getSelectedMask() != null) { Range range = getSelectedMask().getRange(); getSelectedMask().setBoundary(range.getLowerBound() + point - maskMovePoint, range.getUpperBound() + point - maskMovePoint); maskMovePoint = point; fireMaskUpdateEvent(getSelectedMask()); } } private void changeMaskXMax(double x) { Range range = getSelectedMask().getRange(); getSelectedMask().setBoundary(Math.min(range.getLowerBound(), x), Math.max(range.getLowerBound(), x)); fireMaskUpdateEvent(getSelectedMask()); } private void changeMaskXMin(double x) { Range range = getSelectedMask().getRange(); getSelectedMask().setBoundary(Math.min(range.getUpperBound(), x), Math.max(range.getUpperBound(), x)); fireMaskUpdateEvent(getSelectedMask()); } private void updateCurrentDomainMask(double startX, double endX) { if (currentMaskRectangle != null) { currentMaskRectangle.setMin(Math.min(startX, endX)); currentMaskRectangle.setMax(Math.max(startX, endX)); fireMaskUpdateEvent(currentMaskRectangle); } } public void selectMask(double chartX, double chartY) { if (Double.isNaN(chartX)) { setSelectedMask(null); return; } if (getSelectedMask() == null) { for (AbstractMask mask : getMasks()) { if (mask instanceof RangeMask) { if (((RangeMask) mask).getRange().contains(chartX)) { setSelectedMask(mask); break; } } } } else { RangeMask newSelection = null; if (getMasks().contains(getSelectedMask())) { int index = getMasks().indexOf(getSelectedMask()); for (int i = index + 1; i < getMasks().size(); i++) { RangeMask mask = (RangeMask) getMasks().get(i); if (mask.getRange().contains(chartX)) { newSelection = mask; break; } } if (newSelection == null) { for (int i = 0; i < index; i++) { RangeMask mask = (RangeMask) getMasks().get(i); if (mask.getRange().contains(chartX)) { newSelection = mask; break; } } } setSelectedMask(newSelection); } else { setSelectedMask(null); selectMask(chartX, chartY); } } // if (getSelectedMask() != null) // System.out.println("selected mask: x[" + getSelectedMask().getMin() + ", " // + getSelectedMask().getMax() + "]"); } private void selectInternalLegend(boolean isSelected) { isInternalLegendSelected = isSelected; } private int followDomainTrace(int seriesIndex, int domainLocation) { if (seriesIndex >= getDataset().getSeriesCount()) { return -1; } double xInChart = ChartMaskingUtilities.translateScreenX(domainLocation, getScreenDataArea(), getChart()); XYDataset dataset = getChart().getXYPlot().getDataset(); IXYErrorDataset patternDataset = (IXYErrorDataset) dataset; int itemIndex = patternDataset.getItemFromX(seriesIndex, xInChart); if (itemIndex >= 0 && itemIndex < patternDataset.getItemCount(seriesIndex)) { double chartX = patternDataset.getXValue(seriesIndex, itemIndex); double chartY = patternDataset.getYValue(seriesIndex, itemIndex); Point2D axisTrace = ChartMaskingUtilities.translateChartPoint(new Point2D.Double(chartX, chartY), getScreenDataArea(), getChart()); setChartX(chartX); setChartY(chartY); setSeriesIndex(seriesIndex); setItemIndex(itemIndex); if (dataset instanceof IXYErrorDataset) { setChartError(((IXYErrorDataset) dataset).getYError(seriesIndex, itemIndex)); } setHorizontalTraceLocation((int) axisTrace.getX()); setVerticalTraceLocation((int) axisTrace.getY()); if (getHorizontalAxisTrace() || getVerticalAxisTrace() || isToolTipFollowerEnabled()) { repaint(); } return seriesIndex; } return -1; } private void setItemIndex(int index) { this.itemIndex = index; } private void setSeriesIndex(int index) { this.seriesIndex = index; } private int getItemIndex() { return itemIndex; } private int getSeriesIndex() { return seriesIndex; } @Override public void moveSelectedMask(int direction) { if (getSelectedMask() == null) { return; } Range range = getSelectedMask().getRange(); switch (direction) { case SWT.ARROW_LEFT: getSelectedMask().setRange(Range.shift(range, -getBinWidth())); fireMaskUpdateEvent(getSelectedMask()); break; case SWT.ARROW_RIGHT: getSelectedMask().setRange(Range.shift(range, getBinWidth())); fireMaskUpdateEvent(getSelectedMask()); break; default: break; } repaint(); } private double getBinWidth() { double binWidth = 0; try { ValueAxis axis = getChart().getXYPlot().getDomainAxis(); double max = axis.getUpperBound(); double min = axis.getLowerBound(); binWidth = (max - min) / StaticValues.DOMAIN_MASK_SHIFT_RESOLUTION; if (axis.isInverted()) { binWidth = -binWidth; } } catch (Exception e) { e.printStackTrace(); } return binWidth; } @Override protected Color getAxisTraceColor() { return axisTraceColor; } @Override public RangeMask getSelectedMask() { return (RangeMask) super.getSelectedMask(); } private int getCurveIndex(IXYErrorSeries pattern) { XYDataset dataset = getDataset(); if (dataset instanceof IXYErrorDataset) { return ((IXYErrorDataset) dataset).indexOf(pattern); } return -1; } @Override public Color getCurveColor(IXYErrorSeries pattern) { int index = getCurveIndex(pattern); System.err.println("the curve index is " + index); if (index >= 0) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { return (Color) ((XYLineAndShapeRenderer) renderer).getSeriesPaint(index); } } return null; } @Override public boolean isCurveMarkerFilled(IXYErrorSeries pattern) { int index = getCurveIndex(pattern); if (index >= 0) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { return ((XYLineAndShapeRenderer) renderer).getSeriesShapesFilled(index); } } return false; } @Override public Shape getCurveMarkerShape(IXYErrorSeries pattern) { int index = getCurveIndex(pattern); if (index >= 0) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { return ((XYLineAndShapeRenderer) renderer).getSeriesShape(index); } } return null; } @Override public Stroke getCurveStroke(IXYErrorSeries pattern) { int index = getCurveIndex(pattern); if (index >= 0) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { return ((XYLineAndShapeRenderer) renderer).getSeriesStroke(index); } } return null; } @Override public boolean isCurveVisible(IXYErrorSeries pattern) { int index = getCurveIndex(pattern); if (index >= 0) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { return ((XYLineAndShapeRenderer) renderer).isSeriesVisible(index); } } return false; } @Override public boolean isErrorBarEnabled() { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYErrorRenderer) { return ((XYErrorRenderer) renderer).getDrawYError(); } return false; } @Override public boolean isLogarithmXEnabled() { ValueAxis axis = getXYPlot().getDomainAxis(); if (axis instanceof LogarithmizableAxis) { return ((LogarithmizableAxis) axis).isLogarithmic(); } return false; } @Override public boolean isLogarithmYEnabled() { ValueAxis axis = getXYPlot().getRangeAxis(); if (axis instanceof LogarithmizableAxis) { return ((LogarithmizableAxis) axis).isLogarithmic(); } return false; } @Override public boolean isMarkerEnabled() { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { return ((XYLineAndShapeRenderer) renderer).getBaseShapesVisible(); } return false; } @Override public void setCurveColor(IXYErrorSeries pattern, Color color) { int index = getCurveIndex(pattern); if (index >= 0) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { ((XYLineAndShapeRenderer) renderer).setSeriesPaint(index, color); } } } @Override public void setCurveMarkerFilled(IXYErrorSeries pattern, boolean filled) { int index = getCurveIndex(pattern); if (index >= 0) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { ((XYLineAndShapeRenderer) renderer).setSeriesShapesFilled(index, filled); } } } @Override public void setCurveMarkerShape(IXYErrorSeries pattern, MarkerShape shape) { int index = getCurveIndex(pattern); if (index >= 0) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { ((XYLineAndShapeRenderer) renderer).setSeriesShape(index, shape.getShape()); } } } @Override public void setCurveMarkerVisible(IXYErrorSeries pattern, boolean isMarkerVisible) { int index = getCurveIndex(pattern); if (index >= 0) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { ((XYLineAndShapeRenderer) renderer).setSeriesShapesVisible(index, isMarkerVisible); } } } @Override public void setCurveStroke(IXYErrorSeries pattern, float stroke) { int index = getCurveIndex(pattern); if (index >= 0) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { ((XYLineAndShapeRenderer) renderer).setSeriesStroke(index, new BasicStroke(stroke)); } } } @Override public void setCurveVisible(IXYErrorSeries pattern, boolean visible) { int index = getCurveIndex(pattern); if (index >= 0) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { ((XYLineAndShapeRenderer) renderer).setSeriesVisible(index, visible); } } } @Override public void setErrorBarEnabled(boolean enabled) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYErrorRenderer) { ((XYErrorRenderer) renderer).setDrawYError(enabled); } } @Override public void setLogarithmXEnabled(boolean enabled) { ValueAxis axis = getXYPlot().getDomainAxis(); if (axis instanceof LogarithmizableAxis) { ((LogarithmizableAxis) axis).setLogarithmic(enabled); axis.setAutoRange(true); } } @Override public void setLogarithmYEnabled(boolean enabled) { ValueAxis axis = getXYPlot().getRangeAxis(); if (axis instanceof LogarithmizableAxis) { ((LogarithmizableAxis) axis).setLogarithmic(enabled); axis.setAutoRange(true); } // ValueAxis oldAxis = getXYPlot().getRangeAxis(); // LogarithmicAxis logAxis = new LogarithmicAxis(oldAxis.getLabel()); // logAxis.setRange(oldAxis.getRange()); //// logAxis.setAllowNegativesFlag(true); // getXYPlot().setRangeAxis(logAxis); // updatePlot(); } @Override public void setMarkerEnabled(boolean enabled) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYLineAndShapeRenderer) { ((XYLineAndShapeRenderer) renderer).setBaseShapesVisible(enabled); for (int i = 0; i < getXYPlot().getSeriesCount(); i++) { ((XYLineAndShapeRenderer) renderer).setSeriesShapesVisible(i, enabled); } } } @Override public Stroke getErrorBarStroke() { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYErrorRenderer) { return ((XYErrorRenderer) renderer).getErrorStroke(); } return null; } @Override public void setErrorBarStroke(float stroke) { XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYErrorRenderer) { ((XYErrorRenderer) renderer).setErrorStroke(new BasicStroke(stroke)); } } @Override protected void drawToolTipFollower(Graphics2D g2, int x, int y) { Rectangle2D dataArea = getScreenDataArea(); if (((int) dataArea.getMinX() <= x) && (x <= (int) dataArea.getMaxX()) && ((int) dataArea.getMinY() <= y) && (y <= (int) dataArea.getMaxY())) { String text = ""; if (indexInTooltip) { text += "#" + getItemIndex() + ", "; } text += String.format("(%." + mouseFollowerXPrecision + "f, %." + mouseFollowerYPrecision + "f", getChartX(), getChartY()); boolean isErrorEnabled = false; XYItemRenderer renderer = getXYPlot().getRenderer(); if (renderer instanceof XYErrorRenderer) { isErrorEnabled = ((XYErrorRenderer) renderer).getDrawYError(); } if (isErrorEnabled) { text += String.format(" \u00B1%." + mouseFollowerYPrecision + "f", getChartError()); } text += ")"; int xLoc = x + 10; int yLoc = y + 20; double width = text.length() * 5.5; double height = 15; if (xLoc + width > dataArea.getMaxX()) { xLoc = (int) (x - width); } if (yLoc + height > dataArea.getMaxY()) { yLoc = (int) (y - height); } Rectangle2D toolTipArea = new Rectangle2D.Double(xLoc, yLoc, width, height); g2.setColor(Color.lightGray); g2.fill(toolTipArea); g2.setColor(Color.black); g2.drawString(text, xLoc + 3, yLoc + 11); } } @Override public void setSelectedSeries(int seriesIndex) { selectSeries(seriesIndex); } /** * @param chartError the chartError to set */ public void setChartError(double chartError) { this.chartError = chartError; } /** * @return the chartError */ public double getChartError() { return chartError; } @Override public void addMask(AbstractMask mask) { if (mask instanceof RangeMask) { super.addMask(mask); } } @Override public void doHelp() { showPropertyEditor(6); } @Override public void doExport(IExporter exporter) throws IOException { boolean isMultipleSeries = getDataset().getSeriesCount() > 1; JFileChooser fileChooser = new JFileChooser(); String currentDirectory = System.getProperty(StaticValues.SYSTEM_SAVE_PATH_LABEL); if (currentDirectory != null) { File savePath = new File(currentDirectory); if (savePath.exists() && savePath.isDirectory()) { fileChooser.setCurrentDirectory(savePath); } } String fileExtension = exporter.getExtensionName(); ExtensionFileFilter extensionFilter = new ExtensionFileFilter(exporter.toString(), "." + fileExtension); fileChooser.addChoosableFileFilter(extensionFilter); if (isMultipleSeries) { fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); } int option = fileChooser.showSaveDialog(this); if (option == JFileChooser.APPROVE_OPTION) { String filename = fileChooser.getSelectedFile().getPath(); int confirm = JOptionPane.YES_OPTION; File selectedFile; if (isMultipleSeries) { selectedFile = new File(filename); if (!selectedFile.exists()) { selectedFile.mkdirs(); } exporter.export(selectedFile, getDataset()); System.setProperty(StaticValues.SYSTEM_SAVE_PATH_LABEL, fileChooser.getSelectedFile().getAbsolutePath()); } else { if (!filename.toLowerCase().endsWith("." + fileExtension)) { filename = filename + "." + fileExtension; } selectedFile = new File(filename); if (selectedFile.exists()) { confirm = JOptionPane.showConfirmDialog(this, selectedFile.getName() + " exists, overwrite?", "Confirm Overwriting", JOptionPane.YES_NO_OPTION); } else { selectedFile.createNewFile(); } if (confirm == JOptionPane.YES_OPTION) { exporter.export(selectedFile, getDataset()); System.setProperty(StaticValues.SYSTEM_SAVE_PATH_LABEL, fileChooser.getSelectedFile().getParent()); } } } } @Override public void setLogarithmEnabled(boolean enabled) { setLogarithmYEnabled(enabled); } @Override public boolean isLogarithmEnabled() { return isLogarithmYEnabled(); } @Override public IHelpProvider getHelpProvider() { return null; } @Override protected void saveAsText(BufferedWriter writer) throws IOException { IDataset dataset = getDataset(); if (dataset != null) { DatasetUtils.export((IXYErrorDataset) dataset, writer, ExportFormat.XYSIGMA); } } @Override public void setLegendPosition(LegendPosition position) { if (position == LegendPosition.NONE) { isInternalLegendEnabled = false; getChart().getLegend().setVisible(false); repaint(); } else if (position == LegendPosition.BOTTOM) { isInternalLegendEnabled = false; getChart().getLegend().setVisible(true); getChart().getLegend().setPosition(RectangleEdge.BOTTOM); repaint(); } else if (position == LegendPosition.TOP) { isInternalLegendEnabled = false; getChart().getLegend().setVisible(true); getChart().getLegend().setPosition(RectangleEdge.TOP); repaint(); } else if (position == LegendPosition.RIGHT) { isInternalLegendEnabled = false; getChart().getLegend().setVisible(true); getChart().getLegend().setPosition(RectangleEdge.RIGHT); repaint(); } else if (position == LegendPosition.LEFT) { isInternalLegendEnabled = false; getChart().getLegend().setVisible(true); getChart().getLegend().setPosition(RectangleEdge.LEFT); repaint(); } else if (position == LegendPosition.INTERNAL) { isInternalLegendEnabled = true; getChart().getLegend().setVisible(false); repaint(); } } @Override public LegendPosition getLegendPosition() { if (isInternalLegendEnabled) { return LegendPosition.INTERNAL; } else { LegendTitle legend = getChart().getLegend(); if (legend != null) { if (legend.isVisible()) { if (legend.getPosition() == RectangleEdge.TOP) { return LegendPosition.TOP; } else if (legend.getPosition() == RectangleEdge.BOTTOM) { return LegendPosition.BOTTOM; } else if (legend.getPosition() == RectangleEdge.RIGHT) { return LegendPosition.RIGHT; } else if (legend.getPosition() == RectangleEdge.LEFT) { return LegendPosition.LEFT; } } } } return LegendPosition.NONE; } @Override public void setMouseFollowerXPrecision(int xPrecision) { mouseFollowerXPrecision = xPrecision; } @Override public void setMouseFollowerYPrecision(int yPrecision) { mouseFollowerYPrecision = yPrecision; } }