/*******************************************************************************
* Copyright (c) 2008-2011 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;
}
/*
* @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() {
if (plusErrors == null) {
return null;
}
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() {
if (minusErrors == null) {
return null;
}
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);
gc.setForeground(getColor());
// get plus/minus error
double plusError = error;
double minusError = error;
if (plusErrors != null && plusErrors.length > seriesIndex) {
plusError = plusErrors[seriesIndex];
}
if (minusErrors != null && minusErrors.length > seriesIndex) {
minusError = minusErrors[seriesIndex];
}
// draw error bar
draw(gc, h, v, axis, plusError, minusError);
gc.setLineWidth(oldLineWidth);
}
/**
* 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);
}
}
}
}