/*******************************************************************************
* Copyright (c) 2013 Luigi Sgro. All rights reserved. This
* program and the accompanying materials are made available under the terms of
* the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Luigi Sgro - initial API and implementation
******************************************************************************/
package com.quantcomponents.chart.series;
import java.util.Date;
import org.eclipse.swt.graphics.Rectangle;
import com.quantcomponents.chart.IAxis;
import com.quantcomponents.chart.IChartMetrics;
import com.quantcomponents.chart.IDataRange;
import com.quantcomponents.chart.IMarkScaleSelector;
import com.quantcomponents.core.calendar.ITradingCalendar;
/**
* Implementation of {@link com.quantcomponents.chart.IChartMetrics} for double series indexed by {@link java.util.Date}
*
*/
public class TimeChartMetrics implements IChartMetrics<Date, Double> {
private static final int AVG_PIXEL_PER_LABEL_X = 50;
private static final int AVG_PIXEL_PER_LABEL_Y = 40;
private static final int DEFAULT_MAX_MARK_NUM_X = 10;
private static final int DEFAULT_MAX_MARK_NUM_Y = 20;
private static final long DEFAULT_POINT_INTERVAL = 5L * 60 * 1000;
private final ITradingCalendar tradingCalendar;
private final IMarkScaleSelector<Date> scaleSelectorX;
private final IMarkScaleSelector<Double> scaleSelectorY;
private TimeAxis xAxis;
private DoubleAxis yAxis;
private Rectangle drawingArea;
private IDataRange<Date, Double> dataRange;
private long pointInterval = DEFAULT_POINT_INTERVAL;
private int maxMarkNumberX = DEFAULT_MAX_MARK_NUM_X;
private int maxMarkNumberY = DEFAULT_MAX_MARK_NUM_Y;
private int marginLeft;
private int marginTop;
private int marginRight;
private int marginBottom;
private boolean recalcNeeded;
public TimeChartMetrics(ITradingCalendar tradingCalendar, IMarkScaleSelector<Date> scaleSelectorX, IMarkScaleSelector<Double> scaleSelectorY) {
this.tradingCalendar = tradingCalendar;
this.scaleSelectorX = scaleSelectorX;
this.scaleSelectorY = scaleSelectorY;
}
public synchronized void setMargins(int marginLeft, int marginTop, int marginRight, int marginBottom) {
this.marginLeft = marginLeft;
this.marginTop = marginTop;
this.marginRight = marginRight;
this.marginBottom = marginBottom;
recalcNeeded = true;
}
@Override
public synchronized void setDataRange(IDataRange<Date, Double> dataRange) {
this.dataRange = dataRange;
recalcNeeded = true;
}
@Override
public synchronized void setDrawingArea(Rectangle drawingArea) {
this.drawingArea = drawingArea;
recalcNeeded = true;
}
public synchronized void setPointInterval(long pointInterval) {
this.pointInterval = pointInterval;
recalcNeeded = true;
}
public synchronized void setMaxMarkNumberX(int maxMarkNumberX) {
this.maxMarkNumberX = maxMarkNumberX;
recalcNeeded = true;
}
public synchronized void setMaxMarkNumberY(int maxMarkNumberY) {
this.maxMarkNumberY = maxMarkNumberY;
recalcNeeded = true;
}
@Override
public synchronized IAxis<Date> xAxis() {
recalculateIfNeeded();
return xAxis;
}
@Override
public synchronized IAxis<Double> yAxis() {
recalculateIfNeeded();
return yAxis;
}
private void recalculateIfNeeded() {
if (recalcNeeded) {
if (dataRange != null && drawingArea != null) {
maxMarkNumberX = (int) (drawingArea.width / AVG_PIXEL_PER_LABEL_X);
xAxis = new TimeAxis(tradingCalendar, scaleSelectorX, dataRange.getLowX(),
dataRange.getHighX(), drawingArea.x + marginLeft, drawingArea.x + drawingArea.width - marginRight,
pointInterval, maxMarkNumberX);
maxMarkNumberY = (int) (drawingArea.height / AVG_PIXEL_PER_LABEL_Y);
yAxis = new DoubleAxis(true, scaleSelectorY, dataRange.getLowY(), dataRange.getHighY(), drawingArea.y + marginTop,
drawingArea.y + drawingArea.height - marginBottom, maxMarkNumberY);
}
recalcNeeded = false;
}
}
}