Add vertical waveforms legend option in graphs (V. legend checkbox)

This commit is contained in:
stefan schippers 2026-03-02 15:35:05 +01:00
parent e537320e78
commit 347ce951a7
3 changed files with 119 additions and 10 deletions

View File

@ -3264,6 +3264,9 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
gr->legend = 1;
val = get_tok_value(r->prop_ptr,"legend", 0);
if(val[0]) gr->legend = atoi(val);
gr->vlegend = 0;
val = get_tok_value(r->prop_ptr,"vlegend", 0);
if(val[0]) gr->vlegend = atoi(val);
/* draw mode (0: Line, 1: Histo. Default: Line) */
val = get_tok_value(r->prop_ptr,"mode", 0);
@ -3519,7 +3522,6 @@ static void draw_graph_variables(int wcnt, int wave_color, int n_nodes, int swee
int flags, const char *ntok, const char *stok, const char *bus_msb, Graph_ctx *gr)
{
char tmpstr[1024];
/* clipping everything outside container area */
bbox(START, 0.0, 0.0, 0.0, 0.0);
bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2);
@ -3558,7 +3560,35 @@ static void draw_graph_variables(int wcnt, int wave_color, int n_nodes, int swee
my_free(_ALLOC_ID_, &alias_ptr);
my_free(_ALLOC_ID_, &ntok_ptr);
}
if(gr->digital) {
if(gr->vlegend && !gr->digital) {
double xt = gr->rx1 + 5;
double yt;
yt = gr->y1 + (double)wcnt / (double)n_nodes * (gr->h) ;
if(!(flags & 2)) { /* NOT cursor1 with measures */
#if HAS_CAIRO == 1
if(gr->hilight_wave == wcnt) {
xctx->cairo_font =
cairo_toy_font_face_create("Sans-Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_face(xctx->cairo_ctx, xctx->cairo_font);
cairo_set_font_face(xctx->cairo_save_ctx, xctx->cairo_font);
cairo_font_face_destroy(xctx->cairo_font);
}
#endif
dbg(0, "%g %g %s\n", xt, yt, tmpstr);
my_snprintf(tmpstr, S(tmpstr), "%s", str_replace(tmpstr, "\\ ", " ", 0, -1));
draw_string(wave_color, NOW, tmpstr, 0, 0, 0, 0,
xt, yt, gr->txtsizey * gr->magy * 0.5, gr->txtsizey * gr->magy * 0.5);
#if HAS_CAIRO == 1
if(gr->hilight_wave == wcnt) {
xctx->cairo_font =
cairo_toy_font_face_create("Sans-Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_face(xctx->cairo_ctx, xctx->cairo_font);
cairo_set_font_face(xctx->cairo_save_ctx, xctx->cairo_font);
cairo_font_face_destroy(xctx->cairo_font);
}
#endif
}
} else if(gr->digital) {
double xt = gr->x1 - 15 * gr->txtsizelab;
double s1 = DIG_NWAVES; /* 1/DIG_NWAVES waveforms fit in graph if unscaled vertically */
double s2 = DIG_SPACE; /* (DIG_NWAVES - DIG_SPACE) spacing between traces */
@ -3622,7 +3652,7 @@ static void show_node_measures(int measure_p, double measure_x, double measure_p
const char *bus_msb, int wave_color, int idx, SPICE_DATA **idx_arr,
int n_bits, int n_nodes, const char *ntok, int wcnt, Graph_ctx *gr, xRect *r, double cursor1)
{
char tmpstr[1024];
char tmpstr[1024] = "";
double yy;
/* show values of signals if cursor1 active */
if(idx == -1) return;
@ -3632,8 +3662,17 @@ static void show_node_measures(int measure_p, double measure_x, double measure_p
}
if(!gr->legend && !gr->digital) return;
if(measure_p >= 0) {
/* draw node values in graph */
char *ntok_ptr = NULL;
char *alias_ptr = NULL;
if(strstr(ntok, ";")) {
my_strdup2(_ALLOC_ID_, &alias_ptr, find_nth(ntok, ";", "\"", 0, 1));
my_strdup2(_ALLOC_ID_, &ntok_ptr, find_nth(ntok, ";", "\"", 0, 2));
}
else {
my_strdup2(_ALLOC_ID_, &alias_ptr, ntok);
my_strdup2(_ALLOC_ID_, &ntok_ptr, ntok);
}
bbox(START, 0.0, 0.0, 0.0, 0.0);
bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2);
bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0);
@ -3643,6 +3682,7 @@ static void show_node_measures(int measure_p, double measure_x, double measure_p
char *fmt1, *fmt2;
double yy1;
if( gr->logx) cursor1 = mylog10(cursor1);
yy1 = xctx->raw->values[idx][measure_p-1];
diffy = xctx->raw->values[idx][measure_p] - yy1;
@ -3665,7 +3705,34 @@ static void show_node_measures(int measure_p, double measure_x, double measure_p
vthl = gr->gy1 * 0.8 + gr->gy2 * 0.2;
get_bus_value(n_bits, hex_digits, idx_arr, measure_p - 1, tmpstr, vthl, vthh);
}
if(!bus_msb && !gr->digital) {
if(gr->vlegend && !gr->digital) {
char str[1024];
double xt = gr->rx1 + 5;
double yt = gr->y1 + (double)wcnt / (double)n_nodes * (gr->h) ;
if(!bus_msb) my_snprintf(str, S(str), "%s (%s)", alias_ptr, tmpstr);
else my_snprintf(str, S(str), "%s", alias_ptr);
#if HAS_CAIRO == 1
if(gr->hilight_wave == wcnt) {
xctx->cairo_font =
cairo_toy_font_face_create("Sans-Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_face(xctx->cairo_ctx, xctx->cairo_font);
cairo_set_font_face(xctx->cairo_save_ctx, xctx->cairo_font);
cairo_font_face_destroy(xctx->cairo_font);
}
#endif
draw_string(wave_color, NOW, str, 0, 0, 0, 0,
xt, yt, gr->txtsizey * gr->magy * 0.5, gr->txtsizey * gr->magy * 0.5);
#if HAS_CAIRO == 1
if(gr->hilight_wave == wcnt) {
xctx->cairo_font =
cairo_toy_font_face_create("Sans-Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_face(xctx->cairo_ctx, xctx->cairo_font);
cairo_set_font_face(xctx->cairo_save_ctx, xctx->cairo_font);
cairo_font_face_destroy(xctx->cairo_font);
}
#endif
} else if(!bus_msb && !gr->digital) {
draw_string(wave_color, NOW, tmpstr, 0, 0, 0, 0,
gr->rx1 + 2 + gr->rw / n_nodes * wcnt, gr->ry1 + gr->txtsizelab * 60,
gr->txtsizelab * 0.8, gr->txtsizelab * 0.8);
@ -3682,6 +3749,8 @@ static void show_node_measures(int measure_p, double measure_x, double measure_p
}
}
bbox(END, 0.0, 0.0, 0.0, 0.0);
my_free(_ALLOC_ID_, &alias_ptr);
my_free(_ALLOC_ID_, &ntok_ptr);
} /* if(measure_p >= 0) */
}
@ -3739,7 +3808,33 @@ int edit_wave_attributes(int what, int i, Graph_ctx *gr)
sweep_idx = get_raw_index(stok, NULL);
if( sweep_idx == -1) sweep_idx = 0;
}
if(gr->digital) {
if(gr->vlegend && !gr->digital) {
double xt1 = gr->rx1 + 5;
double xt2 = gr->x1 - 5;
double yt1 = gr->y1 + (double)wcnt / (double)n_nodes * (gr->h);
double yt2 = yt1 + 1.0 / (double)n_nodes * (gr->h);
if(POINTINSIDE(xctx->mousex_snap, xctx->mousey_snap, xt1, yt1, xt2, yt2)) {
char s[30];
ret = 1;
if(what == 1) {
int save = gr->hilight_wave;
my_snprintf(s, S(s), "%d %d", i, wcnt);
gr->hilight_wave = wcnt;
tclvareval("graph_edit_wave ", s, NULL);
gr->hilight_wave = save;
} else {
if(gr->hilight_wave == wcnt) {
gr->hilight_wave = -1;
my_strdup2(_ALLOC_ID_, &r->prop_ptr,
subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
} else {
gr->hilight_wave = wcnt;
my_strdup2(_ALLOC_ID_, &r->prop_ptr,
subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
}
}
}
} else if(gr->digital) {
double xt1 = gr->rx1; /* <-- waves_selected() is more restrictive than this */
double xt2 = gr->x1 - 20 * gr->txtsizelab;
double s1 = DIG_NWAVES; /* 1/DIG_NWAVES waveforms fit in graph if unscaled vertically */

View File

@ -872,6 +872,7 @@ typedef struct
typedef struct {
int digital;
int legend; /* display graph legend */
int vlegend; /* vertical legend */
double rx1, ry1, rx2, ry2, rw, rh; /* container rectangle, xschem coordinates */
double sx1, sy1, sx2, sy2; /* screen coordinates of above */
/* graph box (smaller than rect container due to margins) in xschem coordinates*/

View File

@ -3411,7 +3411,7 @@ proc graph_set_raw_props {} {
proc graph_edit_properties {n} {
global graph_bus graph_sort graph_digital graph_selected graph_sel_color graph_legend
global graph_unlocked graph_schname graph_logx graph_logy cadlayers graph_rainbow
global graph_vlegend graph_unlocked graph_schname graph_logx graph_logy cadlayers graph_rainbow
global graph_linewidth_mult graph_change_done has_x graph_dialog_default_geometry
global graph_autoload graph_private_cursor
@ -3438,6 +3438,8 @@ proc graph_edit_properties {n} {
if {[xschem getprop rect 2 $n logy] == 1} {set graph_logy 1}
set graph_legend 1
if {[xschem getprop rect 2 $n legend] == 0} {set graph_legend 0}
set graph_vlegend 0
if {[xschem getprop rect 2 $n vlegend] == 1} {set graph_vlegend 1}
set graph_digital 0
if {[xschem getprop rect 2 $n digital] == 1} {set graph_digital 1}
@ -3641,7 +3643,6 @@ proc graph_edit_properties {n} {
pack .graphdialog.top4.r$i -side left
}
# top2 frame
checkbutton .graphdialog.top.legend -text {Legend} -variable graph_legend -indicatoron 1 \
-command {
if { [xschem get schname] eq $graph_schname } {
@ -3650,6 +3651,17 @@ proc graph_edit_properties {n} {
xschem draw_graph $graph_selected
}
}
# top2 frame
checkbutton .graphdialog.top2.vlegend -text {V. legend} -variable graph_vlegend -indicatoron 1 \
-command {
if { [xschem get schname] eq $graph_schname } {
graph_push_undo
xschem setprop -fast rect 2 $graph_selected vlegend $graph_vlegend
xschem draw_graph $graph_selected
}
}
label .graphdialog.top2.labunitx -text {X units}
spinbox .graphdialog.top2.unitx -values {f p n u m 1 k M G T} -width 2 \
-command {
@ -3761,7 +3773,7 @@ proc graph_edit_properties {n} {
if {$graph_mode eq {}} { set graph_mode Line}
.graphdialog.top2.mode set $graph_mode
pack .graphdialog.top2.labunitx .graphdialog.top2.unitx \
pack .graphdialog.top2.vlegend .graphdialog.top2.labunitx .graphdialog.top2.unitx \
.graphdialog.top2.labunity .graphdialog.top2.unity -side left
pack .graphdialog.top2.labdivx .graphdialog.top2.divx \
@ -9362,7 +9374,8 @@ set tctx::global_list {
fix_broken_tiled_fill flat_netlist fullscreen gaw_fd gaw_tcp_address graph_autoload graph_bus
graph_change_done graph_dialog_default_geometry graph_digital graph_legend graph_linewidth_mult
graph_logx graph_logy graph_private_cursor graph_rainbow graph_schname graph_sel_color
graph_sel_wave graph_selected graph_sort graph_unlocked graph_use_ctrl_key hide_empty_graphs
graph_sel_wave graph_selected graph_sort graph_unlocked graph_use_ctrl_key
graph_vlegend hide_empty_graphs
hide_symbols incr_hilight incremental_select infix_interface infowindow_text intuitive_interface
keep_symbols launcher_default_program light_colors line_width live_cursor2_backannotate
local_netlist_dir lvs_ignore lvs_netlist measure_text netlist_dir netlist_show netlist_type