Skip to content

Commit c1cefb9

Browse files
committed
display_float
1 parent 206810a commit c1cefb9

File tree

13 files changed

+100
-90
lines changed

13 files changed

+100
-90
lines changed

lib/bencher_json/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use std::sync::LazyLock;
33
pub use bencher_valid::{
44
BenchmarkName, Boundary, BranchName, CdfBoundary, DateTime, DateTimeMillis, Email, GitHash,
55
Index, IqrBoundary, Jwt, Model, ModelTest, NameId, NameIdKind, NonEmpty, PercentageBoundary,
6-
ResourceId, ResourceIdKind, ResourceName, SampleSize, Sanitize, Secret, Slug, Url, UserName,
7-
ValidError, Window,
6+
ResourceId, ResourceIdKind, ResourceName, SampleSize, Sanitize, Secret, Slug, Units, Url,
7+
UserName, ValidError, Window,
88
};
99
#[cfg(feature = "plus")]
1010
pub use bencher_valid::{

lib/bencher_plot/src/line.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::sync::LazyLock;
22
use std::{io::Cursor, ops::Range};
33

4+
use bencher_json::Units;
45
use bencher_json::{project::perf::JsonPerfMetrics, JsonPerf};
56
use chrono::{DateTime, Duration, Utc};
67
use image::{GenericImageView, ImageBuffer};
@@ -224,6 +225,9 @@ struct LineData {
224225

225226
impl PerfData {
226227
fn new(json_perf: &JsonPerf) -> Option<PerfData> {
228+
// There needs to be at least one measure
229+
let json_measure = json_perf.results.first().map(|result| &result.measure)?;
230+
227231
let mut min_x = None;
228232
let mut max_x = None;
229233
let mut min_y = None;
@@ -264,16 +268,28 @@ impl PerfData {
264268
dimensions,
265269
}
266270
})
267-
.collect();
271+
.collect::<Vec<LineData>>();
268272

269273
if let (Some(min_x), Some(max_x), Some(min_y), Some(max_y)) = (min_x, max_x, min_y, max_y) {
270274
let x_time = max_x - min_x < Duration::days(X_LABELS);
271-
let y_desc = json_perf
272-
.results
273-
.first()
274-
.map_or("Measure: unitless".to_owned(), |result| {
275-
result.measure.to_string()
276-
});
275+
let units = Units::new(*min_y, json_measure.units.clone());
276+
let factor = units.scale_factor();
277+
let min_y = min_y / factor;
278+
let max_y = max_y / factor;
279+
let y_desc = format!("{}: {}", json_measure.name, units.scale_units());
280+
281+
let lines = lines
282+
.into_iter()
283+
.map(|line| LineData {
284+
data: line
285+
.data
286+
.into_iter()
287+
.map(|(x, y)| (x, y / factor))
288+
.collect(),
289+
..line
290+
})
291+
.collect();
292+
277293
Some(PerfData {
278294
lines,
279295
x: (min_x, max_x),

lib/bencher_valid/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub use plus::{
5151
pub use resource_id::{ResourceId, ResourceIdKind};
5252
pub use resource_name::ResourceName;
5353
pub use secret::Secret;
54-
pub use units::{scale_factor, scale_units, BYTES, NANOSECONDS, SECONDS};
54+
pub use units::{Units, BYTES, NANOSECONDS, SECONDS};
5555
pub use user_name::UserName;
5656

5757
const MAX_LEN: usize = 64;

lib/bencher_valid/src/units.rs

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,35 @@
1+
use ordered_float::OrderedFloat;
12
#[cfg(feature = "wasm")]
23
use wasm_bindgen::prelude::*;
34

5+
use crate::ResourceName;
6+
47
pub const NANOSECONDS: &str = "nanoseconds (ns)";
58
pub const SECONDS: &str = "seconds (s)";
69
pub const BYTES: &str = "bytes (B)";
710

11+
#[derive(Debug, Clone)]
12+
pub struct Units {
13+
scale: Scale,
14+
units: ResourceName,
15+
}
16+
17+
impl Units {
18+
pub fn new(min: f64, units: ResourceName) -> Self {
19+
let scale = Scale::new(min, units.as_ref());
20+
Self { scale, units }
21+
}
22+
23+
#[allow(clippy::cast_precision_loss)]
24+
pub fn scale_factor(&self) -> OrderedFloat<f64> {
25+
OrderedFloat::from(self.scale.factor() as f64)
26+
}
27+
28+
pub fn scale_units(&self) -> String {
29+
self.scale.units(self.units.as_ref())
30+
}
31+
}
32+
833
#[derive(Debug, Clone, Copy)]
934
enum Scale {
1035
Nanos(ScaleNanos),
@@ -53,7 +78,7 @@ impl Scale {
5378
}
5479
}
5580

56-
fn as_u64(&self) -> u64 {
81+
fn factor(&self) -> u64 {
5782
match self {
5883
Scale::Nanos(scale) => *scale as u64,
5984
Scale::Secs(scale) => *scale as u64,
@@ -189,11 +214,13 @@ impl ScaleOneE {
189214
}
190215
}
191216

217+
#[allow(dead_code)]
192218
#[cfg_attr(feature = "wasm", wasm_bindgen)]
193219
pub fn scale_factor(min: f64, units: &str) -> u64 {
194-
Scale::new(min, units).as_u64()
220+
Scale::new(min, units).factor()
195221
}
196222

223+
#[allow(dead_code)]
197224
#[cfg_attr(feature = "wasm", wasm_bindgen)]
198225
pub fn scale_units(min: f64, units: &str) -> String {
199226
Scale::new(min, units).units(units)

services/console/src/components/console/deck/hand/card/ReportCard.tsx

+5-49
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
type JsonTestbed,
2323
type JsonThreshold,
2424
} from "../../../../../types/bencher";
25-
import { dateTimeMillis } from "../../../../../util/convert";
25+
import { dateTimeMillis, prettyPrintFloat } from "../../../../../util/convert";
2626
import { BACK_PARAM, encodePath } from "../../../../../util/url";
2727

2828
export interface Props {
@@ -489,10 +489,10 @@ const ValueCell = (props: {
489489

490490
return (
491491
<>
492-
{formatNumber(props.value)}
492+
{prettyPrintFloat(props.value)}
493493
<Show when={percent !== null}>
494494
<br />({percent > 0.0 ? "+" : ""}
495-
{formatNumber(percent)}%)
495+
{prettyPrintFloat(percent)}%)
496496
</Show>
497497
</>
498498
);
@@ -562,8 +562,8 @@ const LimitCell = (props: {
562562
percent: number;
563563
}) => (
564564
<>
565-
{formatNumber(props.limit)}
566-
<br />({formatNumber(props.percent)}%)
565+
{prettyPrintFloat(props.limit)}
566+
<br />({prettyPrintFloat(props.percent)}%)
567567
</>
568568
);
569569

@@ -752,48 +752,4 @@ const union = (lhs: BoundaryLimits, rhs: BoundaryLimits): BoundaryLimits => {
752752
};
753753
};
754754

755-
// biome-ignore lint/style/useEnumInitializers: variants
756-
enum Position {
757-
Whole,
758-
Point,
759-
Decimal,
760-
}
761-
762-
const formatNumber = (number: number): string => {
763-
let numberStr = "";
764-
let position = Position.Decimal;
765-
const formattedNumber = Math.abs(number).toFixed(2);
766-
const isNegative = number < 0;
767-
768-
for (let i = formattedNumber.length - 1; i >= 0; i--) {
769-
const c = formattedNumber[i];
770-
switch (position) {
771-
case Position.Whole:
772-
if (
773-
(formattedNumber.length - 1 - i) % 3 === 0 &&
774-
i !== formattedNumber.length - 1
775-
) {
776-
numberStr = `,${numberStr}`;
777-
}
778-
position = Position.Whole;
779-
break;
780-
case Position.Point:
781-
position = Position.Whole;
782-
break;
783-
case Position.Decimal:
784-
if (c === ".") {
785-
position = Position.Point;
786-
}
787-
break;
788-
}
789-
numberStr = c + numberStr;
790-
}
791-
792-
if (isNegative) {
793-
numberStr = `-${numberStr}`;
794-
}
795-
796-
return numberStr;
797-
};
798-
799755
export default ReportCard;

services/console/src/components/console/deck/hand/card/ViewCard.tsx

+10
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
ModelTest,
1111
} from "../../../../../types/bencher";
1212
import { authUser } from "../../../../../util/auth";
13+
import { prettyPrintFloat } from "../../../../../util/convert";
1314
import { httpGet } from "../../../../../util/http";
1415
import { BACK_PARAM, encodePath } from "../../../../../util/url";
1516
import { testFragment } from "../../../../field/kinds/Model";
@@ -36,6 +37,7 @@ const ViewCard = (props: Props) => {
3637
class={`field-label${(() => {
3738
switch (props.card?.display) {
3839
case Display.RAW:
40+
case Display.FLOAT:
3941
case Display.DATE_TIME:
4042
case Display.SWITCH:
4143
case Display.SELECT:
@@ -128,6 +130,14 @@ const ViewCard = (props: Props) => {
128130
View Threshold
129131
</a>
130132
</Match>
133+
<Match when={props.card?.display === Display.FLOAT}>
134+
<input
135+
class="input is-static"
136+
type="text"
137+
value={prettyPrintFloat(props.value)}
138+
readonly
139+
/>
140+
</Match>
131141
<Match when={props.card?.display === Display.DATE_TIME}>
132142
<input
133143
class="input is-static"

services/console/src/components/console/perf/plot/line/LinePlot.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
type JsonPerfMetrics,
2121
XAxis,
2222
} from "../../../../../types/bencher";
23-
import { prettyPrintNumber } from "../../../../../util/convert";
23+
import { prettyPrintFloat } from "../../../../../util/convert";
2424
import { BACK_PARAM, encodePath } from "../../../../../util/url";
2525
import { Theme } from "../../../../navbar/theme/theme";
2626
import { addTooltips } from "./tooltip";
@@ -547,7 +547,7 @@ const plot_marks = (
547547
fill: color,
548548
title: (datum) =>
549549
to_title(
550-
`${prettyPrintNumber(datum?.raw?.value)}`,
550+
`${prettyPrintFloat(datum?.raw?.value)}`,
551551
result,
552552
datum,
553553
"\nClick to view Metric",
@@ -838,15 +838,15 @@ const alert_image = (
838838

839839
const value_end_title = (limit: BoundaryLimit, result, datum, suffix) =>
840840
to_title(
841-
`${position_label(limit)} Value: ${prettyPrintNumber(datum?.raw?.[value_end_position_key(limit)])}`,
841+
`${position_label(limit)} Value: ${prettyPrintFloat(datum?.raw?.[value_end_position_key(limit)])}`,
842842
result,
843843
datum,
844844
suffix,
845845
);
846846

847847
const limit_title = (limit: BoundaryLimit, result, datum, suffix) =>
848848
to_title(
849-
`${position_label(limit)} Limit: ${prettyPrintNumber(datum?.raw?.[boundary_position_key(limit)])}`,
849+
`${position_label(limit)} Limit: ${prettyPrintFloat(datum?.raw?.[boundary_position_key(limit)])}`,
850850
result,
851851
datum,
852852
suffix,

services/console/src/config/project/alerts.tsx

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { Params } from "astro";
2+
import { PubResourceKind } from "../../components/perf/util";
3+
import { isAllowedProjectEdit } from "../../util/auth";
24
import { ActionButton, Button, Card, Display, Operation, Row } from "../types";
35
import { parentPath, viewUuidPath } from "../util";
4-
import { isAllowedProjectEdit } from "../../util/auth";
5-
import { PubResourceKind } from "../../components/perf/util";
66

77
export const ALERT_ICON = "fas fa-bell";
88

@@ -134,7 +134,7 @@ const alertsConfig = {
134134
kind: Card.NESTED_FIELD,
135135
label: "Metric",
136136
keys: ["metric", "value"],
137-
display: Display.RAW,
137+
display: Display.FLOAT,
138138
},
139139
{
140140
kind: Card.NESTED_FIELD,
@@ -146,19 +146,19 @@ const alertsConfig = {
146146
kind: Card.NESTED_FIELD,
147147
label: "Boundary Baseline",
148148
keys: ["boundary", "baseline"],
149-
display: Display.RAW,
149+
display: Display.FLOAT,
150150
},
151151
{
152152
kind: Card.NESTED_FIELD,
153153
label: "Lower Boundary Limit",
154154
keys: ["boundary", "lower_limit"],
155-
display: Display.RAW,
155+
display: Display.FLOAT,
156156
},
157157
{
158158
kind: Card.NESTED_FIELD,
159159
label: "Upper Boundary Limit",
160160
keys: ["boundary", "upper_limit"],
161-
display: Display.RAW,
161+
display: Display.FLOAT,
162162
},
163163
{
164164
kind: Card.FIELD,

services/console/src/config/project/alerts_pub.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Params } from "astro";
2-
import { Button, Card, Display } from "../types";
32
import { PubResourceKind } from "../../components/perf/util";
3+
import { Button, Card, Display } from "../types";
44

55
const alertsPubConfig = {
66
resource: PubResourceKind.Alert,
@@ -64,7 +64,7 @@ const alertsPubConfig = {
6464
kind: Card.NESTED_FIELD,
6565
label: "Metric",
6666
keys: ["metric", "value"],
67-
display: Display.RAW,
67+
display: Display.FLOAT,
6868
},
6969
{
7070
kind: Card.NESTED_FIELD,
@@ -76,19 +76,19 @@ const alertsPubConfig = {
7676
kind: Card.NESTED_FIELD,
7777
label: "Boundary Baseline",
7878
keys: ["boundary", "baseline"],
79-
display: Display.RAW,
79+
display: Display.FLOAT,
8080
},
8181
{
8282
kind: Card.NESTED_FIELD,
8383
label: "Lower Boundary Limit",
8484
keys: ["boundary", "lower_limit"],
85-
display: Display.RAW,
85+
display: Display.FLOAT,
8686
},
8787
{
8888
kind: Card.NESTED_FIELD,
8989
label: "Upper Boundary Limit",
9090
keys: ["boundary", "upper_limit"],
91-
display: Display.RAW,
91+
display: Display.FLOAT,
9292
},
9393
{
9494
kind: Card.FIELD,

0 commit comments

Comments
 (0)