00001 #ifndef graph_h
00002 #define graph_h
00003
00004 #include <ivstream.h>
00005 #include <OS/list.h>
00006 #include <OS/string.h>
00007 #include <InterViews/observe.h>
00008 #include "scenevie.h"
00009
00010 class DataVec;
00011 class Color;
00012 class Brush;
00013 struct Symbol;
00014 class Symlist;
00015 class GraphLine;
00016 class GLabel;
00017 class GPolyLine;
00018 class SymChooser;
00019 class Event;
00020 class GraphVector;
00021 class HocCommand;
00022 class LineExtension;
00023 class TelltaleState;
00024 struct Object;
00025
00026 declarePtrList(LineList, GraphLine);
00027
00028
00029 class GraphItem : public MonoGlyph {
00030 public:
00031 enum { ERASE_LINE=1, ERASE_AXIS };
00032 GraphItem(Glyph* g, boolean = true, boolean pick = true);
00033 virtual ~GraphItem();
00034 virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
00035 virtual void save(ostream&, Coord, Coord);
00036 virtual void erase(Scene*, GlyphIndex, int erase_type);
00037 boolean save() { return save_; }
00038 void save(boolean s) {save_ = s;}
00039 virtual boolean is_polyline();
00040 virtual boolean is_mark();
00041 virtual boolean is_fast() { return false;}
00042 virtual boolean is_graphVector() { return false;}
00043 private:
00044 boolean save_;
00045 boolean pick_;
00046 };
00047
00048 class Graph : public Scene {
00049 public:
00050 enum {CROSSHAIR = Scene::EXTRATOOL, CHANGELABEL, PICK, EXTRAGRAPHTOOL};
00051 Graph(boolean = true);
00052 virtual ~Graph();
00053 void axis(DimensionName, float min, float max, float pos = 0.,
00054 int ntics = -1, int nminor=0,
00055 int invert = 0, boolean number = true);
00056 GraphLine* add_var(const char*, const Color*, const Brush*,
00057 boolean usepointer, int fixtype = 1, double* p = nil,
00058 const char* lab = nil, Object* obj = nil);
00059 void x_expr(const char*, boolean usepointer);
00060 void add_polyline(GPolyLine*);
00061 void add_graphVector(GraphVector*);
00062 void begin();
00063 void plot(float);
00064 void flush();
00065 void fast_flush();
00066 void begin_line(const char* s = nil);
00067 void begin_line(const Color*, const Brush*, const char* s = nil);
00068 void line(Coord x, Coord y);
00069 void mark(Coord x, Coord y, char style='+', float size=12,
00070 const Color* =nil, const Brush* =nil);
00071 void erase();
00072 virtual void erase_all();
00073 void erase_lines();
00074 virtual void delete_label(GLabel*);
00075 virtual boolean change_label(GLabel*, const char*, GLabel* gl=nil);
00076 virtual void help();
00077 void keep_lines();
00078 void keep_lines_toggle();
00079 void family(boolean);
00080 void family(const char*);
00081 void family_label_chooser();
00082 void new_axis();
00083 void erase_axis();
00084 void view_axis();
00085 void view_box();
00086 void change_prop();
00087 void color(int);
00088 void brush(int);
00089 const Color* color() const {return color_;}
00090 const Brush* brush() const {return brush_;}
00091 void set_cross_action(const char*, boolean vectorcopy=false);
00092 void cross_action(char, GPolyLine*, int);
00093 void cross_action(char, Coord, Coord);
00094 void simgraph();
00095
00096 virtual void draw(Canvas*, const Allocation&) const;
00097 virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
00098 virtual GlyphIndex glyph_index(const Glyph*);
00099 virtual void new_size(Coord x1, Coord y1, Coord x2, Coord y2);
00100 virtual void wholeplot(Coord &x1, Coord& y1, Coord& x2, Coord& y2)const;
00101
00102
00103 GLabel* label(float x, float y, const char* s, int fixtype,
00104 float scale, float x_align, float y_align, const Color*);
00105 GLabel* label(float x, float y, const char* s, float n=0, int fixtype = -1);
00106 GLabel* label(const char* s, int fixtype = -1);
00107 GLabel* new_proto_label() const;
00108 void fixed(float scale);
00109 void vfixed(float scale);
00110 void relative(float scale);
00111 void align(float x, float y);
00112 void choose_sym();
00113 void name(char*);
00114 void change_label_color(GLabel*);
00115 void change_line_color(GPolyLine*);
00116 void update_ptrs();
00117
00118 virtual void save_phase1(ostream&);
00119 virtual void save_phase2(ostream&);
00120 int labeltype() const { return label_fixtype_; }
00121 static boolean label_chooser(const char*, char*, GLabel*, Coord x = 400., Coord y = 400.);
00122
00123 virtual void see_range_plot(GraphVector*);
00124 static void ascii(ostream*);
00125 static ostream* ascii();
00126 private:
00127 void extension_start();
00128 void extension_continue();
00129 void ascii_save(ostream& o) const;
00130 void family_value();
00131 private:
00132 Symlist* symlist_;
00133 LineList line_list_;
00134 int loc_;
00135 DataVec* x_;
00136 boolean extension_flushed_;
00137 SymChooser* sc_;
00138 static SymChooser* fsc_;
00139 CopyString* var_name_;
00140 GPolyLine* current_polyline_;
00141
00142 const Color* color_;
00143 const Brush* brush_;
00144 int label_fixtype_;
00145 float label_scale_;
00146 float label_x_align_, label_y_align_;
00147 float label_x_, label_y_, label_n_;
00148 TelltaleState* keep_lines_toggle_;
00149 boolean family_on_;
00150 GLabel* family_label_;
00151 double family_val_;
00152 int family_cnt_;
00153 HocCommand* cross_action_;
00154 boolean vector_copy_;
00155
00156 Symbol* x_expr_;
00157 double* x_pval_;
00158
00159 GraphVector* rvp_;
00160 static ostream* ascii_;
00161 };
00162
00163 class DataVec :public Resource {
00164 public:
00165 DataVec(int size);
00166 DataVec(const DataVec*);
00167 virtual ~DataVec();
00168 void add(float);
00169 float max() const, min() const;
00170 float max(int low, int high), min(int, int);
00171 int loc_max() const, loc_min() const;
00172 void erase();
00173 int count() const { return count_;}
00174 void write();
00175 float get_val(int i) const {return y_[i];}
00176 int size() const { return size_; }
00177 const Coord* vec() { return y_;}
00178 void running_start();
00179 float running_max();
00180 float running_min();
00181 Object** new_vect(GLabel* g = nil)const;
00182 private:
00183 int count_, size_, iMinLoc_, iMaxLoc_;
00184 int running_min_loc_, running_max_loc_;
00185 float* y_;
00186 };
00187
00188 class DataPointers : public Resource {
00189 public:
00190 DataPointers(int size = 50);
00191 virtual ~DataPointers();
00192 void add(double*);
00193 void erase() { count_ = 0; }
00194 int size() { return size_;}
00195 int count() {return count_;}
00196 double* p(int i) { return px_[i]; }
00197 void update_ptrs();
00198 private:
00199 int count_, size_;
00200 double** px_;
00201 };
00202
00203 class GPolyLine : public Glyph {
00204 public:
00205 GPolyLine(DataVec* x, const Color* = nil, const Brush* = nil);
00206 GPolyLine(DataVec* x, DataVec* y, const Color* = nil, const Brush* = nil);
00207 GPolyLine(GPolyLine*);
00208 virtual ~GPolyLine();
00209
00210 virtual void request(Requisition&) const;
00211 virtual void allocate(Canvas*, const Allocation&, Extension&);
00212 virtual void draw(Canvas*, const Allocation&) const;
00213 virtual void draw_specific(Canvas*, const Allocation&, int, int) const;
00214 virtual void print(Printer*, const Allocation&) const;
00215 virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
00216 virtual void save(ostream&);
00217 virtual void pick_vector();
00218
00219 void plot(Coord x, Coord y);
00220 void erase() { y_->erase();}
00221 virtual void erase_line(Scene*, GlyphIndex);
00222
00223 void color(const Color*);
00224 void brush(const Brush*);
00225 const Color* color() const {return color_;}
00226 const Brush* brush() const {return brush_;}
00227
00228 Coord x(int index) const { return x_->get_val(index); }
00229 Coord y(int index) const { return y_->get_val(index); }
00230 const DataVec* x_data() const {return x_;}
00231 const DataVec* y_data() const {return y_;}
00232
00233 GLabel* label() const { return glabel_; }
00234 void label(GLabel*);
00235 void label_loc(Coord& x, Coord& y)const;
00236
00237
00238 boolean near(Coord, Coord, float, const Transformer&) const;
00239
00240 int nearest(Coord, Coord, const Transformer&, int index = -1) const;
00241 boolean keepable() { return keepable_;}
00242 private:
00243 void init(DataVec*, DataVec*, const Color*, const Brush*);
00244 protected:
00245 DataVec* y_;
00246 DataVec* x_;
00247 const Color* color_;
00248 const Brush* brush_;
00249 GLabel* glabel_;
00250 boolean keepable_;
00251 };
00252
00253 class GraphLine : public GPolyLine , public Observer {
00254 public:
00255 GraphLine(const char*, DataVec* x, Symlist**, const Color* = nil, const Brush* = nil,
00256 boolean usepointer=0, double* pd = nil, Object* obj = nil);
00257 virtual ~GraphLine();
00258
00259 virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
00260 virtual void save(ostream&);
00261
00262 void plot();
00263
00264 const char* name() const;
00265 LineExtension* extension() { return extension_; }
00266 void extension_start();
00267 void extension_continue();
00268 const Color* save_color() const { return save_color_;}
00269 const Brush* save_brush() const { return save_brush_;}
00270 void save_color(const Color*);
00271 void save_brush(const Brush*);
00272 boolean change_expr(const char*, Symlist**);
00273 virtual void update(Observable*);
00274 boolean valid(boolean check = false);
00275 virtual void erase_line(Scene*, GlyphIndex) {erase();}
00276 void simgraph_activate(boolean);
00277 void simgraph_init();
00278 void simgraph_continuous(double);
00279 void update_ptrs();
00280 private:
00281 Symbol* expr_;
00282 double* pval_;
00283 LineExtension* extension_;
00284 const Color* save_color_;
00285 const Brush* save_brush_;
00286 boolean valid_;
00287 Object* obj_;
00288 DataVec* simgraph_x_sav_;
00289 };
00290
00291 class GraphVector : public GPolyLine , public Observer{
00292 public:
00293 GraphVector(const char*, const Color* = nil, const Brush* = nil);
00294 virtual ~GraphVector();
00295 virtual void request(Requisition&) const;
00296 void begin();
00297 void add(float, double*);
00298 virtual void save(ostream&);
00299 const char* name() const;
00300 boolean trivial() const;
00301
00302 virtual boolean choose_sym(Graph*);
00303 virtual void update(Observable*);
00304 DataPointers* py_data() { return dp_; }
00305 void update_ptrs();
00306 private:
00307 DataPointers* dp_;
00308 CopyString name_;
00309 boolean disconnect_defer_;
00310 };
00311
00312 class GPolyLineItem : public GraphItem {
00313 public:
00314 GPolyLineItem(Glyph* g) : GraphItem(g){}
00315 virtual ~GPolyLineItem(){};
00316 virtual boolean is_polyline();
00317 virtual void save(ostream& o, Coord, Coord){
00318 ((GPolyLine*)body())->save(o);}
00319 virtual void erase(Scene* s, GlyphIndex i, int type) {
00320 if (type & GraphItem::ERASE_LINE) {
00321 s->remove(i);
00322 }
00323 }
00324 };
00325
00326 class GLabel : public Glyph {
00327 public:
00328 GLabel(const char* s, const Color*, int fixtype = 1, float size = 12,
00329 float x_align = 0., float y_align = 0.);
00330 virtual ~GLabel();
00331 virtual Glyph* clone() const;
00332
00333 virtual void request(Requisition&) const;
00334 virtual void allocate(Canvas*, const Allocation&, Extension&);
00335 virtual void draw(Canvas*, const Allocation&) const;
00336 virtual void save(ostream&, Coord, Coord);
00337 virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
00338
00339 void text(const char*);
00340 void fixed(float scale);
00341 void vfixed(float scale);
00342 void relative(float scale);
00343 void align(float x, float y);
00344 void color(const Color*);
00345
00346 boolean fixed() const {return fixtype_ == 1;}
00347 float scale() const { return scale_;}
00348 const char* text() const { return text_.string();}
00349 int fixtype() const {return fixtype_;}
00350 float x_align() const {return x_align_;}
00351 float y_align() const {return y_align_;}
00352 const Color* color() const { return color_;}
00353 boolean erase_flag() { return erase_flag_; }
00354 void erase_flag(boolean b) { erase_flag_ = b; }
00355
00356 GPolyLine* labeled_line() const { return gpl_; }
00357 private:
00358 void need(Canvas*, const Allocation&, Extension&)const;
00359 friend void GPolyLine::label(GLabel*);
00360 private:
00361 int fixtype_;
00362 float scale_;
00363 float x_align_, y_align_;
00364 CopyString text_;
00365 Glyph* label_;
00366 const Color* color_;
00367 GPolyLine* gpl_;
00368 boolean erase_flag_;
00369 };
00370
00371 class ColorPalette {
00372 public:
00373 ColorPalette();
00374 virtual ~ColorPalette();
00375 const Color* color(int)const;
00376 const Color* color(int, char*);
00377 const Color* color(int, const Color*);
00378 int color(const Color*)const;
00379
00380
00381 enum {COLOR_SIZE = 100};
00382 private:
00383 const Color* color_palette[COLOR_SIZE];
00384 };
00385 class BrushPalette {
00386 public:
00387 BrushPalette();
00388 virtual ~BrushPalette();
00389 const Brush* brush(int)const;
00390 const Brush* brush(int index, int pattern, Coord width);
00391 int brush(const Brush*)const;
00392 enum {BRUSH_SIZE = 25};
00393 private:
00394 const Brush* brush_palette[BRUSH_SIZE];
00395 };
00396 extern ColorPalette* colors;
00397 extern BrushPalette* brushes;
00398
00399 #endif