Skip to content

Commit

Permalink
Histogram (#670)
Browse files Browse the repository at this point in the history
* doc: update readme

* feat: histogram
  • Loading branch information
PeterPanZH authored Jun 19, 2020
1 parent 69c9030 commit 7bdb74b
Show file tree
Hide file tree
Showing 52 changed files with 1,852 additions and 710 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</p>

<p align="center">
<a href="javascript:void(0)"><img src="https://img.shields.io/badge/QQ_Group-1045783368-52B6EF?style=social&logo=tencent-qq&logoColor=000&logoWidth=20" alt="QQ Group" /></a>
<a href="https://jq.qq.com/?_wv=1027&k=TyzyVT4C" target="_blank" rel="noreferrer"><img src="https://img.shields.io/badge/QQ_Group-1045783368-52B6EF?style=social&logo=tencent-qq&logoColor=000&logoWidth=20" alt="QQ Group" /></a>
</p>

## 介绍
Expand Down Expand Up @@ -245,7 +245,9 @@ app.run(logdir="./log")

## 开源贡献

VisualDL 是由 [PaddlePaddle](https://www.paddlepaddle.org/)[ECharts](https://echarts.apache.org/) 合作推出的开源项目。欢迎所有人使用,提意见以及贡献代码。
VisualDL 是由 [PaddlePaddle](https://www.paddlepaddle.org/)[ECharts](https://echarts.apache.org/) 合作推出的开源项目。
Graph 相关功能由 [Netron](https://github.com/lutzroeder/netron) 提供技术支持。
欢迎所有人使用,提意见以及贡献代码。


## 更多细节
Expand All @@ -254,7 +256,7 @@ VisualDL 是由 [PaddlePaddle](https://www.paddlepaddle.org/) 和 [ECharts](http

## 技术交流

欢迎您加入VisualDL官方qq群:1045783368 与飞桨团队以及其他用户共同针对VisualDL进行讨论与交流。
欢迎您加入VisualDL官方QQ群:1045783368 与飞桨团队以及其他用户共同针对VisualDL进行讨论与交流。

<p align="center">
<img src="https://user-images.githubusercontent.com/48054808/82522691-c2758680-9b5c-11ea-9aee-fca994aba175.png" width="20%"/>
Expand Down
1 change: 1 addition & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ This project is based on following projects:
- [React](https://reactjs.org/)
- [ECharts](https://echarts.apache.org/)
- [wasm-pack](https://rustwasm.github.io/wasm-pack/)
- [Netron](https://github.com/lutzroeder/netron)

## Author
<table><tr><td align="center"><a href="https://github.com/PeterPanZH"><img src="https://avatars0.githubusercontent.com/u/3366499?s=460&v=4" width="120px;" alt="PeterPanZH"/><br /><sub><b>PeterPanZH</b></sub></a></td><td align="center"><a href="https://github.com/Niandalu"><img src="https://avatars1.githubusercontent.com/u/6406875?s=460&v=4" width="120px;" alt="Niandalu"/><br /><sub><b>Niandalu</b></sub></a></td></tr></table>
Expand Down
2 changes: 2 additions & 0 deletions frontend/README_cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ VisualDL 支持最新版本的 [Google Chrome](https://www.google.com/chrome/)
- [Next.js](https://nextjs.org/)
- [React](https://reactjs.org/)
- [ECharts](https://echarts.apache.org/)
- [wasm-pack](https://rustwasm.github.io/wasm-pack/)
- [Netron](https://github.com/lutzroeder/netron)

## 作者
<table><tr><td align="center"><a href="https://github.com/PeterPanZH"><img src="https://avatars0.githubusercontent.com/u/3366499?s=460&v=4" width="120px;" alt="PeterPanZH"/><br /><sub><b>PeterPanZH</b></sub></a></td><td align="center"><a href="https://github.com/Niandalu"><img src="https://avatars1.githubusercontent.com/u/6406875?s=460&v=4" width="120px;" alt="Niandalu"/><br /><sub><b>Niandalu</b></sub></a></td></tr></table>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Dimension, DivideParams, Point, Reduction, divide} from '~/resource/high-dimensional';
import {Dimension, Reduction, divide} from '~/resource/high-dimensional';
import React, {FunctionComponent, useMemo} from 'react';
import {contentHeight, primaryColor, rem} from '~/utils/style';

Expand All @@ -10,11 +10,8 @@ import {useRunningRequest} from '~/hooks/useRequest';
import {useTranslation} from '~/utils/i18n';

const divideWasm = () =>
import('@visualdl/wasm').then(({divide}) => (params: DivideParams) =>
(divide(params.points, params.labels, !!params.visibility, params.keyword ?? '') as unknown) as [
Point[],
Point[]
]
import('@visualdl/wasm').then(({high_dimensional_divide}): typeof divide => params =>
high_dimensional_divide(params.points, params.labels, !!params.visibility, params.keyword ?? '')
);
const divideWorker = () => new Worker('~/worker/high-dimensional/divide.worker.ts', {type: 'module'});

Expand Down
170 changes: 170 additions & 0 deletions frontend/packages/core/components/HistogramPage/HistogramChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import {HistogramData, Modes, OffsetData, OverlayData, options as chartOptions, transform} from '~/resource/histogram';
import LineChart, {LineChartRef} from '~/components/LineChart';
import React, {FunctionComponent, useCallback, useMemo, useRef, useState} from 'react';
import StackChart, {StackChartRef} from '~/components/StackChart';
import {rem, size} from '~/utils/style';

import ChartToolbox from '~/components/ChartToolbox';
import {EChartOption} from 'echarts';
import {Run} from '~/types';
import ee from '~/utils/event';
import queryString from 'query-string';
import styled from 'styled-components';
import useHeavyWork from '~/hooks/useHeavyWork';
import {useRunningRequest} from '~/hooks/useRequest';
import {useTranslation} from '~/utils/i18n';

const transformWasm = () =>
import('@visualdl/wasm').then(({histogram_transform}): typeof transform => params =>
histogram_transform(params.data, params.mode)
);
const transformWorker = () => new Worker('~/worker/histogram/transform.worker.ts', {type: 'module'});

const Wrapper = styled.div`
${size('100%', '100%')}
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: space-between;
`;

const StyledLineChart = styled(LineChart)`
flex-grow: 1;
`;

const StyledStackChart = styled(StackChart)`
flex-grow: 1;
`;

const Toolbox = styled(ChartToolbox)`
margin-left: ${rem(20)};
margin-right: ${rem(20)};
margin-bottom: ${rem(18)};
`;

const Error = styled.div`
${size('100%', '100%')}
display: flex;
justify-content: center;
align-items: center;
`;

type HistogramChartProps = {
cid: symbol;
run: Run;
tag: string;
mode: Modes;
running?: boolean;
onToggleMaximized?: (maximized: boolean) => void;
};

const HistogramChart: FunctionComponent<HistogramChartProps> = ({cid, run, tag, mode, running}) => {
const {t} = useTranslation(['histogram', 'common']);

const echart = useRef<LineChartRef | StackChartRef>(null);

const {data: dataset, error, loading} = useRunningRequest<HistogramData>(
`/histogram/list?${queryString.stringify({run: run.label, tag})}`,
!!running
);

const [maximized, setMaximized] = useState<boolean>(false);
const toggleMaximized = useCallback(() => {
ee.emit('toggle-chart-size', cid, !maximized);
setMaximized(m => !m);
}, [cid, maximized]);

const title = useMemo(() => `${tag} (${run.label})`, [tag, run.label]);

const params = useMemo(
() => ({
data: dataset ?? [],
mode
}),
[dataset, mode]
);
const data = useHeavyWork(transformWasm, transformWorker, transform, params);

const chartData = useMemo(() => {
type Optional<T> = T | undefined;
if (mode === Modes.Overlay) {
return (data as Optional<OverlayData>)?.data.map(items => ({
name: `step${items[0][1]}`,
data: items,
encode: {
x: [2],
y: [3]
}
}));
}
if (mode === Modes.Offset) {
return {
...((data as Optional<OffsetData>) ?? {})
};
}
}, [data, mode]);

const options = useMemo(
() => ({
...chartOptions[mode],
color: [run.colors[0]]
}),
[mode, run]
);

const chart = useMemo(() => {
if (mode === Modes.Overlay) {
return (
<StyledLineChart
ref={echart as React.RefObject<LineChartRef>}
title={title}
data={chartData as EChartOption<EChartOption.SeriesLine>['series']}
options={options}
loading={loading}
/>
);
}
if (mode === Modes.Offset) {
return (
<StyledStackChart
ref={echart as React.RefObject<StackChartRef>}
title={title}
data={chartData as EChartOption<EChartOption.SeriesCustom>['series'] & OffsetData}
options={options}
loading={loading}
/>
);
}
return null;
}, [chartData, loading, mode, options, title]);

// display error only on first fetch
if (!data && error) {
return <Error>{t('common:error')}</Error>;
}

return (
<Wrapper>
{chart}
<Toolbox
items={[
{
icon: 'maximize',
activeIcon: 'minimize',
tooltip: t('histogram:maximize'),
activeTooltip: t('histogram:minimize'),
toggle: true,
onClick: toggleMaximized
},
{
icon: 'download',
tooltip: t('histogram:download-image'),
onClick: () => echart.current?.saveAsImage()
}
]}
/>
</Wrapper>
);
};

export default HistogramChart;
Loading

0 comments on commit 7bdb74b

Please sign in to comment.