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;
+}
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) {
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
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);
}
Graph* graph_widget_get_graph(GraphWidget* gw) {
return gw->graph;
}
+
#include <graphwidget.h>
#include <matdb-dotcode.h>
+#undef DEBUG
+
struct xy_properties {
GString *xprop;
GString *yprop;
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{
//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);