Commit 39a7b870 authored by Arturo Espinosa's avatar Arturo Espinosa

More stuff

parent b71d4a0d
......@@ -33,6 +33,8 @@ graph_SOURCES = \
graph-view-scatter.h \
graph-view-stock.c \
graph-view-stock.h \
graph-view-util.c \
graph-view-util.h \
layout.c \
layout.h \
layout-view.c \
......
......@@ -129,3 +129,13 @@ graph_vector_low_high (GraphVector *vector, double *low, double *high)
*high = v;
}
}
int
graph_vector_buffer_size (GraphVector *vector)
{
g_return_val_if_fail (vector != NULL, 0);
/* For now, the current implementation keeps an entire copy of the data */
return graph_vector_count (vector);
}
......@@ -17,16 +17,18 @@ struct _GraphVector {
void *change_data;
};
GraphVector *graph_vector_new (GNOME_Gnumeric_Vector vector,
GraphVectorChangeNotifyFn change,
void *change_data,
gboolean guess);
void graph_vector_destroy (GraphVector *graph_vector);
int graph_vector_count (GraphVector *vector);
char *graph_vector_get_string (GraphVector *vector, int pos);
double graph_vector_get_double (GraphVector *vector, int pos);
void graph_vector_low_high (GraphVector *vector, double *low, double *high);
GraphVector *graph_vector_new (GNOME_Gnumeric_Vector vector,
GraphVectorChangeNotifyFn change,
void *change_data,
gboolean guess);
void graph_vector_destroy (GraphVector *graph_vector);
int graph_vector_count (GraphVector *vector);
char *graph_vector_get_string (GraphVector *vector, int pos);
double graph_vector_get_double (GraphVector *vector, int pos);
void graph_vector_low_high (GraphVector *vector, double *low, double *high);
int graph_vector_buffer_size (GraphVector *vector);
#endif
......@@ -13,28 +13,16 @@
#include "graph.h"
#include "graph-view.h"
#include "graph-view-colbar.h"
typedef struct {
GraphView *graph_view;
Graph *graph;
GdkDrawable *drawable;
int x, y;
int width, height;
int xl, yl;
double units_per_slot;
int margin;
int inter_item_margin;
double scale;
} ColbarDrawCtx;
#include "graph-view-util.h"
static double
colbar_map_point (ColbarDrawCtx *ctx, double point)
colbar_map_point (ViewDrawCtx *ctx, double point)
{
return (fabs (ctx->graph->low) + point) * ctx->scale;
}
static void
column_draw (ColbarDrawCtx *ctx, int item,
column_draw (ViewDrawCtx *ctx, int item,
double x1, double y1, double x2, double y2)
{
int height, width, px, py;
......@@ -47,7 +35,6 @@ column_draw (ColbarDrawCtx *ctx, int item,
y1 -= ctx->y;
y2 -= ctx->y;
printf ("%d: (%g, %g) (%g, %g) ... ", item, x1, y1, x2, y2);
if (ctx->graph->direction == GNOME_Graph_DIR_BAR){
py = MIN (x1, x2);
height = fabs (x2-x1);
......@@ -65,7 +52,6 @@ column_draw (ColbarDrawCtx *ctx, int item,
width = x2 - x1;
}
printf ("%d,%d,%d,%d\n", px, py, width, height);
gdk_draw_rectangle (
ctx->drawable, ctx->graph_view->fill_gc, TRUE,
px, py, width, height);
......@@ -76,14 +62,14 @@ column_draw (ColbarDrawCtx *ctx, int item,
}
static void
setup_gc (ColbarDrawCtx *ctx, int series, int item)
setup_gc (ViewDrawCtx *ctx, int series, int item)
{
gdk_gc_set_foreground (ctx->graph_view->fill_gc,
&ctx->graph_view->palette [series % ctx->graph_view->n_palette]);
}
static void
graph_view_colbar_draw_nth_clustered (ColbarDrawCtx *ctx, int item)
graph_view_colbar_draw_nth_clustered (ViewDrawCtx *ctx, int item)
{
const int n_series = ctx->graph->layout->n_series;
const int item_base = item * ctx->units_per_slot + ctx->margin;
......@@ -107,7 +93,7 @@ graph_view_colbar_draw_nth_clustered (ColbarDrawCtx *ctx, int item)
}
static void
graph_view_colbar_draw_nth_stacked (ColbarDrawCtx *ctx, int item)
graph_view_colbar_draw_nth_stacked (ViewDrawCtx *ctx, int item)
{
const int n_series = ctx->graph->layout->n_series;
int item_base = item * ctx->units_per_slot;
......@@ -143,7 +129,7 @@ graph_view_colbar_draw_nth_stacked (ColbarDrawCtx *ctx, int item)
}
static void
graph_view_colbar_draw_nth_stacked_full (ColbarDrawCtx *ctx, int item)
graph_view_colbar_draw_nth_stacked_full (ViewDrawCtx *ctx, int item)
{
const int n_series = ctx->graph->layout->n_series;
int item_base = item * ctx->units_per_slot;
......@@ -204,7 +190,7 @@ graph_view_colbar_draw_nth_stacked_full (ColbarDrawCtx *ctx, int item)
}
static void
graph_view_colbar_draw_nth (ColbarDrawCtx *ctx, int item)
graph_view_colbar_draw_nth (ViewDrawCtx *ctx, int item)
{
switch (ctx->graph->chart_type){
case GNOME_Graph_CHART_TYPE_CLUSTERED:
......@@ -224,33 +210,39 @@ graph_view_colbar_draw_nth (ColbarDrawCtx *ctx, int item)
}
}
static void
graph_view_draw_area (ViewDrawCtx *ctx, int first, int last)
{
#if 0
#endif
}
void
graph_view_colbar_draw (GraphView *graph_view, GdkDrawable *drawable, int x, int y, int width, int height)
{
ColbarDrawCtx ctx;
ViewDrawCtx ctx;
int first, last, i;
gboolean is_bar;
printf ("Divisions: %d\n", graph_view->graph->divisions);
if (graph_view->graph->divisions == 0)
return;
ctx.x = x;
ctx.y = y;
ctx.width = width;
ctx.height = height;
ctx.drawable = drawable;
ctx.graph_view = graph_view;
ctx.graph = graph_view->graph;
ctx.yl = graph_view->bbox.y1 - graph_view->bbox.y0;
ctx.xl = graph_view->bbox.x1 - graph_view->bbox.x0;
if (graph_view->graph->direction == GNOME_Graph_DIR_BAR){
ctx.units_per_slot = ctx.yl / graph_view->graph->divisions;
SETUP_VIEW_CTX (ctx, graph_view, drawable, x, y, width, height);
is_bar = ctx.graph->direction == GNOME_Graph_DIR_BAR;
if (ctx.graph->plot_mode != GNOME_Graph_PLOT_COLBAR)
is_bar = FALSE;
if (is_bar){
ctx.units_per_slot = ctx.yl / ctx.graph->divisions;
first = y / ctx.units_per_slot;
last = (y + width) / ctx.units_per_slot;
ctx.scale = ctx.xl / ctx.graph->y_size;
} else {
ctx.units_per_slot = ctx.xl / graph_view->graph->divisions;
ctx.units_per_slot = ctx.xl / ctx.graph->divisions;
first = x / ctx.units_per_slot;
last = (x + width) / ctx.units_per_slot;
ctx.scale = ctx.yl / ctx.graph->y_size;
......@@ -261,8 +253,17 @@ graph_view_colbar_draw (GraphView *graph_view, GdkDrawable *drawable, int x, int
ctx.margin = ctx.units_per_slot / 20;
ctx.inter_item_margin = 0;
for (i = first; i <= last; i++)
graph_view_colbar_draw_nth (&ctx, i);
switch (ctx.graph->plot_mode){
case GNOME_Graph_PLOT_COLBAR:
for (i = first; i <= last; i++)
graph_view_colbar_draw_nth (&ctx, i);
break;
case GNOME_Graph_PLOT_AREA:
case GNOME_Graph_PLOT_LINES:
graph_view_draw_area (&ctx, first, last);
break;
}
}
......@@ -11,178 +11,112 @@
#include "graph.h"
#include "graph-view.h"
#include "graph-view-scatter.h"
#include "graph-view-util.h"
#include "graph-vector.h"
typedef struct {
GraphView *graph_view;
Graph *graph;
GdkDrawable *drawable;
GdkGC *gc;
int x, y;
int width, height;
int xl, yl;
/* Dimensions of our symbols, a rough idea of the size */
int dim;
} ScatterDrawCtx;
typedef enum {
SYMBOL_POINT,
SYMBOL_CROSS_1,
SYMBOL_CROSS_2,
SYMBOL_CIRCLE,
SYMBOL_FILLED_CIRCLE,
SYMBOL_SQUARE,
SYMBOL_FILLED_SQUARE,
SYMBOL_TRIANGLE,
SYMBOL_FILLED_TRIANGLE,
SYMBOL_CROSS_CIRCLE,
SYMBOL_CROSS_FILLED_CIRCLE,
SYMBOL_LAST
} Symbols;
static Symbols
setup_symbol (ScatterDrawCtx *ctx, int series)
/*
* Maps the x,y point to a canvas point
*/
static void
plot_point (ViewDrawCtx *ctx, int xi, double x, int series, double y)
{
/*
* FIXME: This can be much improved
*/
gdk_gc_set_foreground (ctx->graph_view->fill_gc,
&ctx->graph_view->palette [series % ctx->graph_view->n_palette]);
return (Symbols) series % (SYMBOL_LAST-1);
Symbol sym;
sym = symbol_setup (ctx, series);
symbol_draw (ctx, sym, MAP_X (ctx, x), MAP_Y (ctx, y));
}
/*
* This assumes the GC has been prepared previously
*/
static void
put_symbol (ScatterDrawCtx *ctx, Symbols sym, int px, int py)
draw_line (ViewDrawCtx *ctx, double x1, double y1, double x2, double y2)
{
gboolean fill = FALSE;
const int dim = ctx->dim;
const int dim_h = dim / 2;
px -= ctx->x;
py -= ctx->y;
switch (sym){
case SYMBOL_FILLED_SQUARE:
case SYMBOL_FILLED_TRIANGLE:
case SYMBOL_FILLED_CIRCLE:
fill = TRUE;
default:
}
switch (sym){
case SYMBOL_POINT:
gdk_draw_point (ctx->drawable, ctx->gc, px, py);
break;
case SYMBOL_CROSS_1:
gdk_draw_line (
ctx->drawable, ctx->gc,
px - dim_h, py - dim_h,
px + dim_h, py + dim_h);
gdk_draw_line (
ctx->drawable, ctx->gc,
px + dim_h, py - dim_h,
px - dim_h, py + dim_h);
break;
case SYMBOL_CROSS_2:
gdk_draw_line (
ctx->drawable, ctx->gc,
px, py - dim_h,
px, py + dim_h);
gdk_draw_line (
ctx->drawable, ctx->gc,
px + dim_h, py,
px - dim_h, py);
break;
case SYMBOL_CROSS_CIRCLE:
case SYMBOL_CROSS_FILLED_CIRCLE:
gdk_draw_arc (
ctx->drawable, ctx->gc, fill,
px - dim_h, py - dim_h,
dim, dim, 0, 360 * 64);
break;
case SYMBOL_SQUARE:
case SYMBOL_FILLED_SQUARE:
gdk_draw_rectangle (
ctx->drawable, ctx->gc, fill,
px - dim_h, py - dim_h, dim, dim);
break;
case SYMBOL_TRIANGLE:
case SYMBOL_FILLED_TRIANGLE: {
GdkPoint *tpoints = g_new (GdkPoint, 4);
gdk_draw_line (
ctx->drawable, ctx->graph_view->fill_gc,
MAP_X (ctx, x1), MAP_Y (ctx, y1),
MAP_X (ctx, x2), MAP_Y (ctx, y2));
}
tpoints [0].x = px - dim/2;
tpoints [0].y = py + dim/2;
tpoints [1].x = px;
tpoints [1].y = py - dim/2;
void
graph_view_line_plot (GraphView *graph_view, GdkDrawable *drawable,
int x, int y, int width, int height)
{
GraphVector **vectors = graph_view->graph->layout->vectors;
GraphVector *x_vector = vectors [0];
const int vector_count = graph_view->graph->layout->n_series;
const int x_vals = graph_vector_count (x_vector);
int vector;
ViewDrawCtx ctx;
tpoints [2].x = px + dim/2;
tpoints [2].y = tpoints [0].y;
SETUP_VIEW_CTX (ctx, graph_view, drawable, x, y, width, height);
tpoints [3] = tpoints [0];
for (vector = 1; vector < vector_count; vector ++){
double last_x, last_y;
int xi;
gdk_draw_polygon (ctx->drawable, ctx->gc, fill, tpoints, 4);
break;
}
last_y = graph_vector_get_double (vectors [vector], 0);
last_x = graph_vector_get_double (x_vector, 0);
default:
g_assert_not_reached ();
}
}
for (xi = 1; xi < x_vals; xi++){
double tx, ty;
/*
* Maps the x,y point to a canvas point
*/
static void
plot_point (ScatterDrawCtx *ctx, int xi, double x, int series, double y)
{
tx = graph_vector_get_double (x_vector, xi);
ty = graph_vector_get_double (vectors [vector], xi);
symbol_setup (&ctx, vector);
draw_line (&ctx, last_x, last_y, tx, ty);
last_x = tx;
last_y = ty;
}
}
}
void
graph_view_scatter_plot (GraphView *graph_view, GdkDrawable *drawable,
int x, int y, int width, int height)
{
ScatterDrawCtx ctx;
GraphVector **vectors = graph_view->graph->layout->vectors;
GraphVector *x_vector = vectors [0];
int x_vals = graph_vector_count (x_vector);
int vector_count = graph_view->graph->layout->n_series;
const int x_vals = graph_vector_count (x_vector);
const int vector_count = graph_view->graph->layout->n_series;
int xi;
ViewDrawCtx ctx;
SETUP_VIEW_CTX (ctx, graph_view, drawable, x, y, width, height);
ctx.x = x;
ctx.y = y;
ctx.width = width;
ctx.height = height;
ctx.drawable = drawable;
ctx.graph_view = graph_view;
ctx.graph = graph_view->graph;
ctx.yl = graph_view->bbox.y1 - graph_view->bbox.y0;
ctx.xl = graph_view->bbox.x1 - graph_view->bbox.x0;
ctx.dim = MIN (ctx.xl, ctx.yl) / 50;
ctx.dim = MIN (ctx.xl, ctx.yl) / 40;
if (ctx.dim > 8)
ctx.dim = 8;
if (ctx.dim < 2)
ctx.dim = 2;
/*
* FIXME:
*
* We should process this in chunks, as the local vector cache
* only holds a limited set of values (ok, 4k-ish)
* and we want to avoid trashing by calling the provider
* a lot
*/
for (xi = 0; xi < x_vals; xi++){
int vector;
double const xv = graph_vector_get_double (x_vector, xi);
int vector;
for (vector = 1; vector < vector_count; vector++){
double y;
y = graph_vector_get_double (vectors [vector], xi);
printf ("%d: %g %g [%g %g]\n", xi, xv, y, ctx.graph->x_size, ctx.graph->y_size);
plot_point (&ctx, xi, xv, vector, y);
}
}
}
......@@ -4,5 +4,8 @@
void graph_view_scatter_plot (GraphView *graph_view, GdkDrawable *drawable,
int x, int y, int width, int height);
void graph_view_line_plot (GraphView *graph_view, GdkDrawable *drawable,
int x, int y, int width, int height);
#endif /* GRAPH_VIEW_SCATTER_H_ */
/*
* Graph-view-util.h: utilities used to render in a graph view
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* Copyright 1999, International GNOME Support (http://www.gnome-support.com)
*/
#include <config.h>
#include "src/portability.h"
#include "graph.h"
#include "graph-view.h"
#include "graph-view-util.h"
Symbol
symbol_setup (ViewDrawCtx *ctx, int series)
{
/*
* FIXME: This can be much improved
*/
gdk_gc_set_foreground (
ctx->graph_view->fill_gc,
&ctx->graph_view->palette [series % ctx->graph_view->n_palette]);
return (Symbol) series % (SYMBOL_LAST-1);
}
void
symbol_draw (ViewDrawCtx *ctx, Symbol sym, int px, int py)
{
gboolean fill = FALSE;
const int dim = ctx->dim;
const int dim_h = dim / 2;
switch (sym){
case SYMBOL_FILLED_SQUARE:
case SYMBOL_FILLED_TRIANGLE:
case SYMBOL_FILLED_CIRCLE:
fill = TRUE;
default:
}
switch (sym){
case SYMBOL_POINT:
gdk_draw_point (ctx->drawable, ctx->gc, px, py);
break;
case SYMBOL_CROSS_1:
gdk_draw_line (
ctx->drawable, ctx->gc,
px - dim_h, py - dim_h,
px + dim_h, py + dim_h);
gdk_draw_line (
ctx->drawable, ctx->gc,
px + dim_h, py - dim_h,
px - dim_h, py + dim_h);
break;
case SYMBOL_CROSS_2:
gdk_draw_line (
ctx->drawable, ctx->gc,
px, py - dim_h,
px, py + dim_h);
gdk_draw_line (
ctx->drawable, ctx->gc,
px + dim_h, py,
px - dim_h, py);
break;
case SYMBOL_FILLED_CIRCLE:
case SYMBOL_CIRCLE:
gdk_draw_arc (
ctx->drawable, ctx->gc, fill,
px - dim_h, py - dim_h,
dim, dim, 0, 360 * 64);
break;
case SYMBOL_SQUARE:
case SYMBOL_FILLED_SQUARE:
gdk_draw_rectangle (
ctx->drawable, ctx->gc, fill,
px - dim_h, py - dim_h, dim, dim);
break;
case SYMBOL_TRIANGLE:
case SYMBOL_FILLED_TRIANGLE: {
GdkPoint *tpoints = g_new (GdkPoint, 4);
tpoints [0].x = px - dim/2;
tpoints [0].y = py + dim/2;
tpoints [1].x = px;
tpoints [1].y = py - dim/2;
tpoints [2].x = px + dim/2;
tpoints [2].y = tpoints [0].y;
tpoints [3] = tpoints [0];
gdk_draw_polygon (ctx->drawable, ctx->gc, fill, tpoints, 4);
break;
}
default:
g_assert_not_reached ();
}
}
#ifndef GRAPH_VIEW_UTIL_H
#define GRAPH_VIEW_UTIL_H
typedef enum {
SYMBOL_POINT,
SYMBOL_CROSS_1,
SYMBOL_CROSS_2,
SYMBOL_CIRCLE,
SYMBOL_FILLED_CIRCLE,
SYMBOL_SQUARE,
SYMBOL_FILLED_SQUARE,
SYMBOL_TRIANGLE,
SYMBOL_FILLED_TRIANGLE,
SYMBOL_LAST
} Symbol;
typedef struct {
GraphView *graph_view;
Graph *graph;
GdkDrawable *drawable;
GdkGC *gc;
int x, y;
int width, height;
int xl, yl;
/* Dimensions of our symbols, a rough idea of the size */
int dim;
/* Units per slot for columns and bars displays */
double units_per_slot;
/* Margin for column and bar displays */
int margin;
int inter_item_margin;
double scale;
} ViewDrawCtx;
Symbol symbol_setup (ViewDrawCtx *ctx, int series);
void symbol_draw (ViewDrawCtx *ctx, Symbol sym, int px, int py);
#define SETUP_VIEW_CTX(ctx,gv,d,vx,vy,w,h) \
ctx.x = vx;\
ctx.y = vy;\
ctx.width = w;\
ctx.height = h;\
ctx.drawable = d;\
ctx.graph_view = gv;\
ctx.graph = gv->graph;\
ctx.yl = gv->bbox.y1 - gv->bbox.y0;\
ctx.xl = gv->bbox.x1 - gv->bbox.x0;
/*
* Macros used by various plotting modes.
*
* Entry points:
*
* MAP_X(Context *ctx, double x)
* MAP_Y(Context *ctx, double y)
*
* The Column/Bar does not use this one, it uses ctx->scale, because it
* has to handle 2 different scaling systems depending on column or bar.
*/
/*
* Maps a pixel value in the 0..xl,0..yl ranges to an actual
* position in the canvas (ctx->{x,y} contains the offset of the pixmap
* we draw into).
*
* y axis also gets flipped.
*/
#define CANVAS_MAP_X(ctx,xv) ((xv) - ctx->x)
#define CANVAS_MAP_Y(ctx,yv) ((ctx->yl - yv) - ctx->y)
#define ADJUST_Y(ctx,y) (y - ctx->graph->low)
/*
* Maps a x,y coordinate to a pixel value
*/
#define MAP_X(ctx,xv) CANVAS_MAP_X (ctx, (((xv) * ctx->xl) / ctx->graph->x_size))
#define MAP_Y(ctx,yv) CANVAS_MAP_Y (ctx, (((ADJUST_Y (ctx,yv)) * ctx->yl) / ctx->graph->y_size))
#endif /* GRAPH_VIEW_UTIL_H */
......@@ -183,13 +183,9 @@ graph_view_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int
case GNOME_Graph_CHART_TYPE_CLUSTERED:
case GNOME_Graph_CHART_TYPE_STACKED:
case GNOME_Graph_CHART_TYPE_STACKED_FULL:
if (graph->plot_mode == GNOME_Graph_PLOT_COLBAR){
graph_view_colbar_draw (
graph_view, drawable,
x, y, width, height);
return;
}
graph_view_plot (graph_view, drawable, x, y, width, height);
graph_view_colbar_draw (
graph_view, drawable,
x, y, width, height);
break;
case GNOME_Graph_CHART_TYPE_BUBBLES:
......@@ -198,6 +194,9 @@ graph_view_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int
case GNOME_Graph_CHART_TYPE_SCATTER:
graph_view_scatter_plot (graph_view, drawable, x, y, width, height);
if (graph_view->graph->scatter_conn == GNOME_Graph_SCATTER_CONN_LINES)
graph_view_line_plot (graph_view, drawable, x, y, width, height);
break;
case GNOME_Graph_CHART_TYPE_SURFACE_2D:
......
......@@ -26,13 +26,14 @@ GNOME_Graph_Chart chart;
CORBA_Environment ev;
#define VECS 4
#define VECS 5
#define VECLEN 4
struct {
double data [4];
Vector *vector;
} vecs [VECS] = {
{ { 0.0, 1.0, 2.0, 3.0 }, NULL },
{ { 0.5, 8, 2, 5 }, NULL },
{ { 2, 3, 4, 5 }, NULL },
{ { 3, 4, 5, 2 }, NULL },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment