diff --git a/src/bin/plot.py b/src/bin/plot.py index dbb26bf..9a40897 100755 --- a/src/bin/plot.py +++ b/src/bin/plot.py @@ -87,6 +87,13 @@ def main(): nargs="*", help="Remove this span name (multiple use)", ) + parser.add_argument( + "--inline-field", + action="store_true", + help="If the is only one field, display its value inline. " + "Since the text is not limited to its box, text can overlap and " + "become unreadable.", + ) parser.add_argument( "--color-top", default="#FF780088", @@ -283,6 +290,18 @@ def main(): r = Rectangle(x, y, width, height, fill=args.color_bottom) r.append_title(tooltip) d.append(r) + if args.inline_field and len(full_span.fields) == 1: + text = next(iter(full_span.fields.values())) + d.append( + Text( + text, + "0.7em", + x=x, + y=y + height // 2, + dominant_baseline="middle", + text_anchor="start", + ) + ) d.save_svg(args.output or Path(args.input).with_suffix(".svg")) diff --git a/src/bin/plot.rs b/src/bin/plot.rs index 0781470..bb7fa34 100644 --- a/src/bin/plot.rs +++ b/src/bin/plot.rs @@ -17,6 +17,11 @@ struct Args { /// Remove spans shorter than this, in seconds #[clap(long)] min_length: Option, + /// If the is only one field, display its value inline. + /// + /// Since the text is not limited to its box, text can overlap and become unreadable. + #[clap(long)] + inline_field: bool, /// Remove spans with this name #[clap(long)] remove: Option>, @@ -51,6 +56,7 @@ fn main() -> Result<()> { multi_lane: args.multi_lane, min_length: args.min_length.map(Duration::from_secs_f32), remove: args.remove.map(|remove| remove.into_iter().collect()), + inline_field: args.inline_field, color_top: args.color_top, color_bottom: args.color_bottom, }; diff --git a/src/plot.rs b/src/plot.rs index fe56c9a..794da25 100644 --- a/src/plot.rs +++ b/src/plot.rs @@ -37,6 +37,10 @@ pub struct PlotConfig { pub min_length: Option, /// Remove spans with this name. pub remove: Option>, + /// If the is only one field, display its value inline. + /// + /// Since the text is not limited to its box, text can overlap and become unreadable. + pub inline_field: bool, /// The color for the plots in the active region (default: semi-transparent orange). pub color_top: String, /// The color for the plots in the total region (default: semi-transparent blue). @@ -49,6 +53,7 @@ impl Default for PlotConfig { multi_lane: false, min_length: None, remove: None, + inline_field: false, // TODO(konstin): Pick a proper color scheme, maybe ggplot or matplotlib? color_top: "#FF780088".to_string(), color_bottom: "#0076FF88".to_string(), @@ -278,7 +283,8 @@ pub fn plot( .flatten() .map(|(key, value)| format!("{key}: {value}")) .join("\n"); - format!("{} {:.3}s\n{}", span.name, span.secs(), fields) + // https://github.com/bodoni/svg/issues/76 + format!("{} {:.3}s\n{}", span.name, span.secs(), fields).replace("<", "<") }; // Draw the active top half of each span @@ -304,40 +310,53 @@ pub fn plot( .set("height", layout.bar_height / 2) .set("fill", config.color_top.to_string()) // Add tooltip - // https://github.com/bodoni/svg/issues/76 - .add(Title::new().add(node::Text::new(format_tooltip(span).replace("<", "<")))), + .add(Title::new().add(node::Text::new(format_tooltip(span)))), ) } // Draw the total bottom half of each span for full_span in full_spans.values() { + let x = layout.text_col_width as f32 + + layout.content_col_width as f32 * full_span.start.as_secs_f32() / end.as_secs_f32(); + let y = name_offsets[full_span.name.as_str()] + * (layout.bar_height + layout.section_padding_height) + + extra_lane_height * extra_lanes_cumulative[full_span.name.as_str()] + + extra_lane_height * span_lanes[&full_span.id] + + layout.bar_height / 2; + let width = layout.content_col_width as f32 + * (full_span.end - full_span.start).as_secs_f32() + / end.as_secs_f32(); + let height = layout.bar_height / 2; document = document.add( Rectangle::new() - .set( - "x", - layout.text_col_width as f32 - + layout.content_col_width as f32 * full_span.start.as_secs_f32() - / end.as_secs_f32(), - ) - .set( - "y", - name_offsets[full_span.name.as_str()] - * (layout.bar_height + layout.section_padding_height) - + extra_lane_height * extra_lanes_cumulative[full_span.name.as_str()] - + extra_lane_height * span_lanes[&full_span.id] - + layout.bar_height / 2, - ) - .set( - "width", - layout.content_col_width as f32 - * (full_span.end - full_span.start).as_secs_f32() - / end.as_secs_f32(), - ) - .set("height", layout.bar_height / 2) + .set("x", x) + .set("y", y) + .set("width", width) + .set("height", height) .set("fill", config.color_bottom.to_string()) // Add tooltip .add(Title::new().add(node::Text::new(format_tooltip(full_span)))), - ) + ); + let mut fields = full_span + .fields + .as_ref() + .map(|map| map.values()) + .into_iter() + .flatten(); + if let Some(value) = fields.next() { + if config.inline_field && fields.next().is_none() { + document = document.add( + Text::new() + // https://github.com/bodoni/svg/issues/76 + .add(node::Text::new(value.replace("<", "<"))) + .set("x", x) + .set("y", y + height / 2) + .set("font-size", "0.7em") + .set("dominant-baseline", "middle") + .set("text-anchor", "start"), + ) + } + } } document }