added [t]rack bindkey in graph to display the wave closest to mouse in multiple dataset plots

This commit is contained in:
Stefan Frederik 2022-09-02 17:11:50 +02:00
parent ad152b24a3
commit ae1bed65f4
4 changed files with 158 additions and 6 deletions

View File

@ -471,6 +471,25 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
}
}
}
else if((key == 't') ) {
int dset = -1;
if(!gr->digital && i == xctx->graph_master) {
const char *d = get_tok_value(r->prop_ptr, "dataset", 0);
if(d[0]) {
dset = atoi(d);
} else {
dset = -1;
}
if(dset >= 0) {
my_strdup(1448, &r->prop_ptr, subst_token(r->prop_ptr, "dataset", "-1"));
} else {
dset = find_closest_wave(i, gr);
my_strdup(1448, &r->prop_ptr, subst_token(r->prop_ptr, "dataset", my_itoa(dset)));
}
need_redraw = 1;
}
} /* key == 't' */
else if(key == XK_Left) {
double delta;
if(xctx->graph_left) {
@ -483,7 +502,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
yy2 = gr->gy2 + var * b / delta;
yy1 = gr->gy1 - var * a / delta;
my_strdup(1451, &r->prop_ptr, subst_token(r->prop_ptr, "y1", dtoa(yy1)));
my_strdup(1448, &r->prop_ptr, subst_token(r->prop_ptr, "y2", dtoa(yy2)));
my_strdup(1517, &r->prop_ptr, subst_token(r->prop_ptr, "y2", dtoa(yy2)));
need_redraw = 1;
}
} else {
@ -1487,6 +1506,10 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
}
if(key=='t' && state == 0) /* place text */
{
if(waves_selected(event, state, button)) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
if(xctx->semaphore >= 2) break;
xctx->last_command = 0;
xctx->mx_double_save = xctx->mousex_snap;

View File

@ -2506,6 +2506,134 @@ int calc_custom_data_yrange(int sweep_idx, const char *express, Graph_ctx *gr)
return idx;
}
int find_closest_wave(int i, Graph_ctx *gr)
{
double xval, yval;
char *node = NULL, *sweep = NULL;
int sweep_idx = 0;
char *saven, *saves, *nptr, *sptr;
const char *ntok, *stok;
int wcnt = 0, idx, expression;
char *express = NULL;
xRect *r = &xctx->rect[GRIDLAYER][i];
int closest_dataset = -1;
double min=-1.0;
if(gr->digital) return -1;
yval = G_Y(xctx->mousey);
xval = G_X(xctx->mousex);
if(gr->logx) xval = pow(10, xval);
if(gr->logy) yval = pow(10, yval);
dbg(0, "x=%g y=%g\n", xval, yval);
/* get data to plot */
my_strdup2(474, &node, get_tok_value(r->prop_ptr,"node",0));
my_strdup2(1012, &sweep, get_tok_value(r->prop_ptr,"sweep",0));
nptr = node;
sptr = sweep;
/* process each node given in "node" attribute, get also associated sweep var if any*/
while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", &saven)) ) {
if(strstr(ntok, ",")) {
if(find_nth(ntok, ";,", 2)[0]) continue; /* bus signal: skip */
}
stok = my_strtok_r(sptr, "\t\n ", "\"", &saves);
nptr = sptr = NULL;
dbg(1, "ntok=%s\n", ntok);
if(stok && stok[0]) {
sweep_idx = get_raw_index(stok);
if( sweep_idx == -1) {
sweep_idx = 0;
}
}
/* if ntok following possible 'alias;' definition contains spaces --> custom data plot */
idx = -1;
expression = 0;
if(xctx->graph_values) {
if(strstr(ntok, ";")) {
my_strdup2(1191, &express, find_nth(ntok, ";", 2));
} else {
my_strdup2(1192, &express, ntok);
}
if(strstr(express, " ")) {
expression = 1;
}
}
if(expression) idx = plot_raw_custom_data(sweep_idx, 0, xctx->graph_allpoints-1, express);
else idx = get_raw_index(express);
if( idx != -1 ) {
int p, dset, ofs;
int first, last;
double xx, yy ; /* the p-th point */
double start;
double end;
int sweepvar_wrap = 0; /* incremented on new dataset or sweep variable wrap */
ofs = 0;
start = (gr->gx1 <= gr->gx2) ? gr->gx1 : gr->gx2;
end = (gr->gx1 <= gr->gx2) ? gr->gx2 : gr->gx1;
/* loop through all datasets found in raw file */
for(dset = 0 ; dset < xctx->graph_datasets; dset++) {
double prev_x, prev_prev_x;
int cnt=0, wrap;
register SPICE_DATA *gvx = xctx->graph_values[sweep_idx];
register SPICE_DATA *gvy = xctx->graph_values[idx];
first = -1;
/* Process "npoints" simulation items
* p loop split repeated 2 timed (for x and y points) to preserve cache locality */
prev_prev_x = prev_x = 0;
last = ofs;
for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) {
if(gr->logx) xx = mylog10(gvx[p]);
else xx = gvx[p];
if(gr->logy) yy = mylog10(gvy[p]);
else yy = gvy[p];
wrap = (sweep_idx == 0 && cnt > 1 && XSIGN(xx - prev_x) != XSIGN(prev_x - prev_prev_x));
if(first != -1) {
if(xx > end || xx < start || wrap) {
dbg(1, "find_closest_wave(): last=%d\n", last);
first = -1;
}
}
if(wrap) {
cnt = 0;
sweepvar_wrap++;
}
if(xx >= start && xx <= end) {
if(first == -1) first = p;
if( XSIGN(xval - xx) != XSIGN(xval - prev_x)) {
if(min < 0.0) {
min = fabs(yval - yy);
closest_dataset = sweepvar_wrap;
} else {
double tmp = fabs(yval - yy);
if(tmp < min) {
min = tmp;
closest_dataset = sweepvar_wrap;
}
}
dbg(1, "find_closest_wave(): xval=%g yval=%g xx=%g yy=%g sweepvar_wrap=%d ntok=%s\n",
xval, yval, xx, yy, sweepvar_wrap, ntok);
}
last = p;
cnt++;
} /* if(xx >= start && xx <= end) */
prev_prev_x = prev_x;
prev_x = xx;
} /* for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) */
/* offset pointing to next dataset */
ofs += xctx->graph_npoints[dset];
sweepvar_wrap++;
} /* for(dset...) */
} /* if( (idx = get_raw_index(ntok)) != -1 ) */
wcnt++;
} /* while( (ntok = my_strtok_r(nptr, "\n\t ", "", &saven)) ) */
dbg(0, "closest dataset=%d\n", closest_dataset);
if(express) my_free(1487, &express);
my_free(478, &node);
my_free(1262, &sweep);
return closest_dataset;
}
/* flags:
@ -2581,9 +2709,9 @@ void draw_graph(int i, const int flags, Graph_ctx *gr)
expression = 0;
if(xctx->graph_values && !bus_msb) {
if(strstr(ntok, ";")) {
my_strdup2(1191, &express, find_nth(ntok, ";", 2));
my_strdup2(460, &express, find_nth(ntok, ";", 2));
} else {
my_strdup2(1192, &express, ntok);
my_strdup2(473, &express, ntok);
}
if(strstr(express, " ")) {
expression = 1;
@ -2696,11 +2824,11 @@ void draw_graph(int i, const int flags, Graph_ctx *gr)
my_free(1403, &point);
if(idx_arr) my_free(1455, &idx_arr);
} /* if( (idx = get_raw_index(bus_msb ? bus_msb : ntok)) != -1 ) */
} /* if( expression || (idx = get_raw_index(bus_msb ? bus_msb : express)) != -1 ) */
wcnt++;
if(bus_msb) my_free(1453, &bus_msb);
} /* while( (ntok = my_strtok_r(nptr, "\n\t ", "", &saven)) ) */
if(express) my_free(1487, &express);
if(express) my_free(1520, &express);
my_free(1391, &node);
my_free(1392, &color);
my_free(1408, &sweep);

View File

@ -121,7 +121,7 @@ void hash_all_names(int n)
for(i=0; i<xctx->instances; i++) {
has_fmt_attr = get_tok_value((xctx->inst[i].ptr + xctx->sym)->prop_ptr, fmt_attr, 2)[0] ? 1 : 0;
if(xctx->inst[i].instname && xctx->inst[i].instname[0]) {
my_strdup(1519, &type,(xctx->inst[i].ptr+ xctx->sym)->type);
my_strdup(1526, &type,(xctx->inst[i].ptr+ xctx->sym)->type);
if(!type || !has_fmt_attr || IS_LABEL_SH_OR_PIN(type) ) continue;
my_strdup(1254, &upinst, xctx->inst[i].instname);
strtoupper(upinst);

View File

@ -1041,6 +1041,7 @@ extern int calc_custom_data_yrange(int sweep_idx, const char *express, Graph_ctx
extern int schematic_waves_loaded(void);
extern int edit_wave_attributes(int what, int i, Graph_ctx *gr);
extern void draw_graph(int i, int flags, Graph_ctx *gr);
extern int find_closest_wave(int i, Graph_ctx *gr);
extern void setup_graph_data(int i, const int flags, int skip, Graph_ctx *gr);
extern double timer(int start);
extern void enable_layers(void);