implement zoom/move/full on y axis graphs

This commit is contained in:
Stefan Frederik 2021-12-25 13:37:49 +01:00
parent 907005e7e3
commit 1f44a960cb
5 changed files with 259 additions and 70 deletions

View File

@ -167,15 +167,16 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
double wx2 = 8e-6;
double wy2 = 4;
double x1, y1, x2, y2, marginx, marginy;
double cx;
double cx, dx, cy;
int divx = 10;
int divy = 5;
const char *val;
char s[30];
int n, c, i;
double xx1, xx2;
double xx1, xx2, yy1, yy2;
int need_redraw = 0;
double delta_threshold = 0.25;
int dataset = 0;
#if HAS_CAIRO==1
cairo_save(xctx->cairo_ctx);
@ -203,74 +204,247 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
if(val[0]) wx2 = atof(val);
val = get_tok_value(xctx->rect[c][n].prop_ptr,"y2",0);
if(val[0]) wy2 = atof(val);
val = get_tok_value(xctx->rect[c][n].prop_ptr,"dataset",0);
if(val[0]) dataset = atoi(val);
if(dataset >= xctx->datasets) dataset = xctx->datasets - 1;
calc_graph_area(c, n, &x1, &y1, &x2, &y2, &marginx, &marginy);
/* cache coefficients for faster graph coord transformations */
cx = (x2 - x1) / (wx2 - wx1);
dx = x1 - wx1 * cx;
cy = (y1 - y2) / (wy2 - wy1);
dbg(1, "%g %g %g %g - %d %d\n", wx1, wy1, wx2, wy2, divx, divy);
}
if(event == MotionNotify && (state & Button2Mask)) {
double delta = (wx2 - wx1) / divx;
dbg(1, "waves_callback: Motion: %g %g --> %g %g\n",
xctx->mx_double_save, xctx->my_double_save, xctx->mousex_snap, xctx->mousey_snap);
delta_threshold = 0.10;
if(fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(cx * delta) * delta_threshold) {
xx1 = wx1 + (xctx->mx_double_save - xctx->mousex_snap) / cx;
xx2 = wx2 + (xctx->mx_double_save - xctx->mousex_snap) / cx;
if(i >= xctx->lastsel -1) { /* update saved mouse position after processing all graphs */
xctx->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap;
double delta;
if(xctx->mousex_snap < W_X(wx1)) {
delta = (wy2 - wy1) / divy;
delta_threshold = 0.10;
if(fabs(xctx->my_double_save - xctx->mousey_snap) > fabs(cy * delta) * delta_threshold) {
yy1 = wy1 + (xctx->my_double_save - xctx->mousey_snap) / cy;
yy2 = wy2 + (xctx->my_double_save - xctx->mousey_snap) / cy;
if(i >= xctx->lastsel -1) { /* update saved mouse position after processing all graphs */
xctx->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap;
}
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1424, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1425, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
need_redraw = 1;
}
} else {
delta = (wx2 - wx1) / divx;
delta_threshold = 0.10;
if(fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(cx * delta) * delta_threshold) {
xx1 = wx1 + (xctx->mx_double_save - xctx->mousex_snap) / cx;
xx2 = wx2 + (xctx->mx_double_save - xctx->mousex_snap) / cx;
if(i >= xctx->lastsel -1) { /* update saved mouse position after processing all graphs */
xctx->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap;
}
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1410, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1411, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
need_redraw = 1;
}
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1410, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1411, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
need_redraw = 1;
}
}
else if(key == XK_Left || (button == Button5 && state == 0)) {
double delta = (wx2 - wx1) / divx;
delta_threshold = 2.0;
xx1 = wx1 - delta * delta_threshold;
xx2 = wx2 - delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1395, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1396, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
else if((button == Button5 && state == 0)) {
double delta;
if(xctx->mousex_snap < W_X(wx1)) {
delta = (wy2 - wy1) / divy;
delta_threshold = 1.0;
yy1 = wy1 + delta * delta_threshold;
yy2 = wy2 + delta * delta_threshold;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1420, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1421, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1) / divx;
delta_threshold = 1.0;
xx1 = wx1 - delta * delta_threshold;
xx2 = wx2 - delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1395, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1396, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(key == XK_Right || (button == Button4 && state == 0)) {
double delta = (wx2 - wx1) / divx;
delta_threshold = 2.0;
xx1 = wx1 + delta * delta_threshold;
xx2 = wx2 + delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1397, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1398, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
else if(key == XK_Left) {
double delta;
if(xctx->mousex_snap < W_X(wx1)) {
delta = (wy2 - wy1);
yy2 = wy2 + delta * 0.1;
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1419, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1) / divx;
delta_threshold = 1.0;
xx1 = wx1 - delta * delta_threshold;
xx2 = wx2 - delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1395, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1396, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(key == XK_Down || (button == Button5 && state == ShiftMask)) {
double delta = (wx2 - wx1);
xx2 = wx2 + delta * 0.1;
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1399, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
else if(button == Button4 && state == 0) {
double delta;
if(xctx->mousex_snap < W_X(wx1)) {
delta = (wy2 - wy1) / divy;
delta_threshold = 1.0;
yy1 = wy1 - delta * delta_threshold;
yy2 = wy2 - delta * delta_threshold;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1416, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1417, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1) / divx;
delta_threshold = 1.0;
xx1 = wx1 + delta * delta_threshold;
xx2 = wx2 + delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1397, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1398, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(key == XK_Up || (button == Button4 && state == ShiftMask)) {
double delta = (wx2 - wx1);
xx2 = wx2 - delta * 0.1;
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1400, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
else if(key == XK_Right) {
double delta;
if(xctx->mousex_snap < W_X(wx1)) {
delta = (wy2 - wy1);
yy2 = wy2 - delta * 0.1;
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1418, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1) / divx;
delta_threshold = 1.0;
xx1 = wx1 + delta * delta_threshold;
xx2 = wx2 + delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1397, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1398, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(button == Button5 && state == ShiftMask) {
double delta;
if(xctx->mousex_snap < W_X(wx1)) {
delta = (wy2 - wy1);
yy2 = wy2 + delta * 0.1;
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1419, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1);
xx2 = wx2 + delta * 0.1;
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1399, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(key == XK_Down) {
double delta;
if(xctx->mousex_snap < W_X(wx1)) {
delta = (wy2 - wy1) / divy;
delta_threshold = 1.0;
yy1 = wy1 - delta * delta_threshold;
yy2 = wy2 - delta * delta_threshold;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1420, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1421, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1);
xx2 = wx2 + delta * 0.1;
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1399, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(button == Button4 && state == ShiftMask) {
double delta;
if(xctx->mousex_snap < W_X(wx1)) {
delta = (wy2 - wy1);
yy2 = wy2 - delta * 0.1;
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1418, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1);
xx2 = wx2 - delta * 0.1;
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1400, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(key == XK_Up) {
double delta;
if(xctx->mousex_snap < W_X(wx1)) {
delta = (wy2 - wy1) / divy;
delta_threshold = 1.0;
yy1 = wy1 + delta * delta_threshold;
yy2 = wy2 + delta * delta_threshold;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1416, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1417, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1);
xx2 = wx2 - delta * 0.1;
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1400, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(key == 'f') {
if(xctx->values) {
xx1 = 0.0;
xx2 = xctx->values[0][xctx->npoints[0] -1];
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1409, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1412, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
if(xctx->mousex_snap < W_X(wx1)) {
int i, j;
double v;
double min, max;
char *saven, *nptr, *ntok, *node = NULL;;
my_strdup2(1426, &node, get_tok_value(xctx->rect[c][n].prop_ptr,"node",0));
nptr = node;
while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) {
nptr = NULL;
j = get_raw_index(ntok);
if(j >= 0) {
for(i = 0; i < xctx->npoints[dataset]; i++) {
v = get_raw_value(dataset, j, i);
if(i == 0 || v < min) min = v;
if(i == 0 || v > max) max = v;
}
if(max == min) max += 0.01;
}
}
my_free(1427, &node);
my_snprintf(s, S(s), "%g", min);
my_strdup(1422, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", max);
my_strdup(1423, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
} else {
xx1 = 0; /* get_raw_value(dataset, 0, 0); */
xx2 = get_raw_value(dataset, 0, xctx->npoints[dataset] -1);
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1409, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1412, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
}
need_redraw = 1;
}
}

View File

@ -1651,7 +1651,23 @@ int read_rawfile(const char *f)
dbg(0, "read_rawfile(): failed to open file %s for reading\n", f);
return 0;
}
int get_raw_index(const char *node)
{
struct int_hashentry *entry;
entry = int_hash_lookup(xctx->raw_table, node, 0, XLOOKUP);
if(entry) return entry->value;
return -1;
}
double get_raw_value(int dataset, int idx, int point)
{
int i, ofs;
ofs = 0;
for(i = 0; i < dataset; i++) {
ofs += xctx->npoints[i];
}
return xctx->values[idx][ofs + point];
}
void calc_graph_area(int c, int i, double *x1, double *y1,double *x2,double *y2,
double *marginx, double *marginy)
{
@ -1936,9 +1952,8 @@ void draw_graph(int c, int i, int flags)
dbg(1, "ntok=%s ctok=%s\n", ntok, ctok? ctok: "NULL");
if(ctok && ctok[0]) wave_color = atoi(ctok);
if(stok && stok[0]) {
entry = int_hash_lookup(xctx->raw_table, stok, 0, XLOOKUP);
if(entry && entry->value) sweep_idx = entry->value;
else sweep_idx = 0;
sweep_idx = get_raw_index(stok);
if( sweep_idx == -1) sweep_idx = 0;
}
/* draw sweep variable(s) on x-axis */
if(wcnt == 0 || (stok && stok[0])) {

View File

@ -1944,30 +1944,28 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
{
int i;
char s[30];
int dataset = 0;
cmd_found = 1;
Tcl_ResetResult(interp);
if(xctx->values) {
if(argc > 5) dataset = atoi(argv[5]);
if(argc > 4) {
/* xschem rawfile_query value v(ldcp) 123 */
if(!strcmp(argv[2], "value")) {
struct int_hashentry *entry;
int point = atoi(argv[4]);
const char *node = argv[3];
int idx = -1;
if(point >= 0 && point < xctx->npoints[0]) {
if(point >= 0 && point < xctx->npoints[dataset]) {
if(isonlydigit(node)) {
int i = atoi(node);
if(i >= 0 && i < xctx->nvars) {
idx = i;
}
} else {
entry = int_hash_lookup(xctx->raw_table, node, 0, XLOOKUP);
if(entry) {
idx = entry->value;
}
idx = get_raw_index(node);
}
if(idx >= 0) {
double val = xctx->values[idx][point];
double val = get_raw_value(dataset, idx, point);
my_snprintf(s, S(s), "%g", val);
Tcl_AppendResult(interp, s, NULL);
}

View File

@ -894,6 +894,8 @@ extern char cli_opt_netlist_dir[PATH_MAX];
extern Xschem_ctx *xctx;
/* FUNCTIONS */
extern int get_raw_index(const char *node);
extern double get_raw_value(int dataset, int idx, int point);
extern int schematic_waves_loaded(void);
extern void calc_graph_area(int c, int i, double *x1, double *y1,double *x2, double *y2,
double *marginx,double *marginy);

View File

@ -19,21 +19,21 @@ L 4 570 -170 570 -150 {}
L 4 570 -170 690 -170 {}
L 7 1090 -260 2520 -260 {}
B 2 260 -1080 720 -920 {flags=1
y1 = 0
y2 = 1
y1 = 0.00676696
y2 = 0.922682
divy = 5
x1=1.25e-07
x2=3.75e-07
x1=0
x2=5e-07
divx=10
node="v(cal) v(saout)"
color="4 5"
}
B 2 260 -1220 720 -1090 {flags=1
y1 = 0.645
y2 = 0.655
divy = 10
x1=1.25e-07
x2=3.75e-07
y1 = 0.648
y2 = 0.652
divy = 5
x1=0
x2=5e-07
divx=5
node="v(plus) v(minus)"
color="4 5"}