();
}
/**
* 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();
}
}
}
././@LongLink 0000644 0000000 0000000 00000000155 00000000000 011604 L ustar root root swt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/AbstractSelectorPage.java swt-chart-code-312-trunk/org.swtchart.ext/src/org/swtchart/ext/internal/properties/AbstractSelectorP0000644 0001750 0001750 00000011566 11171376066 034355 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000041600 11223676210 031120 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000003311 11223676210 027425 0 ustar jspricke jspricke package 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/ 0000755 0001750 0001750 00000000000 13275316674 022156 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.ext/META-INF/MANIFEST.MF 0000644 0001750 0001750 00000000437 12657165716 023616 0 ustar jspricke jspricke Manifest-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/ 0000755 0001750 0001750 00000000000 13275316672 022032 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples/.project 0000644 0001750 0001750 00000000615 11032255664 023473 0 ustar jspricke jspricke
org.swtchart.examples
org.eclipse.jdt.core.javabuilder
org.eclipse.jdt.core.javanature
swt-chart-code-312-trunk/org.swtchart.examples/lib/ 0000755 0001750 0001750 00000000000 13275316672 022600 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples/.classpath 0000644 0001750 0001750 00000000553 12657165716 024024 0 ustar jspricke jspricke
swt-chart-code-312-trunk/org.swtchart.examples/src/ 0000755 0001750 0001750 00000000000 13275316671 022620 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples/src/org/ 0000755 0001750 0001750 00000000000 13275316671 023407 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/ 0000755 0001750 0001750 00000000000 13275316671 025246 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/ 0000755 0001750 0001750 00000000000 13275316672 027065 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/LogScaleExample.java 0000644 0001750 0001750 00000004024 11520323141 032711 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000003656 11520323141 033133 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000005051 11520323141 033441 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000004041 11520323141 033411 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000011673 11520323141 032610 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000003613 11520323141 032711 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000004127 11520323141 033121 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000003757 11520323141 033527 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000005735 11520323141 033646 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000004240 11520323141 033052 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000004341 11520323141 033427 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000003710 11520323141 033072 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000004671 11520323141 033005 0 ustar jspricke jspricke package 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.java 0000644 0001750 0001750 00000004233 11520323141 033611 0 ustar jspricke jspricke package 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;
}
} ././@LongLink 0000644 0000000 0000000 00000000152 00000000000 011601 L ustar root root swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/AngledAxisTickLabelsExample.java swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/AngledAxisTickLabelsExample0000644 0001750 0001750 00000003737 11520323141 034267 0 ustar jspricke jspricke package 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/ 0000755 0001750 0001750 00000000000 13275316672 030632 5 ustar jspricke jspricke ././@LongLink 0000644 0000000 0000000 00000000162 00000000000 011602 L ustar root root swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/CustomPaintListenerExample.java swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/CustomPaintListene0000644 0001750 0001750 00000005203 11520315566 034337 0 ustar jspricke jspricke package 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;
}
}
}
././@LongLink 0000644 0000000 0000000 00000000164 00000000000 011604 L ustar root root swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/PxielToDataConversionExample.java swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/PxielToDataConvers0000644 0001750 0001750 00000005031 11520315566 034262 0 ustar jspricke jspricke package 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;
}
} ././@LongLink 0000644 0000000 0000000 00000000155 00000000000 011604 L ustar root root swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/AxisTickBoundsExample.java swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/AxisTickBoundsExam0000644 0001750 0001750 00000006153 11520315566 034257 0 ustar jspricke jspricke package 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;
}
} ././@LongLink 0000644 0000000 0000000 00000000153 00000000000 011602 L ustar root root swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/LegendBoundsExample.java swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/LegendBoundsExampl0000644 0001750 0001750 00000006374 11520315566 034277 0 ustar jspricke jspricke package 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;
}
} ././@LongLink 0000644 0000000 0000000 00000000153 00000000000 011602 L ustar root root swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/SymbolBoundsExample.java swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/SymbolBoundsExampl0000644 0001750 0001750 00000006604 11520323141 034326 0 ustar jspricke jspricke package 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;
}
} ././@LongLink 0000644 0000000 0000000 00000000164 00000000000 011604 L ustar root root swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/DataToPixelConversionExample.java swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/DataToPixelConvers0000644 0001750 0001750 00000004717 11520315566 034274 0 ustar jspricke jspricke package 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;
}
} ././@LongLink 0000644 0000000 0000000 00000000150 00000000000 011577 L ustar root root swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/BarBoundsExample.java swt-chart-code-312-trunk/org.swtchart.examples/src/org/swtchart/examples/advanced/BarBoundsExample.j0000644 0001750 0001750 00000006606 11520315566 034200 0 ustar jspricke jspricke package 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/ 0000755 0001750 0001750 00000000000 13275316671 020214 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart/build.properties 0000644 0001750 0001750 00000000120 11031467471 023413 0 ustar jspricke jspricke source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.
swt-chart-code-312-trunk/org.swtchart/.project 0000644 0001750 0001750 00000001472 11031471226 021651 0 ustar jspricke jspricke
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/.classpath 0000644 0001750 0001750 00000000566 11234141567 022177 0 ustar jspricke jspricke
swt-chart-code-312-trunk/org.swtchart/src/ 0000755 0001750 0001750 00000000000 13275316670 021002 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart/src/org/ 0000755 0001750 0001750 00000000000 13275316670 021571 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/ 0000755 0001750 0001750 00000000000 13275316671 023431 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/IErrorBar.java 0000644 0001750 0001750 00000006642 12657165716 026140 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000004615 12657165716 026612 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000006714 12657165716 026141 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000001330 12657165716 030363 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000013026 12657165716 025320 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000005746 12657165716 025624 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000006003 12657165716 025771 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000004604 12657165716 025477 0 ustar jspricke jspricke /*******************************************************************************
* 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/ 0000755 0001750 0001750 00000000000 13275316671 025245 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/Legend.java 0000644 0001750 0001750 00000035211 12657165716 027315 0 ustar jspricke jspricke /*******************************************************************************
* 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/ 0000755 0001750 0001750 00000000000 13275316671 026211 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/axis/AxisTickLabels.java 0000644 0001750 0001750 00000101273 12657165716 031727 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000014733 12657165716 030610 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000017030 12657165716 030442 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000004703 12657165716 030773 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000024150 12657165716 031600 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000060114 12657165716 027767 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000001713 12657165716 030162 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000005026 12657165716 027035 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000011516 12657165716 027630 0 ustar jspricke jspricke /*******************************************************************************
* 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/ 0000755 0001750 0001750 00000000000 13275316671 027100 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/compress/CompressConfig.java 0000644 0001750 0001750 00000015473 12657165716 032703 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000012414 12657165716 033530 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000020475 12657165716 031553 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000003130 12657165716 031651 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000004504 12657165716 033346 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000007551 12657165716 034254 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000011405 12657165716 027003 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000001627 12657165716 031154 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000025034 12657165716 027202 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000057724 12657165716 030373 0 ustar jspricke jspricke /*******************************************************************************
* 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/ 0000755 0001750 0001750 00000000000 13275316671 026537 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart/src/org/swtchart/internal/series/ErrorBar.java 0000644 0001750 0001750 00000022052 12657165716 031126 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000064174 12657165716 031465 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000040252 12657165716 031271 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000033712 12657165716 031323 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000014546 12657165716 031613 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000044370 12657165716 030651 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000013330 12657165716 026454 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000001264 12657165716 027531 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000001733 12657165716 026215 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000025106 12657165716 025346 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000002045 12657165716 025300 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000005611 12657165716 026274 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000004115 12657165716 026321 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000001543 12657165716 026124 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000002643 12657165716 026262 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000012720 12657165716 025646 0 ustar jspricke jspricke /*******************************************************************************
* 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.java 0000644 0001750 0001750 00000002527 12657165716 025343 0 ustar jspricke jspricke /*******************************************************************************
* 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/ 0000755 0001750 0001750 00000000000 13275316670 021353 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart/META-INF/MANIFEST.MF 0000644 0001750 0001750 00000000414 12657165716 023012 0 ustar jspricke jspricke Manifest-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/ 0000755 0001750 0001750 00000000000 13275316674 022633 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples.ext/build.properties 0000644 0001750 0001750 00000000206 11032257046 026030 0 ustar jspricke jspricke source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml,\
icons/
swt-chart-code-312-trunk/org.swtchart.examples.ext/plugin.xml 0000644 0001750 0001750 00000001061 11032525344 024632 0 ustar jspricke jspricke
swt-chart-code-312-trunk/org.swtchart.examples.ext/.project 0000644 0001750 0001750 00000001256 11032257046 024270 0 ustar jspricke jspricke
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/ 0000755 0001750 0001750 00000000000 13275316674 023746 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples.ext/icons/swtchart.gif 0000644 0001750 0001750 00000000346 11032262531 026254 0 ustar jspricke jspricke GIF89a LASIdg #!
, c&d)]ԉ4 ˰%KUAQ`=G2(VDr7E(Ǫ2|hlaށۇP7tv:xz~: &$! ; swt-chart-code-312-trunk/org.swtchart.examples.ext/.classpath 0000644 0001750 0001750 00000000566 11234141567 024613 0 ustar jspricke jspricke
swt-chart-code-312-trunk/org.swtchart.examples.ext/src/ 0000755 0001750 0001750 00000000000 13275316672 023420 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/ 0000755 0001750 0001750 00000000000 13275316672 024207 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/swtchart/ 0000755 0001750 0001750 00000000000 13275316672 026046 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/swtchart/examples/ 0000755 0001750 0001750 00000000000 13275316674 027666 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/swtchart/examples/Activator.java 0000644 0001750 0001750 00000002163 11152601570 032447 0 ustar jspricke jspricke package 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/ 0000755 0001750 0001750 00000000000 13275316674 030466 5 ustar jspricke jspricke ././@LongLink 0000644 0000000 0000000 00000000156 00000000000 011605 L ustar root root swt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/swtchart/examples/ext/InteractiveChartExample.java swt-chart-code-312-trunk/org.swtchart.examples.ext/src/org/swtchart/examples/ext/InteractiveChartExa0000644 0001750 0001750 00000005637 11171376110 034301 0 ustar jspricke jspricke package 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/ 0000755 0001750 0001750 00000000000 13275316672 023771 5 ustar jspricke jspricke swt-chart-code-312-trunk/org.swtchart.examples.ext/META-INF/MANIFEST.MF 0000644 0001750 0001750 00000000635 12657165716 025433 0 ustar jspricke jspricke Manifest-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