working graphs
This commit is contained in:
parent
8180ac3472
commit
ffcdcc6f9b
107
gui_graph_tab.c
107
gui_graph_tab.c
@ -19,10 +19,9 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <gtkdatabox.h>
|
#include <gtkdatabox.h>
|
||||||
|
#include <gtkdatabox_grid.h>
|
||||||
#include <gtkdatabox_lines.h>
|
#include <gtkdatabox_lines.h>
|
||||||
|
|
||||||
#include "tdc_variable.h"
|
#include "tdc_variable.h"
|
||||||
@ -57,7 +56,7 @@ struct xygraph {
|
|||||||
gfloat yarr[HISTORY];
|
gfloat yarr[HISTORY];
|
||||||
GdkColor *color;
|
GdkColor *color;
|
||||||
|
|
||||||
struct timeval base;
|
int last_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GdkColor * get_color(void)
|
static GdkColor * get_color(void)
|
||||||
@ -99,6 +98,7 @@ static void update_legend(void)
|
|||||||
tmp = g_string_new("");
|
tmp = g_string_new("");
|
||||||
g_list_foreach(graphlist, &update_legend_cb, tmp);
|
g_list_foreach(graphlist, &update_legend_cb, tmp);
|
||||||
|
|
||||||
|
/* strip last \n */
|
||||||
tmp->str[tmp->len -1] = 0x00;
|
tmp->str[tmp->len -1] = 0x00;
|
||||||
|
|
||||||
gtk_label_set_markup(GTK_LABEL(legend), tmp->str);
|
gtk_label_set_markup(GTK_LABEL(legend), tmp->str);
|
||||||
@ -136,6 +136,10 @@ gint gui_graphtab_init(GtkNotebook *notebook)
|
|||||||
GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
|
GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
|
||||||
gtk_databox_set_vruler(GTK_DATABOX(box), GTK_RULER(ruler));
|
gtk_databox_set_vruler(GTK_DATABOX(box), GTK_RULER(ruler));
|
||||||
|
|
||||||
|
GdkColor color = { .red = 0xC000, .green = 0xC000, .blue = 0xC000, };
|
||||||
|
GtkDataboxGraph *grid = gtk_databox_grid_new(10, 10, &color, 1);
|
||||||
|
gtk_databox_graph_add(GTK_DATABOX(box), grid);
|
||||||
|
|
||||||
legend = gtk_label_new(NULL);
|
legend = gtk_label_new(NULL);
|
||||||
gtk_table_attach(GTK_TABLE(table), legend, 1, 2, 3, 4, 0, 0, 10, 10);
|
gtk_table_attach(GTK_TABLE(table), legend, 1, 2, 3, 4, 0, 0, 10, 10);
|
||||||
|
|
||||||
@ -145,16 +149,6 @@ gint gui_graphtab_init(GtkNotebook *notebook)
|
|||||||
GtkWidget *button3 = gtk_button_new_with_label("Stopp");
|
GtkWidget *button3 = gtk_button_new_with_label("Stopp");
|
||||||
gtk_table_attach(GTK_TABLE(table), button3, 3, 4, 3, 4, 0, 0, 10, 10);
|
gtk_table_attach(GTK_TABLE(table), button3, 3, 4, 3, 4, 0, 0, 10, 10);
|
||||||
|
|
||||||
struct tdc_var *var = tdcvar_create(1, 0, "test", 4);
|
|
||||||
gui_graphtab_add_var(var);
|
|
||||||
gui_graphtab_add_var(var);
|
|
||||||
gui_graphtab_add_var(var);
|
|
||||||
gui_graphtab_add_var(var);
|
|
||||||
gui_graphtab_add_var(var);
|
|
||||||
gui_graphtab_add_var(var);
|
|
||||||
gui_graphtab_add_var(var);
|
|
||||||
gui_graphtab_add_var(var);
|
|
||||||
|
|
||||||
GtkWidget *label = gtk_label_new(" Graph ");
|
GtkWidget *label = gtk_label_new(" Graph ");
|
||||||
return gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label);
|
return gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label);
|
||||||
}
|
}
|
||||||
@ -170,18 +164,16 @@ int gui_graphtab_add_var(struct tdc_var *var)
|
|||||||
graph->var = var;
|
graph->var = var;
|
||||||
graph->color = color;
|
graph->color = color;
|
||||||
|
|
||||||
var->privdata_graphtab = graph;
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < HISTORY; i++) {
|
for (i = 0; i < HISTORY; i++) {
|
||||||
graph->xarr[i] = i - HISTORY;
|
graph->xarr[i] = i;
|
||||||
graph->yarr[i] = sin(((int)graph % 127) + i * 4 * M_PI / 1024);
|
graph->yarr[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var->privdata_graphtab = graph;
|
||||||
graphlist = g_list_append(graphlist, graph);
|
graphlist = g_list_append(graphlist, graph);
|
||||||
|
|
||||||
gtk_databox_graph_add(GTK_DATABOX(box), graph->graph);
|
gtk_databox_graph_add(GTK_DATABOX(box), graph->graph);
|
||||||
gtk_databox_auto_rescale(GTK_DATABOX(box), 0.05);
|
|
||||||
update_legend();
|
update_legend();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -190,18 +182,91 @@ int gui_graphtab_add_var(struct tdc_var *var)
|
|||||||
void gui_graphtab_remove_var(struct tdc_var *var)
|
void gui_graphtab_remove_var(struct tdc_var *var)
|
||||||
{
|
{
|
||||||
struct xygraph *graph = (struct xygraph *)var->privdata_graphtab;
|
struct xygraph *graph = (struct xygraph *)var->privdata_graphtab;
|
||||||
|
var->privdata_graphtab = NULL;
|
||||||
|
|
||||||
gtk_databox_graph_remove(GTK_DATABOX(box), graph->graph);
|
gtk_databox_graph_remove(GTK_DATABOX(box), graph->graph);
|
||||||
g_free(graph->graph);
|
|
||||||
free_color(graph->color);
|
free_color(graph->color);
|
||||||
|
|
||||||
graphlist = g_list_remove(graphlist, graph);
|
graphlist = g_list_remove(graphlist, graph);
|
||||||
graph->var->privdata_graphtab = NULL;
|
update_legend();
|
||||||
|
|
||||||
g_free(graph);
|
g_free(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int calc_index(struct timeval *base, struct timeval *now, int step)
|
||||||
|
{
|
||||||
|
struct timeval diff;
|
||||||
|
diff.tv_sec = now->tv_sec - base->tv_sec;
|
||||||
|
diff.tv_usec = now->tv_usec - base->tv_usec;
|
||||||
|
|
||||||
|
diff.tv_usec += diff.tv_sec * 1000000;
|
||||||
|
diff.tv_usec /= 1000;
|
||||||
|
|
||||||
|
return diff.tv_usec / step;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rescale_graphs(gboolean reset)
|
||||||
|
{
|
||||||
|
static GtkDataboxValue min;
|
||||||
|
static GtkDataboxValue max;
|
||||||
|
|
||||||
|
GtkDataboxValue tmp_min, tmp_max;
|
||||||
|
|
||||||
|
if (gtk_databox_calculate_extrema(GTK_DATABOX(box), &tmp_min, &tmp_max) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float swap = tmp_min.y;
|
||||||
|
tmp_min.y = tmp_max.y;
|
||||||
|
tmp_max.y = swap;
|
||||||
|
|
||||||
|
if (!reset) {
|
||||||
|
min.x = MIN(min.x, tmp_min.x);
|
||||||
|
min.y = MAX(min.y, tmp_min.y);
|
||||||
|
max.x = MAX(max.x, tmp_max.x);
|
||||||
|
max.y = MIN(max.y, tmp_max.y);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
min.x = tmp_min.x;
|
||||||
|
min.y = tmp_min.y;
|
||||||
|
max.x = tmp_max.x;
|
||||||
|
max.y = tmp_max.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_databox_set_canvas(GTK_DATABOX(box), min, max);
|
||||||
|
}
|
||||||
|
|
||||||
void gui_graphtab_update_var(struct tdc_var *var)
|
void gui_graphtab_update_var(struct tdc_var *var)
|
||||||
{
|
{
|
||||||
|
static struct timeval base, update;
|
||||||
|
|
||||||
struct xygraph *graph = (struct xygraph *)var->privdata_graphtab;
|
struct xygraph *graph = (struct xygraph *)var->privdata_graphtab;
|
||||||
// do some updates, i think
|
|
||||||
|
struct timeval now;
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
|
||||||
|
int i = calc_index(&base, &now, 10);
|
||||||
|
if (i < 0 || i >= HISTORY) {
|
||||||
|
base.tv_sec = now.tv_sec;
|
||||||
|
base.tv_usec = now.tv_usec;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float last_value = graph->yarr[graph->last_index];
|
||||||
|
while (graph->last_index != i) {
|
||||||
|
graph->last_index++;
|
||||||
|
if (graph->last_index == HISTORY)
|
||||||
|
graph->last_index = 0;
|
||||||
|
|
||||||
|
graph->yarr[graph->last_index] = last_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
graph->yarr[i] = tdcvar_get_double(var);
|
||||||
|
|
||||||
|
if (calc_index(&update, &now, 100) != 0) {
|
||||||
|
update.tv_sec = now.tv_sec;
|
||||||
|
update.tv_usec = now.tv_usec;
|
||||||
|
|
||||||
|
rescale_graphs(FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "tdc_parser.h"
|
#include "tdc_parser.h"
|
||||||
#include "tdc_proto.h"
|
#include "tdc_proto.h"
|
||||||
|
|
||||||
|
#include "gui_graph_tab.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
COL_ID = 0, /* UINT */
|
COL_ID = 0, /* UINT */
|
||||||
COL_GRAPH, /* BOOLEAN */
|
COL_GRAPH, /* BOOLEAN */
|
||||||
@ -52,14 +54,23 @@ static void cell_graph_toggle(GtkCellRendererToggle *cell,
|
|||||||
COL_VALUE, &var,
|
COL_VALUE, &var,
|
||||||
-1);
|
-1);
|
||||||
|
|
||||||
if (var->flags & TDC_GUI_GRAPH)
|
if (var->flags & TDC_GUI_GRAPH) {
|
||||||
var->flags &= ~TDC_GUI_GRAPH;
|
var->flags &= ~TDC_GUI_GRAPH;
|
||||||
else
|
|
||||||
|
if (var->privdata_graphtab != NULL)
|
||||||
|
gui_graphtab_remove_var(var);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (var->privdata_graphtab == NULL)
|
||||||
|
/* bailout if no new graph allowed */
|
||||||
|
if (gui_graphtab_add_var(var) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
var->flags |= TDC_GUI_GRAPH;
|
var->flags |= TDC_GUI_GRAPH;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: assuming board 1
|
// FIXME: assuming board 1
|
||||||
tdcstore_graph_refresh(1, -1);
|
tdcstore_graph_refresh(1, -1);
|
||||||
printf("cell_graph_toggle(%d)\n", var->id);
|
|
||||||
|
|
||||||
gtk_list_store_set(GTK_LIST_STORE(user_data), &it,
|
gtk_list_store_set(GTK_LIST_STORE(user_data), &it,
|
||||||
COL_GRAPH, !toggle,
|
COL_GRAPH, !toggle,
|
||||||
|
@ -156,7 +156,7 @@ static int tdcparser_parse(void)
|
|||||||
|
|
||||||
tdcstore_create_board(address, pkt->name);
|
tdcstore_create_board(address, pkt->name);
|
||||||
tdcstore_refresh_values(address, 250);
|
tdcstore_refresh_values(address, 250);
|
||||||
tdcstore_graph_refresh(address, 50);
|
tdcstore_graph_refresh(address, 20);
|
||||||
tdcparser_send_getvars(address);
|
tdcparser_send_getvars(address);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -232,6 +232,41 @@ int tdcvar_parse_value(struct tdc_var *var, char *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double tdcvar_get_double(struct tdc_var *var)
|
||||||
|
{
|
||||||
|
switch (var->flags & TDC_TYPEMASK) {
|
||||||
|
case TDC_UNSIGNED:
|
||||||
|
switch (var->flags & TDC_SIZEMASK) {
|
||||||
|
case 1: return var->data_uint8;
|
||||||
|
case 2: return var->data_uint16;
|
||||||
|
case 4: return var->data_uint32;
|
||||||
|
case 8: return var->data_uint64;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TDC_SIGNED:
|
||||||
|
switch (var->flags & TDC_SIZEMASK) {
|
||||||
|
case 1: return (int8_t)var->data_uint8;
|
||||||
|
case 2: return (int16_t)var->data_uint16;
|
||||||
|
case 4: return (int32_t)var->data_uint32;
|
||||||
|
case 8: return (int64_t)var->data_uint64;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TDC_FP:
|
||||||
|
case TDC_FP | 0x100:
|
||||||
|
switch (var->flags & TDC_SIZEMASK) {
|
||||||
|
case sizeof(float):
|
||||||
|
return var->data_float;
|
||||||
|
|
||||||
|
case sizeof(double):
|
||||||
|
return var->data_double;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
struct tdc_var * tdcvar_create(int id, uint32_t flags, char *name, int len)
|
struct tdc_var * tdcvar_create(int id, uint32_t flags, char *name, int len)
|
||||||
{
|
{
|
||||||
struct tdc_var *var = g_malloc0(sizeof(struct tdc_var) + len + 1);
|
struct tdc_var *var = g_malloc0(sizeof(struct tdc_var) + len + 1);
|
||||||
|
@ -24,6 +24,7 @@ struct tdc_var {
|
|||||||
void tdcvar_get_value(struct tdc_var *var, char *buf, int size, int viewmode);
|
void tdcvar_get_value(struct tdc_var *var, char *buf, int size, int viewmode);
|
||||||
void tdcvar_get_type(struct tdc_var *var, char *buf, int size);
|
void tdcvar_get_type(struct tdc_var *var, char *buf, int size);
|
||||||
int tdcvar_parse_value(struct tdc_var *var, char *data);
|
int tdcvar_parse_value(struct tdc_var *var, char *data);
|
||||||
|
double tdcvar_get_double(struct tdc_var *var);
|
||||||
|
|
||||||
struct tdc_var * tdcvar_create(int id, uint32_t flags, char *name, int len);
|
struct tdc_var * tdcvar_create(int id, uint32_t flags, char *name, int len);
|
||||||
void tdcvar_update(struct tdc_var *var, uint8_t *data, int len);
|
void tdcvar_update(struct tdc_var *var, uint8_t *data, int len);
|
||||||
|
Loading…
Reference in New Issue
Block a user