swt-chart-code-312-trunk/0000755000175000017500000000000013275316674015572 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.ext/0000755000175000017500000000000013275316675021017 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.ext/build.properties0000644000175000017500000000012011031563732024207 0ustar jsprickejsprickesource.. = src/ output.. = bin/ bin.includes = META-INF/,\ . swt-chart-code-312-trunk/org.swtchart.ext/.project0000644000175000017500000000124511031563732022452 0ustar jsprickejspricke org.swtchart.ext org.eclipse.jdt.core.javabuilder org.eclipse.pde.ManifestBuilder org.eclipse.pde.SchemaBuilder org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature swt-chart-code-312-trunk/org.swtchart.ext/.classpath0000644000175000017500000000056611234141567022776 0ustar jsprickejspricke swt-chart-code-312-trunk/org.swtchart.ext/src/0000755000175000017500000000000013275316674021605 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.ext/src/org/0000755000175000017500000000000013275316674022374 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/0000755000175000017500000000000013275316674024233 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/0000755000175000017500000000000013275316675025034 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/0000755000175000017500000000000013275316675026650 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/SelectionRectangle.java0000644000175000017500000000531411232724631033252 0ustar jsprickejsprickepackage org.swtchart.ext.internal; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; /** * Selection rectangle with mouse to zoom in/out. */ public class SelectionRectangle { /** the start point of selection */ private Point startPoint; /** the end point of selection */ private Point endPoint; /** * Sets the start point. * * @param x * the X coordinate of start point in pixels * @param y * the Y coordinate of start point in pixels */ public void setStartPoint(int x, int y) { startPoint = new Point(x, y); } /** * Sets the end point. * * @param x * the X coordinate of end point in pixels * @param y * the X coordinate of end point in pixels */ public void setEndPoint(int x, int y) { endPoint = new Point(x, y); } /** * Gets the horizontal selected range. * * @return the horizontal selected range in pixels */ public Point getHorizontalRange() { if (startPoint == null || endPoint == null) { return null; } return new Point(startPoint.x, endPoint.x); } /** * Gets the vertical selected range. * * @return the vertical selected range in pixels */ public Point getVerticalRange() { if (startPoint == null || endPoint == null) { return null; } return new Point(startPoint.y, endPoint.y); } /** * Check if selection is disposed. * * @return true if selection is disposed. */ public boolean isDisposed() { return startPoint == null; } /** * Disposes the resource. */ public void dispose() { startPoint = null; endPoint = null; } /** * Draws the selection rectangle on chart panel. * * @param gc * the graphics context */ public void draw(GC gc) { if (startPoint == null || endPoint == null) { return; } int minX; int maxX; if (startPoint.x > endPoint.x) { minX = endPoint.x; maxX = startPoint.x; } else { minX = startPoint.x; maxX = endPoint.x; } int minY; int maxY; if (startPoint.y > endPoint.y) { minY = endPoint.y; maxY = startPoint.y; } else { minY = startPoint.y; maxY = endPoint.y; } gc.drawRectangle(minX, minY, maxX - minX, maxY - minY); } } swt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/0000755000175000017500000000000013275316675031044 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/AxisTickPage.java0000644000175000017500000002011411234141567034206 0ustar jsprickejsprickepackage org.swtchart.ext.internal.properties; import org.eclipse.jface.preference.ColorSelector; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Spinner; import org.swtchart.Constants; import org.swtchart.IAxis; import org.swtchart.IDisposeListener; import org.swtchart.IAxis.Direction; import org.swtchart.ext.InteractiveChart; /** * The tick page on properties dialog. */ public class AxisTickPage extends AbstractSelectorPage { /** the key for axis tick font */ private static final String AXIS_TICK_FONT = "org.swtchart.axistick.font"; /** the key for axis tick foreground */ private static final String AXIS_TICK_FOREGROUND = "org.swtchart.axistick.foreground"; /** the axes */ private IAxis[] axes; /** the show tick button */ protected Button showTickButton; /** the label for font size */ private Label fontSizeLabel; /** the spinner for font size */ protected Spinner fontSizeSpinner; /** the foreground label */ private Label foregroundLabel; /** the foreground button */ protected ColorSelector foregroundButton; /** the states indicating the visibility of axis ticks */ protected boolean[] visibilityStates; /** the font sizes */ protected int[] fontSizes; /** the foreground colors */ protected RGB[] foregroundColors; /** * Constructor. * * @param chart * the chart * @param resources * the properties resources * @param direction * the direction * @param title * the title */ public AxisTickPage(InteractiveChart chart, PropertiesResources resources, Direction direction, String title) { super(chart, resources, title, "Axes:"); if (direction == Direction.X) { this.axes = chart.getAxisSet().getXAxes(); } else if (direction == Direction.Y) { this.axes = chart.getAxisSet().getYAxes(); } visibilityStates = new boolean[axes.length]; fontSizes = new int[axes.length]; foregroundColors = new RGB[axes.length]; } /* * @see AbstractSelectorPage#getListItems() */ @Override protected String[] getListItems() { String[] items = new String[axes.length]; for (int i = 0; i < items.length; i++) { items[i] = String.valueOf(axes[i].getId()); } return items; } /* * @see AbstractSelectorPage#selectInitialValues() */ @Override protected void selectInitialValues() { for (int i = 0; i < axes.length; i++) { visibilityStates[i] = axes[i].getTick().isVisible(); fontSizes[i] = axes[i].getTick().getFont().getFontData()[0] .getHeight(); foregroundColors[i] = axes[i].getTick().getForeground().getRGB(); } } /* * @see AbstractSelectorPage#updateControlSelections() */ @Override protected void updateControlSelections() { showTickButton.setSelection(visibilityStates[selectedIndex]); setControlsEnable(visibilityStates[selectedIndex]); fontSizeSpinner.setSelection(fontSizes[selectedIndex]); foregroundButton.setColorValue(foregroundColors[selectedIndex]); } /* * @see AbstractSelectorPage#addRightPanelContents(Composite) */ @Override protected void addRightPanelContents(Composite parent) { addTickPanel(parent); } /** * Create the tick panel. * * @param parent * the parent to add the tick panel */ private void addTickPanel(Composite parent) { Composite group = new Composite(parent, SWT.NONE); GridData gridData = new GridData(); gridData.horizontalSpan = 2; group.setLayoutData(gridData); group.setLayout(new GridLayout(2, false)); showTickButton = createCheckBoxControl(group, "Show tick"); showTickButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { boolean visible = showTickButton.getSelection(); visibilityStates[selectedIndex] = visible; setControlsEnable(visible); } }); fontSizeLabel = createLabelControl(group, "Font size:"); fontSizeSpinner = createSpinnerControl(group, 8, 30); fontSizeSpinner.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { fontSizes[selectedIndex] = fontSizeSpinner.getSelection(); } }); foregroundLabel = createLabelControl(group, "Color:"); foregroundButton = createColorButtonControl(group); foregroundButton.addListener(new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { foregroundColors[selectedIndex] = foregroundButton .getColorValue(); } }); } /** * Sets the enable state of controls. * * @param enabled * true if controls are enabled */ protected void setControlsEnable(boolean enabled) { fontSizeLabel.setEnabled(enabled); fontSizeSpinner.setEnabled(enabled); foregroundLabel.setEnabled(enabled); foregroundButton.setEnabled(enabled); } /* * @see AbstractPreferencePage#apply() */ @Override public void apply() { for (int i = 0; i < axes.length; i++) { axes[i].getTick().setVisible(visibilityStates[i]); FontData fontData = axes[i].getTick().getFont().getFontData()[0]; fontData.setHeight(fontSizes[i]); Font font = new Font(Display.getDefault(), fontData); axes[i].getTick().setFont(font); final String fontKey = AXIS_TICK_FONT + axes[i].getDirection() + axes[i].getId(); if (resources.getFont(fontKey) == null) { axes[i].addDisposeListener(new IDisposeListener() { public void disposed(Event e) { resources.removeFont(fontKey); } }); } resources.put(fontKey, font); Color color = new Color(Display.getDefault(), foregroundColors[i]); axes[i].getTick().setForeground(color); final String colorKey = AXIS_TICK_FOREGROUND + axes[i].getDirection() + axes[i].getId(); if (resources.getColor(colorKey) == null) { axes[i].addDisposeListener(new IDisposeListener() { public void disposed(Event e) { resources.removeColor(colorKey); } }); } resources.put(colorKey, color); } } /* * @see PreferencePage#performDefaults() */ @Override protected void performDefaults() { visibilityStates[selectedIndex] = true; fontSizes[selectedIndex] = Constants.SMALL_FONT_SIZE; foregroundColors[selectedIndex] = Display.getDefault().getSystemColor( SWT.COLOR_BLUE).getRGB(); updateControlSelections(); super.performDefaults(); } } swt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/ChartPage.java0000644000175000017500000001731711171376066033547 0ustar jsprickejsprickepackage org.swtchart.ext.internal.properties; import org.eclipse.jface.preference.ColorSelector; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Spinner; import org.eclipse.swt.widgets.Text; import org.swtchart.Constants; import org.swtchart.ITitle; import org.swtchart.ext.InteractiveChart; /** * The chart property page on properties dialog. */ public class ChartPage extends AbstractPage { /** the key for plot area background */ private static final String PLOT_AREA_BACKGROUND = "org.swtchart.plotarea.background"; /** the key for chart background */ private static final String CHART_BACKGROUND = "org.swtchart.chart.background"; /** the key for chart background */ private static final String TITLE_FOREGROUND = "org.swtchart.chart.title.foreground"; /** the key for title font */ private static final String TITLE_FONT = "org.swtchart.chart.title.font"; /** the color selector for background color in plot area */ private ColorSelector backgroundInPlotAreaButton; /** the color selector for background */ private ColorSelector backgroundButton; /** the orientation button */ private Button orientationButton; /** the show title button */ protected Button showTitleButton; /** the title label */ private Label titleLabel; /** the title text */ private Text titleText; /** the font size label */ private Label fontSizeLabel; /** the font size spinner */ private Spinner fontSizeSpinner; /** the title color label */ private Label titleColorLabel; /** the title color button */ private ColorSelector titleColorButton; /** * Constructor. * * @param chart * the chart * @param resources * the properties resources * @param title * the title */ public ChartPage(InteractiveChart chart, PropertiesResources resources, String title) { super(chart, resources, title); } /* * @see PreferencePage#createContents(Composite) */ @Override protected Control createContents(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); addChartPanel(composite); addTitleGroup(composite); selectValues(); return composite; } /** * Adds the chart panel. * * @param parent * the parent to add the chart panel */ private void addChartPanel(Composite parent) { Composite panel = new Composite(parent, SWT.NONE); panel.setLayout(new GridLayout(2, false)); createLabelControl(panel, "Background in plot area:"); backgroundInPlotAreaButton = createColorButtonControl(panel); createLabelControl(panel, "Background:"); backgroundButton = createColorButtonControl(panel); orientationButton = createCheckBoxControl(panel, "Vertical orientation:"); } /** * Adds the title group. * * @param parent * the parent to add the title group */ private void addTitleGroup(Composite parent) { Group group = createGroupControl(parent, "Title:", false); showTitleButton = createCheckBoxControl(group, "Show title"); showTitleButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { setTitleControlsEnable(showTitleButton.getSelection()); } }); titleLabel = createLabelControl(group, "Text:"); titleText = createTextControl(group); fontSizeLabel = createLabelControl(group, "Font size:"); fontSizeSpinner = createSpinnerControl(group, 8, 30); titleColorLabel = createLabelControl(group, "Color:"); titleColorButton = createColorButtonControl(group); } /** * Selects the values for controls. */ private void selectValues() { backgroundInPlotAreaButton.setColorValue(chart .getBackgroundInPlotArea().getRGB()); backgroundButton.setColorValue(chart.getBackground().getRGB()); orientationButton.setSelection(chart.getOrientation() == SWT.VERTICAL); ITitle title = chart.getTitle(); showTitleButton.setSelection(title.isVisible()); setTitleControlsEnable(title.isVisible()); titleText.setText(title.getText()); fontSizeSpinner.setSelection(title.getFont().getFontData()[0] .getHeight()); titleColorButton.setColorValue(title.getForeground().getRGB()); } /** * Sets the enable state of title controls. * * @param enabled * true if title controls are enabled */ protected void setTitleControlsEnable(boolean enabled) { titleLabel.setEnabled(enabled); titleText.setEnabled(enabled); fontSizeLabel.setEnabled(enabled); fontSizeSpinner.setEnabled(enabled); titleColorLabel.setEnabled(enabled); titleColorButton.setEnabled(enabled); } /* * @see AbstractPreferencePage#apply() */ @Override public void apply() { Color color = new Color(Display.getDefault(), backgroundInPlotAreaButton.getColorValue()); chart.setBackgroundInPlotArea(color); resources.put(PLOT_AREA_BACKGROUND, color); color = new Color(Display.getDefault(), backgroundButton .getColorValue()); chart.setBackground(color); resources.put(CHART_BACKGROUND, color); chart.setOrientation(orientationButton.getSelection() ? SWT.VERTICAL : SWT.HORIZONTAL); ITitle title = chart.getTitle(); title.setVisible(showTitleButton.getSelection()); title.setText(titleText.getText()); FontData fontData = title.getFont().getFontData()[0]; fontData.setHeight(fontSizeSpinner.getSelection()); Font font = new Font(Display.getDefault(), fontData); title.setFont(font); resources.put(TITLE_FONT, font); color = new Color(Display.getDefault(), titleColorButton .getColorValue()); title.setForeground(color); resources.put(TITLE_FOREGROUND, color); } /* * @see PreferencePage#performDefaults() */ @Override protected void performDefaults() { backgroundInPlotAreaButton.setColorValue(new RGB(255, 255, 255)); backgroundButton.setColorValue(Display.getDefault().getSystemColor( SWT.COLOR_WIDGET_BACKGROUND).getRGB()); orientationButton.setSelection(false); showTitleButton.setSelection(true); setTitleControlsEnable(true); titleText.setText("Chart Title"); fontSizeSpinner.setSelection(Constants.LARGE_FONT_SIZE); titleColorButton.setColorValue(new RGB(0, 0, 255)); super.performDefaults(); } } swt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/GridPage.java0000644000175000017500000001323511234141567033362 0ustar jsprickejsprickepackage org.swtchart.ext.internal.properties; import org.eclipse.jface.preference.ColorSelector; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.swtchart.IAxis; import org.swtchart.LineStyle; import org.swtchart.IAxis.Direction; import org.swtchart.ext.InteractiveChart; /** * The grid page on properties dialog. */ public class GridPage extends AbstractSelectorPage { /** the key for grid foreground */ private static final String GRID_FOREGROUND = "org.swtchart.grid.foreground"; /** the axes */ private IAxis[] axes; /** the style combo */ protected Combo styleCombo; /** the foreground button */ protected ColorSelector foregroundButton; /** the line styles */ protected LineStyle[] styles; /** the foreground colors */ protected RGB[] foregroundColors; /** * Constructor. * * @param chart * the chart * @param resources * the properties resources * @param direction * the direction * @param title * the title */ public GridPage(InteractiveChart chart, PropertiesResources resources, Direction direction, String title) { super(chart, resources, title, "Axes:"); if (direction == Direction.X) { this.axes = chart.getAxisSet().getXAxes(); } else if (direction == Direction.Y) { this.axes = chart.getAxisSet().getYAxes(); } styles = new LineStyle[axes.length]; foregroundColors = new RGB[axes.length]; } /* * @see AbstractSelectorPage#getListItems() */ @Override protected String[] getListItems() { String[] items = new String[axes.length]; for (int i = 0; i < items.length; i++) { items[i] = String.valueOf(axes[i].getId()); } return items; } /* * @see AbstractSelectorPage#selectInitialValues() */ @Override protected void selectInitialValues() { for (int i = 0; i < axes.length; i++) { styles[i] = axes[i].getGrid().getStyle(); foregroundColors[i] = axes[i].getGrid().getForeground().getRGB(); } } /* * @see AbstractSelectorPage#updateControlSelections() */ @Override protected void updateControlSelections() { styleCombo.setText(String.valueOf(styles[selectedIndex])); foregroundButton.setColorValue(foregroundColors[selectedIndex]); } /* * @see AbstractSelectorPage#addRightPanelContents(Composite) */ @Override protected void addRightPanelContents(Composite parent) { addGridPanel(parent); } /** * Adds the grid panel. * * @param parent * the parent to add the grid panel */ private void addGridPanel(Composite parent) { Composite group = new Composite(parent, SWT.NONE); GridData gridData = new GridData(); gridData.horizontalSpan = 2; group.setLayoutData(gridData); group.setLayout(new GridLayout(2, false)); createLabelControl(group, "Line style:"); LineStyle[] values = LineStyle.values(); String[] labels = new String[values.length]; for (int i = 0; i < values.length; i++) { labels[i] = values[i].label; } styleCombo = createComboControl(group, labels); styleCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String value = styleCombo.getText(); LineStyle selectedStyle = LineStyle.NONE; for (LineStyle style : LineStyle.values()) { if (style.label.equals(value)) { selectedStyle = style; } } styles[selectedIndex] = selectedStyle; } }); createLabelControl(group, "Color:"); foregroundButton = createColorButtonControl(group); foregroundButton.addListener(new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { foregroundColors[selectedIndex] = foregroundButton .getColorValue(); } }); } /* * @see AbstractPreferencePage#apply() */ @Override public void apply() { for (int i = 0; i < axes.length; i++) { axes[i].getGrid().setStyle(styles[i]); Color color = new Color(Display.getDefault(), foregroundColors[i]); axes[i].getGrid().setForeground(color); resources.put(GRID_FOREGROUND + axes[i].getDirection() + axes[i].getId(), color); } } /* * @see PreferencePage#performDefaults() */ @Override protected void performDefaults() { styles[selectedIndex] = LineStyle.DOT; foregroundColors[selectedIndex] = Display.getDefault().getSystemColor( SWT.COLOR_GRAY).getRGB(); updateControlSelections(); super.performDefaults(); } } swt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/AxisPage.java0000644000175000017500000003422411234141567033402 0ustar jsprickejsprickepackage org.swtchart.ext.internal.properties; import org.eclipse.jface.preference.ColorSelector; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Spinner; import org.eclipse.swt.widgets.Text; import org.swtchart.Constants; import org.swtchart.IAxis; import org.swtchart.IDisposeListener; import org.swtchart.Range; import org.swtchart.IAxis.Direction; import org.swtchart.IAxis.Position; import org.swtchart.ext.InteractiveChart; /** * The axis page on properties dialog. */ public class AxisPage extends AbstractSelectorPage { /** the key for axis title font */ private static final String AXIS_TITLE_FONT = "org.swtchart.axis.title.font"; /** the key for axis title foreground */ private static final String AXIS_TITLE_FOREGROUND = "org.swtchart.axis.title.foreground"; /** the axes */ private IAxis[] axes; /** the axis direction */ private Direction direction; /** the show title button */ protected Button showTitleButton; /** the label for title */ private Label titleLabel; /** the title text */ protected Text titleText; /** the label for font size */ private Label fontSizeLabel; /** the spinner for font size */ protected Spinner fontSizeSpinner; /** the label for title color */ private Label titleColorLabel; /** the color selector button */ protected ColorSelector titleColorButton; /** the minimum range text */ protected Text minRangeText; /** the maximum range text */ protected Text maxRangeText; /** the position combo box */ protected Combo positionCombo; /** the category button */ protected Button categoryButton; /** the log scale button */ protected Button logScaleButton; /** the states indicating id title is visible */ protected boolean[] titleVisibleStates; /** the title texts */ protected String[] titleTexts; /** the title font sizes */ protected int[] titleFontSizes; /** the title colors */ protected RGB[] titleColors; /** the minimum ranges */ protected double[] minRanges; /** the maximum ranges */ protected double[] maxRanges; /** the positions */ protected Position[] positions; /** the states indicating if category is enabled */ protected boolean[] categoryStates; /** the states indicating if log scale is enabled */ protected boolean[] logScaleStates; /** * Constructor. * * @param chart * the chart * @param resources * the properties resources * @param direction * the direction * @param title * the title */ public AxisPage(InteractiveChart chart, PropertiesResources resources, Direction direction, String title) { super(chart, resources, title, "Axes:"); this.direction = direction; if (direction == Direction.X) { this.axes = chart.getAxisSet().getXAxes(); } else if (direction == Direction.Y) { this.axes = chart.getAxisSet().getYAxes(); } titleVisibleStates = new boolean[axes.length]; titleTexts = new String[axes.length]; titleFontSizes = new int[axes.length]; titleColors = new RGB[axes.length]; minRanges = new double[axes.length]; maxRanges = new double[axes.length]; positions = new Position[axes.length]; if (direction == Direction.X) { categoryStates = new boolean[axes.length]; } logScaleStates = new boolean[axes.length]; } /* * @see AbstractSelectorPage#getListItems() */ @Override protected String[] getListItems() { String[] items = new String[axes.length]; for (int i = 0; i < items.length; i++) { items[i] = String.valueOf(axes[i].getId()); } return items; } /* * @see AbstractSelectorPage#selectInitialValues() */ @Override protected void selectInitialValues() { for (int i = 0; i < axes.length; i++) { titleVisibleStates[i] = axes[i].getTitle().isVisible(); titleTexts[i] = axes[i].getTitle().getText(); titleFontSizes[i] = axes[i].getTitle().getFont().getFontData()[0] .getHeight(); titleColors[i] = axes[i].getTitle().getForeground().getRGB(); minRanges[i] = axes[i].getRange().lower; maxRanges[i] = axes[i].getRange().upper; positions[i] = axes[i].getPosition(); if (direction == Direction.X) { categoryStates[i] = axes[i].isCategoryEnabled(); } logScaleStates[i] = axes[i].isLogScaleEnabled(); } } /* * @see AbstractSelectorPage#updateControlSelections() */ @Override protected void updateControlSelections() { showTitleButton.setSelection(titleVisibleStates[selectedIndex]); setControlsEnable(titleVisibleStates[selectedIndex]); titleText.setText(titleTexts[selectedIndex]); fontSizeSpinner.setSelection(titleFontSizes[selectedIndex]); titleColorButton.setColorValue(titleColors[selectedIndex]); minRangeText.setText(String.valueOf(minRanges[selectedIndex])); maxRangeText.setText(String.valueOf(maxRanges[selectedIndex])); positionCombo.setText(String.valueOf(positions[selectedIndex])); logScaleButton.setSelection(logScaleStates[selectedIndex]); if (direction == Direction.X) { categoryButton.setSelection(categoryStates[selectedIndex]); } } /* * @see AbstractSelectorPage#addRightPanelContents(Composite) */ @Override protected void addRightPanelContents(Composite parent) { addAxisPanel(parent); addTitleGroup(parent); } /** * Adds axis panel. * * @param parent * the parent to add the axis panel */ private void addAxisPanel(Composite parent) { Composite group = new Composite(parent, SWT.NONE); group.setLayout(new GridLayout(2, true)); createLabelControl(group, "Minimum range value:"); minRangeText = createTextControl(group); minRangeText.addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { minRanges[selectedIndex] = Double.valueOf(minRangeText .getText()); } }); createLabelControl(group, "Maximum range value:"); maxRangeText = createTextControl(group); maxRangeText.addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { maxRanges[selectedIndex] = Double.valueOf(maxRangeText .getText()); } }); createLabelControl(group, "Position:"); String[] items = new String[] { Position.Primary.name(), Position.Secondary.name() }; positionCombo = createComboControl(group, items); positionCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { positions[selectedIndex] = Position.valueOf(positionCombo .getText()); } }); logScaleButton = createCheckBoxControl(group, "Enable log scale"); logScaleButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { logScaleStates[selectedIndex] = logScaleButton.getSelection(); } }); if (direction == Direction.X) { categoryButton = createCheckBoxControl(group, "Enable category"); categoryButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { categoryStates[selectedIndex] = categoryButton .getSelection(); } }); } } /** * Adds title group. * * @param parent * the parent to add the title group */ private void addTitleGroup(Composite parent) { Group group = createGroupControl(parent, "Title:", false); showTitleButton = createCheckBoxControl(group, "Show title"); showTitleButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { boolean visible = showTitleButton.getSelection(); titleVisibleStates[selectedIndex] = visible; setControlsEnable(visible); } }); titleLabel = createLabelControl(group, "Text:"); titleText = createTextControl(group); titleText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { titleTexts[selectedIndex] = titleText.getText(); } }); fontSizeLabel = createLabelControl(group, "Font size:"); fontSizeSpinner = createSpinnerControl(group, 8, 30); fontSizeSpinner.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { titleFontSizes[selectedIndex] = fontSizeSpinner.getSelection(); } }); titleColorLabel = createLabelControl(group, "Color:"); titleColorButton = createColorButtonControl(group); titleColorButton.addListener(new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { titleColors[selectedIndex] = titleColorButton.getColorValue(); } }); } /** * Sets the enable state of controls. * * @param enabled * true if controls are enabled */ protected void setControlsEnable(boolean enabled) { titleLabel.setEnabled(enabled); titleText.setEnabled(enabled); fontSizeLabel.setEnabled(enabled); fontSizeSpinner.setEnabled(enabled); titleColorLabel.setEnabled(enabled); titleColorButton.setEnabled(enabled); } /* * @see AbstractPreferencePage#apply() */ @Override public void apply() { for (int i = 0; i < axes.length; i++) { axes[i].getTitle().setVisible(titleVisibleStates[i]); axes[i].getTitle().setText(titleTexts[i]); FontData fontData = axes[i].getTitle().getFont().getFontData()[0]; fontData.setHeight(titleFontSizes[i]); Font font = new Font(Display.getDefault(), fontData); axes[i].getTitle().setFont(font); final String fontKey = AXIS_TITLE_FONT + axes[i].getDirection() + axes[i].getId(); if (resources.getFont(fontKey) == null) { axes[i].addDisposeListener(new IDisposeListener() { public void disposed(Event e) { resources.removeFont(fontKey); } }); } resources.put(fontKey, font); Color color = new Color(Display.getDefault(), titleColors[i]); axes[i].getTitle().setForeground(color); final String colorKey = AXIS_TITLE_FOREGROUND + axes[i].getDirection() + axes[i].getId(); if (resources.getColor(colorKey) == null) { axes[i].addDisposeListener(new IDisposeListener() { public void disposed(Event e) { resources.removeColor(colorKey); } }); } resources.put(colorKey, color); axes[i].setRange(new Range(minRanges[i], maxRanges[i])); axes[i].setPosition(positions[i]); try { axes[i].enableLogScale(logScaleStates[i]); } catch (IllegalStateException e) { axes[i].enableLogScale(false); logScaleButton.setSelection(false); } if (direction == Direction.X) { axes[i].enableCategory(categoryStates[i]); } } } /* * @see PreferencePage#performDefaults() */ @Override protected void performDefaults() { titleVisibleStates[selectedIndex] = true; if (direction == Direction.X) { titleTexts[selectedIndex] = "X Axis"; categoryStates[selectedIndex] = false; } else if (direction == Direction.Y) { titleTexts[selectedIndex] = "Y Axis"; } positions[selectedIndex] = Position.Primary; titleFontSizes[selectedIndex] = Constants.MEDIUM_FONT_SIZE; titleColors[selectedIndex] = Display.getDefault().getSystemColor( SWT.COLOR_BLUE).getRGB(); minRanges[selectedIndex] = 0.0; maxRanges[selectedIndex] = 1.0; logScaleStates[selectedIndex] = false; updateControlSelections(); super.performDefaults(); } } swt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/AbstractPage.java0000644000175000017500000001310211171376066034235 0ustar jsprickejsprickepackage org.swtchart.ext.internal.properties; import org.eclipse.jface.preference.ColorSelector; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Spinner; import org.eclipse.swt.widgets.Text; import org.swtchart.ext.InteractiveChart; /** * Abstract class for properties page. */ public abstract class AbstractPage extends PreferencePage { /** the chart */ protected InteractiveChart chart; /** the properties resources */ protected PropertiesResources resources; /** * Constructor. * * @param chart * the chart * @param resources * the properties resources * @param title * the title */ public AbstractPage(InteractiveChart chart, PropertiesResources resources, String title) { this.chart = chart; this.resources = resources; setTitle(title); } /* * @see PreferencePage#performOk() */ @Override public boolean performOk() { if (getControl() != null) { apply(); chart.redraw(); } return true; } /** * Apply the values specified on controls. */ abstract public void apply(); /** * Creates the group control which contains two columns for controls. * * @param parent * the parent to create the group control * @param text * the group name * @param equal * true if making columns equal width * @return the group */ protected Group createGroupControl(Composite parent, String text, boolean equal) { Group group = new Group(parent, SWT.NULL); group.setText(text); group.setLayout(new GridLayout(2, equal)); group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); return group; } /** * Creates the label. * * @param parent * the parent to create the label * @param text * the label text * @return the label */ protected Label createLabelControl(Composite parent, String text) { Label label = new Label(parent, SWT.NULL); label.setText(text); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.horizontalSpan = 1; label.setLayoutData(gridData); return label; } /** * Creates the color selector. * * @param parent * the parent to create the color selector * @return the color selector */ protected ColorSelector createColorButtonControl(Composite parent) { return new ColorSelector(parent); } /** * Creates the check box. * * @param parent * the parent to create the check box * @param label * the label text * @return {@link Button} control */ protected Button createCheckBoxControl(Composite parent, String label) { Composite composite = new Composite(parent, SWT.NULL); GridData gridData = new GridData(); gridData.horizontalSpan = 2; composite.setLayoutData(gridData); composite.setLayout(new GridLayout(2, false)); Button button = new Button(composite, SWT.CHECK); GridData gridData1 = new GridData(); gridData1.horizontalSpan = 1; button.setLayoutData(gridData1); createLabelControl(composite, label); return button; } /** * Creates the text field. * * @param parent * the parent to create the text field * @return the text */ protected Text createTextControl(Composite parent) { Text text = new Text(parent, SWT.BORDER | SWT.SINGLE); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.horizontalSpan = 1; text.setLayoutData(gridData); return text; } /** * Creates the combo control. * * @param parent * the parent to create the combo * @param items * the combo items * @return the combo */ protected Combo createComboControl(Composite parent, String[] items) { Combo combo = new Combo(parent, SWT.BORDER | SWT.SINGLE); combo.setItems(items); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.horizontalSpan = 1; combo.setLayoutData(gridData); return combo; } /** * Creates the spinner. * * @param parent * the parent to create the spinner * @param min * the minimum value of spinner * @param max * the maximum value of spinner * @return the spinner */ protected Spinner createSpinnerControl(Composite parent, int min, int max) { Spinner spinner = new Spinner(parent, SWT.BORDER); spinner.setMinimum(min); spinner.setMaximum(max); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.horizontalSpan = 1; spinner.setLayoutData(gridData); return spinner; } } swt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/LegendPage.java0000644000175000017500000001406011171376066033674 0ustar jsprickejsprickepackage org.swtchart.ext.internal.properties; import org.eclipse.jface.preference.ColorSelector; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Spinner; import org.swtchart.Constants; import org.swtchart.ILegend; import org.swtchart.ext.InteractiveChart; /** * The legend property page on properties dialog. */ public class LegendPage extends AbstractPage { /** the key for legend font */ private static final String LEGEND_FONT = "org.swtchart.legend.font"; /** the key for legend foreground */ private static final String LEGEND_FOREGROUND = "org.swtchart.legend.foreground"; /** the key for legend background */ private static final String LEGEND_GACKGROUND = "org.swtchart.legend.background"; /** the show legend button */ protected Button showLegendButton; /** the background label */ private Label backgroundLabel; /** the background button */ private ColorSelector backgroundButton; /** the foreground label */ private Label foregroundLabel; /** the foreground button */ private ColorSelector foregroundButton; /** the font size label */ private Label fontSizeLabel; /** the font size spinner */ private Spinner fontSizeSpinner; /** the legend */ private ILegend legend; /** * Constructor. * * @param chart * the chart * @param resources * the properties resources * @param title * the title */ public LegendPage(InteractiveChart chart, PropertiesResources resources, String title) { super(chart, resources, title); legend = chart.getLegend(); } /* * @see PreferencePage#createContents(Composite) */ @Override protected Control createContents(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); addLegendPanel(composite); selectValues(); return composite; } /** * Adds the legend panel. * * @param parent * the parent to add the legend panel */ private void addLegendPanel(Composite parent) { Composite group = new Composite(parent, SWT.NONE); GridData gridData = new GridData(); gridData.horizontalSpan = 2; group.setLayoutData(gridData); group.setLayout(new GridLayout(2, false)); showLegendButton = createCheckBoxControl(group, "Show legend"); showLegendButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { boolean visible = showLegendButton.getSelection(); setControlsEnable(visible); } }); backgroundLabel = createLabelControl(group, "Background:"); backgroundButton = createColorButtonControl(group); foregroundLabel = createLabelControl(group, "Foreground:"); foregroundButton = createColorButtonControl(group); fontSizeLabel = createLabelControl(group, "Font size:"); fontSizeSpinner = createSpinnerControl(group, 8, 30); } /** * Selects the values for controls. */ private void selectValues() { showLegendButton.setSelection(legend.isVisible()); setControlsEnable(legend.isVisible()); backgroundButton.setColorValue(legend.getBackground().getRGB()); foregroundButton.setColorValue(legend.getForeground().getRGB()); fontSizeSpinner.setSelection(legend.getFont().getFontData()[0] .getHeight()); } /** * Sets the enable state of controls. * * @param enabled * true if controls are enabled */ protected void setControlsEnable(boolean enabled) { backgroundLabel.setEnabled(enabled); backgroundButton.setEnabled(enabled); foregroundLabel.setEnabled(enabled); foregroundButton.setEnabled(enabled); fontSizeLabel.setEnabled(enabled); fontSizeSpinner.setEnabled(enabled); } /* * @see AbstractPreferencePage#apply() */ @Override public void apply() { legend.setVisible(showLegendButton.getSelection()); Color color = new Color(Display.getDefault(), backgroundButton .getColorValue()); legend.setBackground(color); resources.put(LEGEND_GACKGROUND, color); color = new Color(Display.getDefault(), foregroundButton .getColorValue()); legend.setForeground(color); resources.put(LEGEND_FOREGROUND, color); FontData fontData = legend.getFont().getFontData()[0]; Font font = new Font(legend.getFont().getDevice(), fontData.getName(), fontSizeSpinner.getSelection(), fontData.getStyle()); legend.setFont(font); resources.put(LEGEND_FONT, font); } /* * @see PreferencePage#performDefaults() */ @Override protected void performDefaults() { showLegendButton.setSelection(true); setControlsEnable(true); backgroundButton.setColorValue(new RGB(255, 255, 255)); foregroundButton.setColorValue(new RGB(0, 0, 0)); fontSizeSpinner.setSelection(Constants.SMALL_FONT_SIZE); super.performDefaults(); } } swt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/SeriesPage.java0000644000175000017500000004765212101522306033725 0ustar jsprickejsprickepackage org.swtchart.ext.internal.properties; import org.eclipse.jface.preference.ColorSelector; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Spinner; import org.swtchart.IBarSeries; import org.swtchart.IDisposeListener; import org.swtchart.ILineSeries; import org.swtchart.ILineSeries.PlotSymbolType; import org.swtchart.ISeries; import org.swtchart.LineStyle; import org.swtchart.ext.InteractiveChart; /** * The series page on properties dialog. */ public class SeriesPage extends AbstractSelectorPage { /** the key for series line color */ private static final String SERIES_LINE_COLOR = "org.swtchart.series.line.color"; /** the key for series symbol color */ private static final String SERIES_SYMBOL_COLOR = "org.swtchart.series.symbol.color"; /** the key for series bar color */ private static final String SERIES_BAR_COLOR = "org.swtchart.series.bar.color"; /** the button for visibility */ protected Button visibleButton; /** the button for stack state */ protected Button stackedButton; /** the x axis id combo */ protected Combo xAxisIdCombo; /** the y axis id combo */ protected Combo yAxisIdCombo; /** the line color button */ protected ColorSelector lineColorButton; /** the line style combo */ protected Combo lineStyleCombo; /** the color selector for symbol */ protected ColorSelector symbolColorButton; /** the symbol type combo */ protected Combo symbolTypeCombo; /** the symbol size spinner */ protected Spinner symbolSizeSpinner; /** the bar color button */ protected ColorSelector barColorButton; /** the padding size spinner */ protected Spinner paddingSizeSpinner; /** the series array */ private ISeries[] series; /** the items for x axis id combo */ private int[] xAxisIdItems; /** the items for y axis id combo */ private int[] yAxisIdItems; /** the states indicating the visibility of series */ protected boolean[] visibleStates; /** the states indicating the series is stacked */ protected boolean[] stackedStates; /** the x axis ids */ protected int[] xAxisIds; /** the y axis ids */ protected int[] yAxisIds; /** the line colors */ protected RGB[] lineColors; /** the line styles */ protected LineStyle[] lineStyles; /** the symbol colors */ protected RGB[] symbolColors; /** the symbol types */ protected PlotSymbolType[] symbolTypes; /** the symbol sizes */ protected int[] symbolSizes; /** the bar colors */ protected RGB[] barColors; /** the paddings */ protected int[] paddings; /** the stack panel */ private Composite stackPanel; /** the stack layout */ private StackLayout stackLayout; /** the line series group */ private Composite lineSeriesGroup; /** the bar series group */ private Composite barSeriesGroup; /** * Constructor. * * @param chart * the chart * @param resources * the properties resources * @param title * the title */ public SeriesPage(InteractiveChart chart, PropertiesResources resources, String title) { super(chart, resources, title, "Series:"); series = chart.getSeriesSet().getSeries(); xAxisIdItems = chart.getAxisSet().getXAxisIds(); yAxisIdItems = chart.getAxisSet().getYAxisIds(); visibleStates = new boolean[series.length]; stackedStates = new boolean[series.length]; xAxisIds = new int[series.length]; yAxisIds = new int[series.length]; lineColors = new RGB[series.length]; lineStyles = new LineStyle[series.length]; symbolColors = new RGB[series.length]; symbolTypes = new PlotSymbolType[series.length]; symbolSizes = new int[series.length]; barColors = new RGB[series.length]; paddings = new int[series.length]; } /* * (non-Javadoc) * * @see * org.swtchart.ext.internal.properties.AbstractSelectorPage#getListItems() */ @Override protected String[] getListItems() { String[] items = new String[series.length]; for (int i = 0; i < items.length; i++) { items[i] = String.valueOf(series[i].getId()); } return items; } /* * @see AbstractSelectorPage#selectInitialValuess() */ @Override protected void selectInitialValues() { for (int i = 0; i < series.length; i++) { visibleStates[i] = series[i].isVisible(); stackedStates[i] = series[i].isStackEnabled(); if (series[i] instanceof ILineSeries) { lineColors[i] = ((ILineSeries) series[i]).getLineColor() .getRGB(); lineStyles[i] = ((ILineSeries) series[i]).getLineStyle(); symbolColors[i] = ((ILineSeries) series[i]).getSymbolColor() .getRGB(); symbolTypes[i] = ((ILineSeries) series[i]).getSymbolType(); symbolSizes[i] = ((ILineSeries) series[i]).getSymbolSize(); } else if (series[i] instanceof IBarSeries) { barColors[i] = ((IBarSeries) series[i]).getBarColor().getRGB(); paddings[i] = ((IBarSeries) series[i]).getBarPadding(); } xAxisIds[i] = series[i].getXAxisId(); yAxisIds[i] = series[i].getYAxisId(); } updateStackPanel(); } /* * @see AbstractSelectorPage#updateControlSelections() */ @Override protected void updateControlSelections() { visibleButton.setSelection(visibleStates[selectedIndex]); stackedButton.setSelection(stackedStates[selectedIndex]); if (xAxisIdCombo != null) { xAxisIdCombo.setText("" + xAxisIds[selectedIndex]); } if (yAxisIdCombo != null) { yAxisIdCombo.setText("" + yAxisIds[selectedIndex]); } if (series[selectedIndex] instanceof ILineSeries) { lineStyleCombo.setText(lineStyles[selectedIndex].label); lineStyleCombo.setEnabled(true); lineColorButton.setColorValue(lineColors[selectedIndex]); symbolColorButton.setColorValue(symbolColors[selectedIndex]); symbolTypeCombo.setText(symbolTypes[selectedIndex].label); symbolSizeSpinner.setSelection(symbolSizes[selectedIndex]); } else if (series[selectedIndex] instanceof IBarSeries) { barColorButton.setColorValue(barColors[selectedIndex]); paddingSizeSpinner.setSelection(paddings[selectedIndex]); } setControlsEnable(series[selectedIndex].isVisible()); updateStackPanel(); } /** * Updates the stack panel. */ private void updateStackPanel() { if (series[selectedIndex] instanceof ILineSeries) { stackLayout.topControl = lineSeriesGroup; } else if (series[selectedIndex] instanceof IBarSeries) { stackLayout.topControl = barSeriesGroup; } stackPanel.layout(); } /* * @see AbstractSelectorPage#addRightPanelContents(Composite) */ @Override protected void addRightPanelContents(Composite parent) { addSeriesGroup(parent); stackPanel = new Composite(parent, SWT.NONE); stackLayout = new StackLayout(); stackPanel.setLayout(stackLayout); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.horizontalSpan = 1; stackPanel.setLayoutData(gridData); addLineSeriesGroup(stackPanel); addBarSeriesGroup(stackPanel); } /** * Adds the series panel. * * @param parent * the parent to add the series panel */ private void addSeriesGroup(Composite parent) { Composite group = new Composite(parent, SWT.NONE); group.setLayout(new GridLayout(2, true)); visibleButton = createCheckBoxControl(group, "Show plot"); visibleButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { boolean visible = visibleButton.getSelection(); visibleStates[selectedIndex] = visible; setControlsEnable(visible); } }); stackedButton = createCheckBoxControl(group, "Stacked series"); stackedButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { stackedStates[selectedIndex] = stackedButton.getSelection(); } }); if (xAxisIdItems.length > 1) { createLabelControl(group, "X Axis:"); String[] items = new String[xAxisIdItems.length]; for (int i = 0; i < items.length; i++) { items[i] = "" + xAxisIdItems[i]; } xAxisIdCombo = createComboControl(group, items); xAxisIdCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { xAxisIds[selectedIndex] = Integer.parseInt(xAxisIdCombo .getText()); } }); } if (yAxisIdItems.length > 1) { createLabelControl(group, "Y Axis:"); String[] items = new String[yAxisIdItems.length]; for (int i = 0; i < items.length; i++) { items[i] = "" + yAxisIdItems[i]; } yAxisIdCombo = createComboControl(group, items); yAxisIdCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { yAxisIds[selectedIndex] = Integer.parseInt(yAxisIdCombo .getText()); } }); } } /** * Adds the line series group. * * @param parent * the parent to add the line series group */ private void addLineSeriesGroup(Composite parent) { lineSeriesGroup = createGroupControl(parent, "Line series:", true); stackLayout.topControl = lineSeriesGroup; createLabelControl(lineSeriesGroup, "Line color:"); lineColorButton = createColorButtonControl(lineSeriesGroup); lineColorButton.addListener(new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { lineColors[selectedIndex] = lineColorButton.getColorValue(); } }); createLabelControl(lineSeriesGroup, "Line style:"); LineStyle[] styles = LineStyle.values(); String[] labels = new String[styles.length]; for (int i = 0; i < styles.length; i++) { labels[i] = styles[i].label; } lineStyleCombo = createComboControl(lineSeriesGroup, labels); lineStyleCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String value = lineStyleCombo.getText(); LineStyle selectedStyle = LineStyle.NONE; for (LineStyle style : LineStyle.values()) { if (style.label.equals(value)) { selectedStyle = style; } } lineStyles[selectedIndex] = selectedStyle; } }); createLabelControl(lineSeriesGroup, "Symbol color:"); symbolColorButton = createColorButtonControl(lineSeriesGroup); symbolColorButton.addListener(new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { symbolColors[selectedIndex] = symbolColorButton.getColorValue(); } }); createLabelControl(lineSeriesGroup, "Symbol type:"); PlotSymbolType[] types = PlotSymbolType.values(); labels = new String[types.length]; for (int i = 0; i < types.length; i++) { labels[i] = types[i].label; } symbolTypeCombo = createComboControl(lineSeriesGroup, labels); symbolTypeCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String value = symbolTypeCombo.getText(); PlotSymbolType selectedType = PlotSymbolType.CIRCLE; for (PlotSymbolType type : PlotSymbolType.values()) { if (type.label.equals(value)) { selectedType = type; } } symbolTypes[selectedIndex] = selectedType; } }); createLabelControl(lineSeriesGroup, "Symbol size:"); symbolSizeSpinner = createSpinnerControl(lineSeriesGroup, 1, 10); symbolSizeSpinner.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { symbolSizes[selectedIndex] = symbolSizeSpinner.getSelection(); } }); } /** * Adds the bar series group. * * @param parent * the parent to add the bar series group */ private void addBarSeriesGroup(Composite parent) { barSeriesGroup = new Composite(parent, SWT.NONE); barSeriesGroup.setLayout(new GridLayout(1, true)); barSeriesGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Group group = createGroupControl(barSeriesGroup, "Bar series:", true); createLabelControl(group, "Color:"); barColorButton = createColorButtonControl(group); barColorButton.addListener(new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { barColors[selectedIndex] = barColorButton.getColorValue(); } }); createLabelControl(group, "Padding size:"); paddingSizeSpinner = createSpinnerControl(group, 0, 100); paddingSizeSpinner.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { paddings[selectedIndex] = paddingSizeSpinner.getSelection(); } }); } /** * Sets the enable state of controls. * * @param enabled * true if controls are enabled */ protected void setControlsEnable(boolean enabled) { lineColorButton.setEnabled(enabled); lineStyleCombo.setEnabled(enabled); stackedButton.setEnabled(enabled); if (xAxisIdCombo != null) { xAxisIdCombo.setEnabled(enabled); } if (yAxisIdCombo != null) { yAxisIdCombo.setEnabled(enabled); } barColorButton.setEnabled(enabled); paddingSizeSpinner.setEnabled(enabled); } /* * @see AbstractPreferencePage#apply() */ @Override public void apply() { for (int i = 0; i < series.length; i++) { series[i].setVisible(visibleStates[i]); if (series[i] instanceof ILineSeries) { Color lineColor = new Color(Display.getDefault(), lineColors[i]); ((ILineSeries) series[i]).setLineColor(lineColor); final String lineColorKey = SERIES_LINE_COLOR + series[i].getId(); if (resources.getColor(lineColorKey) == null) { series[i].addDisposeListener(new IDisposeListener() { public void disposed(Event e) { resources.removeColor(lineColorKey); } }); } resources.put(lineColorKey, lineColor); Color symbolColor = new Color(Display.getDefault(), symbolColors[i]); ((ILineSeries) series[i]).setSymbolColor(symbolColor); final String symbolColorKey = SERIES_SYMBOL_COLOR + series[i].getId(); if (resources.getColor(symbolColorKey) == null) { series[i].addDisposeListener(new IDisposeListener() { public void disposed(Event e) { resources.removeColor(symbolColorKey); } }); } resources.put(symbolColorKey, symbolColor); ((ILineSeries) series[i]).setLineStyle(lineStyles[i]); ((ILineSeries) series[i]).setSymbolType(symbolTypes[i]); ((ILineSeries) series[i]).setSymbolSize(symbolSizes[i]); } else if (series[i] instanceof IBarSeries) { Color barColor = new Color(Display.getDefault(), barColors[i]); ((IBarSeries) series[i]).setBarColor(barColor); final String barColorKey = SERIES_BAR_COLOR + series[i].getId(); if (resources.getColor(barColorKey) == null) { series[i].addDisposeListener(new IDisposeListener() { public void disposed(Event e) { resources.removeColor(barColorKey); } }); } resources.put(barColorKey, barColor); ((IBarSeries) series[i]).setBarPadding(paddings[i]); } try { series[i].enableStack(stackedStates[i]); } catch (IllegalArgumentException e) { stackedStates[i] = false; stackedButton.setSelection(false); } series[i].setXAxisId(xAxisIds[i]); series[i].setYAxisId(yAxisIds[i]); } } /* * @see PreferencePage#performDefaults() */ @Override protected void performDefaults() { visibleStates[selectedIndex] = true; stackedStates[selectedIndex] = false; if (xAxisIdCombo != null) { xAxisIds[selectedIndex] = 0; } if (yAxisIdCombo != null) { yAxisIds[selectedIndex] = 0; } if (series[selectedIndex] instanceof ILineSeries) { lineStyles[selectedIndex] = LineStyle.SOLID; lineColors[selectedIndex] = Display.getDefault().getSystemColor( SWT.COLOR_BLUE).getRGB(); symbolColors[selectedIndex] = Display.getDefault().getSystemColor( SWT.COLOR_DARK_GRAY).getRGB(); symbolTypes[selectedIndex] = PlotSymbolType.CIRCLE; symbolSizes[selectedIndex] = 4; } else if (series[selectedIndex] instanceof IBarSeries) { barColors[selectedIndex] = Display.getDefault().getSystemColor( SWT.COLOR_BLUE).getRGB(); paddings[selectedIndex] = 20; } updateControlSelections(); super.performDefaults(); } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/SeriesLabelPage.javaswt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/SeriesLabelPage.j0000644000175000017500000001704611234141567034203 0ustar jsprickejsprickepackage org.swtchart.ext.internal.properties; import org.eclipse.jface.preference.ColorSelector; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Spinner; import org.swtchart.Constants; import org.swtchart.IDisposeListener; import org.swtchart.ISeries; import org.swtchart.ext.InteractiveChart; /** * The series label page on properties dialog. */ public class SeriesLabelPage extends AbstractSelectorPage { /** the key for series label foreground */ private static final String SERIES_LABEL_FOREGROUND = "org.swtchart.series.foreground"; /** the key for series label font */ private static final String SERIES_LABEL_FONT = "org.swtchart.series.font"; /** the series array */ private ISeries[] series; /** the show label button */ protected Button showLabelButton; /** the color label */ private Label colorLabel; /** the color button */ protected ColorSelector colorButton; /** the font size label */ private Label fontSizeLabel; /** the font size spinner */ protected Spinner fontSizeSpinner; /** the states indicating the visibility of series */ protected boolean[] visibleStates; /** the colors */ protected RGB[] colors; /** the font size */ protected int[] fontSizes; /** * Constructor. * * @param chart * the chart * @param resources * the properties resources * @param title * the title */ public SeriesLabelPage(InteractiveChart chart, PropertiesResources resources, String title) { super(chart, resources, title, "Series:"); series = chart.getSeriesSet().getSeries(); visibleStates = new boolean[series.length]; colors = new RGB[series.length]; fontSizes = new int[series.length]; } /* * @see AbstractSelectorPage#getListItems() */ @Override protected String[] getListItems() { String[] items = new String[series.length]; for (int i = 0; i < items.length; i++) { items[i] = String.valueOf(series[i].getId()); } return items; } /* * @see AbstractSelectorPage#selectInitialValues() */ @Override protected void selectInitialValues() { for (int i = 0; i < series.length; i++) { visibleStates[i] = series[i].getLabel().isVisible(); colors[i] = series[i].getLabel().getForeground().getRGB(); fontSizes[i] = series[i].getLabel().getFont().getFontData()[0] .getHeight(); } } /* * @see AbstractSelectorPage#updateControlSelections() */ @Override protected void updateControlSelections() { showLabelButton.setSelection(visibleStates[selectedIndex]); setControlsEnable(visibleStates[selectedIndex]); colorButton.setColorValue(colors[selectedIndex]); fontSizeSpinner.setSelection(fontSizes[selectedIndex]); } /* * @see AbstractSelectorPage#addRightPanelContents(Composite) */ @Override protected void addRightPanelContents(Composite parent) { addSeriesLabelPanel(parent); } /** * Adds the series label panel. * * @param parent * the parent to add the series label panel */ private void addSeriesLabelPanel(Composite parent) { Composite group = new Composite(parent, SWT.NONE); group.setLayout(new GridLayout(2, false)); showLabelButton = createCheckBoxControl(group, "Show label"); showLabelButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { boolean visible = showLabelButton.getSelection(); visibleStates[selectedIndex] = visible; setControlsEnable(visible); } }); colorLabel = createLabelControl(group, "Color:"); colorButton = createColorButtonControl(group); colorButton.addListener(new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { colors[selectedIndex] = colorButton.getColorValue(); } }); fontSizeLabel = createLabelControl(group, "Font size:"); fontSizeSpinner = createSpinnerControl(group, 8, 30); fontSizeSpinner.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { fontSizes[selectedIndex] = fontSizeSpinner.getSelection(); } }); } /** * Sets the enable state of controls. * * @param enabled * true if controls are enabled */ protected void setControlsEnable(boolean enabled) { colorLabel.setEnabled(enabled); colorButton.setEnabled(enabled); fontSizeLabel.setEnabled(enabled); fontSizeSpinner.setEnabled(enabled); } /* * @see AbstractPreferencePage#apply() */ @Override public void apply() { for (int i = 0; i < series.length; i++) { series[i].getLabel().setVisible(visibleStates[i]); Color color = new Color(Display.getDefault(), colors[i]); series[i].getLabel().setForeground(color); final String colorKey = SERIES_LABEL_FOREGROUND + series[i].getId(); if (resources.getColor(colorKey) == null) { series[i].addDisposeListener(new IDisposeListener() { public void disposed(Event e) { resources.removeColor(colorKey); } }); } resources.put(colorKey, color); FontData fontData = series[i].getLabel().getFont().getFontData()[0]; fontData.setHeight(fontSizes[i]); Font font = new Font(Display.getDefault(), fontData); series[i].getLabel().setFont(font); final String fontKey = SERIES_LABEL_FONT + series[i].getId(); if (resources.getFont(fontKey) == null) { series[i].addDisposeListener(new IDisposeListener() { public void disposed(Event e) { resources.removeFont(fontKey); } }); } resources.put(fontKey, font); } } /* * @see PreferencePage#performDefaults() */ @Override protected void performDefaults() { visibleStates[selectedIndex] = false; colors[selectedIndex] = Display.getDefault().getSystemColor( SWT.COLOR_BLACK).getRGB(); fontSizes[selectedIndex] = Constants.SMALL_FONT_SIZE; updateControlSelections(); super.performDefaults(); } } ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/PropertiesResources.javaswt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/PropertiesResourc0000644000175000017500000000704711171376066034467 0ustar jsprickejsprickepackage org.swtchart.ext.internal.properties; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; /** * SWT resources created with properties dialog. */ public class PropertiesResources { /** the fonts */ private Map fonts; /** the colors */ private Map colors; /** * The constructor. */ public PropertiesResources() { fonts = new HashMap(); colors = new HashMap(); } /** * Gets the font associated with the given key. * * @param key * the key associated with the font to get * @return the font */ public Font getFont(String key) { return fonts.get(key); } /** * Gets the color associated with the given key. * * @param key * the key associated with the color to get * @return the color */ public Color getColor(String key) { return colors.get(key); } /** * Puts the given font. If a font associated with the given key already * exists, the existing font will be disposed. When chart is disposed, all * stored fonts in this object will be disposed. *

* When the resource won't be used, the resource should be disposed and * removed. * * @param key * the key for given font * @param font * the font to be stored */ public void put(String key, Font font) { Font oldFont = fonts.get(key); if (oldFont != null) { oldFont.dispose(); } fonts.put(key, font); } /** * Puts the given color. If a font associated with the given key already * exists, the existing color will be disposed. When chart is disposed, all * stored colors in this object will be disposed. * * @param key * the key for given color * @param color * the color to be stored */ public void put(String key, Color color) { Color oldColor = colors.get(key); if (oldColor != null) { oldColor.dispose(); } colors.put(key, color); } /** * Removes the font associated with the given key. This method will be * invoked typically when removing series object or axis object. * * @param key * the key associated with the font to be removed */ public void removeFont(String key) { Font font = fonts.get(key); if (font != null) { fonts.remove(key); font.dispose(); } } /** * Removes the color associated with the given key. This method will be * invoked typically when removing series object or axis object. * * @param key * the key associated with the color to be removed */ public void removeColor(String key) { Color color = colors.get(key); if (color != null) { colors.remove(key); color.dispose(); } } /** * Disposes the SWT resources. */ public void dispose() { for (Entry entry : fonts.entrySet()) { entry.getValue().dispose(); } for (Entry entry : colors.entrySet()) { entry.getValue().dispose(); } } } ././@LongLink0000644000000000000000000000015500000000000011604 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/AbstractSelectorPage.javaswt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/AbstractSelectorP0000644000175000017500000001156611171376066034355 0ustar jsprickejsprickepackage org.swtchart.ext.internal.properties; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.List; import org.swtchart.ext.InteractiveChart; /** * Abstract class for properties page with selector. */ abstract public class AbstractSelectorPage extends AbstractPage { /** the list */ protected List list; /** the selector name */ private String selector; /** the state indicating if selector is enabled */ private boolean selectorEnabled; /** the selected index */ protected int selectedIndex; /** * Constructor. * * @param chart * the chart * @param resources * the properties resources * @param title * the title * @param selector * the selector name */ public AbstractSelectorPage(InteractiveChart chart, PropertiesResources resources, String title, String selector) { super(chart, resources, title); this.selector = selector; selectedIndex = 0; selectorEnabled = true; } /* * @see PreferencePage#createContents(Composite) */ @Override protected Control createContents(Composite parent) { String[] items = getListItems(); if (items.length < 2) { selectorEnabled = false; } Composite composite = new Composite(parent, SWT.NONE); if (selectorEnabled) { GridLayout layout = new GridLayout(3, true); layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); Label label = new Label(composite, SWT.NULL); label.setText(selector); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.horizontalSpan = 3; label.setLayoutData(gridData); addLeftPanel(composite, items); addRightPanel(composite); } else { GridLayout layout = new GridLayout(1, true); layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); addRightPanelContents(composite); } selectInitialValues(); updateControlSelections(); return composite; } /** * Gets the list items. * * @return the list items */ abstract protected String[] getListItems(); /** * Selects value for each control. */ abstract protected void selectInitialValues(); /** * Adds the left panel. * * @param parent * the parent to add the left panel * @param items * the items to be added to list */ private void addLeftPanel(Composite parent, String[] items) { Composite leftPanel = new Composite(parent, SWT.NULL); GridData gridData = new GridData(GridData.FILL_BOTH); gridData.horizontalSpan = 1; leftPanel.setLayoutData(gridData); GridLayout layout = new GridLayout(1, false); layout.marginHeight = 0; layout.marginWidth = 0; leftPanel.setLayout(layout); list = new List(leftPanel, SWT.BORDER); GridData gridData2 = new GridData(GridData.FILL_BOTH); gridData2.horizontalSpan = 1; list.setLayoutData(gridData2); for (String item : items) { list.add(item); } list.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { selectedIndex = list.getSelectionIndex(); updateControlSelections(); } }); list.select(0); } /** * Adds the right panel. * * @param parent * the parent to add the right panel */ private void addRightPanel(Composite parent) { Composite rightPanel = new Composite(parent, SWT.NULL); GridData gridData = new GridData(GridData.FILL_BOTH); gridData.horizontalSpan = 2; rightPanel.setLayoutData(gridData); rightPanel.setLayout(new GridLayout(1, false)); addRightPanelContents(rightPanel); } /** * Adds the contents on right panel. * * @param parent * the parent to add the contents */ abstract protected void addRightPanelContents(Composite parent); /** * Updates the selection on controls. */ abstract protected void updateControlSelections(); } swt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/InteractiveChart.java0000644000175000017500000004160011223676210031120 0ustar jsprickejsprickepackage org.swtchart.ext; import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.jface.preference.PreferenceManager; import org.eclipse.jface.preference.PreferenceNode; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.Range; import org.swtchart.IAxis.Direction; import org.swtchart.ext.internal.SelectionRectangle; import org.swtchart.ext.internal.properties.AxisPage; import org.swtchart.ext.internal.properties.AxisTickPage; import org.swtchart.ext.internal.properties.ChartPage; import org.swtchart.ext.internal.properties.GridPage; import org.swtchart.ext.internal.properties.LegendPage; import org.swtchart.ext.internal.properties.PropertiesResources; import org.swtchart.ext.internal.properties.SeriesLabelPage; import org.swtchart.ext.internal.properties.SeriesPage; /** * An interactive chart which provides the following abilities. *

    *
  • scroll with arrow keys
  • *
  • zoom in and out with ctrl + arrow up/down keys
  • *
  • context menus for adjusting axis range and zooming in/out.
  • *
  • file selector dialog to save chart to image file.
  • *
  • properties dialog to configure the chart settings
  • *
*/ public class InteractiveChart extends Chart implements PaintListener { /** the filter extensions */ private static final String[] EXTENSIONS = new String[] { "*.jpeg", "*.jpg", "*.png" }; /** the selection rectangle for zoom in/out */ protected SelectionRectangle selection; /** the clicked time in milliseconds */ private long clickedTime; /** the resources created with properties dialog */ private PropertiesResources resources; /** * Constructor. * * @param parent * the parent composite * @param style * the style */ public InteractiveChart(Composite parent, int style) { super(parent, style); init(); } /** * Initializes. */ private void init() { selection = new SelectionRectangle(); resources = new PropertiesResources(); Composite plot = getPlotArea(); plot.addListener(SWT.Resize, this); plot.addListener(SWT.MouseMove, this); plot.addListener(SWT.MouseDown, this); plot.addListener(SWT.MouseUp, this); plot.addListener(SWT.MouseWheel, this); plot.addListener(SWT.KeyDown, this); plot.addPaintListener(this); createMenuItems(); } /** * Creates menu items. */ private void createMenuItems() { Menu menu = new Menu(getPlotArea()); getPlotArea().setMenu(menu); // adjust axis range menu group MenuItem menuItem = new MenuItem(menu, SWT.CASCADE); menuItem.setText(Messages.ADJUST_AXIS_RANGE_GROUP); Menu adjustAxisRangeMenu = new Menu(menuItem); menuItem.setMenu(adjustAxisRangeMenu); // adjust axis range menuItem = new MenuItem(adjustAxisRangeMenu, SWT.PUSH); menuItem.setText(Messages.ADJUST_AXIS_RANGE); menuItem.addListener(SWT.Selection, this); // adjust X axis range menuItem = new MenuItem(adjustAxisRangeMenu, SWT.PUSH); menuItem.setText(Messages.ADJUST_X_AXIS_RANGE); menuItem.addListener(SWT.Selection, this); // adjust Y axis range menuItem = new MenuItem(adjustAxisRangeMenu, SWT.PUSH); menuItem.setText(Messages.ADJUST_Y_AXIS_RANGE); menuItem.addListener(SWT.Selection, this); menuItem = new MenuItem(menu, SWT.SEPARATOR); // zoom in menu group menuItem = new MenuItem(menu, SWT.CASCADE); menuItem.setText(Messages.ZOOMIN_GROUP); Menu zoomInMenu = new Menu(menuItem); menuItem.setMenu(zoomInMenu); // zoom in both axes menuItem = new MenuItem(zoomInMenu, SWT.PUSH); menuItem.setText(Messages.ZOOMIN); menuItem.addListener(SWT.Selection, this); // zoom in X axis menuItem = new MenuItem(zoomInMenu, SWT.PUSH); menuItem.setText(Messages.ZOOMIN_X); menuItem.addListener(SWT.Selection, this); // zoom in Y axis menuItem = new MenuItem(zoomInMenu, SWT.PUSH); menuItem.setText(Messages.ZOOMIN_Y); menuItem.addListener(SWT.Selection, this); // zoom out menu group menuItem = new MenuItem(menu, SWT.CASCADE); menuItem.setText(Messages.ZOOMOUT_GROUP); Menu zoomOutMenu = new Menu(menuItem); menuItem.setMenu(zoomOutMenu); // zoom out both axes menuItem = new MenuItem(zoomOutMenu, SWT.PUSH); menuItem.setText(Messages.ZOOMOUT); menuItem.addListener(SWT.Selection, this); // zoom out X axis menuItem = new MenuItem(zoomOutMenu, SWT.PUSH); menuItem.setText(Messages.ZOOMOUT_X); menuItem.addListener(SWT.Selection, this); // zoom out Y axis menuItem = new MenuItem(zoomOutMenu, SWT.PUSH); menuItem.setText(Messages.ZOOMOUT_Y); menuItem.addListener(SWT.Selection, this); menuItem = new MenuItem(menu, SWT.SEPARATOR); // save as menuItem = new MenuItem(menu, SWT.PUSH); menuItem.setText(Messages.SAVE_AS); menuItem.addListener(SWT.Selection, this); menuItem = new MenuItem(menu, SWT.SEPARATOR); // properties menuItem = new MenuItem(menu, SWT.PUSH); menuItem.setText(Messages.PROPERTIES); menuItem.addListener(SWT.Selection, this); } /* * @see PaintListener#paintControl(PaintEvent) */ public void paintControl(PaintEvent e) { selection.draw(e.gc); } /* * @see Listener#handleEvent(Event) */ @Override public void handleEvent(Event event) { super.handleEvent(event); switch (event.type) { case SWT.MouseMove: handleMouseMoveEvent(event); break; case SWT.MouseDown: handleMouseDownEvent(event); break; case SWT.MouseUp: handleMouseUpEvent(event); break; case SWT.MouseWheel: handleMouseWheel(event); break; case SWT.KeyDown: handleKeyDownEvent(event); break; case SWT.Selection: handleSelectionEvent(event); break; default: break; } } /* * @see Chart#dispose() */ @Override public void dispose() { super.dispose(); resources.dispose(); } /** * Handles mouse move event. * * @param event * the mouse move event */ private void handleMouseMoveEvent(Event event) { if (!selection.isDisposed()) { selection.setEndPoint(event.x, event.y); redraw(); } } /** * Handles the mouse down event. * * @param event * the mouse down event */ private void handleMouseDownEvent(Event event) { if (event.button == 1) { selection.setStartPoint(event.x, event.y); clickedTime = System.currentTimeMillis(); } } /** * Handles the mouse up event. * * @param event * the mouse up event */ private void handleMouseUpEvent(Event event) { if (event.button == 1 && System.currentTimeMillis() - clickedTime > 100) { for (IAxis axis : getAxisSet().getAxes()) { Point range = null; if ((getOrientation() == SWT.HORIZONTAL && axis.getDirection() == Direction.X) || (getOrientation() == SWT.VERTICAL && axis .getDirection() == Direction.Y)) { range = selection.getHorizontalRange(); } else { range = selection.getVerticalRange(); } if (range != null && range.x != range.y) { setRange(range, axis); } } } selection.dispose(); redraw(); } /** * Handles mouse wheel event. * * @param event * the mouse wheel event */ private void handleMouseWheel(Event event) { for (IAxis axis : getAxes(SWT.HORIZONTAL)) { double coordinate = axis.getDataCoordinate(event.x); if (event.count > 0) { axis.zoomIn(coordinate); } else { axis.zoomOut(coordinate); } } for (IAxis axis : getAxes(SWT.VERTICAL)) { double coordinate = axis.getDataCoordinate(event.y); if (event.count > 0) { axis.zoomIn(coordinate); } else { axis.zoomOut(coordinate); } } redraw(); } /** * Handles the key down event. * * @param event * the key down event */ private void handleKeyDownEvent(Event event) { if (event.keyCode == SWT.ARROW_DOWN) { if (event.stateMask == SWT.CTRL) { getAxisSet().zoomOut(); } else { for (IAxis axis : getAxes(SWT.VERTICAL)) { axis.scrollDown(); } } redraw(); } else if (event.keyCode == SWT.ARROW_UP) { if (event.stateMask == SWT.CTRL) { getAxisSet().zoomIn(); } else { for (IAxis axis : getAxes(SWT.VERTICAL)) { axis.scrollUp(); } } redraw(); } else if (event.keyCode == SWT.ARROW_LEFT) { for (IAxis axis : getAxes(SWT.HORIZONTAL)) { axis.scrollDown(); } redraw(); } else if (event.keyCode == SWT.ARROW_RIGHT) { for (IAxis axis : getAxes(SWT.HORIZONTAL)) { axis.scrollUp(); } redraw(); } } /** * Gets the axes for given orientation. * * @param orientation * the orientation * @return the axes */ private IAxis[] getAxes(int orientation) { IAxis[] axes; if (getOrientation() == orientation) { axes = getAxisSet().getXAxes(); } else { axes = getAxisSet().getYAxes(); } return axes; } /** * Handles the selection event. * * @param event * the event */ private void handleSelectionEvent(Event event) { if (!(event.widget instanceof MenuItem)) { return; } MenuItem menuItem = (MenuItem) event.widget; if (menuItem.getText().equals(Messages.ADJUST_AXIS_RANGE)) { getAxisSet().adjustRange(); } else if (menuItem.getText().equals(Messages.ADJUST_X_AXIS_RANGE)) { for (IAxis axis : getAxisSet().getXAxes()) { axis.adjustRange(); } } else if (menuItem.getText().equals(Messages.ADJUST_Y_AXIS_RANGE)) { for (IAxis axis : getAxisSet().getYAxes()) { axis.adjustRange(); } } else if (menuItem.getText().equals(Messages.ZOOMIN)) { getAxisSet().zoomIn(); } else if (menuItem.getText().equals(Messages.ZOOMIN_X)) { for (IAxis axis : getAxisSet().getXAxes()) { axis.zoomIn(); } } else if (menuItem.getText().equals(Messages.ZOOMIN_Y)) { for (IAxis axis : getAxisSet().getYAxes()) { axis.zoomIn(); } } else if (menuItem.getText().equals(Messages.ZOOMOUT)) { getAxisSet().zoomOut(); } else if (menuItem.getText().equals(Messages.ZOOMOUT_X)) { for (IAxis axis : getAxisSet().getXAxes()) { axis.zoomOut(); } } else if (menuItem.getText().equals(Messages.ZOOMOUT_Y)) { for (IAxis axis : getAxisSet().getYAxes()) { axis.zoomOut(); } } else if (menuItem.getText().equals(Messages.SAVE_AS)) { openSaveAsDialog(); } else if (menuItem.getText().equals(Messages.PROPERTIES)) { openPropertiesDialog(); } redraw(); } /** * Opens the Save As dialog. */ private void openSaveAsDialog() { FileDialog dialog = new FileDialog(getShell(), SWT.SAVE); dialog.setText(Messages.SAVE_AS_DIALOG_TITLE); dialog.setFilterExtensions(EXTENSIONS); String filename = dialog.open(); if (filename == null) { return; } int format; if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) { format = SWT.IMAGE_JPEG; } else if (filename.endsWith(".png")) { format = SWT.IMAGE_PNG; } else { format = SWT.IMAGE_UNDEFINED; } if (format != SWT.IMAGE_UNDEFINED) { save(filename, format); } } /** * Opens the properties dialog. */ private void openPropertiesDialog() { PreferenceManager manager = new PreferenceManager(); final String chartTitle = "Chart"; PreferenceNode chartNode = new PreferenceNode(chartTitle); chartNode.setPage(new ChartPage(this, resources, chartTitle)); manager.addToRoot(chartNode); final String legendTitle = "Legend"; PreferenceNode legendNode = new PreferenceNode(legendTitle); legendNode.setPage(new LegendPage(this, resources, legendTitle)); manager.addTo(chartTitle, legendNode); final String xAxisTitle = "X Axis"; PreferenceNode xAxisNode = new PreferenceNode(xAxisTitle); xAxisNode .setPage(new AxisPage(this, resources, Direction.X, xAxisTitle)); manager.addTo(chartTitle, xAxisNode); final String gridTitle = "Grid"; PreferenceNode xGridNode = new PreferenceNode(gridTitle); xGridNode .setPage(new GridPage(this, resources, Direction.X, gridTitle)); manager.addTo(chartTitle + "." + xAxisTitle, xGridNode); final String tickTitle = "Tick"; PreferenceNode xTickNode = new PreferenceNode(tickTitle); xTickNode.setPage(new AxisTickPage(this, resources, Direction.X, tickTitle)); manager.addTo(chartTitle + "." + xAxisTitle, xTickNode); final String yAxisTitle = "Y Axis"; PreferenceNode yAxisNode = new PreferenceNode(yAxisTitle); yAxisNode .setPage(new AxisPage(this, resources, Direction.Y, yAxisTitle)); manager.addTo(chartTitle, yAxisNode); PreferenceNode yGridNode = new PreferenceNode(gridTitle); yGridNode .setPage(new GridPage(this, resources, Direction.Y, gridTitle)); manager.addTo(chartTitle + "." + yAxisTitle, yGridNode); PreferenceNode yTickNode = new PreferenceNode(tickTitle); yTickNode.setPage(new AxisTickPage(this, resources, Direction.Y, tickTitle)); manager.addTo(chartTitle + "." + yAxisTitle, yTickNode); final String seriesTitle = "Series"; PreferenceNode plotNode = new PreferenceNode(seriesTitle); plotNode.setPage(new SeriesPage(this, resources, seriesTitle)); manager.addTo(chartTitle, plotNode); final String labelTitle = "Label"; PreferenceNode labelNode = new PreferenceNode(labelTitle); labelNode.setPage(new SeriesLabelPage(this, resources, labelTitle)); manager.addTo(chartTitle + "." + seriesTitle, labelNode); PreferenceDialog dialog = new PreferenceDialog(getShell(), manager); dialog.create(); dialog.getShell().setText("Properties"); dialog.getTreeViewer().expandAll(); dialog.open(); } /** * Sets the axis range. * * @param range * the axis range in pixels * @param axis * the axis to set range */ private void setRange(Point range, IAxis axis) { if (range == null) { return; } double min = axis.getDataCoordinate(range.x); double max = axis.getDataCoordinate(range.y); axis.setRange(new Range(min, max)); } } swt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/Messages.java0000644000175000017500000000331111223676210027425 0ustar jsprickejsprickepackage org.swtchart.ext; /** * Messages */ public class Messages { /** the menu group for adjust axis range menus */ public static final String ADJUST_AXIS_RANGE_GROUP = "&Adjust Axis Range"; /** the menu for adjust axis range */ public static final String ADJUST_AXIS_RANGE = "&Adjust Axis Range"; /** the menu for adjust X axis range */ public static final String ADJUST_X_AXIS_RANGE = "Adjust &X Axis Range"; /** the menu for adjust Y axis range */ public static final String ADJUST_Y_AXIS_RANGE = "Adjust &Y Axis Range"; /** the menu group for zoom in menus */ public static final String ZOOMIN_GROUP = "Zoom &In"; /** the menu for zoom in */ public static final String ZOOMIN = "Zoom &In\tCtrl+Up"; /** the menu for zoom in X axis */ public static final String ZOOMIN_X = "Zoom In &X Axis"; /** the menu for zoom in Y axis */ public static final String ZOOMIN_Y = "Zoom In &Y Axis"; /** the menu group for zoom out menus */ public static final String ZOOMOUT_GROUP = "Zoom &Out"; /** the menu for zoom out */ public static final String ZOOMOUT = "Zoom &Out\tCtrl+Down"; /** the menu for zoom out X axis */ public static final String ZOOMOUT_X = "Zoom Out &X Axis"; /** the menu for zoom out Y axis */ public static final String ZOOMOUT_Y = "Zoom Out &Y Axis"; /** the menu for save as */ public static final String SAVE_AS = "Save As..."; /** the menu for opening properties dialog */ public static final String PROPERTIES = "P&roperties..."; /** the title for save as dialog */ public static final String SAVE_AS_DIALOG_TITLE = "Save As"; } swt-chart-code-312-trunk/org.swtchart.ext/META-INF/0000755000175000017500000000000013275316674022156 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.ext/META-INF/MANIFEST.MF0000644000175000017500000000043712657165716023616 0ustar jsprickejsprickeManifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: SWTChart Extension Plug-in Bundle-SymbolicName: org.swtchart.ext Bundle-Version: 0.10.0.qualifier Require-Bundle: org.eclipse.jface, org.swtchart Export-Package: org.swtchart.ext Bundle-RequiredExecutionEnvironment: J2SE-1.5 swt-chart-code-312-trunk/org.swtchart.examples/0000755000175000017500000000000013275316672022032 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples/.project0000644000175000017500000000061511032255664023473 0ustar jsprickejspricke org.swtchart.examples org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature swt-chart-code-312-trunk/org.swtchart.examples/lib/0000755000175000017500000000000013275316672022600 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples/.classpath0000644000175000017500000000055312657165716024024 0ustar jsprickejspricke swt-chart-code-312-trunk/org.swtchart.examples/src/0000755000175000017500000000000013275316671022620 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples/src/org/0000755000175000017500000000000013275316671023407 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/0000755000175000017500000000000013275316671025246 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/0000755000175000017500000000000013275316672027065 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/LogScaleExample.java0000644000175000017500000000402411520323141032711 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.ILineSeries; import org.swtchart.ISeries.SeriesType; /** * An example for log scale. */ public class LogScaleExample { private static final double[] ySeries = { 0.6, 0.4, 0.7, 0.06, 1.9, 1.7, 2.6, 5.4, 9.1, 11.2, 23.4, 10.6, 54.2, 40.6, 68.1, 110.5 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Log Scale"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set titles chart.getTitle().setText("Log Scale"); chart.getAxisSet().getXAxis(0).getTitle().setText("Data Points"); chart.getAxisSet().getYAxis(0).getTitle().setText("Amplitude"); // create line series ILineSeries lineSeries = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "line series"); lineSeries.setYSeries(ySeries); // set log scale chart.getAxisSet().getYAxis(0).enableLogScale(true); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/ErrorBarsExample.java0000644000175000017500000000365611520323141033133 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.IErrorBar; import org.swtchart.ISeries; import org.swtchart.ISeries.SeriesType; /** * An example for error bars. */ public class ErrorBarsExample { private static final double[] ySeries = { 0.0, 0.38, 0.71, 0.92, 1.0, 0.92, 0.71, 0.38, 0.0, -0.38, -0.71, -0.92, -1.0, -0.92, -0.71, -0.38 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Error Bars"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); chart.getTitle().setText("Error Bars"); // create series ISeries series = chart.getSeriesSet().createSeries(SeriesType.LINE, "line series"); series.setYSeries(ySeries); // set error bars IErrorBar errorBar = series.getYErrorBar(); errorBar.setVisible(true); errorBar.setError(0.1); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/StackSeriesExample.java0000644000175000017500000000505111520323141033441 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.IBarSeries; import org.swtchart.ISeries.SeriesType; /** * An example for chart with stack series. */ public class StackSeriesExample { private static final double[] ySeries1 = { 1.3, 2.4, 3.9, 2.6, 1.1 }; private static final double[] ySeries2 = { 3.0, 2.1, 1.9, 2.3, 3.2 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Stack Series"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set titles chart.getTitle().setText("Stack Series"); chart.getAxisSet().getXAxis(0).getTitle().setText("Month"); chart.getAxisSet().getYAxis(0).getTitle().setText("Amplitude"); // set category chart.getAxisSet().getXAxis(0).enableCategory(true); chart.getAxisSet().getXAxis(0).setCategorySeries( new String[] { "Jan", "Feb", "Mar", "Apr", "May" }); // create bar series IBarSeries barSeries1 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "bar series 1"); barSeries1.setYSeries(ySeries1); barSeries1.setBarColor(Display.getDefault().getSystemColor( SWT.COLOR_GREEN)); IBarSeries barSeries2 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "bar series 2"); barSeries2.setYSeries(ySeries2); // enable stack series barSeries1.enableStack(true); barSeries2.enableStack(true); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/SeriesLabelExample.java0000644000175000017500000000404111520323141033411 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.ILineSeries; import org.swtchart.ISeries.SeriesType; /** * An example for series label. */ public class SeriesLabelExample { private static final double[] ySeries = { 0.0, 0.38, 0.71, 0.92, 1.0, 0.92, 0.71, 0.38, 0.0, -0.38, -0.71, -0.92, -1.0, -0.92, -0.71, -0.38 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Series Label"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set titles chart.getTitle().setText("Series Label"); chart.getAxisSet().getXAxis(0).getTitle().setText("Data Points"); chart.getAxisSet().getYAxis(0).getTitle().setText("Amplitude"); // create line series ILineSeries lineSeries = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "line series"); lineSeries.setYSeries(ySeries); // set label visible lineSeries.getLabel().setVisible(true); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/RunAllExamples.java0000644000175000017500000001167311520323141032610 0ustar jsprickejsprickepackage org.swtchart.examples; import java.util.Vector; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; import org.swtchart.Chart; import org.swtchart.examples.advanced.AxisTickBoundsExample; import org.swtchart.examples.advanced.BarBoundsExample; import org.swtchart.examples.advanced.CustomPaintListenerExample; import org.swtchart.examples.advanced.DataToPixelConversionExample; import org.swtchart.examples.advanced.LegendBoundsExample; import org.swtchart.examples.advanced.PxielToDataConversionExample; import org.swtchart.examples.advanced.SymbolBoundsExample; /** * The class to run all examples. */ public class RunAllExamples { static Vector basicCharts; static Vector advancedCharts; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Examples"); shell.setSize(750, 400); shell.setLayout(new FillLayout()); SashForm sashForm = new SashForm(shell, SWT.HORIZONTAL); TabFolder tabFolder = new TabFolder(sashForm, SWT.NONE); tabFolder.setLayoutData(new GridData(GridData.FILL_VERTICAL)); tabFolder.setLayout(new FillLayout()); final Composite composite = new Composite(sashForm, SWT.NONE); composite.setLayoutData(new GridData(GridData.FILL_BOTH)); final StackLayout layout = new StackLayout(); composite.setLayout(layout); sashForm.setWeights(new int[] { 1, 2 }); createList("Basic", createBasicCharts(composite), tabFolder, layout, composite); createList("Advanced", createAdvancedCharts(composite), tabFolder, layout, composite); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } private static void createList(String tabName, final Vector charts, TabFolder tabFolder, final StackLayout layout, final Composite composite) { final List list = new List(tabFolder, SWT.H_SCROLL | SWT.V_SCROLL); TabItem basicTabItem = new TabItem(tabFolder, SWT.NONE); basicTabItem.setText(tabName); basicTabItem.setControl(list); for (Chart chart : charts) { list.add(chart.getTitle().getText()); } list.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { Chart chart = charts.get(list.getSelectionIndex()); chart.getAxisSet().adjustRange(); layout.topControl = chart; composite.layout(); } }); } private static Vector createBasicCharts(Composite parent) { basicCharts = new Vector(); basicCharts.add(LineChartExample.createChart(parent)); basicCharts.add(BarChartExample.createChart(parent)); basicCharts.add(ScatterChartExample.createChart(parent)); basicCharts.add(AreaChartExample.createChart(parent)); basicCharts.add(StepChartExample.createChart(parent)); basicCharts.add(StackSeriesExample.createChart(parent)); basicCharts.add(LogScaleExample.createChart(parent)); basicCharts.add(OrientationExample.createChart(parent)); basicCharts.add(CategoryExample.createChart(parent)); basicCharts.add(SeriesLabelExample.createChart(parent)); basicCharts.add(ErrorBarsExample.createChart(parent)); basicCharts.add(MultipleAxesExample.createChart(parent)); basicCharts.add(LargeSeriesExample.createChart(parent)); basicCharts.add(AngledAxisTickLabelsExample.createChart(parent)); return basicCharts; } private static Vector createAdvancedCharts(Composite parent) { basicCharts = new Vector(); basicCharts.add(PxielToDataConversionExample.createChart(parent)); basicCharts.add(DataToPixelConversionExample.createChart(parent)); basicCharts.add(SymbolBoundsExample.createChart(parent)); basicCharts.add(BarBoundsExample.createChart(parent)); basicCharts.add(AxisTickBoundsExample.createChart(parent)); basicCharts.add(LegendBoundsExample.createChart(parent)); basicCharts.add(CustomPaintListenerExample.createChart(parent)); return basicCharts; } } swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/BarChartExample.java0000644000175000017500000000361311520323141032711 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.IBarSeries; import org.swtchart.ISeries.SeriesType; /** * An example for bar chart. */ public class BarChartExample { private static final double[] ySeries = { 0.2, 1.1, 1.9, 2.3, 1.8, 1.5, 1.8, 2.6, 2.9, 3.2 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Bar Chart"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set titles chart.getTitle().setText("Bar Chart"); chart.getAxisSet().getXAxis(0).getTitle().setText("Data Points"); chart.getAxisSet().getYAxis(0).getTitle().setText("Amplitude"); // create bar series IBarSeries barSeries = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "bar series"); barSeries.setYSeries(ySeries); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/StepChartExample.java0000644000175000017500000000412711520323141033121 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.ILineSeries; import org.swtchart.ILineSeries.PlotSymbolType; import org.swtchart.ISeries.SeriesType; /** * An example for step chart. */ public class StepChartExample { private static final double[] ySeries = { 0.0, 0.38, 0.71, 0.92, 1.0, 0.92, 0.71, 0.38, 0.0, -0.38, -0.71, -0.92, -1.0, -0.92, -0.71, -0.38 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Step Chart"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set titles chart.getTitle().setText("Step Chart"); chart.getAxisSet().getXAxis(0).getTitle().setText("Data Points"); chart.getAxisSet().getYAxis(0).getTitle().setText("Amplitude"); // create line series ILineSeries lineSeries = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "line series"); lineSeries.setYSeries(ySeries); lineSeries.setSymbolType(PlotSymbolType.NONE); lineSeries.enableStep(true); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/OrientationExample.java0000644000175000017500000000375711520323141033527 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.IBarSeries; import org.swtchart.ISeries.SeriesType; /** * An example for chart orientation. */ public class OrientationExample { private static final double[] ySeries = { 0.2, 1.1, 1.9, 2.3, 1.8, 1.5, 1.8, 2.6, 2.9, 3.2 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Orientation"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set the chart orientation chart.setOrientation(SWT.VERTICAL); // set titles chart.getTitle().setText("Orientation"); chart.getAxisSet().getXAxis(0).getTitle().setText("Data Points"); chart.getAxisSet().getYAxis(0).getTitle().setText("Amplitude"); // create bar series IBarSeries barSeries = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "bar series"); barSeries.setYSeries(ySeries); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/MultipleAxesExample.java0000644000175000017500000000573511520323141033646 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.ILineSeries; import org.swtchart.IAxis.Position; import org.swtchart.ISeries.SeriesType; /** * An example for multiple axes. */ public class MultipleAxesExample { private static final double[] ySeries1 = { 0.0, 0.38, 0.71, 0.92, 1.0, 0.92, 0.71, 0.38, 0.0, -0.38, -0.71, -0.92, -1.0, -0.92, -0.71, -0.38 }; private static final double[] ySeries2 = { 2, 11, 19, 23, 18, 15, 18, 26, 29, 32, 47, 32, 31, 35, 30, 29 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Multiple Axes"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set titles chart.getTitle().setText("Multiple Axes"); chart.getAxisSet().getXAxis(0).getTitle().setText("Data Points"); chart.getAxisSet().getYAxis(0).getTitle().setText("Amplitude 1"); // create second Y axis int axisId = chart.getAxisSet().createYAxis(); // set the properties of second Y axis IAxis yAxis2 = chart.getAxisSet().getYAxis(axisId); yAxis2.setPosition(Position.Secondary); final Color RED = Display.getDefault().getSystemColor(SWT.COLOR_RED); yAxis2.getTick().setForeground(RED); yAxis2.getTitle().setForeground(RED); yAxis2.getTitle().setText("Amplitude 2"); // create line series ILineSeries lineSeries1 = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "line series 1"); lineSeries1.setYSeries(ySeries1); ILineSeries lineSeries2 = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "line series 2"); lineSeries2.setYSeries(ySeries2); lineSeries2.setLineColor(RED); // assign series to second Y axis lineSeries2.setYAxisId(axisId); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/AreaChartExample.java0000644000175000017500000000424011520323141033052 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.ILineSeries; import org.swtchart.ISeries.SeriesType; /** * An example for area chart. */ public class AreaChartExample { private static final double[] ySeries1 = { 0.1, 0.38, 0.71, 0.92, 1.0 }; private static final double[] ySeries2 = { 1.2, 3.53, 3.1, 0.1, 0.5 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Area Chart"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set titles chart.getTitle().setText("Area Chart"); // create line series ILineSeries lineSeries1 = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "line series 1"); lineSeries1.setYSeries(ySeries1); lineSeries1.setLineColor(Display.getDefault().getSystemColor( SWT.COLOR_RED)); lineSeries1.enableArea(true); ILineSeries lineSeries2 = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "line series 2"); lineSeries2.setYSeries(ySeries2); lineSeries2.enableArea(true); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/LargeSeriesExample.java0000644000175000017500000000434111520323141033427 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.ILineSeries; import org.swtchart.ILineSeries.PlotSymbolType; import org.swtchart.ISeries.SeriesType; /** * An example for large series chart. */ public class LargeSeriesExample { /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Large Series"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set titles chart.getTitle().setText("Large Series"); chart.getAxisSet().getXAxis(0).getTitle().setText("Data Points"); chart.getAxisSet().getYAxis(0).getTitle().setText("Amplitude"); // create line series ILineSeries lineSeries = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "line series"); lineSeries.setYSeries(getSeries()); lineSeries.setSymbolType(PlotSymbolType.NONE); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } private static double[] getSeries() { double[] series = new double[1048576]; for (int i = 0; i < series.length; i++) { series[i] = Math.sin(i * 33 * Math.PI / series.length) + Math.sin(i * 15 * Math.PI / series.length); } return series; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/LineChartExample.java0000644000175000017500000000371011520323141033072 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.ILineSeries; import org.swtchart.ISeries.SeriesType; /** * An example for line chart. */ public class LineChartExample { private static final double[] ySeries = { 0.0, 0.38, 0.71, 0.92, 1.0, 0.92, 0.71, 0.38, 0.0, -0.38, -0.71, -0.92, -1.0, -0.92, -0.71, -0.38 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Line Chart"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set titles chart.getTitle().setText("Line Chart"); chart.getAxisSet().getXAxis(0).getTitle().setText("Data Points"); chart.getAxisSet().getYAxis(0).getTitle().setText("Amplitude"); // create line series ILineSeries lineSeries = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "line series"); lineSeries.setYSeries(ySeries); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/CategoryExample.java0000644000175000017500000000467111520323141033005 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.IBarSeries; import org.swtchart.ISeries.SeriesType; /** * An example for chart with category axis. */ public class CategoryExample { private static final double[] ySeries1 = { 1.3, 2.4, 3.9, 2.6, 1.1 }; private static final double[] ySeries2 = { 3.0, 2.1, 1.9, 2.3, 3.2 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Category Axis"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set titles chart.getTitle().setText("Category Axis"); chart.getAxisSet().getXAxis(0).getTitle().setText("Month"); chart.getAxisSet().getYAxis(0).getTitle().setText("Amplitude"); // set category chart.getAxisSet().getXAxis(0).enableCategory(true); chart.getAxisSet().getXAxis(0).setCategorySeries( new String[] { "Jan", "Feb", "Mar", "Apr", "May" }); // create bar series IBarSeries barSeries1 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "bar series 1"); barSeries1.setYSeries(ySeries1); barSeries1.setBarColor(Display.getDefault().getSystemColor( SWT.COLOR_GREEN)); IBarSeries barSeries2 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "bar series 2"); barSeries2.setYSeries(ySeries2); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/ScatterChartExample.java0000644000175000017500000000423311520323141033611 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.ILineSeries; import org.swtchart.LineStyle; import org.swtchart.ISeries.SeriesType; /** * An example for scatter chart. */ public class ScatterChartExample { private static final double[] xSeries = { 0.0, 2.6, 6.5, 4.4, 5.6, 4.3, 3.4, 10.8, 2.1, 8.9 }; private static final double[] ySeries = { 1.3, 0.0, 3.9, 2.6, 1.1, 0.6, 3.1, 3.5, 5.6, 4.4 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Scatter Chart"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); // set titles chart.getTitle().setText("Scatter Chart"); chart.getAxisSet().getXAxis(0).getTitle().setText("Score A"); chart.getAxisSet().getYAxis(0).getTitle().setText("Score B"); // create scatter series ILineSeries scatterSeries = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "scatter series"); scatterSeries.setLineStyle(LineStyle.NONE); scatterSeries.setXSeries(xSeries); scatterSeries.setYSeries(ySeries); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } }././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/AngledAxisTickLabelsExample.javaswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/AngledAxisTickLabelsExample0000644000175000017500000000373711520323141034267 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.ISeries; import org.swtchart.ISeries.SeriesType; /** * An example for angled axis tick labels. */ public class AngledAxisTickLabelsExample { private static final double[] ySeries = { 1.3, 2.4, 3.9, 2.6, 1.1 }; private static final String[] cagetorySeries = { "aaaaaaaaaa", "bb", "ccccccccccc", "dddddddddd", "eeeeeeeee" }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Angled Axis Tick Labels"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); chart.getTitle().setText("Angled Axis Tick Labels"); // set category chart.getAxisSet().getXAxis(0).enableCategory(true); chart.getAxisSet().getXAxis(0).setCategorySeries(cagetorySeries); chart.getAxisSet().getXAxis(0).getTick().setTickLabelAngle(45); // add bar series ISeries barSeries = chart.getSeriesSet().createSeries(SeriesType.BAR, "bar series"); barSeries.setYSeries(ySeries); chart.getAxisSet().adjustRange(); return chart; } }swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/0000755000175000017500000000000013275316672030632 5ustar jsprickejspricke././@LongLink0000644000000000000000000000016200000000000011602 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/CustomPaintListenerExample.javaswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/CustomPaintListene0000644000175000017500000000520311520315566034337 0ustar jsprickejsprickepackage org.swtchart.examples.advanced; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.ICustomPaintListener; import org.swtchart.IPlotArea; import org.swtchart.ISeries; import org.swtchart.ISeries.SeriesType; /** * An example for custom paint listener. */ public class CustomPaintListenerExample { private static final double[] ySeries = { 0.1, 0.38, 0.41, 0.92, 1.0 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Custom Paint Listener"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); chart.getTitle().setText("Custom Paint Listener"); ISeries lineSeries = chart.getSeriesSet().createSeries(SeriesType.LINE, "line series"); lineSeries.setYSeries(ySeries); // add paint listeners IPlotArea plotArea = (IPlotArea) chart.getPlotArea(); plotArea.addCustomPaintListener(new FrontPaintListener()); plotArea.addCustomPaintListener(new BehindPaintListener()); // adjust the axis range chart.getAxisSet().adjustRange(); return chart; } static class FrontPaintListener implements ICustomPaintListener { public void paintControl(PaintEvent e) { e.gc.setBackground(Display.getDefault().getSystemColor( SWT.COLOR_CYAN)); e.gc.fillRectangle(0, e.height / 2, e.width, 20); } public boolean drawBehindSeries() { return false; } } static class BehindPaintListener implements ICustomPaintListener { public void paintControl(PaintEvent e) { e.gc.fillGradientRectangle(e.x, e.y, e.width, e.height, true); } public boolean drawBehindSeries() { return true; } } } ././@LongLink0000644000000000000000000000016400000000000011604 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/PxielToDataConversionExample.javaswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/PxielToDataConvers0000644000175000017500000000503111520315566034262 0ustar jsprickejsprickepackage org.swtchart.examples.advanced; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.ILineSeries; import org.swtchart.ISeries.SeriesType; /** * An example to convert pixel coordinate into data coordinate. */ public class PxielToDataConversionExample { private static final double[] ySeries = { 0.0, 0.38, 0.71, 0.92, 1.0, 0.92, 0.71, 0.38, 0.0, -0.38, -0.71, -0.92, -1.0, -0.92, -0.71, -0.38 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Pxiel To Data Conversion"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart final Chart chart = new Chart(parent, SWT.NONE); chart.getTitle().setText("Pxiel To Data Conversion"); // get axes final IAxis xAxis = chart.getAxisSet().getXAxis(0); final IAxis yAxis = chart.getAxisSet().getYAxis(0); // create line series ILineSeries series = (ILineSeries) chart.getSeriesSet().createSeries( SeriesType.LINE, "line series"); series.setYSeries(ySeries); // adjust the axis range chart.getAxisSet().adjustRange(); // add mouse move listener to show mouse position on tooltip chart.getPlotArea().addMouseMoveListener(new MouseMoveListener() { public void mouseMove(MouseEvent e) { double x = xAxis.getDataCoordinate(e.x); double y = yAxis.getDataCoordinate(e.y); chart.getPlotArea().setToolTipText("x:" + x + ", y:" + y); } }); return chart; } }././@LongLink0000644000000000000000000000015500000000000011604 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/AxisTickBoundsExample.javaswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/AxisTickBoundsExam0000644000175000017500000000615311520315566034257 0ustar jsprickejsprickepackage org.swtchart.examples.advanced; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.IBarSeries; import org.swtchart.IAxis.Direction; import org.swtchart.ISeries.SeriesType; /** * An example to get bounds of axis tick. */ public class AxisTickBoundsExample { private static final double[] ySeries = { 0.1, 0.1, 0.2, 0.2, 0.3 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Axis Tick Bounds"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart final Chart chart = new Chart(parent, SWT.NONE); chart.getTitle().setText("Axis Tick Bounds"); // create bar series IBarSeries series1 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "series"); series1.setYSeries(ySeries); // adjust the axis range chart.getAxisSet().adjustRange(); // add mouse move listener to chart chart.addMouseMoveListener(new MouseMoveListener() { public void mouseMove(MouseEvent e) { for (IAxis axis : chart.getAxisSet().getAxes()) { Rectangle r = axis.getTick().getBounds(); // check if mouse cursor is on axis tick if (r.x < e.x && e.x < r.x + r.width && r.y < e.y && e.y < r.y + r.height) { // get pixel coordinate on axis tick int pixelCoord; if (axis.getDirection() == Direction.X) { pixelCoord = e.x - r.x; } else { pixelCoord = e.y - r.y; } // get data coordinate double dataCoord = axis.getDataCoordinate(pixelCoord); // show tool-tip chart.setToolTipText(String.valueOf(dataCoord)); return; } } chart.setToolTipText(null); } }); return chart; } }././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/LegendBoundsExample.javaswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/LegendBoundsExampl0000644000175000017500000000637411520315566034277 0ustar jsprickejsprickepackage org.swtchart.examples.advanced; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.IBarSeries; import org.swtchart.ISeries; import org.swtchart.ISeries.SeriesType; /** * An example to get bounds of items on legend. */ public class LegendBoundsExample { private static final double[] ySeries1 = { 0.1, 0.1, 0.2, 0.2, 0.3 }; private static final double[] ySeries2 = { 0.5, 0.5, 0.4, 0.3, 0.2 }; private static final double[] ySeries3 = { 0.3, 0.2, 0.3, 0.4, 0.4 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Legend Bounds"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart final Chart chart = new Chart(parent, SWT.NONE); chart.getTitle().setText("Legend Bounds"); // create bar series IBarSeries series1 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "series 1"); series1.setYSeries(ySeries1); series1.setBarColor(Display.getDefault() .getSystemColor(SWT.COLOR_GREEN)); IBarSeries series2 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "series 2"); series2.setYSeries(ySeries2); series2.setBarColor(Display.getDefault().getSystemColor( SWT.COLOR_MAGENTA)); IBarSeries series3 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "series 3"); series3.setYSeries(ySeries3); // adjust the axis range chart.getAxisSet().adjustRange(); // add mouse move listener to legend final Control legend = (Control) chart.getLegend(); legend.addMouseMoveListener(new MouseMoveListener() { public void mouseMove(MouseEvent e) { for (ISeries series : chart.getSeriesSet().getSeries()) { Rectangle r = chart.getLegend().getBounds(series.getId()); if (r.x < e.x && e.x < r.x + r.width && r.y < e.y && e.y < r.y + r.height) { legend.setToolTipText(series.getId()); return; } } } }); return chart; } }././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/SymbolBoundsExample.javaswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/SymbolBoundsExampl0000644000175000017500000000660411520323141034326 0ustar jsprickejsprickepackage org.swtchart.examples.advanced; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.ILineSeries; import org.swtchart.ISeries; import org.swtchart.ISeries.SeriesType; /** * An example to get bounds of series symbol. */ public class SymbolBoundsExample { private static final double[] ySeries1 = { 0.26, 0.25, 0.29, 0.31, 0.32 }; private static final double[] ySeries2 = { 0.32, 0.31, 0.27, 0.28, 0.26 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Symbol Bounds"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart final Chart chart = new Chart(parent, SWT.NONE); chart.getTitle().setText("Symbol Bounds"); // create line series ILineSeries series1 = (ILineSeries) chart.getSeriesSet().createSeries( SeriesType.LINE, "series 1"); series1.setYSeries(ySeries1); ILineSeries series2 = (ILineSeries) chart.getSeriesSet().createSeries( SeriesType.LINE, "series 2"); series2.setYSeries(ySeries2); series2 .setLineColor(Display.getDefault() .getSystemColor(SWT.COLOR_RED)); // adjust the axis range chart.getAxisSet().adjustRange(); // add mouse move listener to open tooltip on data point chart.getPlotArea().addMouseMoveListener(new MouseMoveListener() { public void mouseMove(MouseEvent e) { for (ISeries series : chart.getSeriesSet().getSeries()) { for (int i = 0; i < series.getYSeries().length; i++) { Point p = series.getPixelCoordinates(i); double distance = Math.sqrt(Math.pow(e.x - p.x, 2) + Math.pow(e.y - p.y, 2)); if (distance < ((ILineSeries) series).getSymbolSize()) { setToolTipText(series, i); return; } } } chart.getPlotArea().setToolTipText(null); } private void setToolTipText(ISeries series, int index) { chart.getPlotArea().setToolTipText( "Series: " + series.getId() + "\nValue: " + series.getYSeries()[index]); } }); return chart; } }././@LongLink0000644000000000000000000000016400000000000011604 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/DataToPixelConversionExample.javaswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/DataToPixelConvers0000644000175000017500000000471711520315566034274 0ustar jsprickejsprickepackage org.swtchart.examples.advanced; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.ILineSeries; import org.swtchart.ISeries.SeriesType; /** * An example to convert data coordinate into pixel coordinate. */ public class DataToPixelConversionExample { private static final int MARGIN = 5; private static final double[] ySeries = { 0.0, 0.38, 0.71, 0.92, 1.0, 0.92, 0.71, 0.38, 0.0, -0.38, -0.71, -0.92, -1.0, -0.92, -0.71, -0.38 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Data To Pixel Conversion"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart Chart chart = new Chart(parent, SWT.NONE); chart.getTitle().setText("Data To Pixel Conversion"); // get Y axis final IAxis yAxis = chart.getAxisSet().getYAxis(0); // create line series ILineSeries series = (ILineSeries) chart.getSeriesSet().createSeries( SeriesType.LINE, "line series"); series.setYSeries(ySeries); // adjust the axis range chart.getAxisSet().adjustRange(); // add paint listener to draw threshold chart.getPlotArea().addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { int y = yAxis.getPixelCoordinate(0.65); e.gc.drawLine(0, y, e.width, y); e.gc.drawText("y=0.65", MARGIN, y + MARGIN); } }); return chart; } }././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/BarBoundsExample.javaswt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/BarBoundsExample.j0000644000175000017500000000660611520315566034200 0ustar jsprickejsprickepackage org.swtchart.examples.advanced; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.swtchart.Chart; import org.swtchart.IBarSeries; import org.swtchart.ISeries; import org.swtchart.ISeries.SeriesType; /** * An example to get bounds of bars. */ public class BarBoundsExample { private static final double[] ySeries1 = { 3.0, 2.1, 1.9, 2.3, 3.2 }; private static final double[] ySeries2 = { 2.0, 3.1, 0.9, 1.3, 2.2 }; /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Bar Bounds"); shell.setSize(500, 400); shell.setLayout(new FillLayout()); createChart(shell); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** * create the chart. * * @param parent * The parent composite * @return The created chart */ static public Chart createChart(Composite parent) { // create a chart final Chart chart = new Chart(parent, SWT.NONE); chart.getTitle().setText("Bar Bounds"); // create bar series IBarSeries series1 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "series 1"); series1.setYSeries(ySeries1); IBarSeries series2 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "series 2"); series2.setYSeries(ySeries2); series2.setBarColor(Display.getDefault() .getSystemColor(SWT.COLOR_GREEN)); // adjust the axis range chart.getAxisSet().adjustRange(); // add mouse move listener to open tooltip on data point chart.getPlotArea().addMouseMoveListener(new MouseMoveListener() { public void mouseMove(MouseEvent e) { for (ISeries series : chart.getSeriesSet().getSeries()) { Rectangle[] rs = ((IBarSeries) series).getBounds(); for (int i = 0; i < rs.length; i++) { if (rs[i] != null) { if (rs[i].x < e.x && e.x < rs[i].x + rs[i].width && rs[i].y < e.y && e.y < rs[i].y + rs[i].height) { setToolTipText(series, i); return; } } } } chart.getPlotArea().setToolTipText(null); } private void setToolTipText(ISeries series, int index) { chart.getPlotArea().setToolTipText( "Series: " + series.getId() + "\nValue: " + series.getYSeries()[index]); } }); return chart; } }swt-chart-code-312-trunk/org.swtchart/0000755000175000017500000000000013275316671020214 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart/build.properties0000644000175000017500000000012011031467471023413 0ustar jsprickejsprickesource.. = src/ output.. = bin/ bin.includes = META-INF/,\ . swt-chart-code-312-trunk/org.swtchart/.project0000644000175000017500000000147211031471226021651 0ustar jsprickejspricke org.swtchart org.eclipse.jdt.core.javabuilder org.eclipse.pde.ManifestBuilder org.eclipse.pde.SchemaBuilder org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature swt-chart-code-312-trunk/org.swtchart/.classpath0000644000175000017500000000056611234141567022177 0ustar jsprickejspricke swt-chart-code-312-trunk/org.swtchart/src/0000755000175000017500000000000013275316670021002 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart/src/org/0000755000175000017500000000000013275316670021571 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart/src/org/swtchart/0000755000175000017500000000000013275316671023431 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart/src/org/swtchart/IErrorBar.java0000644000175000017500000000664212657165716026140 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.eclipse.swt.graphics.Color; /** * An error bar. */ public interface IErrorBar { /** * The error bar type. */ public enum ErrorBarType { /** the error bar in both positive and negative directions */ BOTH("Both"), /** the error bar in positive direction */ PLUS("Plus"), /** the error bar in negative direction */ MINUS("Minus"); /** the label for error bar type */ public final String label; /** * The constructor. * * @param label * error bar type label */ private ErrorBarType(String label) { this.label = label; } } /** * Gets the error type. * * @return the error type */ ErrorBarType getType(); /** * Sets the error type. * * @param type * the error type */ void setType(ErrorBarType type); /** * Gets the error bar color. The default color is dark gray. * * @return the error bar color */ Color getColor(); /** * Sets the error bar color. If null is given, default color will * be set. * * @param color * the error bar color */ void setColor(Color color); /** * Gets the line width to draw error bar. * * @return the line width to draw error bar */ int getLineWidth(); /** * Sets the line width to draw error bar. The default line width is 1. * * @param width * line width to draw error bar */ void setLineWidth(int width); /** * Gets the error. * * @return the error */ double getError(); /** * Sets the error. *

* If errors have been set with {@link #getPlusErrors()} or * {@link #getMinusErrors()}, the value set with this method won't be used. * * @param error * the error */ void setError(double error); /** * Gets the plus errors. * * @return the plus errors, or empty array if errors are not set. */ double[] getPlusErrors(); /** * Sets the plus errors. * * @param errors * the plus errors */ void setPlusErrors(double[] errors); /** * Gets the minus errors. * * @return the minus errors, or empty array if errors are not set. */ double[] getMinusErrors(); /** * Sets the minus errors. * * @param errors * the minus errors */ void setMinusErrors(double[] errors); /** * Sets the visibility state. * * @param visible * the visibility state */ void setVisible(boolean visible); /** * Gets the visibility state. * * @return true if error bar is visible */ boolean isVisible(); } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/ISeriesLabel.java0000644000175000017500000000461512657165716026612 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; /** * A series label. */ public interface ISeriesLabel { /** * Sets the decimal format {@link java.text.DecimalFormat} or/plus plain string. *

* If formats have been set with setFormats(String[]), the format * set with this method will be ignored. *

* If null is given, default format "#.###########" will be set. * * @param format * the format */ void setFormat(String format); /** * Gets the format for label. * * @return the format */ String getFormat(); /** * Sets the formats for all data points. If null or empty array is given, formats will * be cleared, and the format set with setFormat(String) will be used * instead. * * @param formats * the formats */ void setFormats(String[] formats); /** * Gets the formats for all data points. * * @return the formats, or empty array if not set */ String[] getFormats(); /** * Sets the label color. If null is given, default color will be set. * * @param color * the label color */ void setForeground(Color color); /** * Gets the label color. * * @return the label color */ Color getForeground(); /** * Sets the label font. * * @param font * the label font */ void setFont(Font font); /** * Gets the label font. * * @return the label font */ Font getFont(); /** * Sets the label visibility state. * * @param visible * the label visibility state */ void setVisible(boolean visible); /** * Gets the label visibility state. * * @return true if label is visible */ boolean isVisible(); } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/IAxisTick.java0000644000175000017500000000671412657165716026141 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import java.text.Format; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Rectangle; /** * An axis tick. */ public interface IAxisTick { /** the minimum grid step hint */ public static final double MIN_GRID_STEP_HINT = 16; /** * Sets the foreground color of axis tick. * * @param color * the foreground color of axis tick */ public void setForeground(Color color); /** * Gets the foreground color of axis tick. * * @return the foreground color of axis tick */ public Color getForeground(); /** * Sets the font for tick labels. * * @param font * the font for tick labels */ public void setFont(Font font); /** * Gets the font for tick labels. * * @return the font for tick labels */ Font getFont(); /** * Gets the state indicating if tick marks are visible. * * @return true if tick marks are visible */ boolean isVisible(); /** * Sets the state indicating if tick marks are visible. * * @param isVisible * true to make the tick marks visible */ void setVisible(boolean isVisible); /** * Gets the tick mark step hint in pixels. * * @return the tick mark step hint in pixels */ int getTickMarkStepHint(); /** * Sets the tick mark step hint in pixels. * * @param tickMarkStepHint * the tick mark step hint with pixels (> * IAxisTick.MIN_GRID_STEP_HINT) */ void setTickMarkStepHint(int tickMarkStepHint); /** * Gets the tick label angle. * * @return the tick label angle in degree */ int getTickLabelAngle(); /** * Sets the tick label angle. * * @param angle * the angle in degree between 0 and 90. The default value is 0. * If setting 0, tick labels are horizontally shown. If setting * 90, tick labels are vertically shown. */ void setTickLabelAngle(int angle); /** * Sets the format for axis tick label. DecimalFormat and * DateFormat should be used for double[] series and * Date[] series respectively. * * @param format * the format */ void setFormat(Format format); /** * Gets the format for axis tick label. * * @return the format */ Format getFormat(); /** * Gets the bounds of axis tick. *

* This method is typically used for mouse listener to check whether mouse * cursor is on axis tick. Mouse listener can be added to Chart. * * @return the bounds of axis tick. */ Rectangle getBounds(); /** * Gets the tick label values. * * @return the tick label values */ double[] getTickLabelValues(); } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/ICustomPaintListener.java0000644000175000017500000000133012657165716030363 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.eclipse.swt.events.PaintListener; /** * The paint listener to paint on plot area. */ public interface ICustomPaintListener extends PaintListener { /** * Gets the state indicating if painting behind series. * * @return True if painting behind series */ boolean drawBehindSeries(); } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/IAxis.java0000644000175000017500000001302612657165716025320 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; /** * An axis which is composed of title and tick. Grid is associated with axis. */ public interface IAxis { /** An axis direction */ public enum Direction { /** the constant to represent X axis */ X, /** the constant to represent Y axis */ Y } /** An axis position */ public enum Position { /** bottom or left side of chart */ Primary, /** top or right side of chart */ Secondary } /** * Gets the axis id. *

* An axis id is automatically assigned when axis is created. * * @return the axis id */ int getId(); /** * Gets the axis direction. *

* The axis direction is set when axis is created, and won't be changed. * * @return the axis direction */ Direction getDirection(); /** * Gets the axis position. * * @return the axis position */ Position getPosition(); /** * Sets the axis position. * * @param position * the axis position */ void setPosition(Position position); /** * Sets the axis range. * * @param range * the axis range */ void setRange(Range range); /** * Gets the axis range. * * @return the axis range */ Range getRange(); /** * Gets the axis title. * * @return the axis title */ ITitle getTitle(); /** * Gets the axis tick. * * @return the axis tick */ IAxisTick getTick(); /** * Enables the log scale. If enabling log scale, stacking trace and category * axis will be disabled. * * @param enabled * true if enabling log scales * @throws IllegalStateException * if minimum value of series belonging to this axis is less * than zero. */ void enableLogScale(boolean enabled) throws IllegalStateException; /** * Gets the state indicating if log scale is enabled. * * @return true if log scale is enabled */ boolean isLogScaleEnabled(); /** * Gets the grid. The gird interval is identical with the position of axis * tick marks. The horizontal grid is accessible from vertical axis, and the * vertical grid is accessible from horizontal axis. * * @return grid the grid */ IGrid getGrid(); /** * Adjusts the axis range to the series belonging to the axis, so that all * series are completely shown. */ void adjustRange(); /** * Zooms in the axis. */ void zoomIn(); /** * Zooms in the axis at the given coordinate. * * @param coordinate * the coordinate */ void zoomIn(double coordinate); /** * Zooms out the axis. */ void zoomOut(); /** * Zooms out the axis at the given coordinate. * * @param coordinate * the coordinate */ void zoomOut(double coordinate); /** * Scrolls up the axis. */ void scrollUp(); /** * Scrolls up the axis. */ void scrollDown(); /** * Enables category. Category is applicable only for X axis. If enabling * category, log scale will be disabled. If category series are not yet set, * category won't be enabled. * * @param enabled * true if enabling category */ void enableCategory(boolean enabled); /** * Gets the state indicating if category is enabled. * * @return true if category is enabled */ boolean isCategoryEnabled(); /** * Sets the category series. In order to enable category series, * enableCategoryAxis(true) has to be invoked. * * @param series * the category series */ void setCategorySeries(String[] series); /** * Gets the category series. If the category series haven't been set yet, * null will be returned. * * @return the category series */ String[] getCategorySeries(); /** * Gets the pixel coordinate corresponding to the given data coordinate. * * @param dataCoordinate * the data coordinate * @return the pixel coordinate on plot area */ int getPixelCoordinate(double dataCoordinate); /** * Gets the data coordinate corresponding to the given pixel coordinate on * plot area. * * @param pixelCoordinate * the pixel coordinate on plot area * @return the data coordinate */ double getDataCoordinate(int pixelCoordinate); /** * Adds the dispose listener. The newly created color or font for axis can * be disposed with the dispose listener when they are no longer needed. * * @param listener * the dispose listener */ void addDisposeListener(IDisposeListener listener); }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/ILegend.java0000644000175000017500000000574612657165716025624 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Rectangle; /** * A legend for chart. */ public interface ILegend { /** * Sets legend visible. * * @param visible * the visibility state */ void setVisible(boolean visible); /** * Gets the visibility state. * * @return true if legend is visible */ boolean isVisible(); /** * Sets the background color of legend. * * @param color * the background color */ void setBackground(Color color); /** * Gets the background color of legend. * * @return background color of legend. */ Color getBackground(); /** * Sets the foreground color of legend. * * @param color * the foreground color */ void setForeground(Color color); /** * Gets the foreground color of legend. * * @return foreground color of legend. */ Color getForeground(); /** * Gets the font. * * @return the font */ Font getFont(); /** * Sets the font. * * @param font * the font */ void setFont(Font font); /** * Gets the position of legend. * * @return the position of legend. */ int getPosition(); /** * Sets the position of legend. If the position is SWT.LEFT or * SWT.RIGHT, the orientation of series on legend will be vertical. * If the position is SWT.TOP or SWT.BOTTOM, the * orientation will be horizontal. * * @param position * the position of legend that can be SWT.LEFT, * SWT.RIGHT, SWT.TOP or SWT.BOTTOM. */ void setPosition(int position); /** * Gets the rectangle associated with the given series id on legend. This * method is typically used for mouse listener to check whether mouse cursor * is on legend for a certain series. *

* Mouse listener can be added by casting ILegend to * Control. * *

     * Control legend = (Control) chart.getLegend();
     * legend.addMouseListener(...);
     * 
* * @param seriesId * the series id * @return the rectangle associated with the given series id in pixels. */ Rectangle getBounds(String seriesId); }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/IAxisSet.java0000644000175000017500000000600312657165716025771 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; /** * An axis container. By default, axis set has X Axis and Y axis with axis id 0. */ public interface IAxisSet { /** * Creates the X axis. This method is used for multiple axes chart. * * @return the axis id */ int createXAxis(); /** * Creates the Y axis. This method is used for multiple axes chart. * * @return the axis id */ int createYAxis(); /** * Gets the X axis for the given id. * * @param id * the axis id * @return the X axis for the given axis id, or null if there is no * corresponding axis. */ IAxis getXAxis(int id); /** * Gets the Y axis for given index. * * @param id * the axis id * @return the Y axis for the given axis id, or null if there is no * corresponding axis. */ IAxis getYAxis(int id); /** * Gets the array of X axes. * * @return the array of X axes */ IAxis[] getXAxes(); /** * Gets the array of Y axes. * * @return the array of Y axes */ IAxis[] getYAxes(); /** * Gets the array of all axes. * * @return the array of all axes */ IAxis[] getAxes(); /** * Gets the array of X axis ids. * * @return the array of X axis ids */ int[] getXAxisIds(); /** * Gets the array of Y axis ids. * * @return the array of Y axis ids */ int[] getYAxisIds(); /** * Deletes the X Axis for given axis id. The series on the deleted axis will * be moved onto the axis id '0'. The axis whose id is '0' cannot be * removed. * * @param id * the axis id * @throws IllegalArgumentException * if the given axis id is '0', or if there is no axis for the * given id. */ void deleteXAxis(int id); /** * Deletes the Y Axis for given id. The series on the deleted axis will be * moved onto the axis id '0'. The axis whose id is '0' cannot be removed. * * @param id * the axis id * @throws IllegalArgumentException * if the given axis id is '0', or if there is no axis for the * given id. */ void deleteYAxis(int id); /** * Adjusts the axis range of all axes. */ void adjustRange(); /** * Zooms in all axes. */ void zoomIn(); /** * Zooms out all axes. */ void zoomOut(); }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/ITitle.java0000644000175000017500000000460412657165716025477 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; /** * A title. */ public interface ITitle { /** * Sets the title text. * * @param title * the title text */ public void setText(String title); /** * Gets the title text. * * @return the title text */ public String getText(); /** * Sets the font for title text. * * @param font * the font for title text */ public void setFont(Font font); /** * Gets the font for title text. * * @return the font size for title text */ public Font getFont(); /** * Sets the foreground color of title. * * @param color * the foreground color of title */ public void setForeground(Color color); /** * Gets the foreground color of title. * * @return the foreground color of title */ public Color getForeground(); /** * Sets the style ranges. When style ranges are set, the font and background * color set by {@link #setFont(Font)} and {@link #setForeground(Color)} * makes no effect. Instead, the font and background color in style ranges * are used. * * @param styleRanges * the style ranges, or null to clear the currently set * style ranges. */ public void setStyleRanges(StyleRange[] styleRanges); /** * Gets the style ranges. * * @return the style ranges */ public StyleRange[] getStyleRanges(); /** * Sets the visibility state of title. * * @param visible * the visibility state */ void setVisible(boolean visible); /** * Gets the visibility state. * * @return true if title is visible */ boolean isVisible(); }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/0000755000175000017500000000000013275316671025245 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/Legend.java0000644000175000017500000003521112657165716027315 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.swtchart.Chart; import org.swtchart.Constants; import org.swtchart.IBarSeries; import org.swtchart.ILegend; import org.swtchart.ILineSeries; import org.swtchart.ISeries; import org.swtchart.internal.series.LineSeries; import org.swtchart.internal.series.Series; /** * A legend for chart. */ public class Legend extends Composite implements ILegend, PaintListener { /** the plot chart */ private Chart chart; /** the state indicating the legend visibility */ private boolean visible; /** the position of legend */ private int position; /** the margin */ private static final int MARGIN = 5; /** the width of area to draw symbol */ private static final int SYMBOL_WIDTH = 20; /** the line width */ private static final int LINE_WIDTH = 2; /** the default foreground */ private static final Color DEFAULT_FOREGROUND = Display.getDefault() .getSystemColor(SWT.COLOR_BLACK); /** the default background */ private static final Color DEFAULT_BACKGROUND = Display.getDefault() .getSystemColor(SWT.COLOR_WHITE); /** the default font */ private Font defaultFont; /** the default font size */ private static final int DEFAULT_FONT_SIZE = Constants.SMALL_FONT_SIZE; /** the default position */ private static final int DEFAULT_POSITION = SWT.RIGHT; /** the map between series id and cell bounds */ private Map cellBounds; /** * Constructor. * * @param chart * the chart * @param style * the style */ public Legend(Chart chart, int style) { super(chart, style | SWT.DOUBLE_BUFFERED); this.chart = chart; visible = true; position = DEFAULT_POSITION; cellBounds = new HashMap(); defaultFont = new Font(Display.getDefault(), "Tahoma", DEFAULT_FONT_SIZE, SWT.NORMAL); setFont(defaultFont); setForeground(DEFAULT_FOREGROUND); setBackground(DEFAULT_BACKGROUND); addPaintListener(this); } /* * @see Control#setVisible(boolean) */ @Override public void setVisible(boolean visible) { if (this.visible == visible) { return; } this.visible = visible; chart.updateLayout(); } /* * @see Control#isVisible() */ @Override public boolean isVisible() { return visible; } /* * @see Canvas#setFont(Font) */ @Override public void setFont(Font font) { if (font == null) { super.setFont(defaultFont); } else { super.setFont(font); } chart.updateLayout(); } /* * @see Control#setForeground(Color) */ @Override public void setForeground(Color color) { if (color == null) { super.setForeground(DEFAULT_FOREGROUND); } else { super.setForeground(color); } } /* * @see Control#setBackground(Color) */ @Override public void setBackground(Color color) { if (color == null) { super.setBackground(DEFAULT_BACKGROUND); } else { super.setBackground(color); } } /* * @see ILegend#getPosition() */ public int getPosition() { return position; } /* * @see ILegend#setPosition(int) */ public void setPosition(int value) { if (value == SWT.LEFT || value == SWT.RIGHT || value == SWT.TOP || value == SWT.BOTTOM) { position = value; } else { position = DEFAULT_POSITION; } chart.updateLayout(); } /* * @see ILegend#getBounds(String) */ public Rectangle getBounds(String seriesId) { if (seriesId == null) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } return cellBounds.get(seriesId.trim()); } /* * @see Widget#dispose() */ @Override public void dispose() { super.dispose(); if (!defaultFont.isDisposed()) { defaultFont.dispose(); } } /** * Sorts the given series array. For instance, if there are two stack series * in horizontal orientation, the top of stack series should appear at top * of legend. *

* If there are multiple x axes, the given series array will be sorted with * x axis first. And then, the series in each x axis will be sorted with * {@link Legend#sort(List, boolean, boolean)}. * * @param seriesArray * the series array * @return the sorted series array */ private ISeries[] sort(ISeries[] seriesArray) { // create a map between axis id and series list Map> map = new HashMap>(); for (ISeries series : seriesArray) { int axisId = series.getXAxisId(); List list = map.get(axisId); if (list == null) { list = new ArrayList(); } list.add(series); map.put(axisId, list); } // sort an each series list List sortedArray = new ArrayList(); boolean isVertical = chart.getOrientation() == SWT.VERTICAL; for (Entry> entry : map.entrySet()) { boolean isCategoryEnabled = chart.getAxisSet() .getXAxis(entry.getKey()).isCategoryEnabled(); sortedArray.addAll(sort(entry.getValue(), isCategoryEnabled, isVertical)); } return sortedArray.toArray(new ISeries[sortedArray.size()]); } /** * Sorts the given series list which belongs to a certain x axis. *

    *
  • The stacked series will be gathered, and the order of stack series * will be reversed.
  • *
  • In the case of vertical orientation, the order of whole series will * be reversed.
  • *
* * @param seriesList * the series list which belongs to a certain x axis * @param isCategoryEnabled * true if category is enabled * @param isVertical * true in the case of vertical orientation * @return the sorted series array */ private static List sort(List seriesList, boolean isCategoryEnabled, boolean isVertical) { List sortedArray = new ArrayList(); // gather the stacked series reversing the order of stack series int insertIndex = -1; for (int i = 0; i < seriesList.size(); i++) { if (isCategoryEnabled && ((Series) seriesList.get(i)).isValidStackSeries()) { if (insertIndex == -1) { insertIndex = i; } else { sortedArray.add(insertIndex, seriesList.get(i)); continue; } } sortedArray.add(seriesList.get(i)); } // reverse the order of whole series in the case of vertical orientation if (isVertical) { Collections.reverse(sortedArray); } return sortedArray; } /** * Update the layout data. */ public void updateLayoutData() { if (!visible) { setLayoutData(new ChartLayoutData(0, 0)); return; } int width = 0; int height = 0; ISeries[] seriesArray = sort(chart.getSeriesSet().getSeries()); Rectangle r = chart.getClientArea(); Rectangle titleBounds = ((Title) chart.getTitle()).getBounds(); int titleHeight = titleBounds.y + titleBounds.height; int cellHeight = Util.getExtentInGC(getFont(), null).y; if (position == SWT.RIGHT || position == SWT.LEFT) { int columns = 1; int yPosition = MARGIN; int maxCellWidth = 0; for (ISeries series : seriesArray) { if (!series.isVisibleInLegend()) { continue; } String label = getLegendLabel(series); int textWidth = Util.getExtentInGC(getFont(), label).x; int cellWidth = textWidth + SYMBOL_WIDTH + MARGIN * 3; maxCellWidth = Math.max(maxCellWidth, cellWidth); if (yPosition + cellHeight < r.height - titleHeight - MARGIN || yPosition == MARGIN) { yPosition += cellHeight + MARGIN; } else { columns++; yPosition = cellHeight + MARGIN * 2; } cellBounds.put(series.getId(), new Rectangle(maxCellWidth * (columns - 1), yPosition - cellHeight - MARGIN, cellWidth, cellHeight)); height = Math.max(yPosition, height); } width = maxCellWidth * columns; } else if (position == SWT.TOP || position == SWT.BOTTOM) { int rows = 1; int xPosition = 0; for (ISeries series : seriesArray) { if (!series.isVisibleInLegend()) { continue; } String label = getLegendLabel(series); int textWidth = Util.getExtentInGC(getFont(), label).x; int cellWidth = textWidth + SYMBOL_WIDTH + MARGIN * 3; if (xPosition + cellWidth < r.width || xPosition == 0) { xPosition += cellWidth; } else { rows++; xPosition = cellWidth; } cellBounds.put(series.getId(), new Rectangle(xPosition - cellWidth, (cellHeight + MARGIN) * (rows - 1) + MARGIN, cellWidth, cellHeight)); width = Math.max(xPosition, width); } height = (cellHeight + MARGIN) * rows + MARGIN; } setLayoutData(new ChartLayoutData(width, height)); } /** * Gets the legend label. * * @param series * the series * @return the legend label */ private static String getLegendLabel(ISeries series) { String description = series.getDescription(); if (description == null) { return series.getId(); } return description; } /** * Draws the symbol of series. * * @param gc * the graphics context * @param series * the series * @param r * the rectangle to draw the symbol of series */ protected void drawSymbol(GC gc, Series series, Rectangle r) { if (!visible) { return; } if (series instanceof ILineSeries) { // draw plot line gc.setForeground(((ILineSeries) series).getLineColor()); gc.setLineWidth(LINE_WIDTH); int lineStyle = Util.getIndexDefinedInSWT(((ILineSeries) series) .getLineStyle()); int x = r.x; int y = r.y + r.height / 2; if (lineStyle != SWT.NONE) { gc.setLineStyle(lineStyle); gc.drawLine(x, y, x + SYMBOL_WIDTH, y); } // draw series symbol Color color = ((ILineSeries) series).getSymbolColor(); Color[] colors = ((ILineSeries) series).getSymbolColors(); if (colors != null && colors.length > 0) { color = colors[0]; } ((LineSeries) series).drawSeriesSymbol(gc, x + SYMBOL_WIDTH / 2, y, color); } else if (series instanceof IBarSeries) { // draw riser gc.setBackground(((IBarSeries) series).getBarColor()); int size = SYMBOL_WIDTH / 2; int x = r.x + size / 2; int y = (int) (r.y - size / 2d + r.height / 2d); gc.fillRectangle(x, y, size, size); } } /* * @see PaintListener#paintControl(PaintEvent) */ public void paintControl(PaintEvent e) { if (!visible) { return; } GC gc = e.gc; gc.setFont(getFont()); ISeries[] seriesArray = chart.getSeriesSet().getSeries(); if (seriesArray.length == 0) { return; } // draw frame gc.fillRectangle(0, 0, getSize().x - 1, getSize().y - 1); gc.setLineStyle(SWT.LINE_SOLID); gc.setLineWidth(1); gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY)); gc.drawRectangle(0, 0, getSize().x - 1, getSize().y - 1); // draw content for (int i = 0; i < seriesArray.length; i++) { if (!seriesArray[i].isVisibleInLegend()) { continue; } // draw plot line, symbol etc String id = seriesArray[i].getId(); Rectangle r = cellBounds.get(id); drawSymbol(gc, (Series) seriesArray[i], new Rectangle(r.x + MARGIN, r.y + MARGIN, SYMBOL_WIDTH, r.height - MARGIN * 2)); // draw label String label = getLegendLabel(seriesArray[i]); gc.setBackground(getBackground()); gc.setForeground(getForeground()); gc.drawText(label, r.x + SYMBOL_WIDTH + MARGIN * 2, r.y, true); } } }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/axis/0000755000175000017500000000000013275316671026211 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/axis/AxisTickLabels.java0000644000175000017500000010127312657165716031727 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.axis; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.Format; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.Transform; import org.eclipse.swt.widgets.Display; import org.swtchart.Chart; import org.swtchart.IAxis.Position; import org.swtchart.internal.ChartLayoutData; import org.swtchart.internal.Util; /** * Axis tick labels. */ public class AxisTickLabels implements PaintListener { /** the chart */ private final Chart chart; /** the axis */ private final Axis axis; /** the foreground color */ private Color foreground; /** the width hint of tick labels area */ private int widthHint; /** the height hint of tick labels area */ private int heightHint; /** the bounds of tick labels area */ private Rectangle bounds; /** the array of tick label vales */ private final ArrayList tickLabelValues; /** the array of tick label */ private final ArrayList tickLabels; /** the array of tick label position in pixels */ private final ArrayList tickLabelPositions; /** the array of visibility state of tick label */ private final ArrayList tickVisibilities; /** the format for tick labels */ private Format format; /** the default foreground */ private static final int DEFAULT_FOREGROUND = SWT.COLOR_BLUE; /** the default font */ private static final Font DEFAULT_FONT = Display.getDefault() .getSystemFont(); /** the default label format */ private static final String DEFAULT_DECIMAL_FORMAT = "#.###########"; /** the possible tick steps */ private Map possibleTickSteps; /** the time unit for tick step */ private int timeUnit; /** the font */ private Font font; /** * Constructor. * * @param chart * the chart * @param axis * the axis */ protected AxisTickLabels(Chart chart, Axis axis) { this.chart = chart; this.axis = axis; tickLabelValues = new ArrayList(); tickLabels = new ArrayList(); tickLabelPositions = new ArrayList(); tickVisibilities = new ArrayList(); initializePossibleTickSteps(); font = DEFAULT_FONT; foreground = Display.getDefault().getSystemColor(DEFAULT_FOREGROUND); chart.addPaintListener(this); } /** * Initialized the possible tick steps. */ private void initializePossibleTickSteps() { final Integer[] milliseconds = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 999 }; final Integer[] seconds = { 1, 2, 5, 10, 15, 20, 30, 59 }; final Integer[] minutes = { 1, 2, 3, 5, 10, 15, 20, 30, 59 }; final Integer[] hours = { 1, 2, 3, 4, 6, 12, 22 }; final Integer[] dates = { 1, 7, 14, 28 }; final Integer[] months = { 1, 2, 3, 4, 6, 11 }; final Integer[] years = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 }; possibleTickSteps = new HashMap(); possibleTickSteps.put(Calendar.MILLISECOND, milliseconds); possibleTickSteps.put(Calendar.SECOND, seconds); possibleTickSteps.put(Calendar.MINUTE, minutes); possibleTickSteps.put(Calendar.HOUR_OF_DAY, hours); possibleTickSteps.put(Calendar.DATE, dates); possibleTickSteps.put(Calendar.MONTH, months); possibleTickSteps.put(Calendar.YEAR, years); } /** * Sets the foreground color. * * @param color * the foreground color */ public void setForeground(Color color) { if (color == null) { foreground = Display.getDefault() .getSystemColor(DEFAULT_FOREGROUND); } else { foreground = color; } } /** * Gets the foreground color. * * @return the foreground color */ protected Color getForeground() { if (foreground.isDisposed()) { foreground = Display.getDefault() .getSystemColor(DEFAULT_FOREGROUND); } return foreground; } /** * Updates the tick labels. * * @param length * the axis length */ protected void update(int length) { tickLabelValues.clear(); tickLabels.clear(); tickLabelPositions.clear(); if (axis.isValidCategoryAxis()) { updateTickLabelForCategoryAxis(length); } else if (axis.isLogScaleEnabled()) { updateTickLabelForLogScale(length); } else if (axis.isDateEnabled()) { updateTickLabelForDateAxis(length); } else { updateTickLabelForLinearScale(length); } updateTickVisibility(); } /** * Updates tick label for date axis. * * @param length * the length of axis */ private void updateTickLabelForDateAxis(int length) { double min = axis.getRange().lower; double max = axis.getRange().upper; double gridStepHint = Math.abs(max - min) / length * axis.getTick().getTickMarkStepHint(); timeUnit = getTimeUnit(gridStepHint); if (timeUnit == Calendar.MILLISECOND || timeUnit == Calendar.SECOND || timeUnit == Calendar.MINUTE || timeUnit == Calendar.HOUR_OF_DAY || timeUnit == Calendar.DATE) { Integer[] steps = possibleTickSteps.get(timeUnit); for (int i = 0; i < steps.length - 1; i++) { if (gridStepHint < (getPeriodInMillis(timeUnit, steps[i]) + getPeriodInMillis( timeUnit, steps[i + 1])) / 2d) { BigDecimal gridStep = BigDecimal.valueOf(getPeriodInMillis( timeUnit, steps[i])); updateTickLabelForLinearScale(length, gridStep); break; } } } else if (timeUnit == Calendar.MONTH || timeUnit == Calendar.YEAR) { updateTickLabelForMonthOrYear(length, gridStepHint, timeUnit); } } /** * Updates the tick label for month or year. The month and year are handled * differently from other units of time, since 1 month and 1 year can be * different depending on which time to start counting. * * @param length * the length of axis * @param gridStepHint * the grid step hint * @param tickStepUnit * the tick step unit of time */ private void updateTickLabelForMonthOrYear(int length, double gridStepHint, int tickStepUnit) { double min = axis.getRange().lower; double max = axis.getRange().upper; // get initial position Calendar cal = Calendar.getInstance(); cal.setTime(new Date((long) min)); int month = cal.get(Calendar.MONTH); int year = cal.get(Calendar.YEAR); if (tickStepUnit == Calendar.MONTH) { if (month == Calendar.DECEMBER) { year++; month = Calendar.JANUARY; } else { month++; } } else if (tickStepUnit == Calendar.YEAR) { month = Calendar.JANUARY; year++; } // get tick step Integer[] steps = possibleTickSteps.get(tickStepUnit); int step = steps[steps.length - 1]; for (int i = 0; i < steps.length - 1; i++) { if (gridStepHint < (getPeriodInMillis(tickStepUnit, steps[i]) + getPeriodInMillis( tickStepUnit, steps[i + 1])) / 2d) { step = steps[i]; break; } } // set tick labels cal.clear(); cal.set(year, month, 1); while (cal.getTimeInMillis() < max) { tickLabelValues.add(Double.valueOf(cal.getTimeInMillis())); tickLabels.add(format(cal.getTimeInMillis())); int tickLabelPosition = (int) ((cal.getTimeInMillis() - min) / (max - min) * length); tickLabelPositions.add(tickLabelPosition); if (tickStepUnit == Calendar.MONTH) { month += step; if (month + step > Calendar.DECEMBER) { year++; month -= Calendar.DECEMBER + 1; } } else if (tickStepUnit == Calendar.YEAR) { year += step; } cal.clear(); cal.set(year, month, 1); } } /** * Updates tick label for category axis. * * @param length * the length of axis */ private void updateTickLabelForCategoryAxis(int length) { String[] series = axis.getCategorySeries(); if (series == null) { return; } int min = (int) axis.getRange().lower; int max = (int) axis.getRange().upper; int sizeOfTickLabels = (series.length < max - min + 1) ? series.length : max - min + 1; int initialIndex = (min < 0) ? 0 : min; for (int i = 0; i < sizeOfTickLabels; i++) { tickLabels.add(series[i + initialIndex]); int tickLabelPosition = (int) (length * (i + 0.5) / sizeOfTickLabels); tickLabelPositions.add(tickLabelPosition); } } /** * Updates tick label for log scale. * * @param length * the length of axis */ private void updateTickLabelForLogScale(int length) { double min = axis.getRange().lower; double max = axis.getRange().upper; int digitMin = (int) Math.ceil(Math.log10(min)); int digitMax = (int) Math.ceil(Math.log10(max)); final BigDecimal MIN = BigDecimal.valueOf(min); BigDecimal tickStep = pow(10, digitMin - 1); BigDecimal firstPosition; if (MIN.remainder(tickStep).doubleValue() <= 0) { firstPosition = MIN.subtract(MIN.remainder(tickStep)); } else { firstPosition = MIN.subtract(MIN.remainder(tickStep)).add(tickStep); } for (int i = digitMin; i <= digitMax; i++) { for (BigDecimal j = firstPosition; j.doubleValue() <= pow(10, i) .doubleValue(); j = j.add(tickStep)) { if (j.doubleValue() > max) { break; } if (axis.isDateEnabled()) { Date date = new Date((long) j.doubleValue()); tickLabels.add(format(date)); } else { tickLabels.add(format(j.doubleValue())); } tickLabelValues.add(j.doubleValue()); int tickLabelPosition = (int) ((Math.log10(j.doubleValue()) - Math .log10(min)) / (Math.log10(max) - Math.log10(min)) * length); tickLabelPositions.add(tickLabelPosition); } tickStep = tickStep.multiply(pow(10, 1)); firstPosition = tickStep.add(pow(10, i)); } } /** * Updates tick label for normal scale. * * @param length * axis length (>0) */ private void updateTickLabelForLinearScale(int length) { double min = axis.getRange().lower; double max = axis.getRange().upper; updateTickLabelForLinearScale(length, getGridStep(length, min, max)); } /** * Updates tick label for normal scale. * * @param length * axis length (>0) * @param tickStep * the tick step */ private void updateTickLabelForLinearScale(int length, BigDecimal tickStep) { double min = axis.getRange().lower; double max = axis.getRange().upper; final BigDecimal MIN = BigDecimal.valueOf(min); BigDecimal firstPosition; /* if (min % tickStep <= 0) */ if (MIN.remainder(tickStep).doubleValue() <= 0) { /* firstPosition = min - min % tickStep */ firstPosition = MIN.subtract(MIN.remainder(tickStep)); } else { /* firstPosition = min - min % tickStep + tickStep */ firstPosition = MIN.subtract(MIN.remainder(tickStep)).add(tickStep); } // the unit time starts from 1:00 if (axis.isDateEnabled()) { BigDecimal zeroOclock = firstPosition.subtract(BigDecimal .valueOf(3600000)); if (MIN.compareTo(zeroOclock) == -1) { firstPosition = zeroOclock; } } for (BigDecimal b = firstPosition; b.doubleValue() <= max; b = b .add(tickStep)) { if (axis.isDateEnabled()) { Date date = new Date((long) b.doubleValue()); tickLabels.add(format(date)); } else { tickLabels.add(format(b.doubleValue())); } tickLabelValues.add(b.doubleValue()); int tickLabelPosition = (int) ((b.doubleValue() - min) / (max - min) * length); tickLabelPositions.add(tickLabelPosition); } } /** * Updates the visibility of tick labels. */ private void updateTickVisibility() { // initialize the array of tick label visibility state tickVisibilities.clear(); for (int i = 0; i < tickLabelPositions.size(); i++) { tickVisibilities.add(Boolean.TRUE); } if (tickLabelPositions.size() == 0 || axis.getTick().getTickLabelAngle() != 0) { return; } // set the tick label visibility int previousPosition = 0; for (int i = 0; i < tickLabelPositions.size(); i++) { // check if there is enough space to draw tick label boolean hasSpaceToDraw = true; if (i != 0) { hasSpaceToDraw = hasSpaceToDraw(previousPosition, tickLabelPositions.get(i), tickLabels.get(i)); } // check if the tick label value is major boolean isMajorTick = true; if (!axis.isValidCategoryAxis()) { if (axis.isLogScaleEnabled()) { isMajorTick = isMajorTick(tickLabelValues.get(i)); } // check if the same tick label is repeated String currentLabel = tickLabels.get(i); try { double value = Double.parseDouble(currentLabel); if (value != tickLabelValues.get(i)) { isMajorTick = false; } } catch (NumberFormatException e) { // label is not decimal value but string } } if (hasSpaceToDraw && isMajorTick) { previousPosition = tickLabelPositions.get(i); } else { tickVisibilities.set(i, Boolean.FALSE); } } } /** * Gets the tick step unit. * * @param gridStepHint * the grid step hint * @return the tick step unit. */ private int getTimeUnit(double gridStepHint) { final Integer[] units = { Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DATE, Calendar.MONTH, Calendar.YEAR }; for (Integer unit : units) { Integer[] steps = possibleTickSteps.get(unit); if (gridStepHint < (getPeriodInMillis(unit, steps[steps.length - 2]) + getPeriodInMillis( unit, steps[steps.length - 1])) / 2d) { return unit; } } return Calendar.YEAR; } /** * Gets the period in milliseconds of given unit of date and amount. The * period is calculated based on UTC of January 1, 1970. * * @param unit * the unit of time like Calendar.YEAR. * @param amount * the amount of period. * @return the period in milliseconds */ private static long getPeriodInMillis(int unit, int amount) { Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(0); cal.roll(unit, amount); return cal.getTimeInMillis(); } /** * Formats the given object. * * @param obj * the object * @return the formatted string */ private String format(Object obj) { if (format == null) { if (axis.isDateEnabled()) { String dateFormat = "yyyyy.MMMMM.dd"; if (timeUnit == Calendar.MILLISECOND) { dateFormat = "HH:mm:ss.SSS"; } else if (timeUnit == Calendar.SECOND) { dateFormat = "HH:mm:ss"; } else if (timeUnit == Calendar.MINUTE) { dateFormat = "HH:mm"; } else if (timeUnit == Calendar.HOUR_OF_DAY) { dateFormat = "dd HH:mm"; } else if (timeUnit == Calendar.DATE) { dateFormat = "MMMMM d"; } else if (timeUnit == Calendar.MONTH) { dateFormat = "yyyy MMMMM"; } else if (timeUnit == Calendar.YEAR) { dateFormat = "yyyy"; } return new SimpleDateFormat(dateFormat).format(obj); } return new DecimalFormat(DEFAULT_DECIMAL_FORMAT).format(obj); } return format.format(obj); } /** * Checks if the tick label is major (...,0.01,0.1,1,10,100,...). * * @param tickValue * the tick label value * @return true if the tick label is major */ private boolean isMajorTick(double tickValue) { if (!axis.isLogScaleEnabled()) { return true; } if (Math.log10(tickValue) % 1 == 0) { return true; } return false; } /** * Returns the state indicating if there is a space to draw tick label. * * @param previousPosition * the previously drawn tick label position. * @param tickLabelPosition * the tick label position. * @param tickLabel * the tick label text * @return true if there is a space to draw tick label */ private boolean hasSpaceToDraw(int previousPosition, int tickLabelPosition, String tickLabel) { Point p = Util.getExtentInGC(axis.getTick().getFont(), tickLabel); int interval = tickLabelPosition - previousPosition; int textLength = axis.isHorizontalAxis() ? p.x : p.y; int padding = 3; return interval > textLength + padding; } /** * Gets the right margin hint. * * @param length * the axis length * @return the right margin hint */ public int getRightMarginHint(int length) { // search the most right tick label int mostRightLabelIndex = -1; for (int i = tickLabels.size() - 1; i >= 0; i--) { if (tickVisibilities.size() > i && tickVisibilities.get(i)) { mostRightLabelIndex = i; break; } } // calculate right margin hint int rightMarginHint = 0; if (mostRightLabelIndex != -1) { int position = tickLabelPositions.get(mostRightLabelIndex); double angle = axis.getTick().getTickLabelAngle(); int textWidth = Util.getExtentInGC(axis.getTick().getFont(), tickLabels.get(mostRightLabelIndex)).x; if (angle == 0) { rightMarginHint = Math.max(0, position - length + (int) (textWidth / 2d)); } else if (axis.getPosition() == Position.Secondary) { rightMarginHint = Math.max(0, position - length + (int) (textWidth * Math.cos(Math.toRadians(angle)))); } } return rightMarginHint; } /** * Updates the left margin hint. * * @param length * the axis length * @return the left margin hint */ public int getLeftMarginHint(int length) { // search the most left tick label int mostLeftLabelIndex = -1; for (int i = 0; i < tickLabels.size(); i++) { if (tickVisibilities.size() > i && tickVisibilities.get(i)) { mostLeftLabelIndex = i; break; } } // calculate left margin hint int leftMarginHint = 0; if (mostLeftLabelIndex != -1) { int position = tickLabelPositions.get(mostLeftLabelIndex); double angle = axis.getTick().getTickLabelAngle(); int textWidth = Util.getExtentInGC(axis.getTick().getFont(), tickLabels.get(mostLeftLabelIndex)).x; if (angle == 0) { leftMarginHint = Math.max(0, (int) (textWidth / 2d) - position); } else if (axis.getPosition() == Position.Primary) { leftMarginHint = Math.max(0, (int) (textWidth * Math.cos(Math.toRadians(angle))) - position); } } return leftMarginHint; } /** * Gets the max length of tick label. * * @return the max length of tick label */ public int getTickLabelMaxLength() { int maxLength = 0; for (int i = 0; i < tickLabels.size(); i++) { if (tickVisibilities.size() > i && tickVisibilities.get(i) == true) { Point p = Util.getExtentInGC(axis.getTick().getFont(), tickLabels.get(i)); if (p.x > maxLength) { maxLength = p.x; } } } return maxLength; } /** * Calculates the value of the first argument raised to the power of the * second argument. * * @param base * the base * @param exponent * the exponent * @return the value ab in BigDecimal */ private static BigDecimal pow(double base, int exponent) { BigDecimal value; if (exponent > 0) { value = BigDecimal.valueOf(base).pow(exponent); } else { value = BigDecimal.ONE.divide(BigDecimal.valueOf(base).pow( -exponent)); } return value; } /** * Gets the grid step. * * @param lengthInPixels * axis length in pixels * @param min * minimum value * @param max * maximum value * @return rounded value. */ private BigDecimal getGridStep(int lengthInPixels, double min, double max) { if (lengthInPixels <= 0) { throw new IllegalArgumentException( "lengthInPixels must be positive value."); } if (min >= max) { throw new IllegalArgumentException("min must be less than max."); } double length = Math.abs(max - min); double gridStepHint = length / lengthInPixels * axis.getTick().getTickMarkStepHint(); // gridStepHint --> mantissa * 10 ** exponent // e.g. 724.1 --> 7.241 * 10 ** 2 double mantissa = gridStepHint; int exponent = 0; if (mantissa < 1) { while (mantissa < 1) { mantissa *= 10.0; exponent--; } } else { while (mantissa >= 10) { mantissa /= 10.0; exponent++; } } // calculate the grid step with hint. BigDecimal gridStep; if (mantissa > 7.5) { // gridStep = 10.0 * 10 ** exponent gridStep = BigDecimal.TEN.multiply(pow(10, exponent)); } else if (mantissa > 3.5) { // gridStep = 5.0 * 10 ** exponent gridStep = BigDecimal.valueOf(5).multiply(pow(10, exponent)); } else if (mantissa > 1.5) { // gridStep = 2.0 * 10 ** exponent gridStep = BigDecimal.valueOf(2).multiply(pow(10, exponent)); } else { // gridStep = 1.0 * 10 ** exponent gridStep = pow(10, exponent); } return gridStep; } /** * Gets the tick label positions. * * @return the tick label positions */ public ArrayList getTickLabelPositions() { return tickLabelPositions; } /** * Gets the tick label values. * * @return the tick label values */ protected ArrayList getTickLabelValues() { return tickLabelValues; } /** * Sets the font. * * @param font * the font */ protected void setFont(Font font) { if (font == null) { this.font = DEFAULT_FONT; } else { this.font = font; } } /** * Gets the font. * * @return the font */ public Font getFont() { if (font.isDisposed()) { font = DEFAULT_FONT; } return font; } /** * Gets the layout data. * * @return the layout data */ public ChartLayoutData getLayoutData() { return new ChartLayoutData(widthHint, heightHint); } /** * Sets the bounds on chart panel. * * @param x * the x coordinate * @param y * the y coordinate * @param width * the width * @param height * the height */ public void setBounds(int x, int y, int width, int height) { bounds = new Rectangle(x, y, width, height); } /** * Gets the bounds on chart panel. * * @return the bounds on chart panel */ protected Rectangle getBounds() { return bounds; } /** * Disposes the resources. */ protected void dispose() { if (!chart.isDisposed()) { chart.removePaintListener(this); } } /** * Updates the tick labels layout. */ protected void updateLayoutData() { widthHint = SWT.DEFAULT; heightHint = SWT.DEFAULT; if (!axis.getTick().isVisible()) { widthHint = 0; heightHint = 0; } else { if (axis.isHorizontalAxis()) { heightHint = Axis.MARGIN + Util.getExtentInGC(getFont(), null).y; } else { widthHint = Axis.MARGIN; } } } /* * @see PaintListener#paintControl(PaintEvent) */ public void paintControl(PaintEvent e) { if (!axis.getTick().isVisible()) { return; } Color oldBackground = e.gc.getBackground(); e.gc.setBackground(chart.getBackground()); Color oldForeground = e.gc.getForeground(); e.gc.setForeground(getForeground()); if (axis.isHorizontalAxis()) { drawXTick(e.gc); } else { drawYTick(e.gc); } e.gc.setBackground(oldBackground); e.gc.setForeground(oldForeground); } /** * Draw the X tick. * * @param gc * the graphics context */ private void drawXTick(GC gc) { int offset = axis.getTick().getAxisTickMarks().getBounds().x; // draw tick labels gc.setFont(axis.getTick().getFont()); int angle = axis.getTick().getTickLabelAngle(); for (int i = 0; i < tickLabelPositions.size(); i++) { if (axis.isValidCategoryAxis() || tickVisibilities.get(i) == true) { String text = tickLabels.get(i); int textWidth = gc.textExtent(text).x; int textHeight = gc.textExtent(text).y; if (angle == 0) { int x = (int) (tickLabelPositions.get(i) - textWidth / 2d + offset); gc.drawText(text, bounds.x + x, bounds.y); continue; } float x, y; if (axis.getPosition() == Position.Primary) { x = (float) (offset + bounds.x + tickLabelPositions.get(i) - textWidth * Math.cos(Math.toRadians(angle)) - textHeight / 2d * Math.sin(Math.toRadians(angle))); y = (float) (bounds.y + textWidth * Math.sin(Math.toRadians(angle))); } else { x = (float) (offset + bounds.x + tickLabelPositions.get(i) - textHeight / 2d * Math.sin(Math.toRadians(angle))); y = (float) (bounds.y + bounds.height * Math.sin(Math.toRadians(angle))); } drawRotatedText(gc, text, x, y, angle); } } } /** * Draws the rotated text. * * @param gc * the graphics context * @param text * the text * @param x * the x coordinate * @param y * the y coordinate * @param angle * the angle */ private static void drawRotatedText(GC gc, String text, float x, float y, int angle) { // set transform to rotate Transform transform = new Transform(gc.getDevice()); transform.translate(x, y); transform.rotate(360 - angle); gc.setTransform(transform); gc.drawText(text, 0, 0); // clear transform transform.dispose(); gc.setTransform(null); } /** * Draw the Y tick. * * @param gc * the graphics context */ private void drawYTick(GC gc) { int margin = Axis.MARGIN + AxisTickMarks.TICK_LENGTH; // draw tick labels gc.setFont(axis.getTick().getFont()); int figureHeight = gc.textExtent("dummy").y; for (int i = 0; i < tickLabelPositions.size(); i++) { if (tickVisibilities.size() == 0 || tickLabels.size() == 0) { break; } if (tickVisibilities.get(i) == true) { String text = tickLabels.get(i); int x = Axis.MARGIN; if (tickLabels.get(0).startsWith("-") && !text.startsWith("-")) { x += gc.textExtent("-").x; } int y = (int) (bounds.height - 1 - tickLabelPositions.get(i) - figureHeight / 2.0 - margin); gc.drawText(text, bounds.x + x, bounds.y + y); } } } /** * Sets the format for axis tick label. DecimalFormat and * DateFormat should be used for double[] series and * Data[] series respectively. *

* If null is set, default format will be used. * * @param format * the format */ protected void setFormat(Format format) { this.format = format; } /** * Gets the format for axis tick label. * * @return the format */ protected Format getFormat() { return format; } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/axis/AxisTick.java0000644000175000017500000001473312657165716030610 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.axis; import java.text.Format; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Rectangle; import org.swtchart.Chart; import org.swtchart.IAxisTick; import org.swtchart.IAxis.Position; /** * An axis tick. */ public class AxisTick implements IAxisTick { /** the chart */ private Chart chart; /** the axis */ private Axis axis; /** the axis tick labels */ private AxisTickLabels axisTickLabels; /** the axis tick marks */ private AxisTickMarks axisTickMarks; /** true if tick is visible */ private boolean isVisible; /** the tick mark step hint */ private int tickMarkStepHint; /** the tick label angle in degree */ private int tickLabelAngle; /** the default tick mark step hint */ private static final int DEFAULT_TICK_MARK_STEP_HINT = 64; /** * Constructor. * * @param chart * the chart * @param axis * the axis */ protected AxisTick(Chart chart, Axis axis) { this.chart = chart; this.axis = axis; axisTickLabels = new AxisTickLabels(chart, axis); axisTickMarks = new AxisTickMarks(chart, axis); isVisible = true; tickLabelAngle = 0; tickMarkStepHint = DEFAULT_TICK_MARK_STEP_HINT; } /** * Gets the axis tick marks. * * @return the axis tick marks */ public AxisTickMarks getAxisTickMarks() { return axisTickMarks; } /** * Gets the axis tick labels. * * @return the axis tick labels */ public AxisTickLabels getAxisTickLabels() { return axisTickLabels; } /* * @see IAxisTick#setForeground(Color) */ public void setForeground(Color color) { if (color != null && color.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } axisTickMarks.setForeground(color); axisTickLabels.setForeground(color); } /* * @see IAxisTick#getForeground() */ public Color getForeground() { return axisTickMarks.getForeground(); } /* * @see IAxisTick#setFont(Font) */ public void setFont(Font font) { if (font != null && font.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } axisTickLabels.setFont(font); chart.updateLayout(); } /* * @see IAxisTick#getFont() */ public Font getFont() { return axisTickLabels.getFont(); } /* * @see IAxisTick#isVisible() */ public boolean isVisible() { return isVisible; } /* * @see IAxisTick#setVisible(boolean) */ public void setVisible(boolean isVisible) { this.isVisible = isVisible; chart.updateLayout(); } /* * @see IAxisTick#getTickMarkStepHint() */ public int getTickMarkStepHint() { return tickMarkStepHint; } /* * @see IAxisTick#setTickMarkStepHint(int) */ public void setTickMarkStepHint(int tickMarkStepHint) { if (tickMarkStepHint < MIN_GRID_STEP_HINT) { this.tickMarkStepHint = DEFAULT_TICK_MARK_STEP_HINT; } else { this.tickMarkStepHint = tickMarkStepHint; } chart.updateLayout(); } /* * @see IAxisTick#getTickLabelAngle() */ public int getTickLabelAngle() { return tickLabelAngle; } /* * @see IAxisTick#setTickLabelAngle(int) */ public void setTickLabelAngle(int angle) { if (angle < 0 || 90 < angle) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } if (tickLabelAngle != angle) { tickLabelAngle = angle; chart.updateLayout(); } } /* * @see IAxisTick#setFormat(Format) */ public void setFormat(Format format) { axisTickLabels.setFormat(format); chart.updateLayout(); } /* * @see IAxisTick#getFormat() */ public Format getFormat() { return axisTickLabels.getFormat(); } /* * @see IAxisTick#getBounds() */ public Rectangle getBounds() { Rectangle r1 = axisTickMarks.getBounds(); Rectangle r2 = axisTickLabels.getBounds(); Position position = axis.getPosition(); if (position == Position.Primary && axis.isHorizontalAxis()) { return new Rectangle(r1.x, r1.y, r1.width, r1.height + r2.height); } else if (position == Position.Secondary && axis.isHorizontalAxis()) { return new Rectangle(r1.x, r2.y, r1.width, r1.height + r2.height); } else if (position == Position.Primary && !axis.isHorizontalAxis()) { return new Rectangle(r2.x, r1.y, r1.width + r2.width, r1.height); } else if (position == Position.Secondary && !axis.isHorizontalAxis()) { return new Rectangle(r1.x, r1.y, r1.width + r2.width, r1.height); } else { throw new IllegalStateException("unknown axis position"); } } /* * @see IAxisTick#getTickLabelValues() */ public double[] getTickLabelValues() { List list = axisTickLabels.getTickLabelValues(); double[] values = new double[list.size()]; for (int i = 0; i < values.length; i++) { values[i] = list.get(i); } return values; } /** * Updates the tick around per 64 pixel. * * @param length * the axis length */ public void updateTick(int length) { if (length <= 0) { axisTickLabels.update(1); } else { axisTickLabels.update(length); } } /** * Updates the tick layout. */ protected void updateLayoutData() { axisTickLabels.updateLayoutData(); axisTickMarks.updateLayoutData(); } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/axis/AxisSet.java0000644000175000017500000001703012657165716030442 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.axis; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Set; import org.eclipse.swt.SWT; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.IAxis.Direction; import org.swtchart.IAxisSet; import org.swtchart.ISeries; import org.swtchart.internal.series.SeriesSet; /** * An axis container. By default, axis set has X Axis and Y axis with axis id 0. */ public class AxisSet implements IAxisSet { /** the set of X axes */ private HashMap xAxisMap; /** the set of Y axes */ private HashMap yAxisMap; /** the chart */ private Chart chart; /** * Constructor. * * @param chart * the chart */ public AxisSet(Chart chart) { this.chart = chart; xAxisMap = new HashMap(); yAxisMap = new HashMap(); // add default axes Axis xAxis = new Axis(0, Direction.X, chart); Axis yAxis = new Axis(0, Direction.Y, chart); xAxisMap.put(0, xAxis); yAxisMap.put(0, yAxis); } /** * Gets the axis map for given direction. * * @param direction * the direction * @return the axis map */ private HashMap getAxisMap(Direction direction) { if (direction == Direction.X) { return xAxisMap; } return yAxisMap; } /* * @see IAxisSet#createXAxis() */ public int createXAxis() { return createAxis(Direction.X); } /* * @see IAxisSet#createYAxis() */ public int createYAxis() { return createAxis(Direction.Y); } /** * Creates the axis for given direction. * * @param direction * the direction of axis * @return the created axis id */ private int createAxis(Direction direction) { int id = getUniqueId(direction); Axis axis = new Axis(id, direction, chart); getAxisMap(direction).put(id, axis); chart.updateLayout(); SeriesSet series = (SeriesSet) chart.getSeriesSet(); if (series != null) { series.compressAllSeries(); } return id; } /** * Gets a unique axis id. * * @param direction * the axis direction * @return a unique axis id */ private int getUniqueId(Direction direction) { Set keySet = getAxisMap(direction).keySet(); int i = 0; while (keySet.contains(i)) { i++; } return i; } /* * @see IAxisSet#getXAxis(int) */ public IAxis getXAxis(int id) { return getAxis(id, Direction.X); } /* * @see IAxisSet#getYAxis(int) */ public IAxis getYAxis(int id) { return getAxis(id, Direction.Y); } /** * Gets the axis with axis id for given direction. * * @param id * the axis id * @param direction * the direction * @return the axis */ private IAxis getAxis(int id, Direction direction) { return getAxisMap(direction).get(id); } /* * @see IAxisSet#getXAxes() */ public IAxis[] getXAxes() { Collection values = xAxisMap.values(); return values.toArray(new Axis[values.size()]); } /* * @see IAxisSet#getYAxes() */ public IAxis[] getYAxes() { Collection values = yAxisMap.values(); return values.toArray(new Axis[values.size()]); } /* * @see IAxisSet#getAxes() */ public IAxis[] getAxes() { Collection axes = new ArrayList(); axes.addAll(xAxisMap.values()); axes.addAll(yAxisMap.values()); return axes.toArray(new Axis[axes.size()]); } /* * @see IAxisSet#getXAxisIds() */ public int[] getXAxisIds() { return getAxisIds(Direction.X); } /* * @see IAxisSet#getYAxisIds() */ public int[] getYAxisIds() { return getAxisIds(Direction.Y); } /** * Gets the axis ids for given direction. * * @param direction * the direction * @return the axis ids */ private int[] getAxisIds(Direction direction) { Set keySet = getAxisMap(direction).keySet(); Integer[] array = keySet.toArray(new Integer[keySet.size()]); int[] ids = new int[array.length]; for (int i = 0; i < ids.length; i++) { ids[i] = array[i]; } Arrays.sort(ids); return ids; } /* * @see IAxisSet#deleteXAxis(int) */ public void deleteXAxis(int id) { deleteAxis(id, Direction.X); } /* * @see IAxisSet#deleteYAxis(int) */ public void deleteYAxis(int id) { deleteAxis(id, Direction.Y); } /** * Deletes the axis with the axis id for given direction. * * @param id * the axis id * @param direction * the direction */ private void deleteAxis(int id, Direction direction) { if (id == 0) { SWT.error(SWT.ERROR_CANNOT_BE_ZERO); } if (getAxisMap(direction).get(id) == null) { throw new IllegalArgumentException("Given axis id doesn't exist"); } ((Axis) getAxis(id, direction)).dispose(); getAxisMap(direction).remove(id); for (ISeries series : chart.getSeriesSet().getSeries()) { if (direction == Direction.X) { if (series.getXAxisId() == id) { series.setXAxisId(0); } } else { if (series.getYAxisId() == id) { series.setYAxisId(0); } } } chart.updateLayout(); } /* * @see IAxisSet#adjustRange() */ public void adjustRange() { for (IAxis axis : getAxes()) { ((Axis) axis).adjustRange(false); } chart.updateLayout(); } /* * @see IAxisSet#zoomIn() */ public void zoomIn() { for (IAxis axis : getAxes()) { axis.zoomIn(); } } /* * @see IAxisSet#zoomOut() */ public void zoomOut() { for (IAxis axis : getAxes()) { axis.zoomOut(); } } /** * Updates the layout data. */ public void updateLayoutData() { for (IAxis axis : getAxes()) { ((Axis) axis).updateLayoutData(); } } /** * Refreshes the cache. */ public void refresh() { for (IAxis axis : getAxes()) { ((Axis) axis).refresh(); } } /** * Disposes the resources. */ public void dispose() { for (IAxis axis : getAxes()) { ((Axis) axis).dispose(); } } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/axis/AxisTitle.java0000644000175000017500000000470312657165716030773 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.axis; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.widgets.Display; import org.swtchart.Chart; import org.swtchart.Constants; import org.swtchart.IAxis.Direction; import org.swtchart.internal.Title; /** * An Axis title. */ public class AxisTitle extends Title { /** the default text for X Axis */ private static final String DEFAULT_TEXT_FOR_XAXIS = "X Axis"; /** the default text for X Axis */ private static final String DEFAULT_TEXT_FOR_YAXIS = "Y Axis"; /** the default color */ private static final int DEFAULT_FONT_SIZE = Constants.MEDIUM_FONT_SIZE; /** the default font */ private final Font defaultFont; /** the axis */ private final Axis axis; /** the direction of axis */ private final Direction direction; /** * Constructor. * * @param chart * the chart * @param style * the style * @param axis * the axis * @param direction * the direction */ public AxisTitle(Chart chart, int style, Axis axis, Direction direction) { super(chart); this.axis = axis; this.direction = direction; defaultFont = new Font(Display.getDefault(), "Tahoma", DEFAULT_FONT_SIZE, SWT.BOLD); setFont(defaultFont); setText(getDefaultText()); } /* * @see Title#getDefaultText() */ @Override protected String getDefaultText() { if (direction == Direction.X) { return DEFAULT_TEXT_FOR_XAXIS; } return DEFAULT_TEXT_FOR_YAXIS; } /* * @see Title#isHorizontal() */ @Override protected boolean isHorizontal() { return axis.isHorizontalAxis(); } /* * @see Title#dispose() */ @Override public void dispose() { super.dispose(); if (!defaultFont.isDisposed()) { defaultFont.dispose(); } } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/axis/AxisTickMarks.java0000644000175000017500000002415012657165716031600 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.axis; import java.util.ArrayList; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Display; import org.swtchart.Chart; import org.swtchart.IAxis.Position; import org.swtchart.internal.ChartLayoutData; /** * Axis tick marks. */ public class AxisTickMarks implements PaintListener { /** the chart */ private Chart chart; /** the axis */ private Axis axis; /** the foreground color */ private Color foreground; /** the width hint of tick marks area */ private int widthHint; /** the height hint of tick marks area */ private int heightHint; /** the bounds of tick marks area */ private Rectangle bounds; /** the line width */ protected static final int LINE_WIDTH = 1; /** the tick length */ public static final int TICK_LENGTH = 5; /** the default foreground */ private static final int DEFAULT_FOREGROUND = SWT.COLOR_BLUE; /** * Constructor. * * @param chart * the chart * @param axis * the axis */ public AxisTickMarks(Chart chart, Axis axis) { this.chart = chart; this.axis = axis; foreground = Display.getDefault().getSystemColor(DEFAULT_FOREGROUND); chart.addPaintListener(this); } /** * Sets the foreground color. * * @param color * the foreground color */ public void setForeground(Color color) { if (color == null) { foreground = Display.getDefault() .getSystemColor(DEFAULT_FOREGROUND); } else { foreground = color; } } /** * Gets the foreground color. * * @return the foreground color */ protected Color getForeground() { if (foreground.isDisposed()) { foreground = Display.getDefault() .getSystemColor(DEFAULT_FOREGROUND); } return foreground; } /** * Gets the associated axis. * * @return the axis */ public Axis getAxis() { return axis; } /** * Updates tick marks layout. */ protected void updateLayoutData() { widthHint = SWT.DEFAULT; heightHint = SWT.DEFAULT; if (!axis.getTick().isVisible()) { widthHint = 0; heightHint = 0; } else { if (axis.isHorizontalAxis()) { heightHint = Axis.MARGIN + TICK_LENGTH; } else { widthHint = TICK_LENGTH + Axis.MARGIN; } } } /** * Gets the layout data. * * @return the layout data */ public ChartLayoutData getLayoutData() { return new ChartLayoutData(widthHint, heightHint); } /** * Sets the bounds on chart panel. * * @param x * the x coordinate * @param y * the y coordinate * @param width * the width * @param height * the height */ public void setBounds(int x, int y, int width, int height) { bounds = new Rectangle(x, y, width, height); } /** * Gets the bounds on chart panel. * * @return the bounds on chart panel */ protected Rectangle getBounds() { return bounds; } /** * Disposes the resources. */ protected void dispose() { if (!chart.isDisposed()) { chart.removePaintListener(this); } } /* * @see PaintListener#paintControl(PaintEvent) */ public void paintControl(PaintEvent e) { ArrayList tickLabelPositions = axis.getTick() .getAxisTickLabels().getTickLabelPositions(); Color oldBackground = e.gc.getBackground(); e.gc.setBackground(chart.getBackground()); Color oldForeground = e.gc.getForeground(); e.gc.setForeground(getForeground()); Rectangle oldClipping = e.gc.getClipping(); e.gc.setClipping(bounds); if (axis.isHorizontalAxis()) { drawXTickMarks(e.gc, tickLabelPositions, axis.getPosition()); } else { drawYTickMarks(e.gc, tickLabelPositions, axis.getPosition()); } e.gc.setClipping(oldClipping); e.gc.setBackground(oldBackground); e.gc.setForeground(oldForeground); } /** * Draw the X tick marks. * * @param tickLabelPositions * the tick label positions * @param position * the axis position * @param gc * the graphics context */ private void drawXTickMarks(GC gc, ArrayList tickLabelPositions, Position position) { // draw tick marks gc.setLineStyle(SWT.LINE_SOLID); if (axis.isValidCategoryAxis()) { if (tickLabelPositions.size() > 1) { int step = tickLabelPositions.get(1).intValue() - tickLabelPositions.get(0).intValue(); for (int i = 0; i < tickLabelPositions.size() + 1; i++) { int x; if (i < tickLabelPositions.size()) { x = (int) (tickLabelPositions.get(i).intValue() - step / 2d); } else { x = (int) (tickLabelPositions.get(i - 1).intValue() + step / 2d); } int y = 0; if (position == Position.Secondary) { y = bounds.height - 1 - LINE_WIDTH - TICK_LENGTH; } gc.drawLine(bounds.x + x, bounds.y + y, bounds.x + x, bounds.y + y + TICK_LENGTH); } } } else { for (int i = 0; i < tickLabelPositions.size(); i++) { int x = tickLabelPositions.get(i); int y = 0; if (position == Position.Secondary) { y = bounds.height - 1 - LINE_WIDTH - TICK_LENGTH; } gc.drawLine(bounds.x + x, bounds.y + y, bounds.x + x, bounds.y + y + TICK_LENGTH); } } // draw axis line if (position == Position.Primary) { gc.drawLine(bounds.x, bounds.y, bounds.x + bounds.width - 1, bounds.y); } else { gc.drawLine(bounds.x, bounds.y + bounds.height - 1, bounds.x + bounds.width - 1, bounds.y + bounds.height - 1); } } /** * Draw the Y tick marks. * * @param tickLabelPositions * the tick label positions * @param position * the axis position * @param gc * the graphics context */ private void drawYTickMarks(GC gc, ArrayList tickLabelPositions, Position position) { // draw tick marks gc.setLineStyle(SWT.LINE_SOLID); if (axis.isValidCategoryAxis()) { if (tickLabelPositions.size() > 1) { int step = tickLabelPositions.get(1).intValue() - tickLabelPositions.get(0).intValue(); for (int i = 0; i < tickLabelPositions.size() + 1; i++) { int x = 0; int y; if (i < tickLabelPositions.size()) { y = (int) (tickLabelPositions.get(i).intValue() - step / 2d); } else { y = (int) (tickLabelPositions.get(i - 1).intValue() + step / 2d); } if (position == Position.Primary) { x = bounds.width - 1 - LINE_WIDTH - TICK_LENGTH; } else { x = LINE_WIDTH; } gc.drawLine(bounds.x + x, bounds.y + y, bounds.x + x + TICK_LENGTH, bounds.y + y); } } } else { int y = 0; for (int i = 0; i < tickLabelPositions.size(); i++) { int x = 0; if (position == Position.Primary) { x = bounds.width - 1 - LINE_WIDTH - TICK_LENGTH; } else { x = LINE_WIDTH; } y = bounds.height - 1 - tickLabelPositions.get(i); gc.drawLine(bounds.x + x, bounds.y + y, bounds.x + x + TICK_LENGTH, bounds.y + y); } } // draw axis line if (position == Position.Primary) { gc.drawLine(bounds.x + bounds.width - 1, bounds.y, bounds.x + bounds.width - 1, bounds.y + bounds.height - 1); } else { gc.drawLine(bounds.x, bounds.y, bounds.x, bounds.y + bounds.height - 1); } } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/axis/Axis.java0000644000175000017500000006011412657165716027767 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.axis; import java.util.ArrayList; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Event; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.IDisposeListener; import org.swtchart.IGrid; import org.swtchart.ISeries; import org.swtchart.ITitle; import org.swtchart.Range; import org.swtchart.internal.Grid; import org.swtchart.internal.series.Series; import org.swtchart.internal.series.SeriesSet; /** * An axis. */ public class Axis implements IAxis { /** the margin in pixels */ public final static int MARGIN = 5; /** the default minimum value of range */ public final static double DEFAULT_MIN = 0d; /** the default maximum value of range */ public final static double DEFAULT_MAX = 1d; /** the default minimum value of log scale range */ public final static double DEFAULT_LOG_SCALE_MIN = 0.1d; /** the default maximum value of log scale range */ public final static double DEFAULT_LOG_SCALE_MAX = 1d; /** the ratio to be zoomed */ private static final double ZOOM_RATIO = 0.2; /** the ratio to be scrolled */ private static final double SCROLL_RATIO = 0.1; /** the maximum resolution with digits */ private static final double MAX_RESOLUTION = 13; /** the axis id */ private int id; /** the axis direction */ private Direction direction; /** the axis position */ private Position position; /** the minimum value of axis range */ private double min; /** the maximum value of axis range */ private double max; /** the axis title */ private AxisTitle title; /** the axis tick */ private AxisTick tick; /** the grid */ private Grid grid; /** the plot chart */ private Chart chart; /** the state if the axis scale is log scale */ private boolean logScaleEnabled; /** the state indicating if axis type is category */ private boolean categoryAxisEnabled; /** the category series */ private String[] categorySeries; /** the number of riser per category */ private int numRisers; /** the state indicating if the axis is horizontal */ private boolean isHorizontalAxis; /** the plot area width */ private int width; /** the plot area height */ private int height; /** the list of dispose listeners */ private List listeners; /** * Constructor. * * @param id * the axis index * @param direction * the axis direction (X or Y) * @param chart * the chart */ public Axis(int id, Direction direction, Chart chart) { this.id = id; this.direction = direction; this.chart = chart; grid = new Grid(this); title = new AxisTitle(chart, SWT.NONE, this, direction); tick = new AxisTick(chart, this); listeners = new ArrayList(); // sets initial default values position = Position.Primary; min = DEFAULT_MIN; max = DEFAULT_MAX; if (direction == Direction.X) { title.setText("X axis"); } else if (direction == Direction.Y) { title.setText("Y axis"); } logScaleEnabled = false; categoryAxisEnabled = false; } /* * @see IAxis#getId() */ public int getId() { return id; } /* * @see IAxis#getDirection() */ public Direction getDirection() { return direction; } /* * @see IAxis#getPosition() */ public Position getPosition() { return position; } /* * @see IAxis#setPosition(Position) */ public void setPosition(Position position) { if (position == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); } if (this.position == position) { return; } this.position = position; chart.updateLayout(); } /* * @see IAxis#setRange(Range) */ public void setRange(Range range) { setRange(range, true); } /** * Sets the axis range. * * @param range * the axis range * @param update * true if updating the chart layout */ public void setRange(Range range, boolean update) { if (range == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); return; // to suppress warnings... } if (Double.isNaN(range.lower) || Double.isNaN(range.upper) || Double.isInfinite(range.lower) || Double.isInfinite(range.upper) || range.lower > range.upper) { throw new IllegalArgumentException("Illegal range: " + range); } if (min == range.lower && max == range.upper) { return; } if (isValidCategoryAxis()) { min = (int) range.lower; max = (int) range.upper; if (min < 0) { min = 0; } if (max > categorySeries.length - 1) { max = categorySeries.length - 1; } } else { if (range.lower == range.upper) { throw new IllegalArgumentException("Given range is invalid"); } if (logScaleEnabled && range.lower <= 0) { range.lower = min; } if (Math.abs(range.lower / (range.upper - range.lower)) > Math.pow( 10, MAX_RESOLUTION)) { return; } min = range.lower; max = range.upper; } if (update) { chart.updateLayout(); } } /* * @see IAxis#getRange() */ public Range getRange() { return new Range(min, max); } /* * @see IAxis#getTitle() */ public ITitle getTitle() { return title; } /* * @see IAxis#getTick() */ public AxisTick getTick() { return tick; } /* * @see IAxis#enableLogScale(boolean) */ public void enableLogScale(boolean enabled) throws IllegalStateException { if (logScaleEnabled == enabled) { return; } if (enabled) { // check if series contain zero or negative value double minSeriesValue = getMinSeriesValue(); if (minSeriesValue <= 0) { throw new IllegalStateException( "Series contain zero or negative value."); } // adjust the range in order not to have zero or negative value if (min <= 0) { min = Double.isNaN(minSeriesValue) ? DEFAULT_LOG_SCALE_MIN : minSeriesValue; } if (max < min) { max = DEFAULT_LOG_SCALE_MAX; } // disable category axis if (categoryAxisEnabled) { categoryAxisEnabled = false; ((SeriesSet) chart.getSeriesSet()).updateCompressor(this); } } logScaleEnabled = enabled; chart.updateLayout(); ((SeriesSet) chart.getSeriesSet()).compressAllSeries(); } /** * Gets the minimum value of series belonging to this axis. * * @return the minimum value of series belonging to this axis */ private double getMinSeriesValue() { double minimum = Double.NaN; for (ISeries series : chart.getSeriesSet().getSeries()) { if (series.getYSeries().length == 0) { continue; } double lower; if (direction == Direction.X && series.getXAxisId() == getId()) { lower = ((Series) series).getXRange().lower; } else if (direction == Direction.Y && series.getYAxisId() == getId()) { lower = ((Series) series).getYRange().lower; } else { continue; } if (Double.isNaN(minimum) || lower < minimum) { minimum = lower; } } return minimum; } /* * @see IAxis#isLogScaleEnabled() */ public boolean isLogScaleEnabled() { return logScaleEnabled; } /* * @see IAxis#getGrid() */ public IGrid getGrid() { return grid; } /* * @see IAxis#adjustRange() */ public void adjustRange() { adjustRange(true); } /** * Adjusts the axis range to the series belonging to the axis. * * @param update * true if updating chart layout */ public void adjustRange(boolean update) { if (isValidCategoryAxis()) { setRange(new Range(0, categorySeries.length - 1)); return; } double minimum = Double.NaN; double maximum = Double.NaN; for (ISeries series : chart.getSeriesSet().getSeries()) { int axisId = direction == Direction.X ? series.getXAxisId() : series.getYAxisId(); if (!series.isVisible() || getId() != axisId) { continue; } // get axis length int length; if (isHorizontalAxis) { length = chart.getPlotArea().getSize().x; } else { length = chart.getPlotArea().getSize().y; } // get min and max value of series Range range = ((Series) series).getAdjustedRange(this, length); if (Double.isNaN(minimum) || range.lower < minimum) { minimum = range.lower; } if (Double.isNaN(maximum) || range.upper > maximum) { maximum = range.upper; } } // set adjusted range if (!Double.isNaN(minimum) && !Double.isNaN(maximum)) { if (minimum == maximum) { double margin = (minimum == 0)? 1d : Math.abs(minimum / 2d); minimum -= margin; maximum += margin; } setRange(new Range(minimum, maximum), update); } } /* * @see IAxis#zoomIn() */ public void zoomIn() { zoomIn((max + min) / 2d); } /* * @see IAxis#zoomIn(double) */ public void zoomIn(double coordinate) { double lower = min; double upper = max; if (isValidCategoryAxis()) { if (lower != upper) { if ((min + max) / 2d < coordinate) { lower = min + 1; } else if (coordinate < (min + max) / 2d) { upper = max - 1; } else { lower = min + 1; upper = max - 1; } } } else if (isLogScaleEnabled()) { double digitMin = Math.log10(min); double digitMax = Math.log10(max); double digitCoordinate = Math.log10(coordinate); lower = Math.pow(10, digitMin + 2 * SCROLL_RATIO * (digitCoordinate - digitMin)); upper = Math.pow(10, digitMax + 2 * SCROLL_RATIO * (digitCoordinate - digitMax)); } else { lower = min + 2 * ZOOM_RATIO * (coordinate - min); upper = max + 2 * ZOOM_RATIO * (coordinate - max); } setRange(new Range(lower, upper)); } /* * @see IAxis#zoomOut() */ public void zoomOut() { zoomOut((min + max) / 2d); } /* * @see IAxis#zoomOut(double) */ public void zoomOut(double coordinate) { double lower = min; double upper = max; if (isValidCategoryAxis()) { if ((min + max) / 2d < coordinate && min != 0) { lower = min - 1; } else if (coordinate < (min + max) / 2d && max != categorySeries.length - 1) { upper = max + 1; } else { lower = min - 1; upper = max + 1; } } else if (isLogScaleEnabled()) { double digitMin = Math.log10(min); double digitMax = Math.log10(max); double digitCoordinate = Math.log10(coordinate); lower = Math.pow(10, (digitMin - ZOOM_RATIO * digitCoordinate) / (1 - ZOOM_RATIO)); upper = Math.pow(10, (digitMax - ZOOM_RATIO * digitCoordinate) / (1 - ZOOM_RATIO)); } else { lower = (min - 2 * ZOOM_RATIO * coordinate) / (1 - 2 * ZOOM_RATIO); upper = (max - 2 * ZOOM_RATIO * coordinate) / (1 - 2 * ZOOM_RATIO); } setRange(new Range(lower, upper)); } /* * @see IAxis#scrollUp() */ public void scrollUp() { double lower = min; double upper = max; if (isValidCategoryAxis()) { if (upper < categorySeries.length - 1) { lower = min + 1; upper = max + 1; } } else if (isLogScaleEnabled()) { double digitMax = Math.log10(upper); double digitMin = Math.log10(lower); upper = Math.pow(10, digitMax + (digitMax - digitMin) * SCROLL_RATIO); lower = Math.pow(10, digitMin + (digitMax - digitMin) * SCROLL_RATIO); } else { lower = min + (max - min) * SCROLL_RATIO; upper = max + (max - min) * SCROLL_RATIO; } setRange(new Range(lower, upper)); } /* * @see IAxis#scrollDown() */ public void scrollDown() { double lower = min; double upper = max; if (isValidCategoryAxis()) { if (lower >= 1) { lower = min - 1; upper = max - 1; } } else if (isLogScaleEnabled()) { double digitMax = Math.log10(upper); double digitMin = Math.log10(lower); upper = Math.pow(10, digitMax - (digitMax - digitMin) * SCROLL_RATIO); lower = Math.pow(10, digitMin - (digitMax - digitMin) * SCROLL_RATIO); } else { lower = min - (max - min) * SCROLL_RATIO; upper = max - (max - min) * SCROLL_RATIO; } setRange(new Range(lower, upper)); } /* * @see IAxis#isCategoryEnabled() */ public boolean isCategoryEnabled() { return categoryAxisEnabled; } /** * Gets the state indicating if the axis is valid category axis. * * @return true if the axis is valid category axis */ public boolean isValidCategoryAxis() { return categoryAxisEnabled && categorySeries != null && categorySeries.length != 0; } /* * @see IAxis#enableCategory(boolean) */ public void enableCategory(boolean enabled) { if (categoryAxisEnabled == enabled) { return; } if (enabled) { if (direction == Direction.Y) { throw new IllegalStateException( "Y axis cannot be category axis."); } if (categorySeries != null && categorySeries.length != 0) { min = (min < 0 || min >= categorySeries.length) ? 0 : (int) min; max = (max < 0 || max >= categorySeries.length) ? max = categorySeries.length - 1 : (int) max; } logScaleEnabled = false; } categoryAxisEnabled = enabled; chart.updateLayout(); ((SeriesSet) chart.getSeriesSet()).updateCompressor(this); ((SeriesSet) chart.getSeriesSet()).updateStackAndRiserData(); } /* * @see IAxis#setCategorySeries(String[]) */ public void setCategorySeries(String[] series) { if (series == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); return; // to suppress warnings... } if (direction == Direction.Y) { throw new IllegalStateException("Y axis cannot be category axis."); } String[] copiedSeries = new String[series.length]; System.arraycopy(series, 0, copiedSeries, 0, series.length); categorySeries = copiedSeries; if (isValidCategoryAxis()) { min = (min < 0) ? 0 : (int) min; max = (max >= categorySeries.length) ? max = categorySeries.length - 1 : (int) max; } chart.updateLayout(); ((SeriesSet) chart.getSeriesSet()).updateCompressor(this); ((SeriesSet) chart.getSeriesSet()).updateStackAndRiserData(); } /* * @see IAxis#getCategorySeries() */ public String[] getCategorySeries() { String[] copiedCategorySeries = null; if (categorySeries != null) { copiedCategorySeries = new String[categorySeries.length]; System.arraycopy(categorySeries, 0, copiedCategorySeries, 0, categorySeries.length); } return copiedCategorySeries; } /* * @see IAxis#getPixelCoordinate(double) */ public int getPixelCoordinate(double dataCoordinate) { return getPixelCoordinate(dataCoordinate, min, max); } /** * Gets the pixel coordinate corresponding to the given data coordinate. * * @param dataCoordinate * the data coordinate * @param lower * the min value of range * @param upper * the max value of range * @return the pixel coordinate on plot area */ public int getPixelCoordinate(double dataCoordinate, double lower, double upper) { int pixelCoordinate; if (isHorizontalAxis) { if (logScaleEnabled) { pixelCoordinate = (int) ((Math.log10(dataCoordinate) - Math .log10(lower)) / (Math.log10(upper) - Math.log10(lower)) * width); } else if (categoryAxisEnabled) { pixelCoordinate = (int) ((dataCoordinate + 0.5 - lower) / (upper + 1 - lower) * width); } else { pixelCoordinate = (int) ((dataCoordinate - lower) / (upper - lower) * width); } } else { if (logScaleEnabled) { pixelCoordinate = (int) ((Math.log10(upper) - Math .log10(dataCoordinate)) / (Math.log10(upper) - Math.log10(lower)) * height); } else if (categoryAxisEnabled) { pixelCoordinate = (int) ((upper - dataCoordinate + 0.5) / (upper + 1 - lower) * height); } else { pixelCoordinate = (int) ((upper - dataCoordinate) / (upper - lower) * height); } } return pixelCoordinate; } /* * @see IAxis#getDataCoordinate(int) */ public double getDataCoordinate(int pixelCoordinate) { return getDataCoordinate(pixelCoordinate, min, max); } /** * Gets the data coordinate corresponding to the given pixel coordinate on * plot area. * * @param pixelCoordinate * the pixel coordinate on plot area * @param lower * the min value of range * @param upper * the max value of range * @return the data coordinate */ public double getDataCoordinate(int pixelCoordinate, double lower, double upper) { double dataCoordinate; if (isHorizontalAxis) { if (logScaleEnabled) { dataCoordinate = Math.pow(10, pixelCoordinate / (double) width * (Math.log10(upper) - Math.log10(lower)) + Math.log10(lower)); } else if (categoryAxisEnabled) { dataCoordinate = Math.floor(pixelCoordinate / (double) width * (upper + 1 - lower) + lower); } else { dataCoordinate = pixelCoordinate / (double) width * (upper - lower) + lower; } } else { if (logScaleEnabled) { dataCoordinate = Math.pow(10, Math.log10(upper) - pixelCoordinate / (double) height * (Math.log10(upper) - Math.log10(lower))); } else if (categoryAxisEnabled) { dataCoordinate = Math.floor(upper + 1 - pixelCoordinate / (double) height * (upper + 1 - lower)); } else { dataCoordinate = (height - pixelCoordinate) / (double) height * (upper - lower) + lower; } } return dataCoordinate; } /** * Sets the number of risers per category. * * @param numRisers * the number of risers per category */ public void setNumRisers(int numRisers) { this.numRisers = numRisers; } /** * Gets the number of risers per category. * * @return number of riser per category */ public int getNumRisers() { return numRisers; } /** * Checks if the axis is horizontal. X axis is not always horizontal. Y axis * can be horizontal with Chart.setOrientation(SWT.VERTICAL). * * @return true if the axis is horizontal */ public boolean isHorizontalAxis() { int orientation = chart.getOrientation(); return (direction == Direction.X && orientation == SWT.HORIZONTAL) || (direction == Direction.Y && orientation == SWT.VERTICAL); } /** * Disposes the resources. */ protected void dispose() { tick.getAxisTickLabels().dispose(); tick.getAxisTickMarks().dispose(); title.dispose(); for (IDisposeListener listener : listeners) { listener.disposed(new Event()); } } /* * @see IAxis#addDisposeListener(IDisposeListener) */ public void addDisposeListener(IDisposeListener listener) { listeners.add(listener); } /** * Updates the layout data. */ public void updateLayoutData() { title.updateLayoutData(); tick.updateLayoutData(); } /** * Refreshes the cache. */ public void refresh() { int orientation = chart.getOrientation(); isHorizontalAxis = (direction == Direction.X && orientation == SWT.HORIZONTAL) || (direction == Direction.Y && orientation == SWT.VERTICAL); width = chart.getPlotArea().getBounds().width; height = chart.getPlotArea().getBounds().height; } /** * Gets the state indicating if date is enabled. * * @return true if date is enabled */ public boolean isDateEnabled() { if (!isHorizontalAxis) { return false; } for (ISeries series : chart.getSeriesSet().getSeries()) { if (series.getXAxisId() != id) { continue; } if (((Series) series).isDateSeries() && series.isVisible()) { return true; } } return false; } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/ChartTitle.java0000644000175000017500000000171312657165716030162 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal; import org.swtchart.Chart; /** * A chart title. */ public class ChartTitle extends Title { /** the default text */ private static final String DEFAULT_TEXT = "Chart Title"; /** * Constructor. * * @param chart * the plot chart */ public ChartTitle(Chart chart) { super(chart); setText(getDefaultText()); } /* * @see Title#getDefaultText() */ @Override protected String getDefaultText() { return DEFAULT_TEXT; } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/Util.java0000644000175000017500000000502612657165716027035 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Display; import org.swtchart.LineStyle; /** * A utility class providing generic methods. */ public final class Util { /** * Gets the text extent with given font in GC. If the given font is * null or already disposed, point containing size zero will be * returned. * * @param font * the font * @param text * the text * @return a point containing text extent */ public static Point getExtentInGC(Font font, String text) { if (font == null || font.isDisposed()) { return new Point(0, 0); } // create GC int ARBITRARY_WIDTH = 10; int ARBITRARY_HEIGHT = 10; Image image = new Image(Display.getCurrent(), ARBITRARY_WIDTH, ARBITRARY_HEIGHT); GC gc = new GC(image); // get extent of text with given font gc.setFont(font); Point p; if (text == null || "".equals(text.trim())) { p = new Point(0, gc.getFontMetrics().getHeight()); } else { p = gc.textExtent(text); } // dispose resources image.dispose(); gc.dispose(); return p; } /** * Gets the index defined in SWT. * * @param lineStyle * the line style * @return the index defined in SWT. */ public static int getIndexDefinedInSWT(LineStyle lineStyle) { switch (lineStyle) { case NONE: return SWT.NONE; case SOLID: return SWT.LINE_SOLID; case DASH: return SWT.LINE_DASH; case DOT: return SWT.LINE_DOT; case DASHDOT: return SWT.LINE_DASHDOT; case DASHDOTDOT: return SWT.LINE_DASHDOTDOT; default: return SWT.LINE_SOLID; } } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/PlotArea.java0000644000175000017500000001151612657165716027630 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal; import java.util.ArrayList; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.IBarSeries; import org.swtchart.ICustomPaintListener; import org.swtchart.ILineSeries; import org.swtchart.IPlotArea; import org.swtchart.ISeries; import org.swtchart.ISeriesSet; import org.swtchart.internal.series.Series; import org.swtchart.internal.series.SeriesSet; /** * Plot area to draw series and grids. */ public class PlotArea extends Composite implements PaintListener, IPlotArea { /** the chart */ protected Chart chart; /** the set of plots */ protected SeriesSet seriesSet; /** the custom paint listeners */ List paintListeners; /** the default background color */ private static final int DEFAULT_BACKGROUND = SWT.COLOR_WHITE; /** * Constructor. * * @param chart * the chart * @param style * the style */ public PlotArea(Chart chart, int style) { super(chart, style | SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED); this.chart = chart; seriesSet = new SeriesSet(chart); paintListeners = new ArrayList(); setBackground(Display.getDefault().getSystemColor(DEFAULT_BACKGROUND)); addPaintListener(this); } /** * Gets the set of series. * * @return the set of series */ public ISeriesSet getSeriesSet() { return seriesSet; } /* * @see Control#setBounds(int, int, int, int) */ @Override public void setBounds(int x, int y, int width, int height) { super.setBounds(x, y, width, height); ((SeriesSet) getSeriesSet()).compressAllSeries(); } /* * @see Control#setBackground(Color) */ @Override public void setBackground(Color color) { if (color == null) { super.setBackground(Display.getDefault().getSystemColor( DEFAULT_BACKGROUND)); } else { super.setBackground(color); } } /* * @see IPlotArea#addCustomPaintListener(ICustomPaintListener) */ public void addCustomPaintListener(ICustomPaintListener listener) { paintListeners.add(listener); } /* * @see IPlotArea#removeCustomPaintListener(ICustomPaintListener) */ public void removeCustomPaintListener(ICustomPaintListener listener) { paintListeners.remove(listener); } /* * @see PaintListener#paintControl(PaintEvent) */ public void paintControl(PaintEvent e) { Point p = getSize(); GC gc = e.gc; // draw the plot area background Color oldBackground = gc.getBackground(); gc.setBackground(getBackground()); gc.fillRectangle(0, 0, p.x, p.y); // draw grid for (IAxis axis : chart.getAxisSet().getAxes()) { ((Grid) axis.getGrid()).draw(gc, p.x, p.y); } // draw behind series for (ICustomPaintListener listener : paintListeners) { if (listener.drawBehindSeries()) { listener.paintControl(e); } } // draw series. The line series should be drawn on bar series. for (ISeries series : chart.getSeriesSet().getSeries()) { if (series instanceof IBarSeries) { ((Series) series).draw(gc, p.x, p.y); } } for (ISeries series : chart.getSeriesSet().getSeries()) { if (series instanceof ILineSeries) { ((Series) series).draw(gc, p.x, p.y); } } // draw over series for (ICustomPaintListener listener : paintListeners) { if (!listener.drawBehindSeries()) { listener.paintControl(e); } } e.gc.setBackground(oldBackground); } /* * @see Widget#dispose() */ @Override public void dispose() { super.dispose(); seriesSet.dispose(); } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/compress/0000755000175000017500000000000013275316671027100 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/compress/CompressConfig.java0000644000175000017500000001547312657165716032703 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.compress; /** * Configuration for compression. */ public class CompressConfig { /** the width in pixels */ private long widthInPixels; /** the height in pixels */ private long heightInPixels; /** the lower value of X range */ private double xLowerValue; /** the upper value of X range */ private double xUpperValue; /** the lower value of Y range */ private double yLowerValue; /** the upper value of Y range */ private double yUpperValue; /** the state indicating whether the X axis is log scale */ private boolean xLogScale; /** the state indicating whether the Y axis is log scale */ private boolean yLogScale; /** * Constructor. */ public CompressConfig() { widthInPixels = 1024; heightInPixels = 512; xLogScale = false; yLogScale = false; } /** * Constructor. * * @param config * the configuration for compression */ public CompressConfig(CompressConfig config) { widthInPixels = config.getWidthInPixel(); heightInPixels = config.getHeightInPixel(); xLowerValue = config.getXLowerValue(); xUpperValue = config.getXUpperValue(); yLowerValue = config.getYLowerValue(); yUpperValue = config.getYUpperValue(); xLogScale = config.isXLogScale(); yLogScale = config.isYLogScale(); } /* * @see Object#equals(Object) */ @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof CompressConfig)) { return false; } CompressConfig config = (CompressConfig) obj; if (widthInPixels != config.getWidthInPixel() || heightInPixels != config.getHeightInPixel()) { return false; } double diff = Math.abs(xLowerValue - config.getXLowerValue()) / (xUpperValue - xLowerValue); if (diff > 1.0 / widthInPixels) { return false; } diff = Math.abs(xUpperValue - config.getXUpperValue()) / (xUpperValue - xLowerValue); if (diff > 1.0 / widthInPixels) { return false; } diff = Math.abs(yLowerValue - config.getYLowerValue()) / (yUpperValue - yLowerValue); if (diff > 1.0 / heightInPixels) { return false; } diff = Math.abs(yUpperValue - config.getYUpperValue()) / (yUpperValue - yLowerValue); if (diff > 1.0 / heightInPixels) { return false; } if (config.isXLogScale() != xLogScale) { return false; } if (config.isYLogScale() != yLogScale) { return false; } return true; } /* * @see Object#hashCode() */ @Override public int hashCode() { return 0; } /** * Sets the size in pixels. * * @param width * the width in pixels * @param height * the height in pixels */ public void setSizeInPixel(long width, long height) { widthInPixels = width; heightInPixels = height; } /** * Gets the width of plot area in pixels * * @return the width of plot area in pixels */ public long getWidthInPixel() { return widthInPixels; } /** * Gets the height of plot area in pixels * * @return the height of plot area in pixels */ public long getHeightInPixel() { return heightInPixels; } /** * Sets the X range. * * @param lower * the lower value of x range * @param upper * the upper value of x range */ public void setXRange(double lower, double upper) { xLowerValue = lower; xUpperValue = upper; } /** * Sets the Y range. * * @param lower * the lower value of y range * @param upper * the upper value of y range */ public void setYRange(double lower, double upper) { yLowerValue = lower; yUpperValue = upper; } /** * Gets the lower value of x range. * * @return the lower value of x range */ public double getXLowerValue() { return xLowerValue; } /** * Gets the upper value of x range. * * @return the upper value of x range */ public double getXUpperValue() { return xUpperValue; } /** * Gets the lower value of y range. * * @return the lower value of y range */ public double getYLowerValue() { return yLowerValue; } /** * Gets the upper value of y range. * * @return the upper value of y range */ public double getYUpperValue() { return yUpperValue; } /** * Gets the state indicating whether the X axis is log scale. * * @return true if the X axis is log scale */ public boolean isXLogScale() { return xLogScale; } /** * Sets the state indicating whether the X axis is log scale. * * @param value * the state indicating whether the X axis is log scale */ public void setXLogScale(boolean value) { this.xLogScale = value; } /** * Gets the state indicating whether the Y axis is log scale. * * @return true if the Y axis is log scale */ public boolean isYLogScale() { return yLogScale; } /** * Sets the state indicating whether the Y axis is log scale. * * @param value * the state indicating whether the Y axis is log scale */ public void setYLogScale(boolean value) { this.yLogScale = value; } /* * @see Object#toString() */ @Override public String toString() { return "pixelWidth = " + widthInPixels + ", " + "pixelHeight = " + heightInPixels + ", " + "xLowerValue = " + xLowerValue + ", " + "xUpperValue = " + xUpperValue + ", " + "yLowerValue = " + yLowerValue + ", " + "yUpperValue = " + yUpperValue + ", " + yLogScale; } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/compress/CompressLineSeries.java0000644000175000017500000001241412657165716033530 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.compress; import java.util.ArrayList; /** * A compressor for line series data. */ public class CompressLineSeries extends Compress { /** the state indicating the relation between previous and current data points */ enum STATE { /** stepping over x range */ SteppingOverXRange, /** stepping over y range */ SteppingOverYRange, /** out of range again */ OutOfRangeAgain, /** stepping out of x range */ SteppingOutOfXRange, /** stepping in x range */ SteppingInXRange, /** stepping out of y range */ SteppingOutOfYRange, /** stepping out of range */ SteppingOutOfRange, /** in range again */ InRangeAgain, /** stepping in range */ SteppingInRange; } /** the flag indicating whether the previous point is out of range */ private boolean isPrevOutOfRange; /* * @see Compress#addNecessaryPlots(ArrayList, ArrayList, ArrayList) */ @Override protected void addNecessaryPlots(ArrayList xList, ArrayList yList, ArrayList indexList) { isPrevOutOfRange = true; for (int i = 0; i < xSeries.length && i < ySeries.length; i++) { STATE state = getState(i); switch (state) { case SteppingOutOfYRange: addToList(xList, yList, indexList, xSeries[i], ySeries[i], i); break; case SteppingOverYRange: case SteppingInRange: case SteppingInXRange: addToList(xList, yList, indexList, xSeries[i - 1], ySeries[i - 1], i - 1); addToList(xList, yList, indexList, xSeries[i], ySeries[i], i); break; case SteppingOverXRange: case SteppingOutOfXRange: addToList(xList, yList, indexList, xSeries[i - 1], ySeries[i - 1], i - 1); addToList(xList, yList, indexList, xSeries[i], ySeries[i], i); i = xSeries.length; break; case SteppingOutOfRange: addToList(xList, yList, indexList, xSeries[i], ySeries[i], i); i = xSeries.length; break; case InRangeAgain: if (!isInSameGridAsPrevious(xSeries[i], ySeries[i])) { addToList(xList, yList, indexList, xSeries[i], ySeries[i], i); } break; case OutOfRangeAgain: break; default: break; } } } /** * Gets the state for each plot. * * @param index * the index for plot * @return the state of plot for the given index */ private STATE getState(int index) { STATE state; if (xLower <= xSeries[index] && xSeries[index] <= xUpper) { if (yLower <= ySeries[index] && ySeries[index] <= yUpper) { if (index > 0 && isPrevOutOfRange) { state = STATE.SteppingInRange; } else { state = STATE.InRangeAgain; } } else { if (isPrevOutOfRange) { if (index > 0 && ((ySeries[index - 1] < yLower && ySeries[index] > yUpper) || ySeries[index - 1] > yUpper && ySeries[index] < yLower)) { state = STATE.SteppingOverYRange; } else if (index > 0 && xSeries[index - 1] < xLower && xSeries[index] > xLower) { state = STATE.SteppingInXRange; } else { state = STATE.OutOfRangeAgain; } } else { state = STATE.SteppingOutOfYRange; } } } else { if (!isPrevOutOfRange) { state = STATE.SteppingOutOfRange; } else if (index > 0 && xSeries[index - 1] < xUpper && xSeries[index] > xUpper) { state = STATE.SteppingOutOfXRange; } else if (index > 0 && xSeries[index - 1] < xLower && xSeries[index] > xUpper) { state = STATE.SteppingOverXRange; } else { state = STATE.OutOfRangeAgain; } } // set flag if (xLower <= xSeries[index] && xSeries[index] <= xUpper && yLower <= ySeries[index] && ySeries[index] <= yUpper) { isPrevOutOfRange = false; } else { isPrevOutOfRange = true; } return state; } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/compress/Compress.java0000644000175000017500000002047512657165716031553 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.compress; import java.util.ArrayList; /** * A base class for compressor providing default implementations. */ public abstract class Compress implements ICompress { /** the previous X grid index */ protected int previousXGridIndex; /** the previous Y grid index */ protected int previousYGridIndex; /** the configuration for compressor */ protected CompressConfig config; /** the previous configuration for compressor */ protected CompressConfig prevConfig; /** the flag indicating whether the data is compressed */ protected boolean compressed; /** the source X series to be compressed */ protected double[] xSeries = null; /** the source Y series to be compressed */ protected double[] ySeries = null; /** the compressed X series */ protected transient double[] compressedXSeries = null; /** the compressed Y series */ protected transient double[] compressedYSeries = null; /** the compressed series indexes */ protected transient int[] compressedIndexes = null; /** the lower value of x range */ protected double xLower; /** the upper value of x range */ protected double xUpper; /** the lower value of y range */ protected double yLower; /** the upper value of y range */ protected double yUpper; /** the state indicating if x axis is log scale */ private boolean isXLogScale; /** the state indicating if y axis is log scale */ private boolean isYLogScale; /** the plot area width in pixels */ private long widthInPixel; /** the plot area height in pixels */ private long heightInPixel; /* * @see ICompress#setXSeries(double[]) */ public void setXSeries(double[] xSeries) { if (xSeries == null) { return; } double[] copiedSeries = new double[xSeries.length]; System.arraycopy(xSeries, 0, copiedSeries, 0, xSeries.length); this.xSeries = copiedSeries; compressedXSeries = copiedSeries; compressedIndexes = new int[xSeries.length]; for (int i = 0; i < xSeries.length; i++) { compressedIndexes[i] = i; } compressed = false; } /* * @see ICompress#setYSeries(double[]) */ public void setYSeries(double[] ySeries) { if (ySeries == null) { return; } double[] copiedSeries = new double[ySeries.length]; System.arraycopy(ySeries, 0, copiedSeries, 0, ySeries.length); this.ySeries = copiedSeries; compressedYSeries = copiedSeries; compressed = false; } /* * @see ICompress#getCompressedXSeries() */ public double[] getCompressedXSeries() { double[] copiedSeries = new double[compressedXSeries.length]; System.arraycopy(compressedXSeries, 0, copiedSeries, 0, compressedXSeries.length); return copiedSeries; } /* * @see ICompress#getCompressedYSeries() */ public double[] getCompressedYSeries() { double[] copiedSeries = new double[compressedYSeries.length]; System.arraycopy(compressedYSeries, 0, copiedSeries, 0, compressedYSeries.length); return copiedSeries; } /* * @see ICompress#getCompressedIndexes() */ public int[] getCompressedIndexes() { int[] copiedSeries = new int[compressedIndexes.length]; System.arraycopy(compressedIndexes, 0, copiedSeries, 0, compressedIndexes.length); return copiedSeries; } /* * @see ICompress#compress(CompressConfig) */ final public boolean compress(CompressConfig compressConfig) { if ((compressConfig.equals(prevConfig) && compressed) || xSeries == null || ySeries == null) { return false; } // store the previous configuration prevConfig = new CompressConfig(compressConfig); this.config = compressConfig; // store into fields to improve performance xLower = config.getXLowerValue(); xUpper = config.getXUpperValue(); yLower = config.getYLowerValue(); yUpper = config.getYUpperValue(); isXLogScale = config.isXLogScale(); isYLogScale = config.isYLogScale(); widthInPixel = config.getWidthInPixel(); heightInPixel = config.getHeightInPixel(); previousXGridIndex = -1; previousYGridIndex = -1; ArrayList xList = new ArrayList(); ArrayList yList = new ArrayList(); ArrayList indexList = new ArrayList(); // add necessary plots to the array addNecessaryPlots(xList, yList, indexList); compressedXSeries = new double[xList.size()]; compressedYSeries = new double[yList.size()]; compressedIndexes = new int[indexList.size()]; for (int i = 0; i < xList.size(); i++) { compressedXSeries[i] = xList.get(i); compressedYSeries[i] = yList.get(i); compressedIndexes[i] = indexList.get(i); } compressed = true; return true; } /** * Adds the necessary plots. * * @param xList * the array in which x coordinate for necessary plot is stored * @param yList * the array in which y coordinate for necessary plot is stored * @param indexList * the array in which series index for necessary plot is stored */ abstract protected void addNecessaryPlots(ArrayList xList, ArrayList yList, ArrayList indexList); /** * Adds the given coordinate to list. * * @param xList * the list to store the X coordinate * @param yList * the list to store the Y coordinate * @param indexList * the list to store the series index * @param x * the X coordinate * @param y * the Y coordinate * @param index * the series index */ protected void addToList(ArrayList xList, ArrayList yList, ArrayList indexList, double x, double y, int index) { xList.add(x); yList.add(y); indexList.add(index); } /** * Checks if the given coordinate is in the same grid as previous. * * @param x * the X coordinate * @param y * the Y coordinate * @return true if the given coordinate is in the same grid as previous */ protected boolean isInSameGridAsPrevious(double x, double y) { int xGridIndex; int yGridIndex; // calculate the X grid index if (isXLogScale) { double lower = Math.log10(xLower); double upper = Math.log10(xUpper); xGridIndex = (int) ((Math.log10(x) - lower) / (upper - lower) * widthInPixel); } else { xGridIndex = (int) ((x - xLower) / (xUpper - xLower) * widthInPixel); } // calculate the Y grid index if (isYLogScale) { double lower = Math.log10(yLower); double upper = Math.log10(yUpper); yGridIndex = (int) ((Math.log10(y) - lower) / (upper - lower) * heightInPixel); } else { yGridIndex = (int) ((y - yLower) / (yUpper - yLower) * heightInPixel); } // check if the grid index is the same as previous boolean isInSameGridAsPrevious = (xGridIndex == previousXGridIndex && yGridIndex == previousYGridIndex); // store the previous grid index previousXGridIndex = xGridIndex; previousYGridIndex = yGridIndex; return isInSameGridAsPrevious; } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/compress/ICompress.java0000644000175000017500000000313012657165716031651 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.compress; /** * A Compressor. */ public interface ICompress { /** * Gets the compressed X series * * @return the compressed X series */ public abstract double[] getCompressedXSeries(); /** * Gets the compressed Y series * * @return the compressed Y series */ public abstract double[] getCompressedYSeries(); /** * Gets the compressed series indexes * * @return the compressed series indexes */ public abstract int[] getCompressedIndexes(); /** * Sets X series which have to be sorted. * * @param xSeries * the X series */ public abstract void setXSeries(double[] xSeries); /** * sets the Y series * * @param ySeries * the Y series */ public abstract void setYSeries(double[] ySeries); /** * Ignores the points which are in the same grid as the previous point. * * @param config * the configuration for compression * @return true if the compression succeeds */ public abstract boolean compress(CompressConfig config); }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/compress/CompressBarSeries.java0000644000175000017500000000450412657165716033346 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.compress; import java.util.ArrayList; /** * A compressor for bar series data. */ public class CompressBarSeries extends Compress { /* * @see Compress#addNecessaryPlots(ArrayList, ArrayList, ArrayList) */ @Override protected void addNecessaryPlots(ArrayList xList, ArrayList yList, ArrayList indexList) { double prevX = xSeries[0]; double maxY = Double.NaN; int prevIndex = 0; for (int i = 0; i < xSeries.length && i < ySeries.length; i++) { if (xSeries[i] >= config.getXLowerValue()) { if (isInSameGridXAsPrevious(xSeries[i])) { if (maxY < ySeries[i]) { maxY = ySeries[i]; } } else { if (!Double.isNaN(maxY)) { addToList(xList, yList, indexList, prevX, maxY, prevIndex); } prevX = xSeries[i]; maxY = ySeries[i]; prevIndex = i; } } if (xSeries[i] > config.getXUpperValue()) { break; } } addToList(xList, yList, indexList, prevX, maxY, prevIndex); } /** * Checks if the given x coordinate is in the same grid as previous. * * @param x * the X coordinate * @return true if the given coordinate is in the same grid as previous */ private boolean isInSameGridXAsPrevious(double x) { int xGridIndex = (int) ((x - config.getXLowerValue()) / (config.getXUpperValue() - config.getXLowerValue()) * config .getWidthInPixel()); boolean isInSameGridAsPrevious = (xGridIndex == previousXGridIndex); previousXGridIndex = xGridIndex; return isInSameGridAsPrevious; } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/compress/CompressScatterSeries.java0000644000175000017500000000755112657165716034254 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.compress; import java.util.ArrayList; /** * A compressor for scatter series data */ public class CompressScatterSeries extends Compress { /** the state indicating if line is visible */ private boolean isLineVisible; /** flag indicating whether the grid is occupied */ private boolean occupied[][]; /* * @see Compress#addNecessaryPlots(ArrayList, ArrayList, ArrayList) */ @Override protected void addNecessaryPlots(ArrayList xList, ArrayList yList, ArrayList indexList) { if (isLineVisible) { for (int i = 0; i < xSeries.length && i < ySeries.length; i++) { if (!isInSameGridAsPrevious(xSeries[i], ySeries[i])) { addToList(xList, yList, indexList, xSeries[i], ySeries[i], i); } } } else { int width = (int) config.getWidthInPixel(); int height = (int) config.getHeightInPixel(); if (width <= 0 || height <= 0) { return; } // initialize flag occupied = new boolean[width][height]; for (int i = 0; i < xSeries.length && i < ySeries.length; i++) { if (xSeries[i] >= xLower && xSeries[i] <= xUpper && ySeries[i] >= yLower && ySeries[i] <= yUpper && !isOccupied(xSeries[i], ySeries[i])) { addToList(xList, yList, indexList, xSeries[i], ySeries[i], i); } } } } /** * check if the grid is already occupied * * @param x * the X coordinate * @param y * the Y coordinate * @return true if the grid is already occupied */ private boolean isOccupied(double x, double y) { int xGridIndex; int yGridIndex; // calculate the X grid index if (config.isXLogScale()) { double lower = Math.log10(config.getXLowerValue()); double upper = Math.log10(config.getXUpperValue()); xGridIndex = (int) ((Math.log10(x) - lower) / (upper - lower) * config .getWidthInPixel()); } else { xGridIndex = (int) ((x - config.getXLowerValue()) / (config.getXUpperValue() - config.getXLowerValue()) * config .getWidthInPixel()); } // calculate the Y grid index if (config.isYLogScale()) { double lower = Math.log10(config.getYLowerValue()); double upper = Math.log10(config.getYUpperValue()); yGridIndex = (int) ((Math.log10(y) - lower) / (upper - lower) * config .getHeightInPixel()); } else { yGridIndex = (int) ((y - config.getYLowerValue()) / (config.getYUpperValue() - config.getYLowerValue()) * config .getHeightInPixel()); } boolean isOccupied = occupied[xGridIndex][yGridIndex]; occupied[xGridIndex][yGridIndex] = true; return isOccupied; } /** * Sets the state indicating if the line is visible. * * @param visible * the state indicating if the line is visible */ public void setLineVisible(boolean visible) { isLineVisible = visible; } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/Grid.java0000644000175000017500000001140512657165716027003 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal; import java.util.ArrayList; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.widgets.Display; import org.swtchart.IGrid; import org.swtchart.LineStyle; import org.swtchart.internal.axis.Axis; /** * A grid. */ public class Grid implements IGrid { /** the axis */ private Axis axis; /** the grid color */ private Color color; /** the visibility state */ private boolean isVisible; /** the line style */ private LineStyle lineStyle; /** the line width */ private final static int LINE_WIDTH = 1; /** the default style */ private final static LineStyle DEFAULT_STYLE = LineStyle.DOT; /** the default color */ private final static int DEFAULT_FOREGROUND = SWT.COLOR_GRAY; /** * Constructor. * * @param axis * the axis */ public Grid(Axis axis) { this.axis = axis; color = Display.getDefault().getSystemColor(DEFAULT_FOREGROUND); lineStyle = DEFAULT_STYLE; isVisible = true; } /* * @see IGrid#getForeground() */ public Color getForeground() { if (color.isDisposed()) { color = Display.getDefault().getSystemColor(DEFAULT_FOREGROUND); } return color; } /* * @see IGrid#setForeground(Color) */ public void setForeground(Color color) { if (color != null && color.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } if (color == null) { this.color = Display.getDefault() .getSystemColor(DEFAULT_FOREGROUND); } else { this.color = color; } } /* * @see IGrid#getStyle() */ public LineStyle getStyle() { return lineStyle; } /* * @see IGrid#setStyle(LineStyle) */ public void setStyle(LineStyle style) { if (style == null) { this.lineStyle = DEFAULT_STYLE; } else { this.lineStyle = style; } } /** * Draws grid. * * @param gc * the graphics context * @param width * the width to draw grid * @param height * the height to draw grid */ protected void draw(GC gc, int width, int height) { if (!isVisible || lineStyle.equals(LineStyle.NONE)) { return; } int xWidth; if (axis.isHorizontalAxis()) { xWidth = width; } else { xWidth = height; } Color oldForeground = gc.getForeground(); gc.setForeground(getForeground()); ArrayList tickLabelPosition = axis.getTick() .getAxisTickLabels().getTickLabelPositions(); gc.setLineStyle(Util.getIndexDefinedInSWT(lineStyle)); if (axis.isValidCategoryAxis()) { int step = 0; if (tickLabelPosition.size() > 1) { step = tickLabelPosition.get(1).intValue() - tickLabelPosition.get(0).intValue(); } else { step = xWidth; } int x = (int) (tickLabelPosition.get(0).intValue() - step / 2d); for (int i = 0; i < tickLabelPosition.size() + 1; i++) { x += step; if (x >= xWidth) { continue; } if (axis.isHorizontalAxis()) { gc.drawLine(x, LINE_WIDTH, x, height - LINE_WIDTH); } else { gc.drawLine(LINE_WIDTH, x, width - LINE_WIDTH, x); } } } else { for (int i = 0; i < tickLabelPosition.size(); i++) { int x = tickLabelPosition.get(i).intValue(); if (x >= xWidth) { continue; } if (axis.isHorizontalAxis()) { gc.drawLine(x, LINE_WIDTH, x, height - LINE_WIDTH); } else { gc.drawLine(LINE_WIDTH, height - 1 - x, width - LINE_WIDTH, height - 1 - x); } } } gc.setForeground(oldForeground); } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/ChartLayoutData.java0000644000175000017500000000162712657165716031154 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal; /** * The chart layout data */ public class ChartLayoutData { /** the width hint */ public int widthHint; /** the height hint */ public int heightHint; /** * Constructor. * * @param widthHint * the width hint * @param heightHint * the height hint */ public ChartLayoutData(int widthHint, int heightHint) { this.widthHint = widthHint; this.heightHint = heightHint; } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/Title.java0000644000175000017500000002503412657165716027202 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.TextLayout; import org.eclipse.swt.graphics.Transform; import org.eclipse.swt.widgets.Display; import org.swtchart.Chart; import org.swtchart.Constants; import org.swtchart.ITitle; /** * A base class for title. */ public class Title implements ITitle, PaintListener { /** the chart */ protected Chart chart; /** the title text */ protected String text; /** the foreground color */ private Color foreground; /** the font */ private Font font; /** the style ranges */ private StyleRange[] styleRanges; /** The text layout */ private final TextLayout textLayout; /** the visibility state of axis */ protected boolean isVisible; /** the default font */ private final Font defaultFont; /** the bounds of title */ private Rectangle bounds; /** the layout data */ private ChartLayoutData layoutData; /** the default font size */ private static final int DEFAULT_FONT_SIZE = Constants.LARGE_FONT_SIZE; /** the default color */ private static final int DEFAULT_FOREGROUND = SWT.COLOR_BLUE; /** the default text */ private static final String DEFAULT_TEXT = ""; /** * Constructor. * * @param parent * the parent composite */ public Title(Chart parent) { this.chart = parent; text = DEFAULT_TEXT; isVisible = true; defaultFont = new Font(Display.getDefault(), "Tahoma", DEFAULT_FONT_SIZE, SWT.BOLD); textLayout = new TextLayout(Display.getDefault()); bounds = new Rectangle(0, 0, 0, 0); font = defaultFont; setForeground(Display.getDefault().getSystemColor(DEFAULT_FOREGROUND)); parent.addPaintListener(this); } /* * @see ITitle#setText(String) */ public void setText(String text) { String title; if (text == null) { title = getDefaultText(); } else { title = text; } textLayout.setText(title); this.text = title; chart.updateLayout(); // text could be changed to blank } /** * Gets the default title text. * * @return the default title text */ protected String getDefaultText() { return DEFAULT_TEXT; } /* * @see ITitle#getText() */ public String getText() { return text; } /** * Sets the font. * * @param font * the font */ public void setFont(Font font) { if (font == null) { this.font = defaultFont; } else if (font.isDisposed()) { throw new IllegalArgumentException("disposed font is given"); } else { this.font = font; } chart.updateLayout(); } /** * Gets the font. * * @return the font */ public Font getFont() { if (font.isDisposed()) { font = defaultFont; } return font; } /** * Sets the foreground color. * * @param color * the foreground color */ public void setForeground(Color color) { if (color == null) { foreground = Display.getDefault() .getSystemColor(DEFAULT_FOREGROUND); } else if (color.isDisposed()) { throw new IllegalArgumentException("disposed color is given"); } else { foreground = color; } } /** * Gets the foreground color. * * @return the foreground color */ public Color getForeground() { return foreground; } /* * @see ITitle#setStyleRanges(StyleRange[]) */ public void setStyleRanges(StyleRange[] ranges) { styleRanges = ranges; if (styleRanges != null) { for (StyleRange range : styleRanges) { if (range != null) { textLayout.setStyle(range, range.start, range.start + range.length); } } } chart.updateLayout(); } /* * @see ITitle#getStyleRanges() */ public StyleRange[] getStyleRanges() { return styleRanges; } /* * @see ITitle#setVisible(boolean) */ public void setVisible(boolean isVisible) { if (this.isVisible == isVisible) { return; } this.isVisible = isVisible; chart.updateLayout(); } /* * @see ITitle#isVisible() */ public boolean isVisible() { return isVisible; } /** * Gets the state indicating if showing title horizontally. * * @return the state indicating if showing title horizontally */ protected boolean isHorizontal() { return true; } /** * Updates the title layout data. */ public void updateLayoutData() { int height; int width; if (isVisible() && !text.trim().equals("")) { if (styleRanges == null) { Point p = Util.getExtentInGC(getFont(), text); width = p.x; height = p.y; } else { Rectangle r = textLayout.getBounds(); width = r.width; height = r.height; } } else { width = 0; height = 0; } if (isHorizontal()) { setLayoutData(new ChartLayoutData(width, height)); } else { setLayoutData(new ChartLayoutData(height, width)); } } /** * Sets the layout data. * * @param layoutData * the layout data */ public void setLayoutData(ChartLayoutData layoutData) { this.layoutData = layoutData; } /** * Gets the layout data. * * @return the layout data */ public ChartLayoutData getLayoutData() { return layoutData; } /** * Disposes the resources. */ public void dispose() { if (!defaultFont.isDisposed()) { defaultFont.dispose(); } if (!textLayout.isDisposed()) { textLayout.dispose(); } chart.removePaintListener(this); } /* * @see PaintListener#paintControl(PaintEvent) */ public void paintControl(PaintEvent e) { if (text == null || text.equals("") || !isVisible) { return; } Font oldFont = e.gc.getFont(); Color oldForeground = getForeground(); e.gc.setFont(getFont()); e.gc.setForeground(getForeground()); if (isHorizontal()) { drawHorizontalTitle(e.gc); } else { drawVerticalTitle(e.gc); } e.gc.setFont(oldFont); e.gc.setForeground(oldForeground); } /** * Sets the bounds on chart panel. * * @param x * the x coordinate * @param y * the y coordinate * @param width * the width * @param height * the height */ public void setBounds(int x, int y, int width, int height) { bounds = new Rectangle(x, y, width, height); } /** * Gets the bounds on chart panel. * * @return the bounds on chart panel */ public Rectangle getBounds() { return bounds; } /** * Draws the horizontal title. * * @param gc * The graphics context */ private void drawHorizontalTitle(GC gc) { boolean useStyleRanges = styleRanges != null; int x = getBounds().x; int y = getBounds().y; if (useStyleRanges) { textLayout.draw(gc, x, y); } else { gc.drawText(text, x, y, true); } } /** * Draws the vertical title. * * @param gc * The graphics context */ private void drawVerticalTitle(GC gc) { boolean useStyleRanges = styleRanges != null; int textWidth = getBounds().height; int textHeight = getBounds().width; // widen for italic font int margin = textHeight / 10; textWidth += margin; /* * create image to draw text. If drawing text on rotated graphics * context instead of drawing rotated image, the text shape becomes a * bit ugly especially with small font with bold. */ Image image = new Image(Display.getCurrent(), textWidth, textHeight); GC tmpGc = new GC(image); if (useStyleRanges) { textLayout.draw(tmpGc, 0, 0); } else { tmpGc.setBackground(chart.getBackground()); tmpGc.setForeground(getForeground()); tmpGc.setFont(getFont()); tmpGc.fillRectangle(image.getBounds()); tmpGc.drawText(text, 0, 0); } // set transform to rotate Transform oldTransform = new Transform(gc.getDevice()); gc.getTransform(oldTransform); Transform transform = new Transform(gc.getDevice()); transform.translate(0, textWidth); transform.rotate(270); gc.setTransform(transform); // draw the image on the rotated graphics context int x = getBounds().x; int y = getBounds().y; gc.drawImage(image, -y, x); gc.setTransform(oldTransform); // dispose resources tmpGc.dispose(); transform.dispose(); image.dispose(); } }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/ChartLayout.java0000644000175000017500000005772412657165716030373 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal; import java.util.HashMap; import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Layout; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.IAxis.Position; import org.swtchart.IAxisSet; import org.swtchart.internal.axis.Axis; import org.swtchart.internal.axis.AxisTickLabels; import org.swtchart.internal.axis.AxisTickMarks; import org.swtchart.internal.axis.AxisTitle; /** * Manages the layout on plot chart panel. */ public class ChartLayout extends Layout { /** the title height */ private int titleHeight; /** the title width */ private int titleWidth; /** the legend width */ private int legendWidth; /** the legend height */ private int legendHeight; /** the bottom axis height */ private int bottomAxisHeight; /** the top axis height */ private int topAxisHeight; /** the left axis width */ private int leftAxisWidth; /** the right axis width */ private int rightAxisWidth; /** the plot area width */ private int plotAreaWidth; /** the plot area height */ private int plotAreaHeight; /** the chart title */ private ChartTitle title; /** the legend */ private Legend legend; /** the plot area */ private PlotArea plot; /** the axes */ private Axis[] axes; /** the horizontal axes */ private Axis[] horizontalAxes; /** the vertical axes */ private Axis[] verticalAxes; /** the map between axis and axis layout data */ private Map axisLayoutDataMap; /** the offset for bottom axis */ private int bottomAxisOffset = 0; /** the offset for top axis */ private int topAxisOffset = 0; /** the offset for left axis */ private int leftAxisOffset = 0; /** the offset for right axis */ private int rightAxisOffset = 0; /** the margin */ public static final int MARGIN = 5; /** the padding */ public static final int PADDING = 5; /** * Constructor. */ public ChartLayout() { initWidgetSizeVariables(); axisLayoutDataMap = new HashMap(); } /** * Initializes the size variables of widgets. */ private void initWidgetSizeVariables() { titleHeight = 0; titleWidth = 0; bottomAxisHeight = 0; topAxisHeight = 0; leftAxisWidth = 0; rightAxisWidth = 0; legendWidth = 0; legendHeight = 0; plotAreaWidth = 0; plotAreaHeight = 0; } /* * @see Layout#computeSize(Composite , int, int, boolean) */ @Override protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { return new Point(wHint, hHint); } /* * @see Layout#layout(Composite, boolean) */ @Override protected void layout(Composite composite, boolean flushCache) { if (!parseControls(composite)) { return; } Rectangle r = composite.getClientArea(); initWidgetSizeVariables(); initTitleAndLegendSize(); initAxisSize(); computePlotAreaSize(r); computeAxisSize(r); adjustForRotatedTickLabels(r); adjustForMostLeftRightTickLabel(r); layoutTitle(r); layoutLegend(r); layoutPlot(r); layoutAxes(r); } /** * Parses the controls on given composite. * * @param composite * the composite * @return true if all children found */ private boolean parseControls(Composite composite) { for (Control child : composite.getChildren()) { if (child instanceof Legend) { legend = (Legend) child; } else if (child instanceof PlotArea) { plot = (PlotArea) child; } } if (composite instanceof Chart) { IAxisSet axisSet = ((Chart) composite).getAxisSet(); if (axisSet != null) { axes = (Axis[]) axisSet.getAxes(); if (((Chart) composite).getOrientation() == SWT.HORIZONTAL) { horizontalAxes = (Axis[]) axisSet.getXAxes(); verticalAxes = (Axis[]) axisSet.getYAxes(); } else { verticalAxes = (Axis[]) axisSet.getXAxes(); horizontalAxes = (Axis[]) axisSet.getYAxes(); } } title = (ChartTitle) ((Chart) composite).getTitle(); } if (title == null || legend == null || plot == null || axes == null) { // the initialization of chart is not completed yet return false; } return true; } /** * Initializes the size of title and legend. */ private void initTitleAndLegendSize() { titleWidth = ((ChartLayoutData) title.getLayoutData()).widthHint; titleHeight = ((ChartLayoutData) title.getLayoutData()).heightHint; legendWidth = ((ChartLayoutData) legend.getLayoutData()).widthHint; legendHeight = ((ChartLayoutData) legend.getLayoutData()).heightHint; } /** * Initializes the size of axes. */ private void initAxisSize() { axisLayoutDataMap.clear(); for (Axis axis : axes) { AxisLayoutData layoutData = new AxisLayoutData(axis); if (layoutData.titleLayoutdata == null || layoutData.tickLabelsLayoutdata == null || layoutData.tickMarksLayoutdata == null) { continue; } axisLayoutDataMap.put(axis, layoutData); Position position = axis.getPosition(); if (position == Position.Primary && axis.isHorizontalAxis()) { bottomAxisHeight += layoutData.titleLayoutdata.heightHint + layoutData.tickLabelsLayoutdata.heightHint + layoutData.tickMarksLayoutdata.heightHint; } else if (position == Position.Secondary && axis.isHorizontalAxis()) { topAxisHeight += layoutData.titleLayoutdata.heightHint + layoutData.tickLabelsLayoutdata.heightHint + layoutData.tickMarksLayoutdata.heightHint; } else if (position == Position.Primary && !axis.isHorizontalAxis()) { leftAxisWidth += layoutData.titleLayoutdata.widthHint + layoutData.tickLabelsLayoutdata.widthHint + layoutData.tickMarksLayoutdata.widthHint; } else if (position == Position.Secondary && !axis.isHorizontalAxis()) { rightAxisWidth += layoutData.titleLayoutdata.widthHint + layoutData.tickLabelsLayoutdata.widthHint + layoutData.tickMarksLayoutdata.widthHint; } } } /** * Computes the size of plot area. * * @param r * the rectangle to layout */ private void computePlotAreaSize(Rectangle r) { int legendPosition = legend.getPosition(); plotAreaWidth = r.width - leftAxisWidth - rightAxisWidth - (legendPosition == SWT.LEFT || legendPosition == SWT.RIGHT ? legendWidth + (legendWidth == 0 ? 0 : PADDING) : 0) - MARGIN * 2; plotAreaHeight = r.height - bottomAxisHeight - topAxisHeight - titleHeight - MARGIN * 2 - (titleHeight == 0 ? 0 : PADDING) - (legendPosition == SWT.TOP || legendPosition == SWT.BOTTOM ? legendHeight + (legendHeight == 0 ? 0 : PADDING) : 0); } /** * Computes the size of axes updating tick labels. * * @param r * the rectangle to layout */ private void computeAxisSize(Rectangle r) { // update vertical axis tick labels updateVerticalAxisTick(); // compute axis width for (IAxis axis : verticalAxes) { int tickAreaWidth = Axis.MARGIN; if (axis.getTick().isVisible()) { tickAreaWidth = ((Axis) axis).getTick().getAxisTickLabels() .getTickLabelMaxLength(); } AxisLayoutData axisLayout = axisLayoutDataMap.get(axis); axisLayout.tickLabelsLayoutdata.widthHint += tickAreaWidth; if (axis.getPosition() == Position.Primary) { leftAxisWidth += tickAreaWidth; } else { rightAxisWidth += tickAreaWidth; } } // compute axis height for (IAxis axis : horizontalAxes) { if (axis.getTick().isVisible()) { continue; } if (axis.getPosition() == Position.Primary) { bottomAxisHeight += Axis.MARGIN; } else { topAxisHeight += Axis.MARGIN; } } // update plot area width computePlotAreaSize(r); // update horizontal axis tick labels updateHorizontalAxisTick(); } /** * Adjust the axis size for rotated tick labels. * * @param r * the rectangle to layout */ private void adjustForRotatedTickLabels(Rectangle r) { for (IAxis axis : horizontalAxes) { double angle = axis.getTick().getTickLabelAngle(); if (angle == 0 || !axis.getTick().isVisible()) { continue; } // update tick label height int tickLabelMaxLength = ((Axis) axis).getTick() .getAxisTickLabels().getTickLabelMaxLength(); AxisLayoutData layoutData = axisLayoutDataMap.get(axis); int height = Axis.MARGIN + (int) (tickLabelMaxLength * Math.sin(Math.toRadians(angle)) + Util .getExtentInGC(layoutData.axisTickLabels.getFont(), null).y * Math.cos(Math.toRadians(angle))); int delta = height - layoutData.tickLabelsLayoutdata.heightHint; layoutData.tickLabelsLayoutdata.heightHint = height; // update axis height if (axis.getPosition() == Position.Primary) { bottomAxisHeight += delta; } else { topAxisHeight += delta; } // update plot area height computePlotAreaSize(r); updateVerticalAxisTick(); } } /** * Adjust the axis size for most left/right tick label. * * @param r * the rectangle to layout */ private void adjustForMostLeftRightTickLabel(Rectangle r) { // get axis margin hint int rightAxisMarginHint = 0; int leftAxisMarginHint = 0; for (IAxis axis : horizontalAxes) { if (!axis.getTick().isVisible()) { continue; } rightAxisMarginHint = Math.max(rightAxisMarginHint, ((Axis) axis).getTick().getAxisTickLabels() .getRightMarginHint(plotAreaWidth)); leftAxisMarginHint = Math.max(leftAxisMarginHint, ((Axis) axis).getTick().getAxisTickLabels() .getLeftMarginHint(plotAreaWidth)); } // have space to draw most right tick label on horizontal axis if ((legendWidth == 0 || legend.getPosition() != SWT.RIGHT) && rightAxisWidth < rightAxisMarginHint) { rightAxisWidth = rightAxisMarginHint; computePlotAreaSize(r); updateHorizontalAxisTick(); } // have space to draw most left tick label on horizontal axis if ((legendWidth == 0 || legend.getPosition() != SWT.LEFT) && leftAxisWidth < leftAxisMarginHint) { leftAxisWidth = leftAxisMarginHint; computePlotAreaSize(r); updateHorizontalAxisTick(); } } /** * Updates the horizontal axis tick. */ private void updateHorizontalAxisTick() { for (IAxis axis : horizontalAxes) { ((Axis) axis).getTick().updateTick(plotAreaWidth); } } /** * Updates the vertical axis tick. */ private void updateVerticalAxisTick(){ for (IAxis axis : verticalAxes) { ((Axis) axis).getTick().updateTick(plotAreaHeight); } } /** * Layouts the title. * * @param r * the rectangle to layout */ private void layoutTitle(Rectangle r) { int x = (int) ((r.width - titleWidth) / 2d); int y = MARGIN; int width = titleWidth; int height = titleHeight; title.setBounds(x, y, width, height); } /** * Layouts the legend. * * @param r * the rectangle to layout */ private void layoutLegend(Rectangle r) { int legendPosition = legend.getPosition(); int tHeight = titleHeight + ((titleHeight == 0) ? 0 : PADDING); int x; int y; if (legendPosition == SWT.RIGHT) { x = r.width - legendWidth - MARGIN; y = (tHeight + r.height - legendHeight) / 2; } else if (legendPosition == SWT.LEFT) { x = MARGIN; y = (tHeight + r.height - legendHeight) / 2; } else if (legendPosition == SWT.TOP) { x = (r.width - legendWidth) / 2; y = tHeight + MARGIN; } else if (legendPosition == SWT.BOTTOM) { x = (r.width - legendWidth) / 2; y = r.height - legendHeight - MARGIN; } else { throw new IllegalStateException(); } int width = legendWidth; int height = legendHeight; if (y < tHeight) { y = tHeight; } legend.setBounds(x, y, width, height); } /** * Layouts the plot. * * @param r * the rectangle to layout */ private void layoutPlot(Rectangle r) { int legendPosition = legend.getPosition(); int x = leftAxisWidth + MARGIN + (legendPosition == SWT.LEFT ? legendWidth + (legendWidth == 0 ? 0 : PADDING) : 0); int y = titleHeight + topAxisHeight + MARGIN + (titleHeight == 0 ? 0 : PADDING) + (legendPosition == SWT.TOP ? legendHeight + (legendHeight == 0 ? 0 : PADDING) : 0); plot.setBounds(x, y, plotAreaWidth, plotAreaHeight); } /** * Layouts the axes. * * @param r * the rectangle to layout */ private void layoutAxes(Rectangle r) { bottomAxisOffset = 0; topAxisOffset = 0; leftAxisOffset = 0; rightAxisOffset = 0; for (Axis axis : axes) { AxisLayoutData layoutData = axisLayoutDataMap.get(axis); Position position = axis.getPosition(); if (position == Position.Primary && axis.isHorizontalAxis()) { layoutBottomAxis(r, layoutData); } else if (position == Position.Secondary && axis.isHorizontalAxis()) { layoutTopAxis(r, layoutData); } else if (position == Position.Primary && !axis.isHorizontalAxis()) { layoutLeftAxis(r, layoutData); } else if (position == Position.Secondary && !axis.isHorizontalAxis()) { layoutRightAxis(r, layoutData); } } } /** * Layouts the bottom axis. * * @param r * the rectangle * @param layoutData * the layout data */ private void layoutBottomAxis(Rectangle r, AxisLayoutData layoutData) { int legendPosition = legend.getPosition(); int height = layoutData.titleLayoutdata.heightHint; int x = leftAxisWidth + MARGIN + (legendPosition == SWT.LEFT ? legendWidth + (legendWidth == 0 ? 0 : PADDING) : 0); int y = r.height - height - bottomAxisOffset - MARGIN - (legendPosition == SWT.BOTTOM ? legendHeight + (legendHeight == 0 ? 0 : PADDING) : 0); bottomAxisOffset += height; if (y - layoutData.tickLabelsLayoutdata.heightHint - layoutData.tickMarksLayoutdata.heightHint < titleHeight + (titleHeight == 0 ? 0 : PADDING)) { y = titleHeight + (titleHeight == 0 ? 0 : PADDING) + layoutData.tickLabelsLayoutdata.heightHint + layoutData.tickMarksLayoutdata.heightHint; } int width = layoutData.titleLayoutdata.widthHint; int titleX = x + (plotAreaWidth - width) / 2; layoutData.axisTitle.setBounds(titleX, y, width, height); height = layoutData.tickLabelsLayoutdata.heightHint; y -= height; bottomAxisOffset += height; layoutData.axisTickLabels.setBounds(0, y, r.width, height); height = layoutData.tickMarksLayoutdata.heightHint; y -= height; bottomAxisOffset += height; layoutData.axisTickMarks.setBounds(x, y, plotAreaWidth, height); } /** * Layouts the top axis. * * @param r * the rectangle * @param layoutData * the layout data */ private void layoutTopAxis(Rectangle r, AxisLayoutData layoutData) { int legendPosition = legend.getPosition(); int height = layoutData.titleLayoutdata.heightHint; int x = leftAxisWidth + MARGIN + (legendPosition == SWT.LEFT ? legendWidth + (legendWidth == 0 ? 0 : PADDING) : 0); int y = titleHeight + topAxisOffset + MARGIN + ((titleHeight == 0) ? 0 : PADDING); topAxisOffset += height; int width = layoutData.titleLayoutdata.widthHint; int titleX = x + (plotAreaWidth - width) / 2; layoutData.axisTitle.setBounds(titleX, y, width, height); y += height; height = layoutData.tickLabelsLayoutdata.heightHint; topAxisOffset += height; layoutData.axisTickLabels.setBounds(0, y, r.width, height); y += height; height = layoutData.tickMarksLayoutdata.heightHint; topAxisOffset += height; layoutData.axisTickMarks.setBounds(x, y, plotAreaWidth, height); } /** * Layouts the left axis. * * @param r * the rectangle * @param layoutData * the layout data */ private void layoutLeftAxis(Rectangle r, AxisLayoutData layoutData) { int legendPosition = legend.getPosition(); int yAxisMargin = Axis.MARGIN + AxisTickMarks.TICK_LENGTH; int width = layoutData.titleLayoutdata.widthHint; int x = MARGIN + leftAxisOffset + (legendPosition == SWT.LEFT ? legendWidth + (legendWidth == 0 ? 0 : PADDING) : 0); int y = titleHeight + topAxisHeight + MARGIN + ((titleHeight == 0) ? 0 : PADDING) + (legendPosition == SWT.TOP ? legendHeight + (legendHeight == 0 ? 0 : PADDING) : 0); leftAxisOffset += width; int height = layoutData.titleLayoutdata.heightHint; int titleY = y + (plotAreaHeight - height) / 2; layoutData.axisTitle.setBounds(x, titleY, width, height); x += width; width = layoutData.tickLabelsLayoutdata.widthHint; leftAxisOffset += width; layoutData.axisTickLabels.setBounds(x, y - yAxisMargin, width, plotAreaHeight + yAxisMargin * 2); x += width; width = layoutData.tickMarksLayoutdata.widthHint; leftAxisOffset += width; layoutData.axisTickMarks.setBounds(x, y, width, plotAreaHeight); } /** * Layouts the right axis. * * @param r * the rectangle * @param layoutData * the layout data */ private void layoutRightAxis(Rectangle r, AxisLayoutData layoutData) { int legendPosition = legend.getPosition(); int yAxisMargin = Axis.MARGIN + AxisTickMarks.TICK_LENGTH; int width = layoutData.titleLayoutdata.widthHint; int x = r.width - width - rightAxisOffset - MARGIN - (legendPosition == SWT.RIGHT ? legendWidth + (legendWidth == 0 ? 0 : PADDING) : 0); int y = titleHeight + topAxisHeight + MARGIN + ((titleHeight == 0) ? 0 : PADDING) + (legendPosition == SWT.TOP ? legendHeight + (legendHeight == 0 ? 0 : PADDING) : 0); rightAxisOffset += width; int height = layoutData.titleLayoutdata.heightHint; int titleY = y + (plotAreaHeight - height) / 2; layoutData.axisTitle.setBounds(x, titleY, width, height); width = layoutData.tickLabelsLayoutdata.widthHint; x -= width; rightAxisOffset += width; layoutData.axisTickLabels.setBounds(x, y - yAxisMargin, width, plotAreaHeight + yAxisMargin * 2); width = layoutData.tickMarksLayoutdata.widthHint; x -= width; rightAxisOffset += width; layoutData.axisTickMarks.setBounds(x, y, width, plotAreaHeight); } /** * Axis layout data. */ private static class AxisLayoutData { /** the axis tick marks */ public AxisTickMarks axisTickMarks; /** the axis tick labels */ public AxisTickLabels axisTickLabels; /** the axis title */ public AxisTitle axisTitle; /** the axis title layout data */ public ChartLayoutData titleLayoutdata; /** the tick label layout data */ public ChartLayoutData tickLabelsLayoutdata; /** the tick marks layout data */ public ChartLayoutData tickMarksLayoutdata; /** * Constructor. * * @param axis * the axis */ public AxisLayoutData(Axis axis) { axisTickMarks = axis.getTick().getAxisTickMarks(); axisTickLabels = axis.getTick().getAxisTickLabels(); axisTitle = (AxisTitle) axis.getTitle(); titleLayoutdata = (ChartLayoutData) axisTitle.getLayoutData(); tickLabelsLayoutdata = axisTickLabels.getLayoutData(); tickMarksLayoutdata = axisTickMarks.getLayoutData(); } } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/series/0000755000175000017500000000000013275316671026537 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/series/ErrorBar.java0000644000175000017500000002205212657165716031126 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.series; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.widgets.Display; import org.swtchart.IErrorBar; import org.swtchart.internal.axis.Axis; /** * The error bar. */ public class ErrorBar implements IErrorBar { /** the default line width */ private static final int DEFAULT_LINE_WIDTH = 1; /** the default error */ private static final double DEFAULT_ERROR = 1d; /** the default color */ private static final int DEFAULT_COLOR = SWT.COLOR_DARK_GRAY; /** the default error bar type */ private static final ErrorBarType DEFAULT_TYPE = ErrorBarType.BOTH; /** the color */ private Color color; /** the line width */ private int lineWidth; /** the error */ private double error; /** the plus errors */ private double[] plusErrors; /** the minus errors */ private double[] minusErrors; /** the error bar type */ private ErrorBarType type; /** the visibility state */ private boolean isVisible; /** * The constructor. */ public ErrorBar() { color = Display.getDefault().getSystemColor(DEFAULT_COLOR); lineWidth = DEFAULT_LINE_WIDTH; error = DEFAULT_ERROR; type = ErrorBarType.BOTH; isVisible = false; plusErrors = new double[0]; minusErrors = new double[0]; } /* * @see IErrorBar#getType() */ public ErrorBarType getType() { return type; } /* * @see IErrorBar#setType(ErrorBarType) */ public void setType(ErrorBarType type) { if (type == null) { this.type = DEFAULT_TYPE; } else { this.type = type; } } /* * @see IErrorBar#getColor() */ public Color getColor() { if (color.isDisposed()) { color = Display.getDefault().getSystemColor(DEFAULT_COLOR); } return color; } /* * @see IErrorBar#setColor(Color) */ public void setColor(Color color) { if (color != null && color.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } if (color == null) { this.color = Display.getDefault().getSystemColor(DEFAULT_COLOR); } else { this.color = color; } } /* * @see IErrorBar#getLineWidth() */ public int getLineWidth() { return lineWidth; } /* * @see IErrorBar#setLineWidth(int) */ public void setLineWidth(int width) { if (width <= 0) { this.lineWidth = DEFAULT_LINE_WIDTH; } else { this.lineWidth = width; } } /* * @see IErrorBar#getError() */ public double getError() { return error; } /* * @see IErrorBar#setError(double) */ public void setError(double error) { if (error < 0) { throw new IllegalArgumentException( "positive value must be given for error."); } this.error = error; } /* * @see IErrorBar#getPlusErrors() */ public double[] getPlusErrors() { double[] copiedSeries = new double[plusErrors.length]; System.arraycopy(plusErrors, 0, copiedSeries, 0, plusErrors.length); return copiedSeries; } /* * @see IErrorBar#setPlusErrors(double[]) */ public void setPlusErrors(double[] errors) { if (errors == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); return; // to suppress warning... } this.plusErrors = new double[errors.length]; System.arraycopy(errors, 0, plusErrors, 0, errors.length); } /* * @see IErrorBar#getMinusErrors() */ public double[] getMinusErrors() { double[] copiedSeries = new double[minusErrors.length]; System.arraycopy(minusErrors, 0, copiedSeries, 0, minusErrors.length); return copiedSeries; } /* * @see IErrorBar#setMinusErrors(double[]) */ public void setMinusErrors(double[] errors) { if (errors == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); return; // to suppress warning... } this.minusErrors = new double[errors.length]; System.arraycopy(errors, 0, minusErrors, 0, errors.length); } /* * @see IErrorBar#isVisible() */ public boolean isVisible() { return isVisible; } /* * @see IErrorBar#setVisible(boolean) */ public void setVisible(boolean visible) { this.isVisible = visible; } /** * Draws error bar. * * @param gc * the graphics context * @param h * the horizontal coordinate to draw error bar * @param v * the vertical coordinate to draw error bar * @param axis * the x axis * @param seriesIndex * the series index */ protected void draw(GC gc, int h, int v, Axis axis, int seriesIndex) { if (!isVisible) { return; } int oldLineWidth = gc.getLineWidth(); gc.setLineWidth(lineWidth); gc.setLineStyle(SWT.LINE_SOLID); Color oldForeground = gc.getForeground(); gc.setForeground(getColor()); // get plus/minus error double plusError = error; double minusError = error; if (plusErrors.length > seriesIndex) { plusError = plusErrors[seriesIndex]; } if (minusErrors.length > seriesIndex) { minusError = minusErrors[seriesIndex]; } // draw error bar draw(gc, h, v, axis, plusError, minusError); gc.setLineWidth(oldLineWidth); gc.setForeground(oldForeground); } /** * Draws the error bar. * * @param gc * the graphics context * @param h * the horizontal coordinate to draw error bar * @param v * the vertical coordinate to draw error bar * @param axis * the axis * @param plusError * the plus error * @param minusError * the minus error */ private void draw(GC gc, int h, int v, Axis axis, double plusError, double minusError) { if (axis.isHorizontalAxis()) { double dataCoordinate = axis.getDataCoordinate(h); int plusErrorInPixels = axis.getPixelCoordinate(dataCoordinate + plusError) - h; int miusErrorInPixels = h - axis.getPixelCoordinate(dataCoordinate - minusError); if (axis.isLogScaleEnabled() && dataCoordinate - plusError < 0) { miusErrorInPixels = h - axis.getPixelCoordinate(axis.getRange().lower); } if (type != ErrorBarType.MINUS) { gc.drawLine(h, v, h + plusErrorInPixels, v); gc.drawLine(h + plusErrorInPixels, v + 1 + lineWidth, h + plusErrorInPixels, v - 1 - lineWidth); } if (type != ErrorBarType.PLUS) { gc.drawLine(h - miusErrorInPixels, v, h, v); gc.drawLine(h - miusErrorInPixels, v + 1 + lineWidth, h - miusErrorInPixels, v - 1 - lineWidth); } } else { double dataCoordinate = axis.getDataCoordinate(v); int plusErrorInPixels = v - axis.getPixelCoordinate(dataCoordinate + plusError); int miusErrorInPixels = axis.getPixelCoordinate(dataCoordinate - minusError) - v; if (axis.isLogScaleEnabled() && dataCoordinate - plusError < 0) { miusErrorInPixels = axis .getPixelCoordinate(axis.getRange().lower) - v; } if (type != ErrorBarType.MINUS) { gc.drawLine(h, v - plusErrorInPixels, h, v); gc.drawLine(h + 1 + lineWidth, v - plusErrorInPixels, h - 1 - lineWidth, v - plusErrorInPixels); } if (type != ErrorBarType.PLUS) { gc.drawLine(h, v, h, v + miusErrorInPixels); gc.drawLine(h + 1 + lineWidth, v + miusErrorInPixels, h - 1 - lineWidth, v + miusErrorInPixels); } } } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/series/LineSeries.java0000644000175000017500000006417412657165716031465 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.series; import java.util.ArrayList; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.widgets.Display; import org.swtchart.Chart; import org.swtchart.IAxis.Direction; import org.swtchart.ILineSeries; import org.swtchart.LineStyle; import org.swtchart.Range; import org.swtchart.internal.Util; import org.swtchart.internal.axis.Axis; import org.swtchart.internal.compress.CompressLineSeries; import org.swtchart.internal.compress.CompressScatterSeries; /** * Line series. */ public class LineSeries extends Series implements ILineSeries { /** the symbol size in pixel */ private int symbolSize; /** the symbol color */ private Color symbolColor; /** the symbol colors */ private Color[] symbolColors; /** the symbol type */ private PlotSymbolType symbolType; /** the line style */ private LineStyle lineStyle; /** the line color */ private Color lineColor; /** the line width */ private int lineWidth; /** the state indicating if area chart is enabled */ private boolean areaEnabled; /** the state indicating if step chart is enabled */ private boolean stepEnabled; /** the anti-aliasing value for drawing line */ private int antialias; /** the alpha value to draw area */ private static final int ALPHA = 50; /** the default line style */ private static final LineStyle DEFAULT_LINE_STYLE = LineStyle.SOLID; /** the default line width */ private static final int DEFAULT_LINE_WIDTH = 1; /** the default line color */ private static final int DEFAULT_LINE_COLOR = SWT.COLOR_BLUE; /** the default symbol color */ private static final int DEFAULT_SYMBOL_COLOR = SWT.COLOR_DARK_GRAY; /** the default symbol size */ private static final int DEFAULT_SIZE = 4; /** the default symbol type */ private static final PlotSymbolType DEFAULT_SYMBOL_TYPE = PlotSymbolType.CIRCLE; /** the default anti-aliasing value */ private static final int DEFAULT_ANTIALIAS = SWT.DEFAULT; /** the margin in pixels attached at the minimum/maximum plot */ private static final int MARGIN_AT_MIN_MAX_PLOT = 6; /** * Constructor. * * @param chart * the chart * @param id * the series id */ protected LineSeries(Chart chart, String id) { super(chart, id); symbolSize = 4; symbolColor = Display.getDefault().getSystemColor(DEFAULT_SYMBOL_COLOR); symbolType = DEFAULT_SYMBOL_TYPE; lineStyle = DEFAULT_LINE_STYLE; lineColor = Display.getDefault().getSystemColor(DEFAULT_LINE_COLOR); areaEnabled = false; antialias = DEFAULT_ANTIALIAS; lineWidth = DEFAULT_LINE_WIDTH; compressor = new CompressLineSeries(); symbolColors = new Color[0]; } /* * @see ILineSeries#getLineStyle() */ public LineStyle getLineStyle() { return lineStyle; } /* * @see ILineSeries#setLineStyle(LineStyle) */ public void setLineStyle(LineStyle style) { if (style == null) { this.lineStyle = DEFAULT_LINE_STYLE; return; } this.lineStyle = style; if (compressor instanceof CompressScatterSeries) { ((CompressScatterSeries) compressor) .setLineVisible(style != LineStyle.NONE); } } /* * @see ILineSeries#getLineColor() */ public Color getLineColor() { if (lineColor.isDisposed()) { lineColor = Display.getDefault().getSystemColor(DEFAULT_LINE_COLOR); } return lineColor; } /* * @see ILineSeries#setLineColor(Color) */ public void setLineColor(Color color) { if (color != null && color.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } if (color == null) { this.lineColor = Display.getDefault().getSystemColor( DEFAULT_LINE_COLOR); } else { this.lineColor = color; } } /* * @see ILineSeries#getLineWidth() */ public int getLineWidth() { return lineWidth; } /* * @see ILineSeries#setLineWidth(int) */ public void setLineWidth(int width) { if (width <= 0) { this.lineWidth = DEFAULT_LINE_WIDTH; } else { this.lineWidth = width; } } /* * @see ILineSeries#getSymbolType() */ public PlotSymbolType getSymbolType() { return symbolType; } /* * @see ILineSeries#setSymbolType(PlotSymbolType) */ public void setSymbolType(PlotSymbolType type) { if (type == null) { this.symbolType = DEFAULT_SYMBOL_TYPE; } else { this.symbolType = type; } } /* * @see ILineSeries#getSymbolSize() */ public int getSymbolSize() { return symbolSize; } /* * @see ILineSeries#setSymbolSize(int) */ public void setSymbolSize(int size) { if (size <= 0) { this.symbolSize = DEFAULT_SIZE; } else { this.symbolSize = size; } } /* * @see ILineSeries#getSymbolColor() */ public Color getSymbolColor() { return symbolColor; } /* * @see ILineSeries#setSymbolColor(Color) */ public void setSymbolColor(Color color) { if (color != null && color.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } if (color == null) { this.symbolColor = Display.getDefault().getSystemColor( DEFAULT_SYMBOL_COLOR); } else { this.symbolColor = color; } } /* * @see ILineSeries#getSymbolColors() */ public Color[] getSymbolColors() { Color[] copiedSymbolColors = new Color[symbolColors.length]; System.arraycopy(symbolColors, 0, copiedSymbolColors, 0, symbolColors.length); return copiedSymbolColors; } /* * @see ILineSeries#setSymbolColors(Color []) */ public void setSymbolColors(Color[] colors) { if (colors == null) { symbolColors = new Color[0]; return; } for (Color color : colors) { if (color.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } } symbolColors = new Color[colors.length]; System.arraycopy(colors, 0, symbolColors, 0, colors.length); } /* * @see Series#setCompressor() */ @Override protected void setCompressor() { if (isXMonotoneIncreasing) { compressor = new CompressLineSeries(); } else { compressor = new CompressScatterSeries(); ((CompressScatterSeries) compressor) .setLineVisible(getLineStyle() != LineStyle.NONE); } } /* * @see ILineSeries#enableArea(boolean) */ public void enableArea(boolean enabled) { areaEnabled = enabled; } /* * @see ILineSeries#isAreaEnabled() */ public boolean isAreaEnabled() { return areaEnabled; } /* * @see ILineSeries#enableStep(boolean) */ public void enableStep(boolean enabled) { stepEnabled = enabled; } /* * @see ILineSeries#isStepEnabled() */ public boolean isStepEnabled() { return stepEnabled; } /* * @see Series#getAdjustedRange(Axis, int) */ @Override public Range getAdjustedRange(Axis axis, int length) { Range range; if (axis.getDirection() == Direction.X) { range = getXRange(); } else { range = getYRange(); } int lowerPlotMargin = getSymbolSize() + MARGIN_AT_MIN_MAX_PLOT; int upperPlotMargin = getSymbolSize() + MARGIN_AT_MIN_MAX_PLOT; return getRangeWithMargin(lowerPlotMargin, upperPlotMargin, length, axis, range); } /* * @see ILineSeries#getAntialias() */ public int getAntialias() { return antialias; } /* * @see ILineSeries#setAntialias(int) */ public void setAntialias(int antialias) { if (antialias != SWT.DEFAULT && antialias != SWT.ON && antialias != SWT.OFF) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } this.antialias = antialias; } /** * Gets the line points to draw line and area. * * @param xseries * the horizontal series * @param yseries * the vertical series * @param indexes * the series indexes * @param index * the index of series * @param xAxis * the X axis * @param yAxis * the Y axis * @return the line points */ private int[] getLinePoints(double[] xseries, double[] yseries, int[] indexes, int index, Axis xAxis, Axis yAxis) { int x1 = xAxis.getPixelCoordinate(xseries[index]); int x2 = xAxis.getPixelCoordinate(xseries[index + 1]); int x3 = x2; int x4 = x1; int y1 = yAxis.getPixelCoordinate(yseries[index]); int y2 = yAxis.getPixelCoordinate(yseries[index + 1]); int y3, y4; double baseYCoordinate = yAxis.getRange().lower > 0 ? yAxis.getRange().lower : 0; if (yAxis.isLogScaleEnabled()) { y3 = yAxis.getPixelCoordinate(yAxis.getRange().lower); y4 = y3; } else if (isValidStackSeries()) { y1 = yAxis.getPixelCoordinate(stackSeries[indexes[index]]); y2 = yAxis.getPixelCoordinate(stackSeries[indexes[index + 1]]); y3 = yAxis.getPixelCoordinate(stackSeries[indexes[index + 1]]) + Math.abs(yAxis.getPixelCoordinate(yseries[index + 1]) - yAxis.getPixelCoordinate(0)) * (xAxis.isHorizontalAxis() ? 1 : -1); y4 = yAxis.getPixelCoordinate(stackSeries[indexes[index]]) + Math.abs(yAxis.getPixelCoordinate(yseries[index]) - yAxis.getPixelCoordinate(0)) * (xAxis.isHorizontalAxis() ? 1 : -1); } else { y3 = yAxis.getPixelCoordinate(baseYCoordinate); y4 = y3; } if (xAxis.isHorizontalAxis()) { return new int[] { x1, y1, x2, y2, x3, y3, x4, y4 }; } return new int[] { y1, x1, y2, x2, y3, x3, y4, x4 }; } /* * @see Series#draw(GC, int, int, Axis, Axis) */ @Override protected void draw(GC gc, int width, int height, Axis xAxis, Axis yAxis) { int oldAntialias = gc.getAntialias(); int oldLineWidth = gc.getLineWidth(); gc.setAntialias(antialias); gc.setLineWidth(lineWidth); if (lineStyle != LineStyle.NONE) { drawLineAndArea(gc, width, height, xAxis, yAxis); } if (symbolType != PlotSymbolType.NONE || getLabel().isVisible() || getXErrorBar().isVisible() || getYErrorBar().isVisible()) { drawSymbolAndLabel(gc, width, height, xAxis, yAxis); } gc.setAntialias(oldAntialias); gc.setLineWidth(oldLineWidth); } /** * Draws the line and area. * * @param gc * the graphics context * @param width * the width to draw series * @param height * the height to draw series * @param xAxis * the x axis * @param yAxis * the y axis */ private void drawLineAndArea(GC gc, int width, int height, Axis xAxis, Axis yAxis) { // get x and y series double[] xseries = compressor.getCompressedXSeries(); double[] yseries = compressor.getCompressedYSeries(); if (xseries.length == 0 || yseries.length == 0) { return; } int[] indexes = compressor.getCompressedIndexes(); if (xAxis.isValidCategoryAxis()) { for (int i = 0; i < xseries.length; i++) { xseries[i] = indexes[i]; } } gc.setLineStyle(Util.getIndexDefinedInSWT(lineStyle)); Color oldForeground = gc.getForeground(); gc.setForeground(getLineColor()); boolean isHorizontal = xAxis.isHorizontalAxis(); if (stepEnabled || areaEnabled || stackEnabled) { for (int i = 0; i < xseries.length - 1; i++) { int[] p = getLinePoints(xseries, yseries, indexes, i, xAxis, yAxis); // draw line if (lineStyle != LineStyle.NONE) { if (stepEnabled) { if (isHorizontal) { gc.drawLine(p[0], p[1], p[2], p[1]); gc.drawLine(p[2], p[1], p[2], p[3]); } else { gc.drawLine(p[0], p[1], p[0], p[3]); gc.drawLine(p[0], p[3], p[2], p[3]); } } else { gc.drawLine(p[0], p[1], p[2], p[3]); } } // draw area if (areaEnabled) { drawArea(gc, p, isHorizontal); } } } else { if (lineStyle == LineStyle.SOLID) { drawLine(gc, xAxis, yAxis, xseries, yseries, isHorizontal); } else if (lineStyle != LineStyle.NONE) { drawLineWithStyle(gc, xAxis, yAxis, xseries, yseries, isHorizontal); } } gc.setForeground(oldForeground); } /* * This method basically does the same things as drawLineWithStyle(), but is * kept being used. The reason is that, drawLineWithStyle() has a workaround * for eclipse bug #243588, and there could be a case that the workaround * doesn't work. To minimize the risk of side effect, this method remains * for solid line style until that bug is fixed and the workaround is * removed. */ private static void drawLine(GC gc, Axis xAxis, Axis yAxis, double[] xseries, double[] yseries, boolean isHorizontal) { double xLower = xAxis.getRange().lower; double xUpper = xAxis.getRange().upper; double yLower = yAxis.getRange().lower; double yUpper = yAxis.getRange().upper; int prevX = xAxis.getPixelCoordinate(xseries[0], xLower, xUpper); int prevY = yAxis.getPixelCoordinate(yseries[0], yLower, yUpper); boolean drawVerticalLine = false; int verticalLineYLower = 0; int verticalLineYUpper = 0; for (int i = 0; i < xseries.length - 1; i++) { int x = xAxis.getPixelCoordinate(xseries[i + 1], xLower, xUpper); int y = yAxis.getPixelCoordinate(yseries[i + 1], yLower, yUpper); if (x == prevX && i < xseries.length - 2) { if (drawVerticalLine) { // extend vertical line verticalLineYLower = Math.min(verticalLineYLower, y); verticalLineYUpper = Math.max(verticalLineYUpper, y); } else { // init vertical line verticalLineYLower = Math.min(prevY, y); verticalLineYUpper = Math.max(prevY, y); drawVerticalLine = true; } } else { // draw vertical line if (drawVerticalLine) { if (isHorizontal) { gc.drawLine(prevX, verticalLineYLower, prevX, verticalLineYUpper); } else { gc.drawLine(verticalLineYLower, prevX, verticalLineYUpper, prevX); } drawVerticalLine = false; } // draw non-vertical line if (isHorizontal) { gc.drawLine(prevX, prevY, x, y); } else { gc.drawLine(prevY, prevX, y, x); } } prevX = x; prevY = y; } } /** * Draws the line segments with line style. *

* When there are multiple data points at the same x pixel coordinate, it is * inefficient to simply draw vertical lines connecting them by overlaying. * Instead, only a single vertical line representing the overlaid multiple * vertical lines is drawn at that x pixel coordinate. *

* That's why vertical line is handled differently from non-vertical line in * this method. * * @param gc * the graphic context * @param xAxis * the x axis * @param yAxis * the y axis * @param xseries * the x series * @param yseries * the y series * @param isHorizontal * true if orientation is horizontal */ private static void drawLineWithStyle(GC gc, Axis xAxis, Axis yAxis, double[] xseries, double[] yseries, boolean isHorizontal) { double xLower = xAxis.getRange().lower; double xUpper = xAxis.getRange().upper; double yLower = yAxis.getRange().lower; double yUpper = yAxis.getRange().upper; List pointList = new ArrayList(); int prevX = xAxis.getPixelCoordinate(xseries[0], xLower, xUpper); int prevY = yAxis.getPixelCoordinate(yseries[0], yLower, yUpper); // add initial point addPoint(pointList, prevX, prevY, isHorizontal); boolean drawVerticalLine = false; int verticalLineYLower = 0; int verticalLineYUpper = 0; for (int i = 0; i < xseries.length - 1; i++) { int x = xAxis.getPixelCoordinate(xseries[i + 1], xLower, xUpper); int y = yAxis.getPixelCoordinate(yseries[i + 1], yLower, yUpper); if (x == prevX && i < xseries.length - 2) { if (drawVerticalLine) { // extend vertical line verticalLineYLower = Math.min(verticalLineYLower, y); verticalLineYUpper = Math.max(verticalLineYUpper, y); } else { // init vertical line verticalLineYLower = Math.min(prevY, y); verticalLineYUpper = Math.max(prevY, y); drawVerticalLine = true; } } else { // add vertical line if (drawVerticalLine) { addPoint(pointList, prevX, verticalLineYLower, isHorizontal); addPoint(pointList, prevX, verticalLineYUpper, isHorizontal); addPoint(pointList, prevX, prevY, isHorizontal); } // add non-vertical line addPoint(pointList, x, y, isHorizontal); drawVerticalLine = false; } prevX = x; prevY = y; } int[] polyline = new int[pointList.size()]; for (int i = 0; i < polyline.length; i++) { polyline[i] = pointList.get(i); } boolean advanced = gc.getAdvanced(); gc.setAdvanced(true); // workaround gc.drawPolyline(polyline); gc.setAdvanced(advanced); } private static void addPoint(List pointList, int x, int y, boolean isHorizontal) { if (isHorizontal) { pointList.add(Integer.valueOf(x)); pointList.add(Integer.valueOf(y)); } else { pointList.add(Integer.valueOf(y)); pointList.add(Integer.valueOf(x)); } } /** * Draws the area. * * @param gc * the graphic context * @param p * the line points * @param isHorizontal * true if orientation is horizontal */ private void drawArea(GC gc, int[] p, boolean isHorizontal) { int alpha = gc.getAlpha(); gc.setAlpha(ALPHA); Color oldBackground = gc.getBackground(); gc.setBackground(getLineColor()); int[] pointArray; if (stepEnabled) { if (isHorizontal) { pointArray = new int[] { p[0], p[1], p[2], p[1], p[4], p[7], p[6], p[7], p[0], p[1] }; } else { pointArray = new int[] { p[0], p[1], p[0], p[3], p[6], p[5], p[6], p[7], p[0], p[1] }; } } else { pointArray = new int[] { p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[0], p[1] }; } gc.fillPolygon(pointArray); gc.setAlpha(alpha); gc.setBackground(oldBackground); } /** * Draws series symbol, label and error bars. * * @param gc * the graphics context * @param width * the width to draw series * @param height * the height to draw series * @param xAxis * the x axis * @param yAxis * the y axis */ private void drawSymbolAndLabel(GC gc, int width, int height, Axis xAxis, Axis yAxis) { // get x and y series double[] xseries = compressor.getCompressedXSeries(); double[] yseries = compressor.getCompressedYSeries(); int[] indexes = compressor.getCompressedIndexes(); if (xAxis.isValidCategoryAxis()) { boolean isValidStackSeries = isValidStackSeries(); for (int i = 0; i < xseries.length; i++) { xseries[i] = indexes[i]; if (isValidStackSeries) { yseries[i] = stackSeries[indexes[i]]; } } } // draw symbol and label for (int i = 0; i < xseries.length; i++) { Color color; if (symbolColors.length > indexes[i]) { color = symbolColors[indexes[i]]; } else { color = getSymbolColor(); } int h, v; if (xAxis.isHorizontalAxis()) { h = xAxis.getPixelCoordinate(xseries[i]); v = yAxis.getPixelCoordinate(yseries[i]); } else { v = xAxis.getPixelCoordinate(xseries[i]); h = yAxis.getPixelCoordinate(yseries[i]); } if (getSymbolType() != PlotSymbolType.NONE) { drawSeriesSymbol(gc, h, v, color); } seriesLabel.draw(gc, h, v, yseries[i], indexes[i], SWT.BOTTOM); xErrorBar.draw(gc, h, v, xAxis, indexes[i]); yErrorBar.draw(gc, h, v, yAxis, indexes[i]); } } /** * Draws series symbol. * * @param gc * the GC object * @param h * the horizontal coordinate to draw symbol * @param v * the vertical coordinate to draw symbol * @param color * the symbol color */ public void drawSeriesSymbol(GC gc, int h, int v, Color color) { int oldAntialias = gc.getAntialias(); gc.setAntialias(SWT.ON); Color oldForeground = gc.getForeground(); gc.setForeground(color); Color oldBackground = gc.getBackground(); gc.setBackground(color); switch (symbolType) { case CIRCLE: gc.fillOval(h - symbolSize, v - symbolSize, symbolSize * 2, symbolSize * 2); break; case SQUARE: gc.fillRectangle(h - symbolSize, v - symbolSize, symbolSize * 2, symbolSize * 2); break; case DIAMOND: int[] diamondArray = { h, v - symbolSize, h + symbolSize, v, h, v + symbolSize, h - symbolSize, v }; gc.fillPolygon(diamondArray); break; case TRIANGLE: int[] triangleArray = { h, v - symbolSize, h + symbolSize, v + symbolSize, h - symbolSize, v + symbolSize }; gc.fillPolygon(triangleArray); break; case INVERTED_TRIANGLE: int[] invertedTriangleArray = { h, v + symbolSize, h + symbolSize, v - symbolSize, h - symbolSize, v - symbolSize }; gc.fillPolygon(invertedTriangleArray); break; case CROSS: gc.setLineStyle(SWT.LINE_SOLID); gc.drawLine(h - symbolSize, v - symbolSize, h + symbolSize, v + symbolSize); gc.drawLine(h - symbolSize, v + symbolSize, h + symbolSize, v - symbolSize); break; case PLUS: gc.setLineStyle(SWT.LINE_SOLID); gc.drawLine(h, v - symbolSize, h, v + symbolSize); gc.drawLine(h - symbolSize, v, h + symbolSize, v); break; case NONE: default: break; } gc.setAntialias(oldAntialias); gc.setBackground(oldBackground); gc.setForeground(oldForeground); } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/series/BarSeries.java0000644000175000017500000004025212657165716031271 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.series; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Display; import org.swtchart.Chart; import org.swtchart.IAxis.Direction; import org.swtchart.IBarSeries; import org.swtchart.Range; import org.swtchart.internal.axis.Axis; import org.swtchart.internal.compress.CompressBarSeries; import org.swtchart.internal.compress.CompressScatterSeries; /** * Bar series. */ public class BarSeries extends Series implements IBarSeries { /** the riser index in a category */ private int riserIndex; /** the riser color */ private Color barColor; /** the bar width */ private int barWidth; /** the padding */ private int padding; /** the bar width style */ private BarWidthStyle barWidthStyle; /** the initial bar width in pixels */ public static final int INITIAL_BAR_WIDTH = 20; /** the initial bar padding in percentage */ public static final int INITIAL_PADDING = 20; /** the alpha value */ private static final int ALPHA = 0xD0; /** the margin in pixels attached at the minimum/maximum plot */ private static final int MARGIN_AT_MIN_MAX_PLOT = 6; /** the default bar color */ private static final int DEFAULT_BAR_COLOR = SWT.COLOR_CYAN; /** * Constructor. * * @param chart * the chart * @param id * the series id */ protected BarSeries(Chart chart, String id) { super(chart, id); barColor = Display.getDefault().getSystemColor(DEFAULT_BAR_COLOR); barWidthStyle = BarWidthStyle.STRETCHED; barWidth = INITIAL_PADDING; padding = INITIAL_PADDING; type = SeriesType.BAR; compressor = new CompressBarSeries(); } /* * @see IBarSeries#getBarWidthStyle(BarWidthStyle) */ public BarWidthStyle getBarWidthStyle(BarWidthStyle style) { return barWidthStyle; } /* * @see IBarSeries#setBarWidthStyle(BarWidthStyle) */ public void setBarWidthStyle(BarWidthStyle style) { this.barWidthStyle = style; } /* * @see IBarSeries#getBarWidth() */ public int getBarWidth() { return barWidth; } /* * @see IBarSeries#setBarWidth(int) */ public void setBarWidth(int width) { if (padding <= 0) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } this.barWidth = width; } /* * @see IBarSeries#getBarPadding() */ public int getBarPadding() { return padding; } /* * @see IBarSeries#setBarPadding(int) */ public void setBarPadding(int padding) { if (padding < 0 || padding > 100) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } this.padding = padding; } /* * @see IBarSeries#getBarColor() */ public Color getBarColor() { if (barColor.isDisposed()) { barColor = Display.getDefault().getSystemColor(DEFAULT_BAR_COLOR); } return barColor; } /* * @see IBarSeries#setBarColor(Color) */ public void setBarColor(Color color) { if (color != null && color.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } if (color == null) { this.barColor = Display.getDefault().getSystemColor( DEFAULT_BAR_COLOR); } else { this.barColor = color; } } /* * @see IBarSeries#getBounds() */ public Rectangle[] getBounds() { Rectangle[] compressedBounds = getBoundsForCompressedSeries(); if (((Axis) chart.getAxisSet().getXAxis(xAxisId)).isValidCategoryAxis()) { return compressedBounds; } Rectangle[] rs = new Rectangle[xSeries.length]; double[] comporessedXSeries = compressor.getCompressedXSeries(); int cnt = 0; for (int i = 0; i < xSeries.length; i++) { if (cnt < comporessedXSeries.length && comporessedXSeries[cnt] == xSeries[i]) { if (compressedBounds[cnt].width != 0 && compressedBounds[cnt].height != 0) { rs[i] = compressedBounds[cnt]; } cnt++; } } return rs; } /** * Gets the array of bar rectangles for compressed series. * * @return the array of bar rectangles for compressed series */ private Rectangle[] getBoundsForCompressedSeries() { Axis xAxis = (Axis) chart.getAxisSet().getXAxis(xAxisId); Axis yAxis = (Axis) chart.getAxisSet().getYAxis(yAxisId); // get x and y series double[] xseries = compressor.getCompressedXSeries(); double[] yseries = compressor.getCompressedYSeries(); int[] indexes = compressor.getCompressedIndexes(); if (xAxis.isValidCategoryAxis()) { for (int i = 0; i < xseries.length; i++) { xseries[i] = indexes[i]; } } Rectangle[] rectangles = new Rectangle[xseries.length]; Range xRange = xAxis.getRange(); Range yRange = yAxis.getRange(); for (int i = 0; i < xseries.length; i++) { int x = xAxis.getPixelCoordinate(xseries[i]); int y = yAxis .getPixelCoordinate(isValidStackSeries() ? stackSeries[indexes[i]] : yseries[i]); double baseYCoordinate = yAxis.getRange().lower > 0 ? yAxis .getRange().lower : 0; double riserwidth = getRiserWidth(xseries, i, xAxis, xRange.lower, xRange.upper); double riserHeight = Math.abs(yAxis.getPixelCoordinate(yseries[i], yRange.lower, yRange.upper) - yAxis.getPixelCoordinate( yAxis.isLogScaleEnabled() ? yRange.lower : baseYCoordinate, yRange.lower, yRange.upper)); // adjust riser x coordinate and riser width for multiple series int riserCnt = xAxis.getNumRisers(); if (riserCnt > 1) { if (xAxis.isHorizontalAxis()) { x = (int) (x - riserwidth / 2d + riserwidth / riserCnt * (riserIndex + 0.5)); } else { x = (int) (x - riserwidth / 2d + riserwidth / riserCnt * (riserCnt - riserIndex - 0.5)); } riserwidth /= riserCnt; } if (xAxis.isHorizontalAxis()) { // adjust coordinate for negative series if (y > yAxis.getPixelCoordinate(0)) { y = yAxis.getPixelCoordinate(0); } int width = (int) Math.ceil(riserwidth); width = (width == 0) ? 1 : width; rectangles[i] = getVisibleRectangle((int) Math.floor(x - riserwidth / 2d), y, width, (int) riserHeight); } else { // adjust coordinate for negative series if (y < yAxis.getPixelCoordinate(0)) { y = yAxis.getPixelCoordinate(0); } int height = (int) Math.ceil(riserwidth); height = (height == 0) ? 1 : height; rectangles[i] = getVisibleRectangle((int) (y - riserHeight), (int) Math.floor(x - riserwidth / 2d), (int) riserHeight, height); } } return rectangles; } /** * Gets the rectangle that is visible part of given rectangle. * * @param x * The x coordinate * @param y * The y coordinate * @param width * the width * @param height * The height * @return The visible rectangle */ private Rectangle getVisibleRectangle(int x, int y, int width, int height) { final int offset = 5; int newX = x; int newY = y; int newWidth = width; int newHeight = height; if (x < 0) { newX = -offset; newWidth += x + offset; } if (y < 0) { newY = -offset; newHeight += y + offset; } Point size = chart.getPlotArea().getSize(); if (x + width > size.x) { newWidth -= x + width - size.x + offset; if (newWidth < 0) { newWidth = 0; } } if (y + height > size.y) { newHeight -= y + height - size.y + offset; if (newHeight < 0) { newHeight = 0; } } return new Rectangle(newX, newY, newWidth, newHeight); } /** * Sets the index of riser in a category. * * @param riserIndex * the index of riser in a category */ protected void setRiserIndex(int riserIndex) { this.riserIndex = riserIndex; } /* * @see Series#setCompressor() */ @Override protected void setCompressor() { if (isXMonotoneIncreasing) { compressor = new CompressBarSeries(); } else { compressor = new CompressScatterSeries(); } } /* * @see Series#getAdjustedRange(Axis, int) */ @Override public Range getAdjustedRange(Axis axis, int length) { // calculate a range which has margin Range range; int lowerPlotMargin; int upperPlotMargin; if (axis.getDirection() == Direction.X) { double lowerRiserWidth = getRiserWidth(xSeries, 0, axis, minX, maxX); double upperRiserWidth = getRiserWidth(xSeries, xSeries.length - 1, axis, minX, maxX); lowerPlotMargin = (int) (lowerRiserWidth / 2d + MARGIN_AT_MIN_MAX_PLOT); upperPlotMargin = (int) (upperRiserWidth / 2d + MARGIN_AT_MIN_MAX_PLOT); range = getXRange(); } else { range = getYRange(); if (range.upper < 0) { range.upper = 0; } if (range.lower > 0) { range.lower = axis.isLogScaleEnabled() ? minY : 0; } lowerPlotMargin = (range.lower == 0) ? 0 : MARGIN_AT_MIN_MAX_PLOT; upperPlotMargin = (range.upper == 0) ? 0 : MARGIN_AT_MIN_MAX_PLOT; } return getRangeWithMargin(lowerPlotMargin, upperPlotMargin, length, axis, range); } /** * Gets the riser width. * * @param series * the X series * @param index * the series index * @param xAxis * the X axis * @param min * the min value of range * @param max * the max value of range * @return the raiser width in pixels */ private int getRiserWidth(double[] series, int index, Axis xAxis, double min, double max) { // get two x coordinates double upper; double lower; if (series.length == 1) { upper = series[0] + 0.5; lower = series[0] - 0.5; } else if (index != series.length - 1 && (index == 0 || series[index + 1] - series[index] < series[index] - series[index - 1])) { upper = series[index + 1]; lower = series[index]; } else { upper = series[index]; lower = series[index - 1]; } if (barWidthStyle == BarWidthStyle.STRETCHED) { // get riser width without padding int width = Math.abs(xAxis.getPixelCoordinate(upper, min, max) - xAxis.getPixelCoordinate(lower, min, max)); // adjust for padding width *= (100 - padding) / 100d; // symbol size should be at least more than 1 if (width == 0) { width = 1; } return width; } else if (barWidthStyle == BarWidthStyle.FIXED) { return barWidth; } throw new IllegalStateException("unknown bar width style"); } /** * Gets the color for riser frame. The color will be darker or lighter than * the given color. * * @param color * the riser color * @return the riser frame color */ private static Color getFrameColor(Color color) { int red = color.getRed(); int green = color.getGreen(); int blue = color.getBlue(); red *= (red > 128) ? 0.8 : 1.2; green *= (green > 128) ? 0.8 : 1.2; blue *= (blue > 128) ? 0.8 : 1.2; return new Color(color.getDevice(), red, green, blue); } /* * @see Series#draw(GC, int, int, Axis, Axis) */ @Override protected void draw(GC gc, int width, int height, Axis xAxis, Axis yAxis) { // draw riser Rectangle[] rs = getBoundsForCompressedSeries(); for (int i = 0; i < rs.length; i++) { drawRiser(gc, rs[i].x, rs[i].y, rs[i].width, rs[i].height); } // draw label and error bars if (seriesLabel.isVisible() || xErrorBar.isVisible() || yErrorBar.isVisible()) { double[] yseries = compressor.getCompressedYSeries(); int[] indexes = compressor.getCompressedIndexes(); for (int i = 0; i < rs.length; i++) { seriesLabel.draw(gc, rs[i].x + rs[i].width / 2, rs[i].y + rs[i].height / 2, yseries[i], indexes[i], SWT.CENTER); int h, v; if (xAxis.isHorizontalAxis()) { if (xAxis.isCategoryEnabled()) { h = rs[i].x + rs[i].width / 2; } else { h = xAxis.getPixelCoordinate(xSeries[indexes[i]]); } v = yAxis.getPixelCoordinate(ySeries[indexes[i]]); } else { if (xAxis.isCategoryEnabled()) { v = rs[i].y + rs[i].height / 2; } else { v = xAxis.getPixelCoordinate(xSeries[indexes[i]]); } h = yAxis.getPixelCoordinate(ySeries[indexes[i]]); } xErrorBar.draw(gc, h, v, xAxis, indexes[i]); yErrorBar.draw(gc, h, v, yAxis, indexes[i]); } } } /** * Draws riser. * * @param gc * the graphics context * @param h * the horizontal coordinate * @param v * the vertical coordinate * @param width * the riser width * @param height * the riser height */ private void drawRiser(GC gc, int h, int v, int width, int height) { int alpha = gc.getAlpha(); gc.setAlpha(ALPHA); Color oldBackground = gc.getBackground(); gc.setBackground(getBarColor()); gc.fillRectangle(h, v, width, height); gc.setLineStyle(SWT.LINE_SOLID); Color frameColor = getFrameColor(getBarColor()); Color oldForeground = gc.getForeground(); gc.setForeground(frameColor); gc.drawRectangle(h, v, width, height); frameColor.dispose(); gc.setAlpha(alpha); gc.setBackground(oldBackground); gc.setForeground(oldForeground); } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/series/SeriesSet.java0000644000175000017500000003371212657165716031323 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.series; import java.math.BigDecimal; import java.util.LinkedHashMap; import java.util.Map.Entry; import java.util.Set; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.IAxis.Direction; import org.swtchart.ISeries; import org.swtchart.ISeries.SeriesType; import org.swtchart.ISeriesSet; import org.swtchart.Range; import org.swtchart.internal.axis.Axis; import org.swtchart.internal.compress.CompressConfig; import org.swtchart.internal.compress.ICompress; /** * A series container. */ public class SeriesSet implements ISeriesSet { /** the chart */ private final Chart chart; /** the series */ private LinkedHashMap seriesMap; /** * Constructor. * * @param chart * the chart */ public SeriesSet(Chart chart) { this.chart = chart; seriesMap = new LinkedHashMap(); } /* * @see ISeriesSet#createSeries(ISeries.SeriesType, String) */ public ISeries createSeries(SeriesType type, String id) { if (id == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); return null; // to suppress warning... } String trimmedId = id.trim(); if ("".equals(trimmedId)) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } Series series = null; if (type == SeriesType.BAR) { series = new BarSeries(chart, trimmedId); } else if (type == SeriesType.LINE) { series = new LineSeries(chart, trimmedId); } else { SWT.error(SWT.ERROR_INVALID_ARGUMENT); return null; // to suppress warning... } Series oldSeries = seriesMap.get(trimmedId); if (oldSeries != null) { oldSeries.dispose(); } int[] xAxisIds = chart.getAxisSet().getXAxisIds(); int[] yAxisIds = chart.getAxisSet().getYAxisIds(); series.setXAxisId(xAxisIds[0]); series.setYAxisId(yAxisIds[0]); seriesMap.put(trimmedId, series); Axis axis = (Axis) chart.getAxisSet().getXAxis(xAxisIds[0]); if (axis != null) { updateStackAndRiserData(); } // legend will be shown if there is previously no series. chart.updateLayout(); return series; } /* * @see ISeriesSet#getSeries(String) */ public ISeries getSeries(String id) { if (id == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); } String trimmedId = id.trim(); return seriesMap.get(trimmedId); } /* * @see ISeriesSet#getSeries() */ public ISeries[] getSeries() { Set keys = seriesMap.keySet(); ISeries[] series = new ISeries[keys.size()]; int i = 0; for (String key : keys) { series[i++] = seriesMap.get(key); } return series; } /* * @see ISeriesSet#deleteSeries(String) */ public void deleteSeries(String id) { String trimmedId = validateSeriesId(id); seriesMap.get(trimmedId).dispose(); seriesMap.remove(trimmedId); updateStackAndRiserData(); // legend will be hidden if this is the last series chart.updateLayout(); } /* * @see ISeriesSet#bringForward(String) */ public void bringForward(String id) { String trimmedId = validateSeriesId(id); String seriesId = null; LinkedHashMap newSeriesMap = new LinkedHashMap(); for (Entry entry : seriesMap.entrySet()) { if (entry.getKey().equals(trimmedId)) { seriesId = trimmedId; continue; } newSeriesMap.put(entry.getKey(), entry.getValue()); if (seriesId != null) { newSeriesMap.put(seriesId, seriesMap.get(seriesId)); seriesId = null; } } if (seriesId != null) { newSeriesMap.put(seriesId, seriesMap.get(seriesId)); } seriesMap = newSeriesMap; updateStackAndRiserData(); chart.updateLayout(); } /* * @see ISeriesSet#bringToFront(String) */ public void bringToFront(String id) { String trimmedId = validateSeriesId(id); Series series = seriesMap.get(trimmedId); seriesMap.remove(trimmedId); seriesMap.put(series.getId(), series); updateStackAndRiserData(); chart.updateLayout(); } /* * @see ISeriesSet#sendBackward(String) */ public void sendBackward(String id) { String trimmedId = validateSeriesId(id); String seriesId = null; LinkedHashMap newSeriesMap = new LinkedHashMap(); for (Entry entry : seriesMap.entrySet()) { if (!entry.getKey().equals(trimmedId) || seriesId == null) { newSeriesMap.put(entry.getKey(), entry.getValue()); seriesId = entry.getKey(); continue; } newSeriesMap.remove(seriesId); newSeriesMap.put(entry.getKey(), entry.getValue()); newSeriesMap.put(seriesId, seriesMap.get(seriesId)); } seriesMap = newSeriesMap; updateStackAndRiserData(); chart.updateLayout(); } /* * @see ISeriesSet#sendToBack(String) */ public void sendToBack(String id) { String trimmedId = validateSeriesId(id); LinkedHashMap newSeriesMap = new LinkedHashMap(); newSeriesMap.put(trimmedId, seriesMap.get(trimmedId)); for (Entry entry : seriesMap.entrySet()) { if (!entry.getKey().equals(trimmedId)) { newSeriesMap.put(entry.getKey(), entry.getValue()); } } seriesMap = newSeriesMap; updateStackAndRiserData(); chart.updateLayout(); } /** * Disposes the series. */ public void dispose() { for (Entry entry : seriesMap.entrySet()) { entry.getValue().dispose(); } } /** * Validates the given series id. * * @param id * the series id. * @return the valid series id */ private String validateSeriesId(String id) { if (id == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); } String trimmedId = id.trim(); if (seriesMap.get(trimmedId) == null) { throw new IllegalArgumentException("Given series id doesn't exist"); } return trimmedId; } /** * Compresses all series data. */ public void compressAllSeries() { if (!chart.isCompressEnabled()) { return; } CompressConfig config = new CompressConfig(); final int PRECISION = 2; Point p = chart.getPlotArea().getSize(); int width = p.x * PRECISION; int height = p.y * PRECISION; config.setSizeInPixel(width, height); for (ISeries series : getSeries()) { int xAxisId = series.getXAxisId(); int yAxisId = series.getYAxisId(); IAxis xAxis = chart.getAxisSet().getXAxis(xAxisId); IAxis yAxis = chart.getAxisSet().getYAxis(yAxisId); if (xAxis == null || yAxis == null) { continue; } Range xRange = xAxis.getRange(); Range yRange = yAxis.getRange(); if (xRange == null || yRange == null) { continue; } double xMin = xRange.lower; double xMax = xRange.upper; double yMin = yRange.lower; double yMax = yRange.upper; config.setXLogScale(xAxis.isLogScaleEnabled()); config.setYLogScale(yAxis.isLogScaleEnabled()); double lower = xMin - (xMax - xMin) * 0.015; double upper = xMax + (xMax - xMin) * 0.015; if (xAxis.isLogScaleEnabled()) { lower = ((Series) series).getXRange().lower; } config.setXRange(lower, upper); lower = yMin - (yMax - yMin) * 0.015; upper = yMax + (yMax - yMin) * 0.015; if (yAxis.isLogScaleEnabled()) { lower = ((Series) series).getYRange().lower; } config.setYRange(lower, upper); ICompress compressor = ((Series) series).getCompressor(); compressor.compress(config); } } /** * Updates the compressor associated with the given axis. *

* In most cases, compressor is updated when series is changed. However, * there is a case that compressor has to be updated with the changes in * axis. * * @param axis * the axis */ public void updateCompressor(Axis axis) { for (ISeries series : getSeries()) { int axisId = (axis.getDirection() == Direction.X) ? series .getXAxisId() : series.getYAxisId(); if (axisId != axis.getId()) { continue; } ICompress compressor = ((Series) series).getCompressor(); if (axis.isValidCategoryAxis()) { String[] categorySeries = axis.getCategorySeries(); if (categorySeries == null) { continue; } double[] xSeries = new double[categorySeries.length]; for (int i = 0; i < xSeries.length; i++) { xSeries[i] = i; } compressor.setXSeries(xSeries); } else if (((Series) series).getXSeries() != null) { compressor.setXSeries(((Series) series).getXSeries()); } } compressAllSeries(); } /** * Updates the stack and riser data. */ public void updateStackAndRiserData() { if (chart.isUpdateSuspended()) { return; } for (IAxis xAxis : chart.getAxisSet().getXAxes()) { ((Axis) xAxis).setNumRisers(0); for (IAxis yAxis : chart.getAxisSet().getYAxes()) { updateStackAndRiserData(xAxis, yAxis); } } } /** * Updates the stack and riser data for given axes. * * @param xAxis * the X axis * @param yAxis * the Y axis */ private void updateStackAndRiserData(IAxis xAxis, IAxis yAxis) { int riserCnt = 0; int stackRiserPosition = -1; double[] stackBarSeries = null; double[] stackLineSeries = null; if (((Axis) xAxis).isValidCategoryAxis()) { String[] categorySeries = xAxis.getCategorySeries(); if (categorySeries != null) { int size = categorySeries.length; stackBarSeries = new double[size]; stackLineSeries = new double[size]; } } for (ISeries series : getSeries()) { if (series.getXAxisId() != xAxis.getId() || series.getYAxisId() != yAxis.getId() || !series.isVisible()) { continue; } if (series.isStackEnabled() && !chart.getAxisSet().getYAxis(series.getYAxisId()) .isLogScaleEnabled() && ((Axis) xAxis).isValidCategoryAxis()) { if (series.getType() == SeriesType.BAR) { if (stackRiserPosition == -1) { stackRiserPosition = riserCnt; riserCnt++; } ((BarSeries) series).setRiserIndex(((Axis) xAxis) .getNumRisers() + stackRiserPosition); setStackSeries(stackBarSeries, series); } else if (series.getType() == SeriesType.LINE) { setStackSeries(stackLineSeries, series); } } else { if (series.getType() == SeriesType.BAR) { ((BarSeries) series).setRiserIndex(((Axis) xAxis) .getNumRisers() + riserCnt++); } } } ((Axis) xAxis).setNumRisers(((Axis) xAxis).getNumRisers() + riserCnt); } /** * Sets the stack series. * * @param stackSeries * the stack series * @param series * the series */ private static void setStackSeries(double[] stackSeries, ISeries series) { double[] ySeries = series.getYSeries(); if (ySeries == null || stackSeries == null) { return; } for (int i = 0; i < stackSeries.length; i++) { if (i >= ySeries.length) { break; } stackSeries[i] = BigDecimal.valueOf(stackSeries[i]) .add(BigDecimal.valueOf(ySeries[i])).doubleValue(); } double[] copiedStackSeries = new double[stackSeries.length]; System.arraycopy(stackSeries, 0, copiedStackSeries, 0, stackSeries.length); ((Series) series).setStackSeries(copiedStackSeries); } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/series/SeriesLabel.java0000644000175000017500000001454612657165716031613 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.series; import java.text.DecimalFormat; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Display; import org.swtchart.ISeriesLabel; import org.swtchart.internal.Util; /** * A series label. */ public class SeriesLabel implements ISeriesLabel { /** the visibility state of series label */ private boolean isVisible; /** the series label font */ protected Font font; /** the series label color */ protected Color color; /** the format for series label */ private String format; /** the formats for series labels */ private String[] formats; /** the default label color */ private static final int DEFAULT_COLOR = SWT.COLOR_BLACK; /** the default font */ private static final Font DEFAULT_FONT = Display.getDefault() .getSystemFont(); /** the default label format */ private static final String DEFAULT_FORMAT = "#.###########"; /** * Constructor. */ public SeriesLabel() { font = DEFAULT_FONT; color = Display.getDefault().getSystemColor(DEFAULT_COLOR); isVisible = false; format = DEFAULT_FORMAT; formats = new String[0]; } /* * @see ISeriesLabel#getFormat() */ public String getFormat() { return format; } /* * @see ISeriesLabel#setFormat(String) */ public void setFormat(String format) { if (format == null) { this.format = DEFAULT_FORMAT; } else { this.format = format; } } /* * @see ISeriesLabel#getFormats() */ public String[] getFormats() { String[] copiedFormats = new String[formats.length]; System.arraycopy(formats, 0, copiedFormats, 0, formats.length); return copiedFormats; } /* * @see ISeriesLabel#setFormats(String[]) */ public void setFormats(String[] formats) { if (formats == null) { this.formats = new String[0]; return; } this.formats = new String[formats.length]; System.arraycopy(formats, 0, this.formats, 0, formats.length); } /* * @see ISeriesLabel#getForeground() */ public Color getForeground() { return color; } /* * @see ISeriesLabel#setForeground(Color) */ public void setForeground(Color color) { if (color != null && color.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } if (color == null) { this.color = Display.getDefault().getSystemColor(DEFAULT_COLOR); } else { this.color = color; } } /* * @see ISeriesLabel#getFont() */ public Font getFont() { if (font.isDisposed()) { font = DEFAULT_FONT; } return font; } /* * @see ISeriesLabel#setFont(Font) */ public void setFont(Font font) { if (font != null && font.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } if (font == null) { this.font = DEFAULT_FONT; } else { this.font = font; } } /* * @see ISeriesLabel#isVisible() */ public boolean isVisible() { return isVisible; } /* * @see ISeriesLabel#setVisible(boolean) */ public void setVisible(boolean visible) { this.isVisible = visible; } /** * Draws series label. * * @param gc * the GC object * @param h * the horizontal coordinate to draw label * @param v * the vertical coordinate to draw label * @param ySeriesValue * the Y series value * @param seriesIndex * the series index * @param alignment * the alignment of label position (SWT.CENTER or SWT.BOTTOM) */ protected void draw(GC gc, int h, int v, double ySeriesValue, int seriesIndex, int alignment) { if (!isVisible) { return; } Color oldForeground = gc.getForeground(); gc.setForeground(color); gc.setFont(getFont()); // get format String format1 = format; if (formats.length > seriesIndex) { format1 = formats[seriesIndex]; } if (format1 == null || format1.equals("")) { return; } // get text String text; if (isDecimalFormat(format1)) { text = new DecimalFormat(format1).format(ySeriesValue); } else { text = format1.replaceAll("'", ""); } // draw label if (alignment == SWT.CENTER) { Point p = Util.getExtentInGC(font, text); gc.drawString(text, (int) (h - p.x / 2d), (int) (v - p.y / 2d), true); } else if (alignment == SWT.BOTTOM) { gc.drawString(text, h, v, true); } gc.setForeground(oldForeground); } /** * Gets the state indicating if decimal format is given. * * @param text * the text to be checked * @return true if decimal format is given */ private static boolean isDecimalFormat(String text) { StringBuilder nonEscapedPart = new StringBuilder(); String[] elements = text.split("'"); if (elements != null) { for (int i = 0; i < elements.length; i += 2) { nonEscapedPart.append(elements[i]); } } if (nonEscapedPart.indexOf("#") == -1 && nonEscapedPart.indexOf("0") == -1) { return false; } return true; } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/series/Series.java0000644000175000017500000004437012657165716030651 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart.internal.series; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Event; import org.swtchart.Chart; import org.swtchart.IAxis; import org.swtchart.IDisposeListener; import org.swtchart.IErrorBar; import org.swtchart.ISeries; import org.swtchart.ISeriesLabel; import org.swtchart.Range; import org.swtchart.IAxis.Direction; import org.swtchart.internal.axis.Axis; import org.swtchart.internal.compress.ICompress; /** * Series. */ abstract public class Series implements ISeries { /** the default series type */ protected static final SeriesType DEFAULT_SERIES_TYPE = SeriesType.LINE; /** the x series */ protected double[] xSeries; /** the y series */ protected double[] ySeries; /** the minimum value of x series */ protected double minX; /** the maximum value of x series */ protected double maxX; /** the minimum value of y series */ protected double minY; /** the maximum value of y series */ protected double maxY; /** the series id */ protected String id; /** the compressor */ protected ICompress compressor; /** the x axis id */ protected int xAxisId; /** the y axis id */ protected int yAxisId; /** the visibility of series */ protected boolean visible; /** the state indicating whether x series are monotone increasing */ protected boolean isXMonotoneIncreasing; /** the series type */ protected SeriesType type; /** the series label */ protected SeriesLabel seriesLabel; /** the x error bar */ protected ErrorBar xErrorBar; /** the y error bar */ protected ErrorBar yErrorBar; /** the chart */ protected Chart chart; /** the state indicating if the series is a stacked type */ protected boolean stackEnabled; /** the stack series */ protected double[] stackSeries; /** the state indicating if the type of X series is Date */ private boolean isDateSeries; /** the state indicating if the series is visible in legend */ private boolean visibleInLegend; /** the series description */ private String description; /** the list of dispose listeners */ private List listeners; /** * Constructor. * * @param chart * the chart * @param id * the series id */ protected Series(Chart chart, String id) { super(); this.chart = chart; this.id = id; xAxisId = 0; yAxisId = 0; visible = true; type = DEFAULT_SERIES_TYPE; stackEnabled = false; isXMonotoneIncreasing = true; seriesLabel = new SeriesLabel(); xErrorBar = new ErrorBar(); yErrorBar = new ErrorBar(); visibleInLegend = true; listeners = new ArrayList(); xSeries = new double[0]; ySeries = new double[0]; } /* * @see ISeries#getId() */ public String getId() { return id; } /* * @see ISeries#setVisible(boolean) */ public void setVisible(boolean visible) { if (this.visible == visible) { return; } this.visible = visible; ((SeriesSet) chart.getSeriesSet()).updateStackAndRiserData(); } /* * @see ISeries#isVisible() */ public boolean isVisible() { return visible; } /* * @see ISeries#getType() */ public SeriesType getType() { return type; } /* * @see ISeries#isStackEnabled() */ public boolean isStackEnabled() { return stackEnabled; } /* * @see ISeries#enableStack(boolean) */ public void enableStack(boolean enabled) { if (enabled && minY < 0) { throw new IllegalStateException( "Stacked series cannot contain minus values."); } if (stackEnabled == enabled) { return; } stackEnabled = enabled; ((SeriesSet) chart.getSeriesSet()).updateStackAndRiserData(); } /* * @see ISeries#setXSeries(double[]) */ public void setXSeries(double[] series) { if (series == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); return; // to suppress warning... } xSeries = new double[series.length]; System.arraycopy(series, 0, xSeries, 0, series.length); isDateSeries = false; if (xSeries.length == 0) { return; } // find the min and max value of x series minX = xSeries[0]; maxX = xSeries[0]; for (int i = 1; i < xSeries.length; i++) { if (minX > xSeries[i]) { minX = xSeries[i]; } if (maxX < xSeries[i]) { maxX = xSeries[i]; } if (xSeries[i - 1] > xSeries[i]) { isXMonotoneIncreasing = false; } } setCompressor(); compressor.setXSeries(xSeries); compressor.setYSeries(ySeries); if (minX <= 0) { IAxis axis = chart.getAxisSet().getXAxis(xAxisId); if (axis != null) { axis.enableLogScale(false); } } } /* * @see ISeries#getXSeries() */ public double[] getXSeries() { double[] copiedSeries = new double[xSeries.length]; System.arraycopy(xSeries, 0, copiedSeries, 0, xSeries.length); return copiedSeries; } /* * @see ISeries#setYSeries(double[]) */ public void setYSeries(double[] series) { if (series == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); return; // to suppress warning... } ySeries = new double[series.length]; System.arraycopy(series, 0, ySeries, 0, series.length); if (ySeries.length == 0) { return; } // find the min and max value of y series minY = ySeries[0]; maxY = ySeries[0]; for (int i = 1; i < ySeries.length; i++) { if (minY > ySeries[i]) { minY = ySeries[i]; } if (maxY < ySeries[i]) { maxY = ySeries[i]; } } if (xSeries.length != series.length) { xSeries = new double[series.length]; for (int i = 0; i < series.length; i++) { xSeries[i] = i; } minX = xSeries[0]; maxX = xSeries[xSeries.length - 1]; isXMonotoneIncreasing = true; } setCompressor(); compressor.setXSeries(xSeries); compressor.setYSeries(ySeries); if (minX <= 0) { IAxis axis = chart.getAxisSet().getXAxis(xAxisId); if (axis != null) { axis.enableLogScale(false); } } if (minY <= 0) { IAxis axis = chart.getAxisSet().getYAxis(yAxisId); if (axis != null) { axis.enableLogScale(false); } stackEnabled = false; } } /* * @see ISeries#getYSeries() */ public double[] getYSeries() { double[] copiedSeries = new double[ySeries.length]; System.arraycopy(ySeries, 0, copiedSeries, 0, ySeries.length); return copiedSeries; } /* * @see ISeries#setXDateSeries(Date[]) */ public void setXDateSeries(Date[] series) { if (series == null) { SWT.error(SWT.ERROR_NULL_ARGUMENT); return; // to suppress warning... } double[] xDateSeries = new double[series.length]; for (int i = 0; i < series.length; i++) { xDateSeries[i] = series[i].getTime(); } setXSeries(xDateSeries); isDateSeries = true; } /* * @see ISeries#getXDateSeries() */ public Date[] getXDateSeries() { if (!isDateSeries) { return new Date[0]; } Date[] series = new Date[xSeries.length]; for (int i = 0; i < series.length; i++) { series[i] = new Date((long) xSeries[i]); } return series; } /** * Gets the state indicating if date series is set. * * @return true if date series is set */ public boolean isDateSeries() { return isDateSeries; } /** * Gets the state indicating if the series is valid stack series. * * @return true if the series is valid stack series */ public boolean isValidStackSeries() { return stackEnabled && stackSeries != null && stackSeries.length > 0 && !chart.getAxisSet().getYAxis(yAxisId).isLogScaleEnabled() && ((Axis) chart.getAxisSet().getXAxis(xAxisId)) .isValidCategoryAxis(); } /** * Gets the X range of series. * * @return the X range of series */ public Range getXRange() { return new Range(minX, maxX); } /** * Gets the adjusted range to show all series in screen. This range includes * the size of plot like symbol or bar. * * @param axis * the axis * @param length * the axis length in pixels * @return the adjusted range */ abstract public Range getAdjustedRange(Axis axis, int length); /** * Gets the Y range of series. * * @return the Y range of series */ public Range getYRange() { double min = minY; double max = maxY; Axis xAxis = (Axis) chart.getAxisSet().getXAxis(xAxisId); if (isValidStackSeries() && xAxis.isValidCategoryAxis()) { for (int i = 0; i < stackSeries.length; i++) { if (max < stackSeries[i]) { max = stackSeries[i]; } } } return new Range(min, max); } /** * Gets the compressor. * * @return the compressor */ protected ICompress getCompressor() { return compressor; } /** * Sets the compressor. */ abstract protected void setCompressor(); /* * @see ISeries#getXAxisId() */ public int getXAxisId() { return xAxisId; } /* * @see ISeries#setXAxisId(int) */ public void setXAxisId(int id) { if (xAxisId == id) { return; } IAxis axis = chart.getAxisSet().getXAxis(xAxisId); if (minX <= 0 && axis != null && axis.isLogScaleEnabled()) { chart.getAxisSet().getXAxis(xAxisId).enableLogScale(false); } xAxisId = id; ((SeriesSet) chart.getSeriesSet()).updateStackAndRiserData(); } /* * @see ISeries#getYAxisId() */ public int getYAxisId() { return yAxisId; } /* * @see ISeries#setYAxisId(int) */ public void setYAxisId(int id) { yAxisId = id; } /* * @see ISeries#getLabel() */ public ISeriesLabel getLabel() { return seriesLabel; } /* * @see ISeries#getXErrorBar() */ public IErrorBar getXErrorBar() { return xErrorBar; } /* * @see ISeries#getYErrorBar() */ public IErrorBar getYErrorBar() { return yErrorBar; } /** * Sets the stack series * * @param stackSeries * The stack series */ protected void setStackSeries(double[] stackSeries) { this.stackSeries = stackSeries; } /* * @see ISeries#getPixelCoordinates(int) */ public Point getPixelCoordinates(int index) { // get the horizontal and vertical axes IAxis hAxis; IAxis vAxis; if (chart.getOrientation() == SWT.HORIZONTAL) { hAxis = chart.getAxisSet().getXAxis(xAxisId); vAxis = chart.getAxisSet().getYAxis(yAxisId); } else if (chart.getOrientation() == SWT.VERTICAL) { hAxis = chart.getAxisSet().getYAxis(yAxisId); vAxis = chart.getAxisSet().getXAxis(xAxisId); } else { throw new IllegalStateException("unknown chart orientation"); //$NON-NLS-1$ } // get the pixel coordinates return new Point(getPixelCoordinate(hAxis, index), getPixelCoordinate( vAxis, index)); } /** * Gets the pixel coordinates with given axis and series index. * * @param axis * the axis * @param index * the series index * @return the pixel coordinates */ private int getPixelCoordinate(IAxis axis, int index) { // get the data coordinate double dataCoordinate; if (axis.getDirection() == Direction.X) { if (axis.isCategoryEnabled()) { dataCoordinate = index; } else { if (index < 0 || xSeries.length <= index) { throw new IllegalArgumentException( "Series index is out of range."); //$NON-NLS-1$ } dataCoordinate = xSeries[index]; } } else if (axis.getDirection() == Direction.Y) { if (isValidStackSeries()) { if (index < 0 || stackSeries.length <= index) { throw new IllegalArgumentException( "Series index is out of range."); //$NON-NLS-1$ } dataCoordinate = stackSeries[index]; } else { if (index < 0 || ySeries.length <= index) { throw new IllegalArgumentException( "Series index is out of range."); //$NON-NLS-1$ } dataCoordinate = ySeries[index]; } } else { throw new IllegalStateException("unknown axis direction"); //$NON-NLS-1$ } // get the pixel coordinate return axis.getPixelCoordinate(dataCoordinate); } /** * Gets the range with given margin. * * @param lowerPlotMargin * the lower margin in pixels * @param upperPlotMargin * the upper margin in pixels * @param length * the axis length in pixels * @param axis * the axis * @param range * the range * @return the range with margin */ protected Range getRangeWithMargin(int lowerPlotMargin, int upperPlotMargin, int length, Axis axis, Range range) { if (length == 0) { return range; } int lowerPixelCoordinate = axis.getPixelCoordinate(range.lower, range.lower, range.upper) + lowerPlotMargin * (axis.isHorizontalAxis() ? -1 : 1); int upperPixelCoordinate = axis.getPixelCoordinate(range.upper, range.lower, range.upper) + upperPlotMargin * (axis.isHorizontalAxis() ? 1 : -1); double lower = axis.getDataCoordinate(lowerPixelCoordinate, range.lower, range.upper); double upper = axis.getDataCoordinate(upperPixelCoordinate, range.lower, range.upper); return new Range(lower, upper); } /* * @see ISeries#setVisibleInLegend(boolean) */ public void setVisibleInLegend(boolean visible) { visibleInLegend = visible; } /* * @see ISeries#isVisibleInLegend() */ public boolean isVisibleInLegend() { return visibleInLegend; } /* * @see ISeries#setDescription(String) */ public void setDescription(String description) { this.description = description; } /* * @see ISeries#getDescription() */ public String getDescription() { return description; } /** * Disposes SWT resources. */ protected void dispose() { for (IDisposeListener listener : listeners) { listener.disposed(new Event()); } } /* * @see IAxis#addDisposeListener(IDisposeListener) */ public void addDisposeListener(IDisposeListener listener) { listeners.add(listener); } /** * Draws series. * * @param gc * the graphics context * @param width * the width to draw series * @param height * the height to draw series */ public void draw(GC gc, int width, int height) { if (!visible || width < 0 || height < 0 || xSeries.length == 0 || ySeries.length == 0) { return; } Axis xAxis = (Axis) chart.getAxisSet().getXAxis(getXAxisId()); Axis yAxis = (Axis) chart.getAxisSet().getYAxis(getYAxisId()); if (xAxis == null || yAxis == null) { return; } draw(gc, width, height, xAxis, yAxis); } /** * Draws series. * * @param gc * the graphics context * @param width * the width to draw series * @param height * the height to draw series * @param xAxis * the x axis * @param yAxis * the y axis */ abstract protected void draw(GC gc, int width, int height, Axis xAxis, Axis yAxis); } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/ILineSeries.java0000644000175000017500000001333012657165716026454 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.eclipse.swt.graphics.Color; /** * Line series. */ public interface ILineSeries extends ISeries { /** * A plot symbol type. */ public enum PlotSymbolType { /** none */ NONE("None"), /** circle */ CIRCLE("Circle"), /** square */ SQUARE("Square"), /** diamond */ DIAMOND("Diamond"), /** triangle */ TRIANGLE("Triangle"), /** inverted triangle */ INVERTED_TRIANGLE("Inverted Triangle"), /** cross */ CROSS("Cross"), /** plus */ PLUS("Plus"); /** the label for plot symbol */ public final String label; /** * Constructor. * * @param label * plot symbol label */ private PlotSymbolType(String label) { this.label = label; } } /** * Gets the symbol type. * * @return the symbol type */ PlotSymbolType getSymbolType(); /** * Sets the symbol type. If null is given, default type * PlotSymbolType.CIRCLE will be set. * * @param type * the symbol type */ void setSymbolType(PlotSymbolType type); /** * Gets the symbol size in pixels. * * @return the symbol size */ int getSymbolSize(); /** * Sets the symbol size in pixels. The default size is 4. * * @param size * the symbol size */ void setSymbolSize(int size); /** * Gets the symbol color. * * @return the symbol color */ Color getSymbolColor(); /** * Sets the symbol color. If null is given, default color will be set. * * @param color * the symbol color */ void setSymbolColor(Color color); /** * Gets the symbol colors. * * @return the symbol colors, or empty array if no symbol colors are set. */ Color[] getSymbolColors(); /** * Sets the symbol colors. Typically, the number of symbol colors is the same as the * number of plots. If the number of symbol colors is less than the number of plots, * the rest of plots will have the common color which is set with * setSymbolColor(Color). * * @param colors * the symbol colors. If null or empty array is given, the color * which is set with setSymbolColor(Color) will be commonly used * for all plots. */ void setSymbolColors(Color[] colors); /** * Gets line style. * * @return line style. */ LineStyle getLineStyle(); /** * Sets line style. If null is given, default line style will be set. * * @param style * line style */ void setLineStyle(LineStyle style); /** * Gets the line color. * * @return the line color */ Color getLineColor(); /** * Sets line color. If null is given, default color will be set. * * @param color * the line color */ void setLineColor(Color color); /** * Gets the line width. * * @return the line width */ int getLineWidth(); /** * Sets the width of line connecting data points and also line drawing * symbol if applicable (i.e. PlotSymbolType.CROSS or * PlotSymbolType.PLUS). The default width is 1. * * @param width * the line width */ void setLineWidth(int width); /** * Enables the area chart. * * @param enabled * true if enabling area chart */ void enableArea(boolean enabled); /** * Gets the state indicating if area chart is enabled. * * @return true if area chart is enabled */ boolean isAreaEnabled(); /** * Enables the step chart. * * @param enabled * true if enabling step chart */ void enableStep(boolean enabled); /** * Gets the state indicating if step chart is enabled. * * @return true if step chart is enabled */ boolean isStepEnabled(); /** * Gets the anti-aliasing value for drawing line. The default value is * SWT.DEFAULT. * * @return the anti-aliasing value which can be SWT.DEFAULT, * SWT.ON or SWT.OFF. */ int getAntialias(); /** * Sets the anti-aliasing value for drawing line. *

* If number of data points is too large, the series is drawn as a * collection of dots rather than lines. In this case, the anti-alias * doesn't really make effect, and just causes performance degradation. * Therefore, client code may automatically enable/disable the anti-alias * for each series depending on the number of data points, or alternatively * may let end-user configure it. * * @param antialias * the anti-aliasing value which can be SWT.DEFAULT, * SWT.ON or SWT.OFF. */ void setAntialias(int antialias); } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/IDisposeListener.java0000644000175000017500000000126412657165716027531 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.eclipse.swt.widgets.Event; /** * The dispose listener. */ public interface IDisposeListener { /** * The method to be invoked when the target is disposed. * * @param e * the event */ void disposed(Event e); }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/LineStyle.java0000644000175000017500000000173312657165716026215 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; /** * A line style. */ public enum LineStyle { /** none */ NONE("None"), /** solid */ SOLID("Solid"), /** dash */ DASH("Dash"), /** dot */ DOT("Dot"), /** dash dot */ DASHDOT("Dash Dot"), /** dash dot dot */ DASHDOTDOT("Dash Dot Dot"); /** the label for line style */ public final String label; /** * Constructor. * * @param label * the label for line style */ private LineStyle(String label) { this.label = label; } }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/Chart.java0000644000175000017500000002510612657165716025346 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.swtchart.internal.ChartLayout; import org.swtchart.internal.ChartLayoutData; import org.swtchart.internal.ChartTitle; import org.swtchart.internal.Legend; import org.swtchart.internal.PlotArea; import org.swtchart.internal.Title; import org.swtchart.internal.axis.AxisSet; import org.swtchart.internal.series.SeriesSet; /** * A chart which are composed of title, legend, axes and plot area. */ public class Chart extends Composite implements Listener { /** the title */ private Title title; /** the legend */ private Legend legend; /** the set of axes */ private AxisSet axisSet; /** the plot area */ private PlotArea plotArea; /** the orientation of chart which can be horizontal or vertical */ private int orientation; /** the state indicating if compressing series is enabled */ private boolean compressEnabled; /** the state indicating if the update of chart appearance is suspended */ private boolean updateSuspended; /** * Constructor. * * @param parent * the parent composite on which chart is placed * @param style * the style of widget to construct */ public Chart(Composite parent, int style) { super(parent, style | SWT.DOUBLE_BUFFERED); orientation = SWT.HORIZONTAL; compressEnabled = true; updateSuspended = false; parent.layout(); setLayout(new ChartLayout()); title = new ChartTitle(this); title.setLayoutData(new ChartLayoutData(SWT.DEFAULT, 100)); legend = new Legend(this, SWT.NONE); legend.setLayoutData(new ChartLayoutData(200, SWT.DEFAULT)); plotArea = new PlotArea(this, SWT.NONE); axisSet = new AxisSet(this); updateLayout(); addListener(SWT.Resize, this); } /** * Gets the chart title. * * @return the chart title */ public ITitle getTitle() { return title; } /** * Gets the legend. * * @return the legend */ public ILegend getLegend() { return legend; } /** * Gets the set of axes. * * @return the set of axes */ public IAxisSet getAxisSet() { return axisSet; } /** * Gets the plot area. * * @return the plot area */ public Composite getPlotArea() { return plotArea; } /** * Gets the set of series. * * @return the set of series */ public ISeriesSet getSeriesSet() { return plotArea.getSeriesSet(); } /* * @see Control#setBackground(Color) */ @Override public void setBackground(Color color) { super.setBackground(color); for (Control child : getChildren()) { if (!(child instanceof PlotArea) && !(child instanceof Legend)) { child.setBackground(color); } } } /** * Gets the background color in plot area. This method is identical with * getPlotArea().getBackground(). * * @return the background color in plot area */ public Color getBackgroundInPlotArea() { return plotArea.getBackground(); } /** * Sets the background color in plot area. * * @param color * the background color in plot area. If null is given, * default background color will be set. * @exception IllegalArgumentException * if given color is disposed */ public void setBackgroundInPlotArea(Color color) { if (color != null && color.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } plotArea.setBackground(color); } /** * Sets the state of chart orientation. The horizontal orientation means * that X axis is horizontal as usual, while the vertical orientation means * that Y axis is horizontal. * * @param orientation * the orientation which can be SWT.HORIZONTAL or SWT.VERTICAL */ @Override public void setOrientation(int orientation) { if (orientation == SWT.HORIZONTAL || orientation == SWT.VERTICAL) { this.orientation = orientation; } updateLayout(); } /** * Gets the state of chart orientation. The horizontal orientation means * that X axis is horizontal as usual, while the vertical orientation means * that Y axis is horizontal. * * @return the orientation which can be SWT.HORIZONTAL or SWT.VERTICAL */ @Override public int getOrientation() { return orientation; } /** * Enables compressing series. By default, compressing series is enabled, * and normally there should be no usecase to disable it. However, if you * suspect that something is wrong in compressing series, you can disable it * to isolate the issue. * * @param enabled * true if enabling compressing series */ public void enableCompress(boolean enabled) { compressEnabled = enabled; } /** * Gets the state indicating if compressing series is enabled. * * @return true if compressing series is enabled */ public boolean isCompressEnabled() { return compressEnabled; } /** * Suspends the update of chart appearance. * *

* By default, when the chart model is changed (e.g. adding new series or * changing chart properties), the chart appearance is updated accordingly. *

* However, when doing a lot of changes in the chart model at once, it is * inefficient that the update happens many times unnecessarily. In this * case, you may want to defer the update until completing whole model * changes in order to have better performance. *

* For example, suppose there is a chart having a large number of series, * the following example code disables the update during changing the model. * *

     * try {
     *     // suspend update
     *     chart.suspendUpdate(true);
     * 
     *     // do some changes for a large number of series
     *     for (ISeries series : chart.getSeriesSet().getSeries()) {
     *         series.enableStack(true);
     *     }
     * } finally {
     *     // resume update
     *     chart.suspendUpdate(false);
     * }
     * 
* * Note that the update has to be resumed right after completing the model * changes in order to avoid showing an incompletely updated chart. * * @param suspend * true to suspend the update of chart appearance */ public void suspendUpdate(boolean suspend) { if (updateSuspended == suspend) { return; } updateSuspended = suspend; // make sure that chart is updated if (!suspend) { updateLayout(); ((SeriesSet) getSeriesSet()).updateStackAndRiserData(); } } /** * Gets the state indicating if the update of chart appearance is suspended. * * @return true if the update of chart appearance is suspended */ public boolean isUpdateSuspended() { return updateSuspended; } /* * @see Listener#handleEvent(Event) */ public void handleEvent(Event event) { switch (event.type) { case SWT.Resize: updateLayout(); redraw(); break; default: break; } } /** * Updates the layout of chart elements. */ public void updateLayout() { if (updateSuspended) { return; } if (legend != null) { legend.updateLayoutData(); } if (title != null) { title.updateLayoutData(); } if (axisSet != null) { axisSet.updateLayoutData(); } layout(); if (axisSet != null) { axisSet.refresh(); } } /* * @see Control#update() */ @Override public void update() { super.update(); for (Control child : getChildren()) { child.update(); } } /* * @see Widget#dispose() */ @Override public void dispose() { title.dispose(); legend.dispose(); axisSet.dispose(); plotArea.dispose(); super.dispose(); } /* * @see Control#redraw() */ @Override public void redraw() { super.redraw(); for (Control child : getChildren()) { child.redraw(); } } /** * Saves to file with given format. * * @param filename * the file name * @param format * the format (SWT.IMAGE_*). The supported formats depend on OS. */ public void save(String filename, int format) { Image image = new Image(Display.getDefault(), getBounds()); GC gc = new GC(image); print(gc); gc.dispose(); ImageData data = image.getImageData(); ImageLoader loader = new ImageLoader(); loader.data = new ImageData[] { data }; loader.save(filename, format); image.dispose(); } /** * Renders off-screen image. * * @param image * The image to render off-screen */ public void renderOffscreenImage(Image image) { GC gc = new GC(image); print(gc); gc.dispose(); } } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/IGrid.java0000644000175000017500000000204512657165716025300 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.eclipse.swt.graphics.Color; /** * A grid. */ public interface IGrid { /** * Gets the foreground color. * * @return the foreground color */ Color getForeground(); /** * Sets the foreground color. * * @param color * the foreground color */ void setForeground(Color color); /** * Gets the line style. * * @return the line style. */ LineStyle getStyle(); /** * Sets the line style. * * @param style * the line style */ void setStyle(LineStyle style); }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/IBarSeries.java0000644000175000017500000000561112657165716026274 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Rectangle; /** * Bar series. */ public interface IBarSeries extends ISeries { /** * Bar width style. */ public enum BarWidthStyle { /** the style stretching the bar width depending on interval of bars. */ STRETCHED, /** the style fixing the bar width regardless of interval of bars. */ FIXED; } /** * Gets the bar width style. * * @param style * the bar width style * @return the bar width style */ BarWidthStyle getBarWidthStyle(BarWidthStyle style); /** * Sets the bar width style. The default is BarWidthStyle.STRETCHED * . * * @param style * the bar width style */ void setBarWidthStyle(BarWidthStyle style); /** * Gets the bar width in pixels. * * @return the bar width in pixels */ int getBarWidth(); /** * Sets the bar width in pixels. The specified bar width is active only when * the bar width style is set to BarWidthStyle.FIXED. * * @param width * the bar width in pixels */ void setBarWidth(int width); /** * Gets the bar padding in percentage. * * @return the bar padding in percentage */ int getBarPadding(); /** * Sets the bar padding in percentage. The specified padding is active only * when the bar width style is set to BarWidthStyle.STRETCHED. * * @param padding * the bar padding in percentage */ void setBarPadding(int padding); /** * Gets the bar color. * * @return the bar color */ Color getBarColor(); /** * Sets the bar color. If null is given, default color will be set. * * @param color * the bar color */ void setBarColor(Color color); /** * Gets the array of bar rectangles. This method is typically used for mouse * listener to check whether mouse cursor is on bar. *

* The returned array has the same size as data points. Depending on X axis * range, some bars can be out of screen. In this case, the rectangles for * invisible bars will be null in the returned array. * * @return the array of bar rectangles in pixels. */ Rectangle[] getBounds(); }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/ISeriesSet.java0000644000175000017500000000411512657165716026321 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.swtchart.ISeries.SeriesType; /** * A series container. */ public interface ISeriesSet { /** * Creates the series. If series for given id already exists, the existing * series will be overwritten. * * @param type * the series type * @param id * the id for series * @return the series */ ISeries createSeries(SeriesType type, String id); /** * Gets the series for given id. * * @param id * the id for series * @return the series, or null if series doesn't exist for the given id. */ ISeries getSeries(String id); /** * Gets the array of series * * @return the array of series */ ISeries[] getSeries(); /** * Deletes the series for given id. * * @param id * the series id * @throws IllegalArgumentException * if there is no series for the given id. */ void deleteSeries(String id); /** * Brings the series for given id forward. * * @param id * the series id */ void bringForward(String id); /** * Brings the series for given id to front. * * @param id * the series id */ void bringToFront(String id); /** * Sends the series for given id backward. * * @param id * the series id */ void sendBackward(String id); /** * Sends the series for given id to back. * * @param id * the series id */ void sendToBack(String id); }swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/IPlotArea.java0000644000175000017500000000154312657165716026124 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; /** * The plot area. */ public interface IPlotArea { /** * Adds the custom paint listener. * * @param listener * the custom paint listener */ public void addCustomPaintListener(ICustomPaintListener listener); /** * Removes the custom paint listener * * @param listener * the custom paint listener */ public void removeCustomPaintListener(ICustomPaintListener listener); } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/Constants.java0000644000175000017500000000264312657165716026262 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import org.eclipse.swt.graphics.RGB; /** * Constant values. */ public class Constants { /** the large font size */ final static public int LARGE_FONT_SIZE = 13; /** the medium font size */ final static public int MEDIUM_FONT_SIZE = 11; /** the small font size */ final static public int SMALL_FONT_SIZE = 9; /** the color for light blue */ @Deprecated final static public RGB LIGHT_BLUE = new RGB(153, 186, 243); /** the color for blue */ @Deprecated final static public RGB BLUE = new RGB(0, 0, 255); /** the color for white */ @Deprecated final static public RGB WHITE = new RGB(255, 255, 255); /** the color for gray */ @Deprecated final static public RGB GRAY = new RGB(200, 200, 200); /** the color for dark gray */ @Deprecated final static public RGB DARK_GRAY = new RGB(150, 150, 150); /** the color for black */ @Deprecated final static public RGB BLACK = new RGB(0, 0, 0); } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/ISeries.java0000644000175000017500000001272012657165716025646 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; import java.util.Date; import org.eclipse.swt.graphics.Point; /** * Series. */ public interface ISeries { /** * A Series type. */ public enum SeriesType { /** the line */ LINE("Line"), /** the bar */ BAR("Bar"); /** the label for series type */ public final String label; /** * Constructor. * * @param label * the label for series type */ private SeriesType(String label) { this.label = label; } } /** * Gets the series id. * * @return the series id */ String getId(); /** * Sets the visibility state. * * @param visible * the visibility state */ void setVisible(boolean visible); /** * Gets the visibility state. * * @return true if series is visible */ boolean isVisible(); /** * Gets the series type. * * @return the series type */ SeriesType getType(); /** * Enables the stack series. The series has to contain only positive values. * * @param enabled * true if enabling stack series * @throws IllegalStateException * if series contains negative values. */ void enableStack(boolean enabled); /** * Gets the state indicating if stack is enabled. * * @return the state indicating if stack is enabled */ boolean isStackEnabled(); /** * Sets the X series. * * @param series * the X series */ void setXSeries(double[] series); /** * Sets the Y series. * * @param series * the Y series */ void setYSeries(double[] series); /** * Gets the X series. If the X series is not set, empty array will be returned. * * @return the X series */ double[] getXSeries(); /** * Gets the Y series. If the Y series haven't been set yet, empty array will be * returned. * * @return the Y series */ double[] getYSeries(); /** * Sets the X date series. *

* X series and X date series are exclusive. X date series will be cleared by setting * X series, and vice versa. * * @param series * the X date series */ void setXDateSeries(Date[] series); /** * Gets the X date series. * * @return the X date series, or empty array if X date series is not set. */ Date[] getXDateSeries(); /** * Gets the X axis id. * * @return the X axis id */ int getXAxisId(); /** * Sets the X axis id. * * @param id * the X axis id. */ void setXAxisId(int id); /** * Gets the Y axis id. * * @return the Y axis id */ int getYAxisId(); /** * Sets the Y axis id. * * @param id * the Y axis id. */ void setYAxisId(int id); /** * Gets the X error bar. This is typically used for scatter chart. * * @return the X error bar */ IErrorBar getXErrorBar(); /** * Gets the Y error bar. * * @return the Y error bar */ IErrorBar getYErrorBar(); /** * Gets the series label. * * @return the series label */ ISeriesLabel getLabel(); /** * Sets the visibility state in legend. * * @param visible * the visibility state in legend */ void setVisibleInLegend(boolean visible); /** * Gets the visibility state in legend. * * @return true if series is visible in legend */ boolean isVisibleInLegend(); /** * Sets the series description. *

* For example, you may store the description explaining what this series * is, and display it on tool tip with mouse hover on the series. *

* By default, legend displays the description, when it is set. * * @param description * the series description, or null to clear it */ void setDescription(String description); /** * Gets the series description * * @return the series description, or null if not set */ String getDescription(); /** * Gets the pixel coordinates corresponding to the given series index. * * @param index * the series index * @return the pixel coordinates */ Point getPixelCoordinates(int index); /** * Adds the dispose listener. The newly created color or font for series can be * disposed with the dispose listener when they are no longer needed. * * @param listener * the dispose listener */ void addDisposeListener(IDisposeListener listener); } swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/Range.java0000644000175000017500000000252712657165716025343 0ustar jsprickejspricke/******************************************************************************* * Copyright (c) 2008-2016 SWTChart project. All rights reserved. * * This code is distributed under the terms of the Eclipse Public License v1.0 * which is available at http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.swtchart; /** * A range. */ public class Range { /** the lower value of range */ public double lower; /** the upper value of range */ public double upper; /** * Constructor. * * @param start * the start value of range * @param end * the end value of range */ public Range(double start, double end) { this.lower = (end > start) ? start : end; this.upper = (end > start) ? end : start; } /** * Constructor. * * @param range * the range */ public Range(Range range) { lower = (range.upper > range.lower) ? range.lower : range.upper; upper = (range.upper > range.lower) ? range.upper : range.lower; } /* * @see Object#toString() */ @Override public String toString() { return "lower=" + lower + ", upper=" + upper; } } swt-chart-code-312-trunk/org.swtchart/META-INF/0000755000175000017500000000000013275316670021353 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart/META-INF/MANIFEST.MF0000644000175000017500000000041412657165716023012 0ustar jsprickejsprickeManifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: SWTChart Plug-in Bundle-SymbolicName: org.swtchart;singleton:=true Bundle-Version: 0.10.0.qualifier Require-Bundle: org.eclipse.swt Export-Package: org.swtchart Bundle-RequiredExecutionEnvironment: J2SE-1.5 swt-chart-code-312-trunk/org.swtchart.examples.ext/0000755000175000017500000000000013275316674022633 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples.ext/build.properties0000644000175000017500000000020611032257046026030 0ustar jsprickejsprickesource.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ plugin.xml,\ icons/ swt-chart-code-312-trunk/org.swtchart.examples.ext/plugin.xml0000644000175000017500000000106111032525344024632 0ustar jsprickejspricke swt-chart-code-312-trunk/org.swtchart.examples.ext/.project0000644000175000017500000000125611032257046024270 0ustar jsprickejspricke org.swtchart.examples.ext org.eclipse.jdt.core.javabuilder org.eclipse.pde.ManifestBuilder org.eclipse.pde.SchemaBuilder org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature swt-chart-code-312-trunk/org.swtchart.examples.ext/icons/0000755000175000017500000000000013275316674023746 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples.ext/icons/swtchart.gif0000644000175000017500000000034611032262531026254 0ustar jsprickejsprickeGIF89aLASIdg#! ,c&d)]ԉ4 ˰%KUAQ`=G2(VDr7E(Ǫ2|hlaށۇP7tv:xz~:&$!;swt-chart-code-312-trunk/org.swtchart.examples.ext/.classpath0000644000175000017500000000056611234141567024613 0ustar jsprickejspricke swt-chart-code-312-trunk/org.swtchart.examples.ext/src/0000755000175000017500000000000013275316672023420 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/0000755000175000017500000000000013275316672024207 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/swtchart/0000755000175000017500000000000013275316672026046 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/swtchart/examples/0000755000175000017500000000000013275316674027666 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/swtchart/examples/Activator.java0000644000175000017500000000216311152601570032447 0ustar jsprickejsprickepackage org.swtchart.examples; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; /** * The activator class controls the plug-in life cycle */ public class Activator extends AbstractUIPlugin { /** The shared instance */ private static Activator plugin; /* * @see AbstractUIPlugin#start(BundleContext) */ @Override public void start(BundleContext context) throws Exception { super.start(context); setPlugin(this); } /* * @see AbstractUIPlugin#stop(BundleContext) */ @Override public void stop(BundleContext context) throws Exception { setPlugin(null); super.stop(context); } /** * Sets the shared instance * * @param activator * the shared instance */ private static void setPlugin(Activator activator) { plugin = activator; } /** * Returns the shared instance * * @return the shared instance */ public static Activator getDefault() { return plugin; } } swt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/swtchart/examples/ext/0000755000175000017500000000000013275316674030466 5ustar jsprickejspricke././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootrootswt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/swtchart/examples/ext/InteractiveChartExample.javaswt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/swtchart/examples/ext/InteractiveChartExa0000644000175000017500000000563711171376110034301 0ustar jsprickejsprickepackage org.swtchart.examples.ext; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.part.ViewPart; import org.swtchart.Chart; import org.swtchart.IBarSeries; import org.swtchart.ILineSeries; import org.swtchart.ISeries.SeriesType; import org.swtchart.ext.InteractiveChart; /** * An example view to show InteractiveChart. */ public class InteractiveChartExample extends ViewPart { private static final String[] categorySeries = { "Mon", "Tue", "Wed", "Thu", "Fri" }; private static final double[] yLineSeries1 = { 4.6, 5.4, 6.9, 5.6, 7.1 }; private static final double[] yLineSeries2 = { 6.0, 5.1, 4.9, 5.3, 4.2 }; private static final double[] yBarSeries1 = { 1.1, 2.9, 3.3, 4.4, 3.5 }; private static final double[] yBarSeries2 = { 4.3, 3.4, 2.8, 2.1, 1.9 }; /** the chart */ private Chart chart; /* * @see WorkbenchPart#createPartControl(Composite) */ @Override public void createPartControl(Composite parent) { parent.setLayout(new FillLayout()); // create an interactive chart chart = new InteractiveChart(parent, SWT.NONE); // set title chart.getTitle().setText("Sample Interactive Chart"); // set category series chart.getAxisSet().getXAxis(0).enableCategory(true); chart.getAxisSet().getXAxis(0).setCategorySeries(categorySeries); // create line series 1 ILineSeries lineSeries1 = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "line series 1"); lineSeries1.setYSeries(yLineSeries1); // create line series 2 ILineSeries lineSeries2 = (ILineSeries) chart.getSeriesSet() .createSeries(SeriesType.LINE, "line series 2"); lineSeries2.setYSeries(yLineSeries2); lineSeries2.setLineColor(Display.getDefault().getSystemColor(SWT.COLOR_RED)); // create bar series 1 IBarSeries barSeries1 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "bar series 1"); barSeries1.setYSeries(yBarSeries1); // create bar series 2 IBarSeries barSeries2 = (IBarSeries) chart.getSeriesSet().createSeries( SeriesType.BAR, "bar series 2"); barSeries2.setYSeries(yBarSeries2); barSeries2.setBarColor(Display.getDefault().getSystemColor(SWT.COLOR_GREEN)); // adjust the axis range chart.getAxisSet().adjustRange(); } /* * @see WorkbenchPart#setFocus() */ @Override public void setFocus() { chart.getPlotArea().setFocus(); } /* * @see WorkbenchPart#dispose() */ @Override public void dispose() { super.dispose(); chart.dispose(); } } swt-chart-code-312-trunk/org.swtchart.examples.ext/META-INF/0000755000175000017500000000000013275316672023771 5ustar jsprickejsprickeswt-chart-code-312-trunk/org.swtchart.examples.ext/META-INF/MANIFEST.MF0000644000175000017500000000063512657165716025433 0ustar jsprickejsprickeManifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: SWTChart Examples Plug-in Bundle-SymbolicName: org.swtchart.examples.ext;singleton:=true Bundle-Version: 0.10.0.qualifier Bundle-Activator: org.swtchart.examples.Activator Bundle-ActivationPolicy: lazy Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, org.swtchart, org.swtchart.ext Bundle-RequiredExecutionEnvironment: J2SE-1.5