未验证 提交 0e38ff74 编写于 作者: P Peter Pan 提交者: GitHub

minor bugs fix (#851)

* fix: get nearest points listed in tooltip of scalar page by selected x-axis

* fix: humanize relative time display in tooltip of scalar chart

* fix: fix y axis range error in scalar chart (fix #765)
上级 f0de5996
...@@ -48,7 +48,7 @@ const Container = styled.div` ...@@ -48,7 +48,7 @@ const Container = styled.div`
cursor: pointer; cursor: pointer;
${transitionProps('color')} ${transitionProps('color')}
&.volumn { &.volume {
font-size: ${rem(20)}; font-size: ${rem(20)};
${size(rem(20), rem(20))} ${size(rem(20), rem(20))}
} }
...@@ -80,7 +80,7 @@ const Container = styled.div` ...@@ -80,7 +80,7 @@ const Container = styled.div`
} }
`; `;
const VolumnSlider = styled(Slider)` const VolumeSlider = styled(Slider)`
margin: ${rem(15)} ${rem(18)}; margin: ${rem(15)} ${rem(18)};
width: ${rem(4)}; width: ${rem(4)};
height: ${rem(100)}; height: ${rem(100)};
...@@ -170,7 +170,7 @@ const Audio: FunctionComponent<AudioProps & WithStyled> = ({ ...@@ -170,7 +170,7 @@ const Audio: FunctionComponent<AudioProps & WithStyled> = ({
const [duration, setDuration] = useState('00:00'); const [duration, setDuration] = useState('00:00');
const [decoding, setDecoding] = useState(false); const [decoding, setDecoding] = useState(false);
const [playing, setPlaying] = useState(false); const [playing, setPlaying] = useState(false);
const [volumn, setVolumn] = useState(100); const [volume, setVolume] = useState(100);
const [playAfterSeek, setPlayAfterSeek] = useState(false); const [playAfterSeek, setPlayAfterSeek] = useState(false);
const play = useCallback(() => player.current?.play(), []); const play = useCallback(() => player.current?.play(), []);
...@@ -199,7 +199,7 @@ const Audio: FunctionComponent<AudioProps & WithStyled> = ({ ...@@ -199,7 +199,7 @@ const Audio: FunctionComponent<AudioProps & WithStyled> = ({
const toggleMute = useCallback(() => { const toggleMute = useCallback(() => {
if (player.current) { if (player.current) {
player.current.toggleMute(); player.current.toggleMute();
setVolumn(player.current.volumn); setVolume(player.current.volume);
} }
}, []); }, []);
...@@ -228,9 +228,9 @@ const Audio: FunctionComponent<AudioProps & WithStyled> = ({ ...@@ -228,9 +228,9 @@ const Audio: FunctionComponent<AudioProps & WithStyled> = ({
useEffect(() => { useEffect(() => {
if (player.current) { if (player.current) {
player.current.volumn = volumn; player.current.volume = volume;
} }
}, [volumn]); }, [volume]);
useEffect(() => { useEffect(() => {
let p: AudioPlayer | null = null; let p: AudioPlayer | null = null;
...@@ -269,15 +269,15 @@ const Audio: FunctionComponent<AudioProps & WithStyled> = ({ ...@@ -269,15 +269,15 @@ const Audio: FunctionComponent<AudioProps & WithStyled> = ({
}; };
}, [data, startTimer, stopTimer, onLoading, onLoad, audioContext]); }, [data, startTimer, stopTimer, onLoading, onLoad, audioContext]);
const volumnIcon = useMemo(() => { const volumeIcon = useMemo(() => {
if (volumn === 0) { if (volume === 0) {
return 'mute'; return 'mute';
} }
if (volumn <= 50) { if (volume <= 50) {
return 'volumn-low'; return 'volume-low';
} }
return 'volumn'; return 'volume';
}, [volumn]); }, [volume]);
if (loading) { if (loading) {
return <SyncLoader color={primaryColor} size="15px" />; return <SyncLoader color={primaryColor} size="15px" />;
...@@ -313,18 +313,18 @@ const Audio: FunctionComponent<AudioProps & WithStyled> = ({ ...@@ -313,18 +313,18 @@ const Audio: FunctionComponent<AudioProps & WithStyled> = ({
interactive interactive
hideOnClick={false} hideOnClick={false}
content={ content={
<VolumnSlider <VolumeSlider
value={volumn} value={volume}
min={0} min={0}
max={100} max={100}
step={1} step={1}
onChange={setVolumn} onChange={setVolume}
orientation="vertical" orientation="vertical"
/> />
} }
> >
<a className="control volumn" onClick={toggleMute}> <a className="control volume" onClick={toggleMute}>
<Icon type={volumnIcon} /> <Icon type={volumeIcon} />
</a> </a>
</Tippy> </Tippy>
</Container> </Container>
......
...@@ -201,7 +201,8 @@ const ScalarChart: FunctionComponent<ScalarChartProps> = ({ ...@@ -201,7 +201,8 @@ const ScalarChart: FunctionComponent<ScalarChartProps> = ({
const formatter = useCallback( const formatter = useCallback(
(params: EChartOption.Tooltip.Format | EChartOption.Tooltip.Format[]) => { (params: EChartOption.Tooltip.Format | EChartOption.Tooltip.Format[]) => {
const series: Dataset[number] = Array.isArray(params) ? params[0].data : params.data; const series: Dataset[number] = Array.isArray(params) ? params[0].data : params.data;
const points = nearestPoint(smoothedDatasets ?? [], runs, series[1]).map((point, index) => ({ const idx = xAxisMap[xAxis];
const points = nearestPoint(smoothedDatasets ?? [], runs, idx, series[idx]).map((point, index) => ({
...point, ...point,
...datasetRanges?.[index] ...datasetRanges?.[index]
})); }));
...@@ -212,7 +213,7 @@ const ScalarChart: FunctionComponent<ScalarChartProps> = ({ ...@@ -212,7 +213,7 @@ const ScalarChart: FunctionComponent<ScalarChartProps> = ({
<TooltipTable run={t('common:runs')} runs={sorted.map(i => i.run)} columns={columns} data={data} /> <TooltipTable run={t('common:runs')} runs={sorted.map(i => i.run)} columns={columns} data={data} />
); );
}, },
[smoothedDatasets, datasetRanges, runs, sortingMethod, maxStepLength, t, i18n] [smoothedDatasets, datasetRanges, runs, sortingMethod, xAxis, maxStepLength, t, i18n]
); );
const options = useMemo( const options = useMemo(
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export type Property = { export type Property = {
name?: string; name?: string;
value: string; value: string;
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type {Point} from './types'; import type {Point} from './types';
export type {Dimension, Reduction, Point} from './types'; export type {Dimension, Reduction, Point} from './types';
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export type Dimension = '2d' | '3d'; export type Dimension = '2d' | '3d';
export type Reduction = 'pca' | 'tsne'; export type Reduction = 'pca' | 'tsne';
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type {EChartOption, VisualMap} from 'echarts'; import type {EChartOption, VisualMap} from 'echarts';
import type {Modes} from './types'; import type {Modes} from './types';
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type {HistogramData, OffsetData, OffsetDataItem, OverlayData, OverlayDataItem} from './types'; import type {HistogramData, OffsetData, OffsetDataItem, OverlayData, OverlayDataItem} from './types';
import {Modes} from './types'; import {Modes} from './types';
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Modes} from './types'; import {Modes} from './types';
export const modes = [Modes.Offset, Modes.Overlay] as const; export const modes = [Modes.Offset, Modes.Overlay] as const;
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export enum Modes { export enum Modes {
Offset = 'offset', Offset = 'offset',
Overlay = 'overlay' Overlay = 'overlay'
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const options = { export const options = {
legend: { legend: {
data: [] data: []
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const nearestPoint = (data: number[][][], recall: number): number[][][] => { export const nearestPoint = (data: number[][][], recall: number): number[][][] => {
return data.map(series => { return data.map(series => {
let delta = Number.POSITIVE_INFINITY; let delta = Number.POSITIVE_INFINITY;
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export type {PRCurveData, Run, StepInfo, Tag} from './types'; export type {PRCurveData, Run, StepInfo, Tag} from './types';
export {TimeType} from './types'; export {TimeType} from './types';
export * from './chart'; export * from './chart';
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Run as BaseRun, Tag as BaseTag, TimeMode} from '~/types'; import {Run as BaseRun, Tag as BaseTag, TimeMode} from '~/types';
export {TimeMode as TimeType}; export {TimeMode as TimeType};
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// cSpell:words maxs coord
import type {Dataset, Range, TooltipData, XAxis} from './types'; import type {Dataset, Range, TooltipData, XAxis} from './types';
import type I18n from 'i18next'; import type I18n from 'i18next';
import type {Run} from '~/types'; import type {Run} from '~/types';
import {format} from 'd3-format'; import {format} from 'd3-format';
import {formatTime} from '~/utils'; import {formatTime} from '~/utils';
import moment from 'moment';
import {xAxisMap} from './index'; import {xAxisMap} from './index';
const valueFormatter = format('.5'); const valueFormatter = format('.5');
const humanizeDuration = (ms: number) => {
const time = moment.duration(ms);
const hour = time.hours();
if (hour) {
time.subtract(hour, 'hour');
}
const minute = time.minutes();
if (minute) {
time.subtract(minute, 'minute');
}
const second = time.asSeconds();
let str = Math.floor(second) + 's';
if (hour) {
str = `${hour}h${minute}m${str}`;
} else if (minute) {
str = `${minute}m${str}`;
}
return str;
};
export const options = { export const options = {
legend: { legend: {
data: [] data: []
...@@ -35,7 +74,7 @@ export const chartData = ({ ...@@ -35,7 +74,7 @@ export const chartData = ({
// smoothed data: // smoothed data:
// [0] wall time // [0] wall time
// [1] step // [1] step
// [2] orginal value // [2] original value
// [3] smoothed value // [3] smoothed value
// [4] relative // [4] relative
const name = runs[i].label; const name = runs[i].label;
...@@ -144,7 +183,7 @@ export const tooltip = (data: TooltipData[], stepLength: number, i18n: typeof I1 ...@@ -144,7 +183,7 @@ export const tooltip = (data: TooltipData[], stepLength: number, i18n: typeof I1
valueFormatter(min ?? Number.NaN), valueFormatter(min ?? Number.NaN),
valueFormatter(max ?? Number.NaN), valueFormatter(max ?? Number.NaN),
formatTime(item[0], i18n.language), formatTime(item[0], i18n.language),
Math.floor(item[4] * 60 * 60) + 's' humanizeDuration(item[4])
]) ])
}; };
}; };
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// cSpell:words quantile accum debias exponentiated
import type {Dataset, ScalarDataset} from './types'; import type {Dataset, ScalarDataset} from './types';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
...@@ -21,8 +39,8 @@ export const transform = ({datasets, smoothing}: {datasets: ScalarDataset[]; smo ...@@ -21,8 +39,8 @@ export const transform = ({datasets, smoothing}: {datasets: ScalarDataset[]; smo
if (i === 0) { if (i === 0) {
startValue = millisecond; startValue = millisecond;
} }
// relative time, millisecond to hours. // relative time in millisecond.
d[4] = Math.floor(millisecond - startValue) / (60 * 60 * 1000); d[4] = Math.floor(millisecond - startValue);
if (!nextVal.isFinite()) { if (!nextVal.isFinite()) {
d[3] = nextVal.toNumber(); d[3] = nextVal.toNumber();
} else { } else {
...@@ -65,12 +83,12 @@ export const range = ({datasets}: {datasets: Dataset[]}) => { ...@@ -65,12 +83,12 @@ export const range = ({datasets}: {datasets: Dataset[]}) => {
export const axisRange = ({datasets, outlier}: {datasets: Dataset[]; outlier: boolean}) => { export const axisRange = ({datasets, outlier}: {datasets: Dataset[]; outlier: boolean}) => {
const ranges = compact( const ranges = compact(
datasets?.map(dataset => { datasets?.map(dataset => {
if (dataset.length == 0) { if (dataset.length === 0) {
return; return void 0;
} }
const values = dataset.map(v => v[2]); const values = dataset.map(v => v[2]);
if (!outlier) { if (!outlier) {
// Get the orgin data range. // Get the origin data range.
return { return {
min: Math.min(...values) ?? 0, min: Math.min(...values) ?? 0,
max: Math.max(...values) ?? 0 max: Math.max(...values) ?? 0
...@@ -97,32 +115,23 @@ export const axisRange = ({datasets, outlier}: {datasets: Dataset[]; outlier: bo ...@@ -97,32 +115,23 @@ export const axisRange = ({datasets, outlier}: {datasets: Dataset[]; outlier: bo
} }
}; };
export const nearestPoint = (data: Dataset[], runs: Run[], step: number) => export const nearestPoint = (data: Dataset[], runs: Run[], idx: number, value: number) => {
data.map((series, index) => { const result: {run: Run; item: Dataset[number]}[] = [];
let nearestItem; data.forEach((series, index) => {
if (step === 0) { const run = runs[index];
nearestItem = series[0]; let d = Number.POSITIVE_INFINITY;
} else { let dv = value;
for (let i = 0; i < series.length; i++) { for (let i = 0; i < series.length; i++) {
const item = series[i]; const dd = Math.abs(series[i][idx] - value);
if (item[1] === step) { if (d > dd) {
nearestItem = item; d = dd;
break; dv = series[i][idx];
}
if (item[1] > step) {
nearestItem = series[i - 1 >= 0 ? i - 1 : 0];
break;
}
if (!nearestItem) {
nearestItem = series[series.length - 1];
}
} }
} }
return { result.push(...series.filter(s => s[idx] === dv).map(item => ({run, item})));
run: runs[index],
item: nearestItem || [0, 0, 0, 0, 0]
};
}); });
return result;
};
export const parseSmoothing = (value: unknown) => { export const parseSmoothing = (value: unknown) => {
const parsedValue = Number.parseFloat(String(value)); const parsedValue = Number.parseFloat(String(value));
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {SortingMethod as SM, XAxis} from './types'; import {SortingMethod as SM, XAxis} from './types';
import type {TooltipData} from './types'; import type {TooltipData} from './types';
...@@ -14,7 +30,7 @@ export const sortingMethodMap: Record<SM, (points: TooltipData[], data: number[] ...@@ -14,7 +30,7 @@ export const sortingMethodMap: Record<SM, (points: TooltipData[], data: number[]
[SM.Default]: (points: TooltipData[]) => points, [SM.Default]: (points: TooltipData[]) => points,
[SM.Descending]: (points: TooltipData[]) => sortBy(points, point => point.item[3]).reverse(), [SM.Descending]: (points: TooltipData[]) => sortBy(points, point => point.item[3]).reverse(),
[SM.Ascending]: (points: TooltipData[]) => sortBy(points, point => point.item[3]), [SM.Ascending]: (points: TooltipData[]) => sortBy(points, point => point.item[3]),
// Compare other ponts width the trigger point, caculate the nearest sort. // Compare other points width the trigger point, calculate the nearest sort.
[SM.Nearest]: (points: TooltipData[], data: number[]) => sortBy(points, point => point.item[3] - data[2]) [SM.Nearest]: (points: TooltipData[], data: number[]) => sortBy(points, point => point.item[3] - data[2])
} as const; } as const;
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Run, TimeMode} from '~/types'; import {Run, TimeMode} from '~/types';
type Value = number; type Value = number;
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export interface TagsData { export interface TagsData {
runs: string[]; runs: string[];
tags: string[][]; tags: string[][];
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
interface AudioPlayerOptions { interface AudioPlayerOptions {
context?: AudioContext; context?: AudioContext;
volumn?: number; volume?: number;
onplay?: () => void; onplay?: () => void;
onstop?: () => void; onstop?: () => void;
} }
...@@ -17,7 +33,7 @@ export class AudioPlayer { ...@@ -17,7 +33,7 @@ export class AudioPlayer {
private stopAt = 0; private stopAt = 0;
private offset = 0; private offset = 0;
private toggleVolumn = 100; private toggleVolume = 100;
public playing = false; public playing = false;
...@@ -44,10 +60,10 @@ export class AudioPlayer { ...@@ -44,10 +60,10 @@ export class AudioPlayer {
return this.decodedSampleRate; return this.decodedSampleRate;
} }
get volumn() { get volume() {
return this.gain.gain.value * 100; return this.gain.gain.value * 100;
} }
set volumn(value: number) { set volume(value: number) {
if (value > 100) { if (value > 100) {
value = 100; value = 100;
} else if (value < 0) { } else if (value < 0) {
...@@ -59,7 +75,7 @@ export class AudioPlayer { ...@@ -59,7 +75,7 @@ export class AudioPlayer {
constructor(options?: AudioPlayerOptions) { constructor(options?: AudioPlayerOptions) {
this.options = { this.options = {
context: options?.context ?? new AudioContext(), context: options?.context ?? new AudioContext(),
volumn: 100, volume: 100,
onplay: () => void 0, onplay: () => void 0,
onstop: () => void 0, onstop: () => void 0,
...options ...options
...@@ -67,7 +83,7 @@ export class AudioPlayer { ...@@ -67,7 +83,7 @@ export class AudioPlayer {
this.contextFromOptions = !!options?.context; this.contextFromOptions = !!options?.context;
this.context = this.options.context; this.context = this.options.context;
this.gain = this.context.createGain(); this.gain = this.context.createGain();
this.volumn = this.options.volumn; this.volume = this.options.volume;
} }
private reset() { private reset() {
...@@ -208,11 +224,11 @@ export class AudioPlayer { ...@@ -208,11 +224,11 @@ export class AudioPlayer {
} }
toggleMute() { toggleMute() {
if (this.volumn === 0) { if (this.volume === 0) {
this.volumn = this.toggleVolumn || 100; this.volume = this.toggleVolume || 100;
} else { } else {
this.toggleVolumn = this.volumn; this.toggleVolume = this.volume;
this.volumn = 0; this.volume = 0;
} }
} }
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {colors} from '~/utils/theme'; import {colors} from '~/utils/theme';
import {format} from 'd3-format'; import {format} from 'd3-format';
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import EventEmitter from 'eventemitter3'; import EventEmitter from 'eventemitter3';
export default new EventEmitter(); export default new EventEmitter();
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type {TFunction} from 'i18next'; import type {TFunction} from 'i18next';
import i18next from 'i18next'; import i18next from 'i18next';
import queryString from 'query-string'; import queryString from 'query-string';
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Fetch from 'i18next-fetch-backend'; import Fetch from 'i18next-fetch-backend';
import LanguageDetector from 'i18next-browser-languagedetector'; import LanguageDetector from 'i18next-browser-languagedetector';
import i18n from 'i18next'; import i18n from 'i18next';
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export function dataURL2Blob(base64: string): Blob { export function dataURL2Blob(base64: string): Blob {
const parts = base64.split(';base64,'); const parts = base64.split(';base64,');
const contentType = parts[0].split(':')[1]; const contentType = parts[0].split(':')[1];
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// cSpell:words quantile
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import moment from 'moment'; import moment from 'moment';
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// cSpell:words pxval mixins grayscale
import 'tippy.js/dist/tippy.css'; import 'tippy.js/dist/tippy.css';
import 'tippy.js/animations/shift-away-subtle.css'; import 'tippy.js/animations/shift-away-subtle.css';
import 'react-toastify/dist/ReactToastify.css'; import 'react-toastify/dist/ReactToastify.css';
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {darken, lighten} from 'polished'; import {darken, lighten} from 'polished';
import {css} from 'styled-components'; import {css} from 'styled-components';
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as funcs from '@visualdl/wasm'; import * as funcs from '@visualdl/wasm';
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pub struct Dataset(f64, i64, f64); pub struct Dataset(f64, i64, f64);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct Smoothed(i64, i64, f64, f64, f64); pub struct Smoothed(i64, i64, f64, f64, i64);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct Range { pub struct Range {
...@@ -44,7 +44,7 @@ pub fn transform(datasets: &Vec<Vec<Dataset>>, smoothing: f64) -> Vec<Vec<Smooth ...@@ -44,7 +44,7 @@ pub fn transform(datasets: &Vec<Vec<Dataset>>, smoothing: f64) -> Vec<Vec<Smooth
let mut num_accum: i32 = 0; let mut num_accum: i32 = 0;
let mut start_value: i64 = 0; let mut start_value: i64 = 0;
for (i, d) in dataset.iter().enumerate() { for (i, d) in dataset.iter().enumerate() {
let mut r: Smoothed = Smoothed(0, d.1, d.2, 0.0, 0.0); let mut r: Smoothed = Smoothed(0, d.1, d.2, 0.0, 0);
let next_val: f64 = d.2; let next_val: f64 = d.2;
// second to millisecond. // second to millisecond.
let millisecond: i64 = d.0.floor() as i64; let millisecond: i64 = d.0.floor() as i64;
...@@ -52,8 +52,8 @@ pub fn transform(datasets: &Vec<Vec<Dataset>>, smoothing: f64) -> Vec<Vec<Smooth ...@@ -52,8 +52,8 @@ pub fn transform(datasets: &Vec<Vec<Dataset>>, smoothing: f64) -> Vec<Vec<Smooth
if i == 0 { if i == 0 {
start_value = millisecond; start_value = millisecond;
} }
// Relative time, millisecond to hours. // Relative time in millisecond.
r.4 = ((millisecond - start_value) as f64) / (60 * 60 * 1000) as f64; r.4 = millisecond - start_value;
if next_val.is_infinite() { if next_val.is_infinite() {
r.3 = next_val; r.3 = next_val;
} else { } else {
...@@ -122,7 +122,7 @@ pub fn axis_range(datasets: &Vec<Vec<Smoothed>>, outlier: bool) -> Range { ...@@ -122,7 +122,7 @@ pub fn axis_range(datasets: &Vec<Vec<Smoothed>>, outlier: bool) -> Range {
if ranges.len() != 0 { if ranges.len() != 0 {
min = ranges min = ranges
.iter() .iter()
.min_by(|x, y| x.min.partial_cmp(&y.max).unwrap()) .min_by(|x, y| x.min.partial_cmp(&y.min).unwrap())
.unwrap() .unwrap()
.min; .min;
max = ranges max = ranges
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册