* Now wit hlabels and line drawing!
authortrelane@digitasaru.net <trelane@digitasaru.net>
Thu, 24 Jul 2008 21:02:18 +0000 (16:02 -0500)
committertrelane@digitasaru.net <trelane@digitasaru.net>
Thu, 24 Jul 2008 21:02:18 +0000 (16:02 -0500)
graph.c
graph.h
graphwidget.c
scdataviz.c

diff --git a/graph.c b/graph.c
index 6da0fb6..66b7e6c 100644 (file)
--- a/graph.c
+++ b/graph.c
@@ -42,26 +42,43 @@ static void graph_class_init(GraphClass *klass) {
 static void graph_init(Graph *graph) {
   graph->symbol = CIRCLE;
   graph->points = g_ptr_array_new();
+  graph->lines = NULL;
 }
 
 Graph *graph_new(void) {
   return g_object_new(GRAPH_TYPE, NULL);
 }
 
-int graph_add_point(Graph* graph, double x, double y) {
-  double *point = (double*)malloc(2*sizeof(double));
-  if(point == NULL) return 1;
-  point[0] = x;
-  point[1] = y;
-  g_ptr_array_add(graph->points, (gpointer)point);
+/*1 means you're stupid and passed NULL*/
+int graph_add_graph_point(Graph* graph, struct graph_point *pt) {
+  if(pt == NULL) return 1;
+  g_ptr_array_add(graph->points, pt);
   if(graph->points->len == 1) {
-    graph->maxx = graph->minx = x;
-    graph->maxy = graph->miny = y;
+    graph->maxx = graph->minx = pt->x;
+    graph->maxy = graph->miny = pt->y;
   }else{
-    if(x > graph->maxx) graph->maxx = x;
-    if(x < graph->minx) graph->minx = x;
-    if(y > graph->maxy) graph->maxy = y;
-    if(y < graph->miny) graph->miny = y;
+    if(pt->x > graph->maxx) graph->maxx = pt->x;
+    if(pt->x < graph->minx) graph->minx = pt->x;
+    if(pt->y > graph->maxy) graph->maxy = pt->y;
+    if(pt->y < graph->miny) graph->miny = pt->y;
   }
   return 0;
 }
+
+/*
+ *
+ *1 means failed to allocate point
+ *NOTE: label is duplicated if not NULL (using g_strdup)
+ */
+int graph_add_point(Graph* graph, double x, double y, const GString *label) {
+  struct graph_point *pt = (struct graph_point*)malloc(sizeof(struct graph_point));
+  if(pt == NULL) return 1;
+  pt->x = x;
+  pt->y = y;
+  pt->label = (label)?g_string_new(label->str):NULL;
+  /*Easiest way to do a line: the control points are the same as this point*/
+  pt->bezier_from_x = pt->bezier_to_x = x;
+  pt->bezier_from_y = pt->bezier_to_y = y;
+  graph_add_graph_point(graph, pt);
+  return 0;
+}
diff --git a/graph.h b/graph.h
index 33112a5..3015d30 100644 (file)
--- a/graph.h
+++ b/graph.h
 
 typedef enum {SQUARE, CIRCLE, STAR, PLUS, MINUS, CROSS} graph_symbol;
 
+struct graph_point {
+  double x;
+  double y;
+  GString *label;
+  /*the Bezier control point FROM HERE to the next point (P1)*/
+  double bezier_from_x;
+  double bezier_from_y;
+  /*the Bezier control point from previous point TO HERE (P2)*/
+  double bezier_to_x;
+  double bezier_to_y;
+};
+
 typedef struct _Graph {
   GObject parent_instance;
   /*Array of n_points sets of x,y coords*/
   GPtrArray *points;
+  /*If you want to, this will override the lines between the points.*/
+  GPtrArray *lines;
   double maxx;
   double minx;
   double maxy;
@@ -54,6 +68,7 @@ typedef struct _GraphClass {
 #define GRAPH_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), GRAPH, GraphClass))
 
 Graph *graph_new(void);
-int graph_add_point(Graph* graph, double x, double y);
+int graph_add_point(Graph* graph, double x, double y, const GString *label);
+int graph_add_graph_point(Graph* graph, struct graph_point *pt);
 
 #endif             /* !GRAPHCLASS_H_ */
index 03da4c6..fe209ca 100644 (file)
@@ -44,17 +44,50 @@ struct drawing_context {
   double yoffset;
   double xscaling;
   double yscaling;
+  double bezier_p0_x;
+  double bezier_p0_y;
+  double bezier_p1_x;
+  double bezier_p1_y;
+  int draw_line;
+  int not_first_point;
 };
 
 static void draw_point(gpointer data, gpointer user_data) {
-  struct drawing_context *cxt = (struct drawing_context *) user_data;
-  double *d = (double*)data;
-  fprintf(stderr, "draw_point(x=%g(%g) y=%g(%g)) xscaling=%g yscaling=%g xoffset=%g yoffset=%g\n", d[0], (d[0] + cxt->xoffset)*cxt->xscaling, d[1], (d[1] + cxt->yoffset)*cxt->yscaling, cxt->xscaling, cxt->yscaling, cxt->xoffset, cxt->yoffset);
-  cairo_arc(cxt->cr, (d[0] + cxt->xoffset)*cxt->xscaling, (d[1] + cxt->yoffset)*cxt->yscaling, cxt->radius, 0, 2*M_PI);
-  cairo_set_source_rgb(cxt->cr, 1, 1, 1);
-  cairo_fill_preserve(cxt->cr);
-  cairo_set_source_rgb(cxt->cr, 0, 0, 0);
-  cairo_stroke(cxt->cr);
+  struct drawing_context *cxt = user_data;
+  struct graph_point *pt = data;
+  double x = (pt->x + cxt->xoffset)*cxt->xscaling;
+  double y = (pt->y + cxt->yoffset)*cxt->yscaling;
+  double bezier_p2_x = (pt->bezier_to_x + cxt->xoffset)*cxt->xscaling;
+  double bezier_p2_y = (pt->bezier_to_y + cxt->yoffset)*cxt->yscaling;
+  #ifdef DEBUG
+  fprintf(stderr, "\tcxt=(cr=%x, rad=%g, xoffset=%g, yoffset=%g, xscaling=%g, yscaling=%g, p0_x=%g, p0_y=%g, p1_x=%g, p1_y=%g, draw_line=%d, not_first_point=%d)\n", (unsigned int)cxt->cr, cxt->radius, cxt->xoffset, cxt->yoffset, cxt->xscaling, cxt->yscaling, cxt->bezier_p0_x, cxt->bezier_p0_y, cxt->bezier_p1_x, cxt->bezier_p1_y, cxt->draw_line, cxt->not_first_point);
+  #endif
+  /*Draw line to here if we need to.*/
+  if(cxt->draw_line && cxt->not_first_point) {
+    /*Note that the cxt points are already normalized*/
+    //cairo_move_to(cxt->cr, cxt->bezier_p0_x, cxt->bezier_p0_y);
+    cairo_curve_to(cxt->cr, cxt->bezier_p1_x, cxt->bezier_p1_y, bezier_p2_x, bezier_p2_y, x, y);
+  }else{
+    cairo_move_to(cxt->cr, x, y);
+  }    
+  #ifdef DEBUG
+  fprintf(stderr, "\t\tpt=(x=%g, y=%g, label=%s, from_x=%g, from_y=%g, to_x=%g, to_y=%g)\n", pt->x, pt->y, pt->label->str, pt->bezier_from_x, pt->bezier_from_y, pt->bezier_to_x, pt->bezier_to_y);
+  fprintf(stderr, "\t\tx=%g, y=%g, p2_x=%g, p2_y=%g\n", x, y, bezier_p2_x, bezier_p2_y);
+  #endif
+  cairo_arc(cxt->cr, x, y, cxt->radius, 0, 2*M_PI);
+  if(pt->label != NULL) {
+    cairo_save(cxt->cr);
+    cairo_translate(cxt->cr, 0, 1);
+    cairo_scale(cxt->cr, 1, -1);
+    cairo_show_text(cxt->cr, pt->label->str);
+    cairo_restore(cxt->cr);
+  }
+  /*Set up the context for the next point*/
+  cxt->bezier_p0_x = x;
+  cxt->bezier_p0_y = y;
+  cxt->bezier_p1_x = (pt->bezier_from_x + cxt->xoffset)*cxt->xscaling;
+  cxt->bezier_p1_y = (pt->bezier_from_y + cxt->yoffset)*cxt->yscaling;
+  cxt->not_first_point=1;
 }
 
 static void draw(GtkWidget *graph, cairo_t *cr) {
@@ -75,7 +108,11 @@ static void draw(GtkWidget *graph, cairo_t *cr) {
   cxt.yscaling = (gw->graph->points->len == 1)? 1 : (1/(gw->graph->maxy - gw->graph->miny));
   cxt.xoffset = (gw->graph->points->len == 1)? (-gw->graph->minx/2) : (-gw->graph->minx);
   cxt.yoffset = (gw->graph->points->len == 1)? (-gw->graph->miny/2) : (-gw->graph->miny);
+  /*Signal that the point is the first point.*/
+  cxt.draw_line=0;
+  cxt.not_first_point=0;
   #ifdef DEBUG
+  fprintf(stderr, "minx=%g, maxx=%g, miny=%g, maxy=%g, xscaling=%g, yscaling=%g, xoffset=%g, yoffset=%g\n", gw->graph->minx, gw->graph->maxx, gw->graph->miny, gw->graph->maxy, cxt.xscaling, cxt.yscaling, cxt.xoffset, cxt.yoffset);
   fprintf(stderr, "x0=%g, y0=%g, width=%g, height=%g\n", x0, y0, height, width);
   fprintf(stderr, "translate=(%g, %g)\n", x0 + ((width>height)?(width-height)/2.0:0), y0+((width > height)?height:width) + ((height>width)?(height-width)/2.0:0));
 #endif
@@ -87,7 +124,14 @@ static void draw(GtkWidget *graph, cairo_t *cr) {
   cairo_translate(cr, x0 + ((inset_width>inset_height)?(inset_width-inset_height)/2.0:0) + offset_width/2, y0+((inset_width > inset_height)?inset_height:inset_width) + ((inset_width>=inset_height)?0:(inset_height-inset_width)/2.0) + offset_height/2 );
   cairo_scale(cr, (inset_width > inset_height)?inset_height:inset_width, (inset_width > inset_height)?-inset_height:-inset_width);
   cairo_set_line_width(cr, 0.005);
-  g_ptr_array_foreach(GRAPH_WIDGET(graph)->graph->points, &draw_point, (gpointer)&cxt);
+  cairo_select_font_face (cr, "Georgia",
+                         CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+  cairo_set_font_size (cr, 0.05);
+  g_ptr_array_foreach(gw->graph->points, &draw_point, (gpointer)&cxt);
+  cairo_set_source_rgb(cr, 1, 1, 1);
+  cairo_fill_preserve(cr);
+  cairo_set_source_rgb(cr, 0, 0, 0);
+  cairo_stroke(cr);
   cairo_restore(cr);
 }
 
@@ -118,3 +162,4 @@ GtkWidget *graph_widget_new(void) {
 Graph* graph_widget_get_graph(GraphWidget* gw) {
   return gw->graph;
 }
+
index 43e7b45..c51f21d 100644 (file)
@@ -31,6 +31,8 @@
 #include <graphwidget.h>
 #include <matdb-dotcode.h>
 
+#undef DEBUG
+
 struct xy_properties {
   GString *xprop;
   GString *yprop;
@@ -40,13 +42,15 @@ struct xy_properties {
 static void put_mat_in_graph(gpointer key, gpointer value, gpointer user_data) {
   struct xy_properties *propmap = user_data;
   struct matdb_material *mat = value;
+  if(!strcasecmp(mat->name->str, "vacuum")) return;
+  if(!strcasecmp(mat->name->str, "pvb")) return;
   double *x, *y;
   #ifdef DEBUG
   fprintf(stderr, "put_mat_in_graph(%s) (x->%s, y->%s): ", (char*)key, propmap->xprop->str, propmap->yprop->str);
   #endif
   if(((x=g_hash_table_lookup(mat->properties, propmap->xprop->str)) != NULL)
      && ((y=g_hash_table_lookup(mat->properties, propmap->yprop->str)) != NULL)) {
-    graph_add_point(propmap->graph, *x, *y);
+    graph_add_point(propmap->graph, *x, *y, mat->name);
   #ifdef DEBUG
     fprintf(stderr, "added (x->%s=%g, y->%s=%g)\n", propmap->xprop->str, *x, propmap->yprop->str, *y);
   }else{
@@ -66,7 +70,7 @@ int main(int   argc, char *argv[])
     //fprintf(stderr, "read_matdb_dotcode(%s, %d)=%x", file->str, err,
     //(int)mdb);
     fprintf(stderr, "err=%d\n", err);
-    print_matdb(mdb);
+    //print_matdb(mdb);
     
     
     gtk_init (&argc, &argv);