1 use super::{PlotContext, PlotData, Plotter};
2 use crate::measurement::ValueFormatter;
3 use crate::report::{BenchmarkId, ComparisonData, MeasurementData, ValueType};
4 use plotters::data::float::pretty_print_float;
5 use plotters::prelude::*;
6
7 use crate::kde;
8 use crate::stats::bivariate::Data;
9 use crate::stats::univariate::Sample;
10
11 static DEFAULT_FONT: FontFamily = FontFamily::SansSerif;
12 static KDE_POINTS: usize = 500;
13 static SIZE: (u32, u32) = (960, 540);
14 static POINT_SIZE: u32 = 3;
15
16 const DARK_BLUE: RGBColor = RGBColor(31, 120, 180);
17 const DARK_ORANGE: RGBColor = RGBColor(255, 127, 0);
18 const DARK_RED: RGBColor = RGBColor(227, 26, 28);
19
20 mod distributions;
21 mod iteration_times;
22 mod pdf;
23 mod regression;
24 mod summary;
25 mod t_test;
26
convert_size(size: Option<(usize, usize)>) -> Option<(u32, u32)>27 fn convert_size(size: Option<(usize, usize)>) -> Option<(u32, u32)> {
28 if let Some((w, h)) = size {
29 return Some((w as u32, h as u32));
30 }
31 None
32 }
33 #[derive(Default)]
34 pub struct PlottersBackend;
35
36 #[allow(unused_variables)]
37 impl Plotter for PlottersBackend {
pdf(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>)38 fn pdf(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>) {
39 if let Some(cmp) = data.comparison {
40 let (path, title) = if ctx.is_thumbnail {
41 (
42 ctx.context.report_path(ctx.id, "relative_pdf_small.svg"),
43 None,
44 )
45 } else {
46 (
47 ctx.context.report_path(ctx.id, "both/pdf.svg"),
48 Some(ctx.id.as_title()),
49 )
50 };
51 pdf::pdf_comparison_figure(
52 path.as_ref(),
53 title,
54 data.formatter,
55 data.measurements,
56 cmp,
57 convert_size(ctx.size),
58 );
59 return;
60 }
61 if ctx.is_thumbnail {
62 pdf::pdf_small(
63 ctx.id,
64 ctx.context,
65 data.formatter,
66 data.measurements,
67 convert_size(ctx.size),
68 );
69 } else {
70 pdf::pdf(
71 ctx.id,
72 ctx.context,
73 data.formatter,
74 data.measurements,
75 convert_size(ctx.size),
76 );
77 }
78 }
79
regression(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>)80 fn regression(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>) {
81 let (title, path) = match (data.comparison.is_some(), ctx.is_thumbnail) {
82 (true, true) => (
83 None,
84 ctx.context
85 .report_path(ctx.id, "relative_regression_small.svg"),
86 ),
87 (true, false) => (
88 Some(ctx.id.as_title()),
89 ctx.context.report_path(ctx.id, "both/regression.svg"),
90 ),
91 (false, true) => (
92 None,
93 ctx.context.report_path(ctx.id, "regression_small.svg"),
94 ),
95 (false, false) => (
96 Some(ctx.id.as_title()),
97 ctx.context.report_path(ctx.id, "regression.svg"),
98 ),
99 };
100
101 if let Some(cmp) = data.comparison {
102 let base_data = Data::new(&cmp.base_iter_counts, &cmp.base_sample_times);
103 regression::regression_comparison_figure(
104 title,
105 path.as_path(),
106 data.formatter,
107 data.measurements,
108 cmp,
109 &base_data,
110 convert_size(ctx.size),
111 );
112 } else {
113 regression::regression_figure(
114 title,
115 path.as_path(),
116 data.formatter,
117 data.measurements,
118 convert_size(ctx.size),
119 );
120 }
121 }
122
iteration_times(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>)123 fn iteration_times(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>) {
124 let (title, path) = match (data.comparison.is_some(), ctx.is_thumbnail) {
125 (true, true) => (
126 None,
127 ctx.context
128 .report_path(ctx.id, "relative_iteration_times_small.svg"),
129 ),
130 (true, false) => (
131 Some(ctx.id.as_title()),
132 ctx.context.report_path(ctx.id, "both/iteration_times.svg"),
133 ),
134 (false, true) => (
135 None,
136 ctx.context.report_path(ctx.id, "iteration_times_small.svg"),
137 ),
138 (false, false) => (
139 Some(ctx.id.as_title()),
140 ctx.context.report_path(ctx.id, "iteration_times.svg"),
141 ),
142 };
143
144 if let Some(cmp) = data.comparison {
145 let base_data = Data::new(&cmp.base_iter_counts, &cmp.base_sample_times);
146 iteration_times::iteration_times_comparison_figure(
147 title,
148 path.as_path(),
149 data.formatter,
150 data.measurements,
151 cmp,
152 convert_size(ctx.size),
153 );
154 } else {
155 iteration_times::iteration_times_figure(
156 title,
157 path.as_path(),
158 data.formatter,
159 data.measurements,
160 convert_size(ctx.size),
161 );
162 }
163 }
164
abs_distributions(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>)165 fn abs_distributions(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>) {
166 distributions::abs_distributions(
167 ctx.id,
168 ctx.context,
169 data.formatter,
170 data.measurements,
171 convert_size(ctx.size),
172 );
173 }
174
rel_distributions(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>)175 fn rel_distributions(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>) {
176 distributions::rel_distributions(
177 ctx.id,
178 ctx.context,
179 data.measurements,
180 data.comparison.unwrap(),
181 convert_size(ctx.size),
182 );
183 }
184
line_comparison( &mut self, ctx: PlotContext<'_>, formatter: &dyn ValueFormatter, all_curves: &[&(&BenchmarkId, Vec<f64>)], value_type: ValueType, )185 fn line_comparison(
186 &mut self,
187 ctx: PlotContext<'_>,
188 formatter: &dyn ValueFormatter,
189 all_curves: &[&(&BenchmarkId, Vec<f64>)],
190 value_type: ValueType,
191 ) {
192 let path = ctx.line_comparison_path();
193 summary::line_comparison(
194 formatter,
195 ctx.id.as_title(),
196 all_curves,
197 &path,
198 value_type,
199 ctx.context.plot_config.summary_scale,
200 );
201 }
202
violin( &mut self, ctx: PlotContext<'_>, formatter: &dyn ValueFormatter, all_curves: &[&(&BenchmarkId, Vec<f64>)], )203 fn violin(
204 &mut self,
205 ctx: PlotContext<'_>,
206 formatter: &dyn ValueFormatter,
207 all_curves: &[&(&BenchmarkId, Vec<f64>)],
208 ) {
209 let violin_path = ctx.violin_path();
210
211 summary::violin(
212 formatter,
213 ctx.id.as_title(),
214 all_curves,
215 &violin_path,
216 ctx.context.plot_config.summary_scale,
217 );
218 }
219
t_test(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>)220 fn t_test(&mut self, ctx: PlotContext<'_>, data: PlotData<'_>) {
221 let title = ctx.id.as_title();
222 let path = ctx.context.report_path(ctx.id, "change/t-test.svg");
223 t_test::t_test(
224 path.as_path(),
225 title,
226 data.comparison.unwrap(),
227 convert_size(ctx.size),
228 );
229 }
230
wait(&mut self)231 fn wait(&mut self) {}
232 }
233