/*
* This code is part of Project Waterloo from King's College London
*
*
* Copyright King's College London 2011-
*
* @author Malcolm Lidierth, King's College London [Contact]
*
* Project Waterloo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Project Waterloo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
*/
package kcl.waterloo.graphics.plots2D;
import java.awt.*;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import kcl.waterloo.effects.GJEffectorInterface;
import kcl.waterloo.graphics.GJGraphInterface;
import kcl.waterloo.graphics.data.GJDataVectorInterface;
import kcl.waterloo.graphics.transforms.GJDataTransformInterface;
import kcl.waterloo.graphics.transforms.NOPTransform;
import kcl.waterloo.marker.GJMarker;
import kcl.waterloo.math.ArrayMath;
import kcl.waterloo.observable.GJAbstractObservable;
import kcl.waterloo.plotmodel2D.GJCyclicArrayList;
import kcl.waterloo.plotmodel2D.GJDataModel;
import kcl.waterloo.plotmodel2D.GJScreenDataInterface;
import kcl.waterloo.plotmodel2D.GJVisualModel;
/**
* Abstract class providing support for both the data model and visual model.
* Subclassed in the {@code GJAbstractPlot} class
*
* @author Malcolm Lidierth, King's College London [Contact]
*/
public abstract class GJAbstractPlotModelImpl extends GJAbstractObservable
implements GJPlotInterface, GJEffectorInterface, GJScreenDataInterface {
/**
* Visual model see {@code GJVisualModel}.
*/
private GJVisualModel visualModel = new GJVisualModel();
/**
* Data model see {@code GJDataModel}.
*/
private GJDataModel dataModel = new GJDataModel();
/**
* Reference to the graph that this plot is in. This is set when isTopPlot()
* returns true.
*
* The {@code getParentGraph} method for other plots search up the plot
* hierarchy and return the parentGraph value from the top plot.
*
* If a new value is set via {@code setParentGraph}, the plot will be copied
* to the specified graph.
*
* This value should not normally be set to {@code null} after a
* plot is added to graph although {@code setParentGraph} supports this for
* use in serialization.
*/
private GJGraphInterface parentGraph = null;
private ArrayList name = new ArrayList();
/**
* A list of plots that are direct descendants of this plot i.e. those for
* which getAncestorPlot returns this instance.
*/
private final ArrayList plotList = new ArrayList();
/**
* Screen buffer used to select plots with mouse
*/
public ArrayList screenDataArray = new ArrayList(20);
/**
* Package-private constructor. This will be invoked implicitly when
* constructing of any concrete class instance extending
* {@code GJAbstractPlot}.
*
*/
GJAbstractPlotModelImpl() {
}
@Override
public final GJGraphInterface getParentGraph() {
GJAbstractPlotModelImpl topPlot = (GJAbstractPlotModelImpl) getTopPlot();
return topPlot.parentGraph;
}
protected void initNewInstance() {
if (parentGraph != null) {
parentGraph.remove(this);
parentGraph = null;
}
}
@Override
public final void setParentGraph(GJGraphInterface gr) {
GJGraphInterface old = getParentGraph();
if (getParentGraph() == null || getParentGraph() == gr) {
if (isTopPlot()) {
// Already a top plot. Just check it is added to the parentGraph -
// this will call add during serialization/de-serialization of
// XML (remember plots are not Components).
parentGraph = gr;
if (!parentGraph.getPlots().contains(this)) {
parentGraph.add(this, false);
}
} else {
// Promoting a plot to become a top plot in the same graph
copyToOtherGraph(gr);
}
} else {
if (isTopPlot()) {
// Moving a top plot between graphs
parentGraph.remove(this);
parentGraph = gr;
if (gr != null) {
gr.add(this);
}
} else {
// Moving a child plot between graphs
copyToOtherGraph(gr);
}
}
getPCS().firePropertyChange("parent", old, parentGraph);
}
private void copyToOtherGraph(GJGraphInterface gr) {
if (getDataModel().getXData() == null) {
setXData(getXData());
}
if (getDataModel().getYData() == null) {
setYData(getYData());
}
getParentPlot().getPlotList().remove(this);
setParentPlot(null);
parentGraph = gr;
gr.add(this);
}
@Override
public final void setData(GJDataVectorInterface o1, GJDataVectorInterface o2) {
setXData(o1);
setYData(o2);
}
@Override
public final void setXData(GJDataVectorInterface> o) {
GJDataVectorInterface> old = getDataModel().getXData();
getDataModel().setXData(o);
getPCS().firePropertyChange("XData", old, getDataModel().getXData());
}
@Override
public final void setYData(GJDataVectorInterface> o) {
GJDataVectorInterface old = getDataModel().getYData();
getDataModel().setYData(o);
getPCS().firePropertyChange("YData", old, getDataModel().getYData());
}
@Override
public final void setXData(double[] x) {
getDataModel().getXData().setDataBufferData(x);
}
@Override
public final void setYData(double[] y) {
getDataModel().getYData().setDataBufferData(y);
}
@Override
public final void setXData(AbstractList extends Number> x) {
getDataModel().getXData().setDataBufferData(x);
}
@Override
public final void setXData(Object mx) {
if (mx == null) {
getDataModel().setXData(null);
} else {
if (mx instanceof Map) {
getDataModel().getXData().setDataBufferData((Map) mx);
}
}
}
@Override
public final void setXData(int[] x) {
getDataModel().getXData().setDataBufferData(x);
}
@Override
public final void setYData(int[] y) {
getDataModel().getYData().setDataBufferData(y);
}
@Override
public final void setYData(AbstractList extends Number> y) {
getDataModel().getYData().setDataBufferData(y);
}
@Override
public final void setYData(Object my) {
if (my == null) {
getDataModel().setXData(null);
} else {
if (my instanceof Map) {
getDataModel().getYData().setDataBufferData((Map) my);
}
}
}
/**
* Returns the tranformed x-values as a double[].
*
* If the data model XData==null, or the underlying data vector has a length
* of zero, data will be retrieved form the parent plot.
*
* @return the x-axis data
*/
@Override
public final double[] getXDataValues() {
if (getDataModel().getXData() == null || getDataModel().getXData().getDimension() == 0) {
if (!isTopPlot()) {
return getTopPlot().getXDataValues();
} else {
return null;
}
} else {
return getDataModel().getXData().getDataValues(getParentGraph().getXTransform());
}
//return getXData().getDataValues();
}
/**
* Returns the x data as a GJDataVectorInterface
*
* @return the x-axis data
*/
@Override
public final GJDataVectorInterface> getXData() {
if (getDataModel().getXData() == null) {
if (!isTopPlot()) {
return getParentPlot().getXData();
} else {
return null;
}
} else {
return getDataModel().getXData();
}
}
/**
* Get method for the y-axis data.
*
* If the data model XData==null, or the underlying data vector has a length
* of zero, data will be retrieved form the parent plot.
*
* @return the y-axis data
*/
@Override
public final double[] getYDataValues() {
if (getDataModel().getYData() == null || getDataModel().getYData().getDimension() == 0) {
if (!isTopPlot()) {
return getParentPlot().getYDataValues();
} else {
return null;
}
} else {
return getDataModel().getYData().getDataValues(getParentGraph().getYTransform());
}
//return getYData().getDataValues();
}
@Override
public final GJDataVectorInterface> getYData() {
if (getDataModel().getYData() == null) {
if (!isTopPlot()) {
return getParentPlot().getYData();
} else {
return null;
}
} else {
return getDataModel().getYData();
}
}
@Override
public final void setExtraData0(double[] val) {
double[] old = getDataModel().getExtraData0();
getDataModel().setExtraData0(val);
getPCS().firePropertyChange("extraData0", old, getDataModel().getExtraData0());
}
@Override
public final void setExtraData1(double[] val) {
double[] old = getDataModel().getExtraData1();
getDataModel().setExtraData1(val);
getPCS().firePropertyChange("extraData1", old, getDataModel().getExtraData1());
}
@Override
public final void setExtraData2(double[] val) {
double[] old = getDataModel().getExtraData2();
getDataModel().setExtraData2(val);
getPCS().firePropertyChange("extraData2", old, getDataModel().getExtraData2());
}
@Override
public final void setExtraData3(double[] val) {
double[] old = getDataModel().getExtraData3();
getDataModel().setExtraData3(val);
getPCS().firePropertyChange("extraData3", old, getDataModel().getExtraData3());
}
/**
* Returns true if this plot is Multiplexed. Refer to the overview above for
* details of how multiplexing is implemented
*
* @return true if multiplexed
*/
@Override
public final boolean isMultiplexed() {
return isMultiplexible() && this.getMultiplexLength() > 1;
}
/**
* Returns the number of series for this plot This is the maximum of the
* lengths of the MarkerArray, EdgeStroke, EdgeColor, LineStroke and
* LineColor arrays. Refer to the overview above for details of how
* multiplexing is implemented
*
* @return true if multiplexed
*/
@Override
public final int getMultiplexLength() {
int[] N = {1, 1, 1, 1, 1, 1};
if (getVisualModel().getMarkerArray() != null) {
N[0] = getVisualModel().getMarkerArray().size();
}
if (getVisualModel().getEdgeStroke() != null) {
N[1] = getVisualModel().getEdgeStroke().size();
}
if (getVisualModel().getEdgeColor() != null) {
N[2] = getVisualModel().getEdgeColor().size();
}
if (getVisualModel().getLineColor() != null) {
N[3] = getVisualModel().getLineColor().size();
}
if (getVisualModel().getLineStroke() != null) {
N[4] = getVisualModel().getLineStroke().size();
}
if (getVisualModel().getFill() != null) {
N[5] = getVisualModel().getFill().size();
}
int n[] = ArrayMath.minmax(N);
return n[1];
}
@Override
public final GJDataTransformInterface getXTransform() {
if (getParentGraph() == null) {
return NOPTransform.getInstance();
} else {
return getParentGraph().getXTransform();
}
}
@Override
public final GJDataTransformInterface getYTransform() {
if (getParentGraph() == null) {
return NOPTransform.getInstance();
} else {
return getParentGraph().getYTransform();
}
}
/**
* Sets the alpha level on the composite used to render this plot. All
* rendering for this plot will be affected. To affect specific features
* only, e.g. a line, set the alpha of the Paint object used for that
* feature instead.
*
* @param val the alpha level 0=transparent 1=opaque (default)
*/
@Override
public final void setAlpha(float val) {
getVisualModel().setAlpha(val);
if (getPlotList() != null) {
for (Iterator it = getPlotList().iterator(); it.hasNext();) {
GJPlotInterface p = it.next();
p.setAlpha(val);
}
}
}
@Override
public final synchronized ArrayList getScreenDataArray() {
return screenDataArray;
}
@Override
public final ArrayList getScreenDataArrayAsCopy() {
return new ArrayList(getScreenDataArray());
}
@Override
public final synchronized void setScreenDataArray(ArrayList ScreenDataArray) {
this.screenDataArray = ScreenDataArray;
}
// @Override
// public final ArrayList getScreenDataArray() {
// return getScreenDataArray();
// }
//
// @Override
// public final ArrayList getScreenDataArrayAsCopy() {
// return getVisualModel().getScreenDataArrayAsCopy();
// }
@Override
public final float getAlpha() {
return getVisualModel().getAlpha();
}
@Override
public final void setCompositeMode(int val) {
getVisualModel().setCompositeMode(val);
}
@Override
public final int getCompositeMode() {
return getVisualModel().getCompositeMode();
}
@Override
public final void setLineColor(GJCyclicArrayList p) {
getVisualModel().setLineColor(new GJCyclicArrayList(p));
}
@Override
public final void setLineStroke(BasicStroke s) {
getVisualModel().setLineStroke(new GJCyclicArrayList(s));
}
@Override
public final void setLineStroke(int i, BasicStroke s) {
getVisualModel().setLineStroke(i, s);
}
@Override
public final void setLineStroke(BasicStroke[] s) {
getVisualModel().setLineStroke(new GJCyclicArrayList(s));
}
@Override
public final void setLineStroke(GJCyclicArrayList s) {
getVisualModel().setLineStroke(new GJCyclicArrayList(s));
}
@Override
public final void setLineStroke(ArrayList s) {
getVisualModel().setLineStroke(new GJCyclicArrayList(s));
}
@Override
public final GJCyclicArrayList getLineStroke() {
return getVisualModel().getLineStroke();
}
@Override
public final GJCyclicArrayList getLineColor() {
return getVisualModel().getLineColor();
}
@Override
public final void setEdgeStroke(BasicStroke[] s) {
getVisualModel().setEdgeStroke(new GJCyclicArrayList(s));
}
@Override
public final void setEdgeStroke(BasicStroke s) {
getVisualModel().setEdgeStroke(new GJCyclicArrayList(s));
}
@Override
public final void setEdgeStroke(int index, BasicStroke s) {
getVisualModel().getEdgeStroke().set(index, s);
}
@Override
public final GJCyclicArrayList getEdgeStroke() {
return getVisualModel().getEdgeStroke();
}
@Override
public final void setEdgeColor(ArrayList p) {
getVisualModel().setEdgeColor(new GJCyclicArrayList(p));
}
@Override
public final void setEdgeColor(Paint[] p) {
getVisualModel().setEdgeColor(new GJCyclicArrayList(p));
}
@Override
public final void setEdgeColor(Paint p) {
getVisualModel().setEdgeColor(new GJCyclicArrayList(p));
}
@Override
public final void setEdgeColor(int i, Paint p) {
getVisualModel().setEdgeColor(i, p);
}
@Override
public final GJCyclicArrayList getEdgeColor() {
return getVisualModel().getEdgeColor();
}
@Override
public final void setFill(ArrayList p) {
getVisualModel().setFill(new GJCyclicArrayList(p));
}
@Override
public final void setFill(Paint[] f) {
getVisualModel().setFill(new GJCyclicArrayList(f));
}
@Override
public final void setFill(Paint f) {
getVisualModel().setFill(new GJCyclicArrayList(f));
}
@Override
public final void setFill(int i, Paint f) {
getVisualModel().setFill(i, f);
}
@Override
public final GJCyclicArrayList getFill() {
return getVisualModel().getFill();
}
@Override
public final GJMarker getMarker(int i) {
return getVisualModel().getMarkerArray().get(i);
}
@Override
public final GJCyclicArrayList getMarkerArray() {
return getVisualModel().getMarkerArray();
}
@Override
public final void setMarkerArray(GJCyclicArrayList arr) {
getVisualModel().setMarkerArray(arr);
}
@Override
public final void setMarkerArray(GJMarker m) {
getVisualModel().setMarkerArray(new GJCyclicArrayList(m));
}
@Override
public final void setMarker(int i, GJMarker s) {
getVisualModel().getMarkerArray().set(i, s);
}
@Override
public final void setMarker(GJMarker s) {
getVisualModel().setMarker(s);
}
@Override
public final void setLineColor(int i, Paint p) {
getVisualModel().getLineColor().set(i, p);
}
@Override
public final void setLineColor(Paint p) {
getVisualModel().setLineColor(new GJCyclicArrayList(p));
}
@Override
public final void setLineColor(Paint[] p) {
getVisualModel().setLineColor(new GJCyclicArrayList(p));
}
@Override
public final synchronized GJVisualModel getVisualModel() {
return visualModel;
}
/**
* @param visualModel the visualModel to set
*/
@Override
public final synchronized void setVisualModel(GJVisualModel visualModel) {
this.visualModel = visualModel;
}
@Override
public final void setMarkerArray(GJMarker[] m) {
getVisualModel().setMarkerArray(m);
}
@Override
public final GJCyclicArrayList getDynamicMarkerSize() {
return getVisualModel().getDynamicMarkerSize();
}
@Override
public final void setDynamicMarkerSize(GJCyclicArrayList DynamicMarkerSize) {
getVisualModel().setDynamicMarkerSize(DynamicMarkerSize);
}
@Override
public final void setEdgeColor(GJCyclicArrayList EdgeColor) {
getVisualModel().setEdgeColor(EdgeColor);
}
@Override
public final void setEdgeStroke(GJCyclicArrayList EdgeStroke) {
getVisualModel().setEdgeStroke(EdgeStroke);
}
@Override
public final void setEdgeStroke(ArrayList EdgeStroke) {
getVisualModel().setEdgeStroke(EdgeStroke);
}
@Override
public final void setFill(GJCyclicArrayList Fill) {
getVisualModel().setFill(Fill);
}
@Override
public final Object getRenderHintState() {
return getVisualModel().getRenderHintState();
}
@Override
public final void setRenderHintState(Object renderHintState) {
getVisualModel().setRenderHintState(renderHintState);
}
@Override
public final Object getTextHintState() {
return getVisualModel().getTextHintState();
}
//
@Override
public final void setTextHintState(Object setTextHintState) {
getVisualModel().setTextHintState(setTextHintState);
}
/**
* @return the dataModel
*/
@Override
public final GJDataModel getDataModel() {
return dataModel;
}
/**
* @param dataModel the dataModel to set
*/
@Override
public final void setDataModel(GJDataModel dataModel) {
this.dataModel = dataModel;
}
/**
* @return the name
*/
@Override
public ArrayList getName() {
return name;
}
/**
* @param name the name to set
*/
@Override
public void setName(ArrayList name) {
this.name = name;
}
public void setName(String name) {
this.name.clear();
this.name.add(name);
}
/**
* @param plotList
*/
@Override
public final void setPlotList(ArrayList plotList) {
ArrayList old = new ArrayList(this.plotList);
this.plotList.clear();
this.plotList.addAll(plotList);
getPCS().firePropertyChange("plotList", old, plotList);
}
/**
* @return the plotList
*/
@Override
public final ArrayList getPlotList() {
return plotList;
}
}
Ads help maintain this website.