summaryrefslogtreecommitdiffstats
path: root/applications/rview/rviewChart.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'applications/rview/rviewChart.cpp')
-rw-r--r--applications/rview/rviewChart.cpp1024
1 files changed, 1024 insertions, 0 deletions
diff --git a/applications/rview/rviewChart.cpp b/applications/rview/rviewChart.cpp
new file mode 100644
index 0000000..3fddcef
--- /dev/null
+++ b/applications/rview/rviewChart.cpp
@@ -0,0 +1,1024 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community 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 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community 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 rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+
+/**
+ * SOURCE: rviewChart.cpp
+ *
+ * MODULE: applications/rview
+ *
+ * PURPOSE:
+ * rView chart viewer. Can display MDD objects of any dimension in a time
+ * series fashion. Possible modes are bar charts, line and spline function
+ * plots.
+ *
+ * COMMENTS:
+ * No comments
+ */
+
+
+// Standard wxWindows preamble.
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+
+// changed in wxWindows 2.4.2:
+//#include "wx_prec.h"
+#include <wx/wxprec.h>
+
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+
+
+#include <string.h>
+#include <iostream.h>
+#include <math.h>
+#include <limits.h>
+
+
+#ifdef EARLY_TEMPLATE
+#define __EXECUTABLE__
+#endif
+
+#include "raslib/rmdebug.hh"
+
+#include "rviewTypes.hh"
+
+#include "labelManager.hh"
+
+#include "rviewUtils.hh"
+#include "rviewDModes.hh"
+#include "rviewPrefs.hh"
+#include "rviewMDD.hh"
+
+
+
+const int chartCanvas::chcanv_cospace = 16;
+const int chartCanvas::chcanv_colength = 6;
+const int chartCanvas::chcanv_exponents = 4;
+
+const int rviewChart::chart_twidth = 64;
+const int rviewChart::chart_theight = 50;
+const int rviewChart::chart_cwidth = 100;
+const int rviewChart::chart_cheight = 50;
+const int rviewChart::chart_minwidth = 100;
+const int rviewChart::chart_minheight = 100;
+const int rviewChart::chart_ctrly = 64;
+const int rviewChart::chart_totaly = rviewDisplay::display_cheight + rviewChart::chart_ctrly;
+
+
+
+chartCanvas::chartCanvas(wxWindow *parent, int x, int y, int w, int h, long style) : wxCanvas(parent, x, y, w, h, style)
+{
+ brush.SetStyle(wxSOLID);
+ brush.SetColour((char)0x80, (char)0x80, (char)0x80);
+ back.SetStyle(wxSOLID);
+ back.SetColour((char)0xe0, (char)0xe0, (char)0xe0);
+ pen.SetStyle(wxSOLID);
+ pen.SetColour(0,0,0);
+ SetBackground(&back);
+ font = new wxFont(12, wxROMAN, wxNORMAL, wxNORMAL);
+ scroll = 0;
+}
+
+
+chartCanvas::~chartCanvas(void)
+{
+ SetBackground(NULL);
+ delete font;
+}
+
+
+
+void chartCanvas::setData(mdd_frame *mf, rviewBaseType bt)
+{
+ mddObj = mf->mdd;
+ dimMDD = (int)(mddObj->spatial_domain().dimension());
+ baseType = bt;
+ if (baseType == rbt_rgb)
+ {
+ brush_r.SetStyle(wxSOLID);
+ brush_r.SetColour((char)0xff, 0, 0);
+ brush_g.SetStyle(wxSOLID);
+ brush_g.SetColour(0, (char)0xff, 0);
+ brush_b.SetStyle(wxSOLID);
+ brush_b.SetColour(0, 0, (char)0xff);
+ pen_r.SetColour((char)0xff, 0, 0);
+ pen_g.SetColour(0, (char)0xff, 0);
+ pen_b.SetColour(0, 0, (char)0xff);
+ }
+}
+
+
+
+int chartCanvas::setProjection(r_Point &p1, r_Point &p2)
+{
+ int i, j;
+ char buffer[STRINGSIZE];
+ float twidth, theight, taux;
+ r_Minterval useInterv;
+
+ pt1 = p1; pt2 = p2; min = 0.0; max = 1.0;
+
+ useInterv= r_Minterval(dimMDD);
+ for (i=0; i<dimMDD; i++)
+ {
+ useInterv << r_Sinterval(pt1[i], pt2[i]);
+ }
+ if (mdd_objectRange(mddObj, useInterv, min, max) == 0)
+ {
+ cerr << lman->lookup("errorBaseType") << endl;
+ return 0;
+ }
+
+ RMDBGONCE(3, RMDebug::module_applications, "chartCanvas", "setProjection(...) min = " << min << ", max = " << max );
+
+ // Determine format to use for numbering the vertical axis
+ taux = fabs(min);
+ if (taux <= pow(10.,(double)-chcanv_exponents)) i = chcanv_exponents;
+ else i = (int)(log(taux)/log(10.));
+ taux = fabs(max);
+ if (taux <= pow(10.,(double)-chcanv_exponents)) j = chcanv_exponents;
+ else j = (int)(log(taux)/log(10.));
+ if (i < j) i = j;
+ if (abs(i) >= chcanv_exponents)
+ {
+ strcpy(format, "%g");
+ }
+ else if (i >= 0)
+ {
+ strcpy(format, "%.0f");
+ }
+ else
+ {
+ sprintf(format, "%%.%df", -i);
+ }
+
+ if (cosys)
+ {
+ SetFont(font);
+ sprintf(buffer, format, min);
+ GetTextExtent(buffer, &twidth, &theight);
+ sprintf(buffer, format, max);
+ GetTextExtent(buffer, &taux, &theight);
+ if (twidth < taux) twidth = taux;
+ coleft = (int)(twidth + chcanv_colength/2);
+ }
+ else
+ coleft = chcanv_cospace;
+
+ return coleft;
+}
+
+
+
+void chartCanvas::setVars(int s, double cs, int ds, bool cy, rviewChartMode cm)
+{
+ step = s;
+ costep = cs;
+ datastep = ds;
+ cosys = cy;
+ cmode = cm;
+}
+
+
+
+// Recurring redraw body
+#define _REDCHARTBAR(wd, pm) \
+ value = (long)(scale * ((*mddPtr)[prun])pm); \
+ if (value < 0) \
+ { \
+ top = orgy; bot = top - (float)value; \
+ } \
+ else \
+ { \
+ top = orgy - (float)value; bot = orgy; \
+ } \
+ if (top < 0) top = 0; if (bot > height) bot = height; \
+ cdc->DrawRect(posx, chcanv_cospace + top, wd, bot - top);
+
+#define _REDCHARTBARLOOP(wd, pm) \
+ for (prun[dim]=pt1[dim]+startOff; prun[dim] <= pt1[dim] + endOff; prun[dim]++, posx+=stepx) \
+ { \
+ _REDCHARTBAR(wd, pm); \
+ }
+
+#define REDCHARTBAR(type) \
+ r_Ref <r_Marray <type> > mddPtr = (r_Ref < r_Marray <type> >)(mddObj); \
+ _REDCHARTBARLOOP(stepx, +0);
+
+void chartCanvas::redrawBar(wxDC *cdc, int height, int dim, int startOff, int endOff, float scale, float posx, float stepx, float orgy)
+{
+ float top, bot;
+ r_Point prun = pt1;
+ long value;
+
+ switch (baseType)
+ {
+ case rbt_bool:
+ {
+ r_Ref <r_Marray <r_Boolean> > mddPtr = (r_Ref < r_Marray <r_Boolean> >)(mddObj);
+ for (prun[dim]=pt1[dim]+startOff; prun[dim] <= pt1[dim]+endOff; prun[dim]++, posx+= stepx)
+ {
+ // This can only be 0 or 1, so don't bother with the sign
+ value = (long)(scale * (*mddPtr)[prun]);
+ cdc->DrawRectangle(posx, chcanv_cospace + orgy - (float)value, stepx, (float)value);
+ }
+ }
+ break;
+ case rbt_char:
+ {
+ REDCHARTBAR(r_Char);
+ }
+ break;
+ case rbt_uchar:
+ {
+ REDCHARTBAR(r_Octet);
+ }
+ break;
+ case rbt_short:
+ {
+ REDCHARTBAR(r_Short);
+ }
+ break;
+ case rbt_ushort:
+ {
+ REDCHARTBAR(r_UShort);
+ }
+ break;
+ case rbt_long:
+ {
+ REDCHARTBAR(r_Long);
+ }
+ break;
+ case rbt_ulong:
+ {
+ REDCHARTBAR(r_ULong);
+ }
+ break;
+ case rbt_rgb:
+ {
+ r_Ref <r_Marray <RGBPixel> > mddPtr = (r_Ref < r_Marray <RGBPixel> >)(mddObj);
+ double oldPosx = posx;
+
+ cdc->SetBrush(&brush_r);
+ _REDCHARTBARLOOP(stepx/3, .red);
+ cdc->SetBrush(&brush_g); posx = oldPosx + stepx/3;
+ _REDCHARTBARLOOP(stepx/3, .green);
+ cdc->SetBrush(&brush_b); posx = oldPosx + 2*stepx/3;
+ _REDCHARTBARLOOP(stepx/3, .blue);
+ cdc->SetBrush(&brush);
+ }
+ break;
+ case rbt_float:
+ {
+ REDCHARTBAR(r_Float);
+ }
+ break;
+ case rbt_double:
+ {
+ REDCHARTBAR(r_Double);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+
+#define _REDCHARTLINELOOP(pm) \
+ prun[dim] = pt1[dim] + startOff; \
+ lastVal = chcanv_cospace + orgy - scale * (((*mddPtr)[prun])pm); \
+ for (prun[dim]++ ; prun[dim]<=pt1[dim]+endOff; prun[dim]++, posx += stepx) \
+ { \
+ newVal = chcanv_cospace + orgy - scale * (((*mddPtr)[prun])pm); \
+ cdc->DrawLine(posx, lastVal, posx+stepx, newVal); \
+ lastVal = newVal; \
+ }
+
+#define REDCHARTLINE(type) \
+ r_Ref<r_Marray<type> > mddPtr = (r_Ref<r_Marray<type> >)(mddObj); \
+ _REDCHARTLINELOOP(+0);
+
+void chartCanvas::redrawLine(wxDC *cdc, int dim, int startOff, int endOff, float scale, float posx, float stepx, float orgy)
+{
+ r_Point prun = pt1;
+ float newVal, lastVal;
+
+ if (pt1[dim] + endOff < pt2[dim]) endOff++;
+
+ switch (baseType)
+ {
+ case rbt_bool:
+ {
+ REDCHARTLINE(r_Boolean);
+ }
+ break;
+ case rbt_char:
+ {
+ REDCHARTLINE(r_Char);
+ }
+ break;
+ case rbt_uchar:
+ {
+ REDCHARTLINE(r_Octet);
+ }
+ break;
+ case rbt_short:
+ {
+ REDCHARTLINE(r_Short);
+ }
+ break;
+ case rbt_ushort:
+ {
+ REDCHARTLINE(r_UShort);
+ }
+ break;
+ case rbt_long:
+ {
+ REDCHARTLINE(r_Long);
+ }
+ break;
+ case rbt_ulong:
+ {
+ REDCHARTLINE(r_ULong);
+ }
+ break;
+ case rbt_rgb:
+ {
+ r_Ref<r_Marray<RGBPixel> > mddPtr = (r_Ref<r_Marray<RGBPixel> >)(mddObj);
+ double oldPosx = posx;
+
+ cdc->SetPen(&pen_r);
+ _REDCHARTLINELOOP(.red);
+ cdc->SetPen(&pen_g); posx = oldPosx + stepx/3;
+ _REDCHARTLINELOOP(.green);
+ cdc->SetPen(&pen_b); posx = oldPosx + 2*stepx/3;
+ _REDCHARTLINELOOP(.blue);
+ cdc->SetPen(&pen);
+ }
+ break;
+ case rbt_float:
+ {
+ REDCHARTLINE(r_Float);
+ }
+ break;
+ case rbt_double:
+ {
+ REDCHARTLINE(r_Double);
+ }
+ break;
+ default: break;
+ }
+}
+
+
+
+#define _REDCHARTSPLINELOOP(pm) \
+ for (prun[dim]=pt1[dim]+startOff; prun[dim]<=pt1[dim]+endOff; prun[dim]++, posx+=stepx, i++) \
+ { \
+ vertices[i].x = posx; \
+ vertices[i].y = chcanv_cospace + orgy - scale * (((*mddPtr)[prun])pm); \
+ RMDBGONCE(4, RMDebug::module_applications, "chartCanvas", "_REDCHARTSPLINELOOP(pm) V: " << vertices[i].x << ',' << vertices[i].y ); \
+ vlist.Append(vertices + i); \
+ }
+
+#define REDCHARTSPLINE(type) \
+ r_Ref<r_Marray<type> > mddPtr = (r_Ref<r_Marray<type> >)(mddObj); \
+ _REDCHARTSPLINELOOP(+0);
+
+void chartCanvas::redrawSpline(wxDC *cdc, int dim, int startOff, int endOff, float scale, float posx, float stepx, float orgy)
+{
+ wxPoint *vertices;
+ wxList vlist;
+ wxPoint point;
+ r_Point prun = pt1;
+ float clipx, clipwidth;
+ int i;
+
+ clipx = posx; clipwidth = (endOff - startOff) * stepx;
+
+ // Need additional vertices left (1) and right (2) for splines
+ if (startOff > 0) {startOff--; posx -= stepx;}
+ endOff += 2; if (pt1[dim] + endOff > pt2[dim]) endOff = pt2[dim] - pt1[dim];
+
+ if ((vertices = new wxPoint[endOff - startOff + 1]) == NULL)
+ {
+ cerr << lman->lookup("errorMemory") << endl;
+ return;
+ }
+
+ // Do not delete the contents of the nodes when the list is killed!
+ vlist.DeleteContents(FALSE);
+
+ // It is _vitally_ important to set the clipping region here, because the boundary vertices
+ // are only there to get curvature right. If you don't set the clipping region you get
+ // redraw errors.
+ cdc->SetClippingRegion(clipx, 0, clipwidth, 10000);
+
+ i = 0;
+ switch (baseType)
+ {
+ case rbt_bool:
+ {
+ REDCHARTSPLINE(r_Boolean);
+ }
+ break;
+ case rbt_char:
+ {
+ REDCHARTSPLINE(r_Char);
+ }
+ break;
+ case rbt_uchar:
+ {
+ REDCHARTSPLINE(r_Octet);
+ }
+ break;
+ case rbt_short:
+ {
+ REDCHARTSPLINE(r_Short);
+ }
+ break;
+ case rbt_ushort:
+ {
+ REDCHARTSPLINE(r_UShort);
+ }
+ break;
+ case rbt_long:
+ {
+ REDCHARTSPLINE(r_Long);
+ }
+ break;
+ case rbt_ulong:
+ {
+ REDCHARTSPLINE(r_ULong);
+ }
+ break;
+ case rbt_rgb:
+ {
+ r_Ref<r_Marray<RGBPixel> > mddPtr = (r_Ref<r_Marray<RGBPixel> >) (mddObj);
+ double oldPosx = posx;
+ cdc->SetPen(&pen_r);
+ _REDCHARTSPLINELOOP(.red);
+ cdc->DrawSpline(&vlist); vlist.Clear();
+ cdc->SetPen(&pen_g); posx = oldPosx + stepx/3; i = 0;
+ _REDCHARTSPLINELOOP(.green);
+ cdc->DrawSpline(&vlist); vlist.Clear();
+ cdc->SetPen(&pen_b); posx = oldPosx + 2*stepx/3; i = 0;
+ _REDCHARTSPLINELOOP(.blue);
+ }
+ break;
+ case rbt_float:
+ {
+ REDCHARTSPLINE(r_Float);
+ }
+ break;
+ case rbt_double:
+ {
+ REDCHARTSPLINE(r_Double);
+ }
+ break;
+ default: break;
+ }
+ RMDBGONCE(3, RMDebug::module_applications, "chartCanvas", "redrawSpline() vertices " << (void*)vertices );
+
+ cdc->DrawSpline(&vlist);
+
+ if (baseType == rbt_rgb)
+ cdc->SetPen(&pen);
+
+ cdc->DestroyClippingRegion();
+
+ // ... we delete the data ourselves.
+ delete [] vertices;
+}
+
+
+
+void chartCanvas::OnPaint(void)
+{
+ wxUpdateIterator upd(this);
+ wxRect rect;
+ int w, h, dim, i, x;
+ float scale, orgy, posx, stepx, cm, y;
+ float twidth, theight;
+ wxCanvasDC *cdc;
+ r_Range startOff, endOff;
+ char buffer[STRINGSIZE];
+ bool redrawAll = FALSE;
+
+ //cout << "chartCanvas::OnPaint()" << endl;
+ for (dim=0; dim<dimMDD; dim++) if (pt1[dim] != pt2[dim]) break;
+ if (dim >= dimMDD) return;
+
+ GetClientSize(&w, &h);
+ // Reserve space for co system
+ h -= 2*chcanv_cospace;
+
+ if (fabs(max-min) < 10*DBL_MIN)
+ {
+ scale = (float)h; orgy = h;
+ }
+ else
+ {
+ scale = ((float)h) / (max - min); orgy = max*scale;
+ }
+ if (scale <= 0) return;
+
+ cdc = GetDC();
+ cdc->BeginDrawing();
+ cdc->SetMapMode(MM_TEXT); // 1 unit = 1 pixel
+ cdc->SetBrush(&brush);
+ cdc->SetPen(&pen);
+ cdc->SetFont(font);
+
+ w = GetScrollPos(wxHORIZONTAL);
+ x = rviewDisplay::display_scrstep * w;
+
+ // On the necessity to redraw everything in case of scroll events see rviewTable.cpp
+ if (w != scroll)
+ {
+ redrawAll = TRUE;
+ GetClientSize(&rect.width, &rect.height);
+ rect.x = 0; rect.y = 0;
+ scroll = w;
+ }
+
+ stepx = (float)step;
+
+ // It's important to use for, not while here, due to continue in the loop body
+ for (; upd ; upd++)
+ {
+ if (!redrawAll) upd.GetRect(&rect);
+
+ // Leave space to the left for co-system
+ startOff = (x + rect.x - coleft) / step;
+ if (startOff < 0) startOff = 0;
+ if (pt1[dim] + startOff > pt2[dim])
+ continue;
+ endOff = (x + rect.x - coleft + rect.width + step - 1) / step;
+ if (pt1[dim] + endOff > pt2[dim]) endOff = (r_Range)(pt2[dim] - pt1[dim]);
+ posx = startOff * stepx + coleft;
+
+ switch (cmode)
+ {
+ case rcm_bar: redrawBar(cdc, h, dim, startOff, endOff, scale, posx, stepx, orgy); break;
+ case rcm_line: redrawLine(cdc, dim, startOff, endOff, scale, posx, stepx, orgy); break;
+ case rcm_spline: redrawSpline(cdc, dim, startOff, endOff, scale, posx, stepx, orgy); break;
+ default: break;
+ }
+
+ // Draw coordinate system?
+ if (cosys)
+ {
+ // co-system
+ y = (min*max < 0) ? orgy : h;
+ // Only draw visible portion of horizontal line to avoid overflows
+ cdc->DrawLine(coleft + startOff * stepx, chcanv_cospace + y, coleft + (endOff+1)*stepx, chcanv_cospace + y);
+
+ // vertical axis
+ if (coleft + chcanv_colength/2 >= rect.x)
+ {
+ cdc->DrawLine(coleft, chcanv_cospace, coleft, chcanv_cospace + h);
+ i = (int)(min / costep);
+ for (cm=i*costep; cm <= (float)max; cm += costep)
+ {
+ posx = orgy - cm*scale;
+ if (posx > h) continue;
+ posx += chcanv_cospace;
+ cdc->DrawLine(coleft - chcanv_colength/2, posx, coleft + chcanv_colength/2, posx);
+ sprintf(buffer, format, cm);
+ cdc->GetTextExtent(buffer, &twidth, &theight);
+ cdc->DrawText(buffer, coleft - chcanv_colength/2 - twidth, posx - theight/2);
+ }
+ }
+
+ // horizontal axis
+ i = startOff/datastep; i *= datastep;
+ for (; i <= endOff; i += datastep)
+ {
+ posx = i*stepx + coleft;
+ cdc->DrawLine(posx, chcanv_cospace + y - chcanv_colength, posx, chcanv_cospace + y + chcanv_colength/2);
+ sprintf(buffer, "%ld", i + pt1[dim]);
+ cdc->GetTextExtent(buffer, &twidth, &theight);
+ cdc->DrawText(buffer, posx - twidth/2, y + chcanv_cospace + chcanv_colength/2);
+ }
+ }
+ }
+ cdc->SetBrush(NULL);
+ cdc->SetPen(NULL);
+ cdc->SetFont(NULL);
+ cdc->EndDrawing();
+
+ //cout << "Leaving OnPaint..." << endl;
+}
+
+
+
+
+
+const char *rviewChart::view_StepSize = "stepSize";
+const char *rviewChart::view_Markers = "markers";
+const char *rviewChart::view_ScrollPos = "scrollPos";
+const char *rviewChart::view_CoSys = "coordSys";
+const char *rviewChart::view_ChartMode = "chartMode";
+
+rviewChart::rviewChart(mdd_frame *mf, unsigned int flags) : rviewDisplay(mf, chart_ctrly, flags)
+{
+ int w, h, i;
+ char *b;
+
+ RMDBGONCE(3, RMDebug::module_applications, "rviewChart", "rviewChart()");
+
+ // Chart mode defaults, put into prefs later
+ cmode = prefs->chartMode;
+ if ((cmode != rcm_bar) && (cmode != rcm_line) && (cmode != rcm_spline)) cmode = rcm_bar;
+ step = prefs->chartStep; cosys = prefs->chartCosys;
+ datastep = prefs->chartMarkx; costep = prefs->chartMarky;
+
+ GetClientSize(&w, &h);
+ w -= 2*display_cnvborder; h -= 2*display_cnvborder + chart_totaly;
+ canvas = new chartCanvas((wxWindow*)this, display_cnvborder, display_cnvborder + chart_totaly, w, h);
+
+ stText = new rviewText(ctrlPanel, step);
+ coText = new rviewText(ctrlPanel, costep);
+ dataText = new rviewText(ctrlPanel, datastep);
+ csBox = new rviewCheckBox(ctrlPanel);
+ csBox->SetValue(cosys);
+
+ canvas->setData(mf, baseType);
+
+ canvas->setVars(step, costep, datastep, cosys, cmode);
+
+ b = projString;
+ b += sprintf(b, "*:*");
+ for (i=1; i<dimMDD; i++)
+ {
+ b += sprintf(b, ", %ld", interv[i].low());
+ }
+ project->SetValue(projString);
+
+ scroll = -1;
+ newProjection();
+
+ setModeDimension(1);
+
+ setMinimumViewerSize(chart_minwidth, chart_minheight);
+}
+
+
+int rviewChart::openViewer(void)
+{
+ RMDBGONCE(3, RMDebug::module_applications, "rviewChart", "openViewer()");
+
+ if (baseType == rbt_none)
+ {
+ rviewErrorbox::reportError(lman->lookup("errorModeBase"), rviewChart::getFrameName(), "openViewer");
+ objectInitializedOK = FALSE;
+ return -1;
+ }
+
+ if (rviewDisplay::openViewer() == 0)
+ {
+ int w, h;
+ wxMenu *modes;
+ char buffer[STRINGSIZE];
+
+ modes = new wxMenu;
+ modes->Append(MENU_CHART_MODE_BAR, "", NULL, TRUE);
+ modes->Append(MENU_CHART_MODE_LINE, "", NULL, TRUE);
+ modes->Append(MENU_CHART_MODE_SPLINE, "", NULL, TRUE);
+
+ sprintf(buffer, "&%s", lman->lookup("menChartMode"));
+ mBar->Append(modes, buffer);
+
+ checkModeMenu();
+
+ GetClientSize(&w, &h);
+ label();
+
+ frameWidth=-1;
+ frameHeight=-1;
+
+ OnSize(w, h);
+
+ Show(TRUE);
+
+ return 0;
+ }
+ return -1;
+}
+
+
+const char *rviewChart::getFrameName(void) const
+{
+ return "rviewChart";
+}
+
+rviewFrameType rviewChart::getFrameType(void) const
+{
+ return rviewFrameTypeChart;
+}
+
+int rviewChart::getViewerType(void) const
+{
+ return RVIEW_RESDISP_CHART;
+}
+
+
+
+// We don't own the mdd object. rviewResult does, so don't delete it!!!
+rviewChart::~rviewChart(void)
+{
+ RMDBGONCE(3, RMDebug::module_applications, "rviewChart", "~rviewChart()");
+ closeViewer();
+}
+
+
+
+void rviewChart::checkModeMenu(void)
+{
+ // tick the right mode in the display window.
+ switch (cmode)
+ {
+ case rcm_bar: lastMode = MENU_CHART_MODE_BAR; break;
+ case rcm_line: lastMode = MENU_CHART_MODE_LINE; break;
+ case rcm_spline: lastMode = MENU_CHART_MODE_SPLINE; break;
+ default: lastMode = MENU_CHART_MODE_BAR; break;
+ }
+ mBar->Check(lastMode, TRUE);
+}
+
+
+void rviewChart::label(void)
+{
+ setDisplayTitle(lman->lookup("titleChart"));
+
+ stText->SetLabel(lman->lookup("textStepC"));
+ csBox->SetLabel(lman->lookup("textCosys"));
+ coText->SetLabel(lman->lookup("textCoStep"));
+ dataText->SetLabel(lman->lookup("textDataStep"));
+
+ mBar->SetLabel(MENU_CHART_MODE_BAR, lman->lookup("menChartModeBar"));
+ mBar->SetLabel(MENU_CHART_MODE_LINE, lman->lookup("menChartModeLine"));
+ mBar->SetLabel(MENU_CHART_MODE_SPLINE, lman->lookup("menChartModeSpline"));
+ mBar->SetLabelTop(fixedNumberOfMenus, lman->lookup("menChartMode"));
+
+ rviewDisplay::label();
+}
+
+
+
+void rviewChart::OnSize(int w, int h)
+{
+ int x, y, i, j;
+
+ RMDBGONCE(3, RMDebug::module_applications, "rviewChart", "OnSize(" << w << ", " << h << " )");
+
+ GetClientSize(&x, &y);
+ i = 2*display_border + chart_totaly + 2*chartCanvas::chcanv_cospace;
+ if (y < i)
+ {
+ y = i;
+ SetClientSize(x, i);
+ }
+ x -= 2*display_border;
+ i = x - 3*chart_twidth - chart_cwidth;
+ j = display_border + display_cheight;
+ stText->SetSize(display_border + i/8, j, chart_twidth - display_border, chart_theight);
+ coText->SetSize(display_border + (3*i)/8 + chart_twidth, j, chart_twidth - display_border, chart_theight);
+ dataText->SetSize(display_border + (5*i)/8 + 2*chart_twidth, j, chart_twidth - display_border, chart_theight);
+ csBox->SetSize(display_border + (7*i)/8 + 3*chart_twidth, j, chart_cwidth, chart_cheight);
+
+ y -= 2*display_border + chart_totaly;
+ canvas->SetSize(display_border, display_border + chart_totaly, x, y);
+ rviewDisplay::OnSize(w, h);
+}
+
+
+
+void rviewChart::OnMenuCommand(int id)
+{
+ rviewChartMode cm;
+
+ RMDBGONCE(3, RMDebug::module_applications, "rviewChart", "OnMenuCommand()");
+
+ switch (id)
+ {
+ case MENU_CHART_MODE_BAR: cm = rcm_bar; break;
+ case MENU_CHART_MODE_LINE: cm = rcm_line; break;
+ case MENU_CHART_MODE_SPLINE: cm = rcm_spline; break;
+ default: cm = rcm_none; break;
+ }
+
+ if (cm != rcm_none)
+ {
+ mBar->Check(lastMode, FALSE);
+ mBar->Check(id, TRUE);
+ lastMode = id; cmode = cm;
+ newProjection();
+ }
+ else
+ rviewDisplay::OnMenuCommand(id);
+}
+
+
+
+int rviewChart::process(wxObject &obj, wxEvent &evt)
+{
+ int type = evt.GetEventType();
+ int h;
+ double hd;
+
+ RMDBGONCE(3, RMDebug::module_applications, "rviewChart", "process()");
+
+ if (type == wxEVENT_TYPE_TEXT_ENTER_COMMAND)
+ {
+ if (&obj == (wxObject*)stText)
+ {
+ if ((h = atoi(stText->GetValue())) > 0)
+ {
+ step = h;
+ newProjection();
+ return 1;
+ }
+ }
+ else if (&obj == (wxObject*)coText)
+ {
+ if ((hd = atof(coText->GetValue())) > 0.0)
+ {
+ costep = hd;
+ newProjection();
+ return 1;
+ }
+ }
+ else if (&obj == (wxObject*)dataText)
+ {
+ if ((h = atoi(dataText->GetValue())) > 0)
+ {
+ datastep = h;
+ newProjection();
+ return 1;
+ }
+ }
+ }
+
+ if ((&obj == (wxObject*)csBox) && (type == wxEVENT_TYPE_CHECKBOX_COMMAND))
+ {
+ cosys = csBox->GetValue();
+ // to force a redraw.
+ newProjection();
+ }
+
+ if (rviewDisplay::process(obj, evt) != 0)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+int rviewChart::newProjection(void)
+{
+ int dim, i;
+
+ RMDBGONCE(3, RMDebug::module_applications, "rviewChart", "newProjection()");
+
+ if (rviewParseProjection(getVirtualDomain(), pt1, pt2, projString) != dimMDD)
+ {
+ rviewErrorbox::reportError(lman->lookup("errorProjection"), rviewChart::getFrameName(), "newProjection");
+ return -1;
+ }
+
+ dim = -1;
+ for (i=0; i<dimMDD; i++)
+ {
+ if (pt1[i] != pt2[i])
+ {
+ if (dim < 0) dim = i;
+ else dim = dimMDD;
+ }
+ }
+ if ((dim < 0) || (dim >= dimMDD))
+ {
+ rviewErrorbox::reportError(lman->lookup("errorProjectFree"), rviewChart::getFrameName(), "newProjection");
+ return -1;
+ }
+ canvas->setVars(step, costep, datastep, cosys, cmode);
+
+ i = canvas->setProjection(pt1, pt2); // returns coleft
+
+ if (scroll >= 0)
+ scroll = canvas->GetScrollPos(wxHORIZONTAL);
+ else
+ scroll = 0;
+
+ canvas->SetScrollbars(display_scrstep, 0, (int)(((pt2[dim] - pt1[dim] + 1)*step + i + display_scrstep - 1) / display_scrstep), 0, display_pgstep, 0, scroll);
+ //canvas->GetVirtualSize(&dim, &i);
+ //cout << "step = " << step << "virtual size = " << dim << " x " << i << endl;
+
+ return 0;
+}
+
+
+int rviewChart::saveView(FILE *fp)
+{
+ int status = rviewDisplay::saveView(fp);
+
+ writeViewParam(fp, view_StepSize, (long)step);
+ long mvals[2];
+ mvals[0] = (long)costep; mvals[1] = (long)datastep;
+ writeViewParam(fp, view_Markers, 2, mvals);
+ writeViewParam(fp, view_ScrollPos, (long)(canvas->GetScrollPos(wxHORIZONTAL)));
+ writeViewParam(fp, view_CoSys, (long)cosys);
+ writeViewParam(fp, view_ChartMode, (long)cmode);
+
+ return status;
+}
+
+
+int rviewChart::readView(const char *key, const char *value)
+{
+ int status = rviewDisplay::readView(key, value);
+
+ if (status == 0)
+ {
+ if (strcmp(key, view_StepSize) == 0)
+ {
+ step = atoi(value);
+ return 1;
+ }
+ else if (strcmp(key, view_Markers) == 0)
+ {
+ long mvals[2];
+ if (readVector(value, 2, mvals) == 0)
+ {
+ costep = (int)mvals[0]; datastep = (int)mvals[1];
+ }
+ return 1;
+ }
+ else if (strcmp(key, view_ScrollPos) == 0)
+ {
+ scroll = atoi(value);
+ return 1;
+ }
+ else if (strcmp(key, view_CoSys) == 0)
+ {
+ cosys = (bool)atoi(value);
+ return 1;
+ }
+ else if (strcmp(key, view_ChartMode) == 0)
+ {
+ cmode = (rviewChartMode)atoi(value);
+ return 1;
+ }
+ return 0;
+ }
+ return status;
+}
+
+
+void rviewChart::loadViewFinished(void)
+{
+ stText->SetValue(step);
+ coText->SetValue(costep);
+ dataText->SetValue(datastep);
+
+ csBox->SetValue(cosys);
+
+ mBar->Check(lastMode, FALSE);
+ checkModeMenu();
+
+ canvas->SetScrollPos(wxHORIZONTAL, scroll);
+}