/*
* Copyright (c) 2002-2006 Samit Basu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "HandleLineSeries.hpp"
#include "HandleList.hpp"
#include "HandleObject.hpp"
#include "HandleAxis.hpp"
#include "IEEEFP.hpp"
HandleLineSeries::HandleLineSeries() {
ConstructProperties();
SetupDefaults();
}
HandleLineSeries::~HandleLineSeries() {
}
// Calculate the limits - should return a vector of the
// form...
// [xmin, xmax, ymin, ymax, zmin, zmax, cmin, cmax, amin, amax]
std::vector<double> HandleLineSeries::GetLimits() {
std::vector<double> xs(VectorPropertyLookup("xdata"));
std::vector<double> ys(VectorPropertyLookup("ydata"));
std::vector<double> zs(VectorPropertyLookup("zdata"));
std::vector<double> limits;
limits.push_back(VecMin(xs));
limits.push_back(VecMax(xs));
limits.push_back(VecMin(ys));
limits.push_back(VecMax(ys));
limits.push_back(VecMin(zs));
limits.push_back(VecMax(zs));
limits.push_back(0);
limits.push_back(0);
limits.push_back(0);
limits.push_back(0);
return limits;
}
void HandleLineSeries::UpdateState() {
// Check that x, y and z data are the same size
// Generate the x coordinates if necessary
std::vector<double> xs(VectorPropertyLookup("xdata"));
std::vector<double> ys(VectorPropertyLookup("ydata"));
std::vector<double> zs(VectorPropertyLookup("zdata"));
if (IsAuto("xdatamode")) {
xs.clear();
for (int i=0;i<ys.size();i++)
xs.push_back(i+1.0);
}
if (zs.size() == 0)
for (int i=0;i<ys.size();i++)
zs.push_back(0.0);
HPVector *sp;
sp = (HPVector*) LookupProperty("xdata");
sp->Data(xs);
sp = (HPVector*) LookupProperty("zdata");
sp->Data(zs);
}
void HandleLineSeries::PaintMe(RenderEngine& gc) {
if (StringCheck("visible","off"))
return;
// Draw the line...
double width(ScalarPropertyLookup("linewidth"));
gc.lineWidth(width);
HPColor *lc = (HPColor*) LookupProperty("color");
// remap...
std::vector<double> xs(VectorPropertyLookup("xdata"));
std::vector<double> ys(VectorPropertyLookup("ydata"));
std::vector<double> zs(VectorPropertyLookup("zdata"));
if (!((xs.size() == ys.size()) && (ys.size() == zs.size())))
return;
std::vector<double> mxs, mys, mzs;
HandleAxis *parent = (HandleAxis*) GetParentAxis();
parent->ReMap(xs,ys,zs,mxs,mys,mzs);
if (!lc->IsNone()) {
gc.color(lc->Data());
gc.setLineStyle(StringPropertyLookup("linestyle"));
// Partition it into segments of finite entries..
int n = 0;
while (n < mxs.size()) {
std::vector<double> local_mxs, local_mys, local_mzs;
while ((n < mxs.size()) && IsFinite(mxs[n]) && IsFinite(mys[n]) && (IsFinite(mzs[n]))) {
local_mxs.push_back(mxs[n]);
local_mys.push_back(mys[n]);
local_mzs.push_back(mzs[n]);
n++;
}
gc.lineSeries(local_mxs,local_mys,local_mzs);
while ((n < mxs.size()) && !(IsFinite(mxs[n]) && IsFinite(mys[n]) && (IsFinite(mzs[n])))) n++;
}
}
// Draw the symbols
HPColor *ec = (HPColor*) LookupProperty("markeredgecolor");
HPColor *fc = (HPColor*) LookupProperty("markerfacecolor");
RenderEngine::SymbolType typ = StringToSymbol(StringPropertyLookup("marker"));
double sze = ScalarPropertyLookup("markersize")/2.0;
// Make sure there's something to draw...
if ((typ != RenderEngine::None) || ec->IsNone() || fc->IsNone()) {
// Calculate the u/v coordinates (pixels)
std::vector<double> uc;
std::vector<double> vc;
for (int i=0;i<mxs.size();i++) {
double u, v;
bool clipped;
gc.toPixels(mxs[i],mys[i],mzs[i],u,v,clipped);
if (!clipped) {
uc.push_back(u); vc.push_back(v);
}
}
gc.setupDirectDraw();
for (int i=0;i<uc.size();i++)
DrawSymbol(gc,typ,uc[i],vc[i],0,sze,ec->Data(),fc->Data(),width);
gc.releaseDirectDraw();
}
}
void HandleLineSeries::SetupDefaults() {
SetThreeVectorDefault("color",0,0,0);
SetConstrainedStringDefault("linestyle","-");
SetScalarDefault("linewidth",1.0);
SetConstrainedStringDefault("marker","none");
SetThreeVectorDefault("markeredgecolor",0,0,0);
SetThreeVectorDefault("markerfacecolor",0,0,0);
SetScalarDefault("markersize",6);
SetStringDefault("type","line");
SetConstrainedStringDefault("visible","on");
SetConstrainedStringDefault("xdatamode","manual");
}
void HandleLineSeries::ConstructProperties() {
//!
//@Module LINEPROPERTIES Line Series Object Properties
//@@Section HANDLE
//@@Usage
//Below is a summary of the properties for a line series.
//\begin{itemize}
// \item @|color| - @|colorspec| - The color that is used to
// draw the line.
// \item @|children| - Not used.
// \item @|displayname| - The name of this line series as it
// appears in a legend.
// \item @|linestyle| - @|{'-','--',':','-.','none'}| - The style of the line.
// \item @|linewidth| - @|scalar| - The width of the line.
// \item @|marker| - @|{'+','o','*','.','x','square','s','diamond','d','^','v','>','<'}| -
// The marker for data points on the line. Some of these are redundant, as @|'square'|
// @|'s'| are synonyms, and @|'diamond'| and @|'d'| are also synonyms.
// \item @|markeredgecolor| - @|colorspec| - The color used to draw the marker. For some
// of the markers (circle, square, etc.) there are two colors used to draw the marker.
// This property controls the edge color (which for unfilled markers) is the primary
// color of the marker.
// \item @|markerfacecolor| - @|colorspec| - The color used to fill the marker. For some
// of the markers (circle, square, etc.) there are two colors used to fill the marker.
// \item @|markersize| - @|scalar| - Control the size of the marker. Defaults to 6, which
// is effectively the radius (in pixels) of the markers.
// \item @|parent| - @|handle| - The axis that contains this object.
// \item @|tag| - @|string| - A string that can be used to tag the object.
// \item @|type| - @|string| - Returns the string @|'line'|.
// \item @|visible| - @|{'on','off'}| - Controls visibility of the the line.
// \item @|xdata| - @|vector| - Vector of x coordinates of points on the line. Must be
// the same size as the @|ydata| and @|zdata| vectors.
// \item @|ydata| - @|vector| - Vector of y coordinates of points on the line. Must be
// the same size as the @|xdata| and @|zdata| vectors.
// \item @|zdata| - @|vector| - Vector of z coordinates of points on the line. Must be
// the same size as the @|xdata| and @|ydata| vectors.
// \item @|xdatamode| - @|{'auto','manual'}| - When set to @|'auto'| FreeMat will autogenerate
// the x coordinates for the points on the line. These values will be @|1,..,N| where
// @|N| is the number of points in the line.
// \item @|userdata| - @|array| - Available to store any variable you
// want in the handle object.
//\end{itemize}
//!
AddProperty(new HPColor,"color");
AddProperty(new HPHandles,"children");
AddProperty(new HPString,"displayname");
AddProperty(new HPLineStyle,"linestyle");
AddProperty(new HPScalar,"linewidth");
AddProperty(new HPSymbol,"marker");
AddProperty(new HPColor,"markeredgecolor");
AddProperty(new HPColor,"markerfacecolor");
AddProperty(new HPScalar,"markersize");
AddProperty(new HPHandles,"parent");
AddProperty(new HPString,"tag");
AddProperty(new HPString,"type");
AddProperty(new HPOnOff,"visible");
AddProperty(new HPVector,"xdata");
AddProperty(new HPAutoManual,"xdatamode");
AddProperty(new HPArray,"userdata");
AddProperty(new HPVector,"ydata");
AddProperty(new HPVector,"zdata");
}
syntax highlighted by Code2HTML, v. 0.9.1