From 0301e86538fabb1e59f45b912a0536fcad068242 Mon Sep 17 00:00:00 2001 From: Peter Pan Date: Fri, 19 Jun 2020 23:18:23 +0800 Subject: [PATCH 1/2] chore: code polishment --- frontend/packages/wasm/Cargo.lock | 97 +++++++++---------- frontend/packages/wasm/Cargo.toml | 14 +-- .../packages/wasm/src/high_dimensional.rs | 22 +++-- frontend/packages/wasm/src/histogram.rs | 8 +- frontend/packages/wasm/src/main.rs | 34 ++++--- frontend/packages/wasm/src/scalar.rs | 10 +- 6 files changed, 91 insertions(+), 94 deletions(-) diff --git a/frontend/packages/wasm/Cargo.lock b/frontend/packages/wasm/Cargo.lock index 2248604f0..3b7e49124 100644 --- a/frontend/packages/wasm/Cargo.lock +++ b/frontend/packages/wasm/Cargo.lock @@ -2,9 +2,9 @@ # It is not intended for manual editing. [[package]] name = "bumpalo" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742" +checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" [[package]] name = "cfg-if" @@ -119,15 +119,15 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" [[package]] name = "js-sys" -version = "0.3.36" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cb931d43e71f560c81badb0191596562bafad2be06a3f9025b845c847c60df5" +checksum = "ce10c23ad2ea25ceca0093bd3192229da4c5b3c0f2de499c1ecac0d98d452177" dependencies = [ "wasm-bindgen", ] @@ -161,18 +161,18 @@ checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" [[package]] name = "pin-project" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75373ff9037d112bb19bc61333a06a159eaeb217660dcfbea7d88e1db823919" +checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b4b44893d3c370407a1d6a5cfde7c41ae0478e31c516c85f67eb3adc51be6d" +checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7" dependencies = [ "proc-macro2", "quote", @@ -187,44 +187,39 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro-hack" -version = "0.5.11" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" [[package]] name = "proc-macro-nested" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" +checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" [[package]] name = "proc-macro2" -version = "1.0.9" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.3" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ "proc-macro2", ] [[package]] name = "ryu" -version = "1.0.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "scoped-tls" @@ -234,15 +229,15 @@ checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" [[package]] name = "serde" -version = "1.0.104" +version = "1.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +checksum = "736aac72d1eafe8e5962d1d1c3d99b0df526015ba40915cb3c49d042e92ec243" [[package]] name = "serde_derive" -version = "1.0.104" +version = "1.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" +checksum = "bf0343ce212ac0d3d6afd9391ac8e9c9efe06b533c8d33f660f6390cc4093f57" dependencies = [ "proc-macro2", "quote", @@ -251,9 +246,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.48" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25" +checksum = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226" dependencies = [ "itoa", "ryu", @@ -268,9 +263,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "syn" -version = "1.0.16" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" +checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6" dependencies = [ "proc-macro2", "quote", @@ -300,9 +295,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.59" +version = "0.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3557c397ab5a8e347d434782bcd31fc1483d927a6826804cec05cc792ee2519d" +checksum = "4c2dc4aa152834bc334f506c1a06b866416a8b6697d5c9f75b9a689c8486def0" dependencies = [ "cfg-if", "serde", @@ -312,9 +307,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.59" +version = "0.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0da9c9a19850d3af6df1cb9574970b566d617ecfaf36eb0b706b6f3ef9bd2f8" +checksum = "ded84f06e0ed21499f6184df0e0cb3494727b0c5da89534e0fcc55c51d812101" dependencies = [ "bumpalo", "lazy_static", @@ -327,9 +322,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "457414a91863c0ec00090dba537f88ab955d93ca6555862c29b6d860990b8a8a" +checksum = "64487204d863f109eb77e8462189d111f27cb5712cc9fdb3461297a76963a2f6" dependencies = [ "cfg-if", "js-sys", @@ -339,9 +334,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.59" +version = "0.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f6fde1d36e75a714b5fe0cffbb78978f222ea6baebb726af13c78869fdb4205" +checksum = "838e423688dac18d73e31edce74ddfac468e37b1506ad163ffaf0a46f703ffe3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -349,9 +344,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.59" +version = "0.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bda4168030a6412ea8a047e27238cadf56f0e53516e1e83fec0a8b7c786f6d" +checksum = "3156052d8ec77142051a533cdd686cba889537b213f948cd1d20869926e68e92" dependencies = [ "proc-macro2", "quote", @@ -362,15 +357,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.59" +version = "0.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc9f36ad51f25b0219a3d4d13b90eb44cd075dff8b6280cca015775d7acaddd8" +checksum = "c9ba19973a58daf4db6f352eda73dc0e289493cd29fb2632eb172085b6521acd" [[package]] name = "wasm-bindgen-test" -version = "0.3.9" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449aeba7035e4a4710cd263bbac33519fa3828bff1c6f642fa8896601e7016ad" +checksum = "0f0dfda4d3b3f8acbc3c291b09208081c203af457fb14a229783b06e2f128aa7" dependencies = [ "console_error_panic_hook", "js-sys", @@ -382,9 +377,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.9" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49449f8dcedc192bd0cf11b5711982decdd4dbad1029f92370e2b1215031dd59" +checksum = "2c2e18093f11c19ca4e188c177fecc7c372304c311189f12c2f9bea5b7324ac7" dependencies = [ "proc-macro2", "quote", @@ -392,9 +387,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.36" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721c6263e2c66fd44501cc5efbfa2b7dfa775d13e4ea38c46299646ed1f9c70a" +checksum = "7b72fe77fd39e4bd3eaa4412fd299a0be6b3dfe9d2597e2f1c20beb968f41d17" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/frontend/packages/wasm/Cargo.toml b/frontend/packages/wasm/Cargo.toml index e17d7500f..e2127e819 100644 --- a/frontend/packages/wasm/Cargo.toml +++ b/frontend/packages/wasm/Cargo.toml @@ -25,13 +25,13 @@ lto = true # default = ["wee_alloc"] [dependencies] -serde = "1.0.104" -serde_derive = "1.0.104" +serde = "1.0.112" +serde_derive = "1.0.112" # The `wasm-bindgen` crate provides the bare minimum functionality needed # to interact with JavaScript. [dependencies.wasm-bindgen] -version = "0.2.59" +version = "0.2.63" features = ["serde-serialize"] # `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size @@ -42,7 +42,7 @@ features = ["serde-serialize"] # The `web-sys` crate allows you to interact with the various browser APIs, # like the DOM. [dependencies.web-sys] -version = "0.3.36" +version = "0.3.40" features = ["console"] # The `console_error_panic_hook` crate provides better debugging of panics by @@ -54,10 +54,10 @@ console_error_panic_hook = "0.1.6" # These crates are used for running unit tests. [dev-dependencies] -wasm-bindgen-test = "0.3.6" +wasm-bindgen-test = "0.3.13" futures = "0.3.5" -js-sys = "0.3.36" -wasm-bindgen-futures = "0.4.9" +js-sys = "0.3.40" +wasm-bindgen-futures = "0.4.13" [package.metadata.wasm-pack.profile.dev] # Should `wasm-opt` be used to further optimize the wasm binary generated after diff --git a/frontend/packages/wasm/src/high_dimensional.rs b/frontend/packages/wasm/src/high_dimensional.rs index 248e6e591..18f251d01 100644 --- a/frontend/packages/wasm/src/high_dimensional.rs +++ b/frontend/packages/wasm/src/high_dimensional.rs @@ -5,9 +5,9 @@ pub struct Point { showing: bool, } impl Point { - pub fn new(name: String, value: Vec, showing: bool) -> Self { + pub fn new(name: &str, value: Vec, showing: bool) -> Self { Point { - name, + name: String::from(name), value, showing, } @@ -23,25 +23,27 @@ impl DividedPoints { } pub fn divide( - points: Vec>, - labels: Vec, + points: &Vec>, + labels: &Vec, visibility: bool, - keyword: String, + keyword: &str, ) -> DividedPoints { let mut matched: Vec = vec![]; let mut missing: Vec = vec![]; for (i, point) in points.iter().enumerate() { - let mut name: String = String::from(""); + let mut name: &str = ""; let ptr: *const String = &labels[i]; if !ptr.is_null() { - name = labels[i].clone(); + unsafe { + name = &(*ptr)[..]; + } } - let point_with_label: Point = Point::new(name.clone(), point.to_vec(), visibility); - if keyword == String::from("") { + let point_with_label: Point = Point::new(name, point.to_vec(), visibility); + if let "" = keyword { missing.push(point_with_label); } else { - if name.contains(&keyword) { + if String::from(name).contains(&keyword) { matched.push(point_with_label); } else { missing.push(point_with_label); diff --git a/frontend/packages/wasm/src/histogram.rs b/frontend/packages/wasm/src/histogram.rs index 499c03b18..48e66a7ce 100644 --- a/frontend/packages/wasm/src/histogram.rs +++ b/frontend/packages/wasm/src/histogram.rs @@ -1,5 +1,3 @@ -use std::f64; - trait FloatIterExt { fn float_min(&mut self) -> f64; fn float_max(&mut self) -> f64; @@ -108,7 +106,7 @@ fn compute_histogram( return result; } -pub fn transform_overlay(data: Vec) -> Overlay { +pub fn transform_overlay(data: &Vec) -> Overlay { struct Temp { time: f64, step: f64, @@ -154,8 +152,8 @@ pub fn transform_overlay(data: Vec) -> Overlay { }; } -pub fn transform_offset(data: Vec) -> Offset { - let overlay: Overlay = transform_overlay(data); +pub fn transform_offset(data: &Vec) -> Offset { + let overlay: Overlay = transform_overlay(&data); let mut min_step: f64 = std::f64::INFINITY; let mut max_step: f64 = std::f64::NEG_INFINITY; let mut min_z: f64 = std::f64::INFINITY; diff --git a/frontend/packages/wasm/src/main.rs b/frontend/packages/wasm/src/main.rs index dccd5f551..ce84b245d 100644 --- a/frontend/packages/wasm/src/main.rs +++ b/frontend/packages/wasm/src/main.rs @@ -14,31 +14,33 @@ pub fn main() {} pub fn scalar_transform(js_datasets: &JsValue, smoothing: f64) -> JsValue { utils::set_panic_hook(); let datasets: Vec> = js_datasets.into_serde().unwrap(); - let result: Vec> = scalar::transform(datasets, smoothing); - return JsValue::from_serde(&result).unwrap(); + let result: Vec> = scalar::transform(&datasets, smoothing); + JsValue::from_serde(&result).unwrap() } #[wasm_bindgen] pub fn scalar_range(js_datasets: &JsValue, outlier: bool) -> JsValue { utils::set_panic_hook(); let datasets: Vec> = js_datasets.into_serde().unwrap(); - let result = scalar::range(datasets, outlier); - return JsValue::from_serde(&result).unwrap(); + let result = scalar::range(&datasets, outlier); + JsValue::from_serde(&result).unwrap() } #[wasm_bindgen] -pub fn histogram_transform(js_data: &JsValue, mode: String) -> JsValue { +pub fn histogram_transform(js_data: &JsValue, mode: &str) -> JsValue { utils::set_panic_hook(); let data: Vec = js_data.into_serde().unwrap(); - if mode == String::from("overlay") { - let result = histogram::transform_overlay(data); - return JsValue::from_serde(&result).unwrap(); + match mode { + "overlay" => { + let result = histogram::transform_overlay(&data); + JsValue::from_serde(&result).unwrap() + } + "offset" => { + let result = histogram::transform_offset(&data); + JsValue::from_serde(&result).unwrap() + } + _ => JsValue::null(), } - if mode == String::from("offset") { - let result = histogram::transform_offset(data); - return JsValue::from_serde(&result).unwrap(); - } - return JsValue::null(); } #[wasm_bindgen] @@ -46,12 +48,12 @@ pub fn high_dimensional_divide( js_points: &JsValue, js_labels: &JsValue, visibility: bool, - keyword: String, + keyword: &str, ) -> JsValue { utils::set_panic_hook(); let points: Vec> = js_points.into_serde().unwrap(); let labels: Vec = js_labels.into_serde().unwrap(); let result: high_dimensional::DividedPoints = - high_dimensional::divide(points, labels, visibility, keyword); - return JsValue::from_serde(&result).unwrap(); + high_dimensional::divide(&points, &labels, visibility, keyword); + JsValue::from_serde(&result).unwrap() } diff --git a/frontend/packages/wasm/src/scalar.rs b/frontend/packages/wasm/src/scalar.rs index ddadebf02..61f91de8c 100644 --- a/frontend/packages/wasm/src/scalar.rs +++ b/frontend/packages/wasm/src/scalar.rs @@ -15,7 +15,7 @@ impl Range { } } -fn quantile(values: Vec, p: f64) -> f64 { +fn quantile(values: &Vec, p: f64) -> f64 { let n: usize = values.len(); if n == 0 { return std::f64::NAN; @@ -33,7 +33,7 @@ fn quantile(values: Vec, p: f64) -> f64 { return value0 + (value1 - value0) * (i - (i0 as f64)); } -pub fn transform(datasets: Vec>, smoothing: f64) -> Vec> { +pub fn transform(datasets: &Vec>, smoothing: f64) -> Vec> { let mut result: Vec> = vec![]; for dataset in datasets.iter() { let mut row: Vec = vec![]; @@ -72,7 +72,7 @@ pub fn transform(datasets: Vec>, smoothing: f64) -> Vec>, outlier: bool) -> Range { +pub fn range(datasets: &Vec>, outlier: bool) -> Range { let mut ranges: Vec = vec![]; for data in datasets.iter() { @@ -90,8 +90,8 @@ pub fn range(datasets: Vec>, outlier: bool) -> Range { ranges.push(Range::new(sorted[0], sorted[n - 1])); } else { ranges.push(Range::new( - quantile(sorted, 0.05_f64), - quantile(values, 0.95), + quantile(&sorted, 0.05_f64), + quantile(&values, 0.95), )); } } From d2f1b06a0683cab88afd51da2d98ddde23c3162a Mon Sep 17 00:00:00 2001 From: Peter Pan Date: Mon, 22 Jun 2020 21:15:58 +0800 Subject: [PATCH 2/2] fix: calculate step width in tooltip (#672) --- .../components/ScalarsPage/ScalarChart.tsx | 24 ++++++++++++++----- .../packages/core/resource/scalars/chart.ts | 10 ++++---- .../packages/core/resource/scalars/data.ts | 8 +++---- .../packages/core/resource/scalars/types.ts | 9 ++++++- frontend/packages/core/utils/chart.ts | 3 +-- 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/frontend/packages/core/components/ScalarsPage/ScalarChart.tsx b/frontend/packages/core/components/ScalarsPage/ScalarChart.tsx index e49f83a58..d6c6de829 100644 --- a/frontend/packages/core/components/ScalarsPage/ScalarChart.tsx +++ b/frontend/packages/core/components/ScalarsPage/ScalarChart.tsx @@ -1,6 +1,7 @@ +import LineChart, {LineChartRef} from '~/components/LineChart'; import { - Dataset, Range, + ScalarDataset, SortingMethod, XAxis, chartData, @@ -13,7 +14,6 @@ import { transform, xAxisMap } from '~/resource/scalars'; -import LineChart, {LineChartRef} from '~/components/LineChart'; import React, {FunctionComponent, useCallback, useMemo, useRef, useState} from 'react'; import {rem, size} from '~/utils/style'; @@ -22,6 +22,7 @@ import {EChartOption} from 'echarts'; import {Run} from '~/types'; import {cycleFetcher} from '~/utils/fetch'; import ee from '~/utils/event'; +import {format} from 'd3-format'; import queryString from 'query-string'; import styled from 'styled-components'; import useHeavyWork from '~/hooks/useHeavyWork'; @@ -110,7 +111,7 @@ const ScalarChart: FunctionComponent = ({ const echart = useRef(null); - const {data: datasets, error, loading} = useRunningRequest<(Dataset | null)[]>( + const {data: datasets, error, loading} = useRunningRequest<(ScalarDataset | null)[]>( runs.map(run => `/scalars/list?${queryString.stringify({run: run.label, tag})}`), !!running, (...urls) => cycleFetcher(urls) @@ -171,15 +172,20 @@ const ScalarChart: FunctionComponent = ({ [smoothedDatasets, runs, xAxis] ); + const maxStepLength = useMemo( + () => String(Math.max(...smoothedDatasets.map(i => Math.max(...i.map(j => j[1]))))).length, + [smoothedDatasets] + ); + const formatter = useCallback( (params: EChartOption.Tooltip.Format | EChartOption.Tooltip.Format[]) => { const data = Array.isArray(params) ? params[0].data : params.data; const step = data[1]; const points = nearestPoint(smoothedDatasets ?? [], runs, step); const sort = sortingMethodMap[sortingMethod]; - return tooltip(sort ? sort(points, data) : points, i18n); + return tooltip(sort ? sort(points, data) : points, maxStepLength, i18n); }, - [smoothedDatasets, runs, sortingMethod, i18n] + [smoothedDatasets, runs, sortingMethod, maxStepLength, i18n] ); const options = useMemo( @@ -191,7 +197,13 @@ const ScalarChart: FunctionComponent = ({ }, xAxis: { type: xAxisType, - ...ranges.x + ...ranges.x, + axisPointer: { + label: { + formatter: + xAxisType === XAxisType.time ? undefined : ({value}: {value: number}) => format('.8')(value) + } + } }, yAxis: { type: yAxisType, diff --git a/frontend/packages/core/resource/scalars/chart.ts b/frontend/packages/core/resource/scalars/chart.ts index 4998472cd..a102fe2b9 100644 --- a/frontend/packages/core/resource/scalars/chart.ts +++ b/frontend/packages/core/resource/scalars/chart.ts @@ -65,7 +65,7 @@ export const chartData = ({data, runs, xAxis}: {data: Dataset[]; runs: Run[]; xA .flat(); // TODO: make it better, don't concat html -export const tooltip = (data: TooltipData[], i18n: I18n) => { +export const tooltip = (data: TooltipData[], stepLength: number, i18n: I18n) => { const indexPropMap = { time: 0, step: 1, @@ -73,10 +73,10 @@ export const tooltip = (data: TooltipData[], i18n: I18n) => { smoothed: 3, relative: 4 } as const; - const widthPropMap = { - run: [60, 180] as [number, number], + const widthPropMap: Record = { + run: [60, 180], time: 150, - step: 40, + step: Math.max(stepLength * 8, 40), value: 60, smoothed: 70, relative: 60 @@ -103,7 +103,7 @@ export const tooltip = (data: TooltipData[], i18n: I18n) => { } as const; }); - const renderContent = (content: string, width: number | [number, number]) => + const renderContent = (content: string, width: number | readonly [number, number]) => `