Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
VisualDL
提交
2d61c8f8
V
VisualDL
项目概览
PaddlePaddle
/
VisualDL
1 年多 前同步成功
通知
88
Star
4655
Fork
642
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
5
Wiki
分析
仓库
DevOps
项目成员
Pages
V
VisualDL
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
5
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
2d61c8f8
编写于
1月 03, 2018
作者:
B
BingBlog
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add histograms
上级
7173540f
变更
22
展开全部
隐藏空白更改
内联
并排
Showing
22 changed file
with
17224 addition
and
36 deletion
+17224
-36
frontend/mock/data/plugin/histograms/histograms.js
frontend/mock/data/plugin/histograms/histograms.js
+16338
-0
frontend/mock/data/plugin/histograms/tags.js
frontend/mock/data/plugin/histograms/tags.js
+30
-0
frontend/mock/data/plugin/scalars/tags.js
frontend/mock/data/plugin/scalars/tags.js
+0
-4
frontend/package.json
frontend/package.json
+5
-1
frontend/src/App.san
frontend/src/App.san
+12
-1
frontend/src/common/component/AppMenu.san
frontend/src/common/component/AppMenu.san
+22
-8
frontend/src/common/component/Charts/chart.san
frontend/src/common/component/Charts/chart.san
+0
-1
frontend/src/common/component/Charts/image.san
frontend/src/common/component/Charts/image.san
+0
-13
frontend/src/histogram/Histogram.san
frontend/src/histogram/Histogram.san
+165
-0
frontend/src/histogram/histogramHelper.js
frontend/src/histogram/histogramHelper.js
+67
-0
frontend/src/histogram/index.js
frontend/src/histogram/index.js
+9
-0
frontend/src/histogram/ui/chart.san
frontend/src/histogram/ui/chart.san
+358
-0
frontend/src/histogram/ui/chartPage.san
frontend/src/histogram/ui/chartPage.san
+94
-0
frontend/src/histogram/ui/config.san
frontend/src/histogram/ui/config.san
+104
-0
frontend/src/home/index.js
frontend/src/home/index.js
+1
-1
frontend/src/images/Images.san
frontend/src/images/Images.san
+0
-1
frontend/src/images/ui/chartPage.san
frontend/src/images/ui/chartPage.san
+2
-4
frontend/src/index.js
frontend/src/index.js
+1
-0
frontend/src/scalars/Scalars.san
frontend/src/scalars/Scalars.san
+2
-1
frontend/src/scalars/index.js
frontend/src/scalars/index.js
+8
-0
frontend/src/scalars/ui/chartPage.san
frontend/src/scalars/ui/chartPage.san
+1
-1
frontend/src/service.js
frontend/src/service.js
+5
-0
未找到文件。
frontend/mock/data/plugin/histograms/histograms.js
0 → 100644
浏览文件 @
2d61c8f8
此差异已折叠。
点击以展开。
frontend/mock/data/plugin/histograms/tags.js
0 → 100644
浏览文件 @
2d61c8f8
/**
* get mock data
*
* @param {string} path request path
* @param {Object} queryParam query params
* @param {Object} postParam post params
* @return {Object}
*/
module
.
exports
=
function
(
path
,
queryParam
,
postParam
)
{
return
{
// moock delay
_timeout
:
0
,
// mock http status
_status
:
200
,
// mock response data
_data
:
{
status
:
0
,
msg
:
'
SUCCESS
'
,
data
:
{
"
test
"
:
{
"
layer1/Wx_plus_b/pre_activations
"
:
{
"
displayName
"
:
"
layer1/Wx_plus_b/pre_activations
"
,
"
description
"
:
""
}
}
}
}
};
};
frontend/mock/data/plugin/scalars/tags.js
浏览文件 @
2d61c8f8
...
...
@@ -165,10 +165,6 @@ module.exports = function (path, queryParam, postParam) {
"
layer1/biases/summaries/stddev_1
"
:
{
"
displayName
"
:
"
layer1/biases/summaries/stddev_1
"
,
"
description
"
:
""
},
"
layer1/biases/summaries/min
"
:
{
"
displayName
"
:
"
layer1/biases/summaries/min
"
,
"
description
"
:
""
}
}
}
...
...
frontend/package.json
浏览文件 @
2d61c8f8
...
...
@@ -13,8 +13,12 @@
},
"dependencies"
:
{
"axios"
:
"^0.16.1"
,
"csshint"
:
"^0.3.3"
,
"d3-format"
:
"^1.2.1"
,
"echarts"
:
"^3.8.5"
,
"file-saver"
:
"^1.3.3"
,
"htmlcs"
:
"^0.4.1"
,
"lesslint"
:
"^1.0.2"
,
"lodash"
:
"^4.17.4"
,
"normalize.css"
:
"^6.0.0"
,
"qs"
:
"^6.5.1"
,
...
...
@@ -43,7 +47,7 @@
"css-loader"
:
"^0.28.0"
,
"express"
:
"^4.16.2"
,
"extract-text-webpack-plugin"
:
"^2.1.0"
,
"fecs"
:
"
^1.5.3
"
,
"fecs"
:
"
1.5.2
"
,
"file-loader"
:
"^0.11.1"
,
"friendly-errors-webpack-plugin"
:
"^1.6.1"
,
"glob"
:
"^7.1.1"
,
...
...
frontend/src/App.san
浏览文件 @
2d61c8f8
<template>
<div id="app">
<ui-app-menu
selected="{{route}}"
on-item-click="menuChange($event)"
></ui-app-menu>
<div id="content-container" class="visual-dl-content-container">
...
...
@@ -21,10 +22,20 @@ export default {
'ui-app-menu': AppMenu
},
initData() {
return {};
return {
route: 'scalars'
};
},
attached() {
router.start();
let route;
if (location.hash) {
route = /(\#\/)(\w*)([?|&]{0,1})/.exec(location.hash)[2];
this.data.set('route', route);
}
else {
location.hash = '#/scalars';
}
},
menuChange({value, url, title}) {
routeTo(url);
...
...
frontend/src/common/component/AppMenu.san
浏览文件 @
2d61c8f8
...
...
@@ -4,7 +4,7 @@
<san-menu slot="right">
<san-menu-item
san-for="item in items"
class="{{selected === item.
valu
e ? 'sm-menu-item-selected' : ''}}"
class="{{selected === item.
nam
e ? 'sm-menu-item-selected' : ''}}"
on-click="handleItemClick(item)"
title="{{item.title}}" />
</san-menu>
...
...
@@ -23,23 +23,28 @@ export default {
},
initData() {
return {
selected: '
1
',
selected: '
scalars
',
items: [
{
value: '1',
url: '/scalars',
title: 'SCALARS'
title: 'SCALARS',
name: 'scalars'
},
{
value: '2',
url: '/images',
title: 'IMAGES'
title: 'IMAGES',
name: 'images'
},
{
url: '/histograms',
title: 'HISTOGRAMS',
name: 'histograms'
}
]
};
},
handleItemClick(item) {
this.data.set('selected', item.
valu
e);
this.data.set('selected', item.
nam
e);
this.fire('item-click', item);
}
};
...
...
@@ -61,7 +66,16 @@ export default {
height 100%
display flex
flex-direction row
.sm-menu-item
.sm-menu-item-content
color #fff
opacity 0.6
.sm-menu-item:hover
background none
opacity 1
.sm-menu-item-selected
background #e4e4e4
.sm-menu-item-content
color #fff
opacity 1
</style>
frontend/src/common/component/Charts/chart.san
浏览文件 @
2d61c8f8
...
...
@@ -457,7 +457,6 @@ export default {
height: 300
});
}
},
getFormatterPoints(data) {
...
...
frontend/src/common/component/Charts/image.san
浏览文件 @
2d61c8f8
...
...
@@ -41,13 +41,11 @@ export default {
if (isActualImageSize) {
width = this.data.get('imgData.width');
height = this.data.get('imgData.height');
console.log('1111', width, height);
}
else {
width = defaultImgWidth;
height = defaultImgHight;
}
// console.log('width:' + width + 'px;height:' + height + 'px');
return 'width:' + width + 'px;height:' + height + 'px';
}
},
...
...
@@ -101,17 +99,6 @@ export default {
});
/* eslint-enable fecs-camelcase */
});
// isActualImageSize change event
this.watch('isActualImageSize', isActualImageSize => {
console.log(isActualImageSize);
});
// isActualImageSize change event
this.watch('runs', runs => {
console.log(runs);
});
},
handleSlideChange(val) {
this.data.set('currentIndex', val);
...
...
frontend/src/histogram/Histogram.san
0 → 100644
浏览文件 @
2d61c8f8
<template>
<div class="visual-dl-scalar-container">
<div class="visual-dl-scalar-left">
<div class="visual-dl-scalar-config-container">
<ui-config
runsItems="{{runsItems}}"
config="{=config=}"
></ui-config>
</div>
</div>
<div class="visual-dl-scalar-right">
<ui-chart-page
config="{{config}}"
runsItems="{{runsItems}}"
tagList="{{filteredTagsList}}"
title="Tags matching {{config.groupNameReg}}"
></ui-chart-page>
<ui-chart-page
san-for="item in groupedTags"
config="{{config}}"
runsItems="{{runsItems}}"
tagList="{{item.tags}}"
title="{{item.group}}"
></ui-chart-page>
</div>
</div>
</template>
<script>
import {getPluginHistogramsTags, getRuns} from '../service';
import config from './ui/config';
import chartPage from './ui/chartPage';
import {debounce, flatten, uniq} from 'lodash';
export default {
components: {
'ui-config': config,
'ui-chart-page': chartPage
},
computed: {
runsItems() {
let runsArray = this.data.get('runsArray') || [];
return runsArray.map(item => {
return {
name: item,
value: item
};
});
},
tagsList() {
let tags = this.data.get('tags');
let runs = Object.keys(tags);
let tagsArray = runs.map(run => Object.keys(tags[run]));
let allUniqTags = uniq(flatten(tagsArray));
// get the data for every chart
return allUniqTags.map(tag => {
let tagList = runs.map(run => {
return {
run,
tag: tags[run][tag]
};
});
return {
tagList,
tag,
group: tag.split('/')[0]
};
});
},
groupedTags() {
let tagsList = this.data.get('tagsList') || [];
// put data in group
let groupData = {};
tagsList.forEach(item => {
let group = item.group;
if (groupData[group] === undefined) {
groupData[group] = [];
groupData[group].push(item);
}
else {
groupData[group].push(item);
}
});
// to array
let groups = Object.keys(groupData);
return groups.map(group => {
return {
group,
tags: groupData[group]
};
});
}
// ,
// filteredConfig() {
// let config = this.data.get('config') || {};
// let filteredConfig = {};
// Object.keys(config).forEach(key => {
// let val = config[key];
// filteredConfig[key] = val;
// });
// return filteredConfig;
// }
},
initData() {
return {
runsArray: [],
tags: [],
config: {
groupNameReg: '.*',
horizontal: 'step',
chartType: 'offset',
runs: [],
running: true
}
};
},
inited() {
getPluginHistogramsTags().then(({errno, data}) => {
this.data.set('tags', data);
// filter when inited
let groupNameReg = this.data.get('config.groupNameReg');
this.filterTagsList(groupNameReg);
});
getRuns().then(({errno, data}) => {
this.data.set('runsArray', data);
this.data.set('config.runs', data);
});
// need debounce, can't use computed
this.watch('config.groupNameReg', debounce(this.filterTagsList, 300));
},
filterTagsList(groupNameReg) {
let tagsList = this.data.get('tagsList') || [];
let regExp = new RegExp(groupNameReg);
let filtedTagsList = tagsList.filter(item => regExp.test(item.tag));
this.data.set('filteredTagsList', filtedTagsList);
}
};
</script>
<style lang="stylus">
@import '../style/variables';
+prefix-classes('visual-dl-scalar-')
.container
padding-left 300px
position relative
.left
width 280px
min-height 300px
border solid 1px #e4e4e4
position absolute
left 0
.right
width 100%
border solid 1px #e4e4e4
min-height 300px
padding 20px
</style>
frontend/src/histogram/histogramHelper.js
0 → 100644
浏览文件 @
2d61c8f8
import
{
min
,
max
,
range
}
from
'
lodash
'
;
export
const
tansformHistogramData
=
hitogramData
=>
{
let
[
time
,
step
,
items
]
=
hitogramData
;
return
{
time
,
step
,
min
:
min
(
items
.
map
(([
left
,
right
,
count
])
=>
left
)),
max
:
max
(
items
.
map
(([
left
,
right
,
count
])
=>
right
)),
items
:
items
.
map
(([
left
,
right
,
count
])
=>
({
left
,
right
,
count
}))
};
};
export
const
computeTempDatas
=
(
histogram
,
min
,
max
,
numbers
=
30
)
=>
{
if
(
max
===
min
)
{
// Create bins even if all the data has a single value.
max
=
min
*
1.1
+
1
;
min
=
min
/
1.1
-
1
;
}
let
stepWidth
=
(
max
-
min
)
/
numbers
;
let
index
=
0
;
return
range
(
min
,
max
,
stepWidth
).
map
(
left
=>
{
let
right
=
left
+
stepWidth
;
let
yValue
=
0
;
while
(
index
<
histogram
.
items
.
length
)
{
let
itemRight
=
Math
.
min
(
max
,
histogram
.
items
[
index
].
right
);
let
itemLeft
=
Math
.
max
(
min
,
histogram
.
items
[
index
].
left
);
let
intersect
=
Math
.
min
(
itemRight
,
right
)
-
Math
.
max
(
itemLeft
,
left
);
let
count
=
(
intersect
/
(
itemRight
-
itemLeft
))
*
histogram
.
items
[
index
].
count
;
yValue
+=
intersect
>
0
?
count
:
0
;
// If `bucketRight` is bigger than `binRight`, then this bin is
// finished and there is data for the next bin, so don't increment
// `index`.
if
(
itemRight
>
right
)
{
break
;
}
index
++
;
}
return
{
x
:
left
,
dx
:
stepWidth
,
y
:
yValue
};
});
};
export
const
tansformToChartData
=
(
tempData
,
time
,
step
)
=>
tempData
.
map
(({
x
,
dx
,
y
})
=>
[
time
,
step
,
x
+
dx
/
2
,
Math
.
floor
(
y
)]);
export
const
originDataToChartData
=
originData
=>
{
let
tempDatas
=
originData
.
map
(
tansformHistogramData
);
let
finalMin
=
min
(
tempDatas
.
map
(({
min
})
=>
min
));
let
finalMax
=
max
(
tempDatas
.
map
(({
max
})
=>
max
));
let
chartData
=
tempDatas
.
map
(
item
=>
{
let
computedTempDatas
=
computeTempDatas
(
item
,
finalMin
,
finalMax
);
let
{
time
,
step
}
=
item
;
return
{
time
,
step
,
items
:
tansformToChartData
(
computedTempDatas
,
time
,
step
)
};
});
return
{
min
:
finalMin
,
max
:
finalMax
,
chartData
};
};
frontend/src/histogram/index.js
0 → 100644
浏览文件 @
2d61c8f8
import
{
router
}
from
'
san-router
'
;
import
Histogram
from
'
./Histogram
'
;
router
.
add
({
target
:
'
#content
'
,
rule
:
'
/histograms
'
,
Component
:
Histogram
});
frontend/src/histogram/ui/chart.san
0 → 100644
浏览文件 @
2d61c8f8
<template>
<div class="visual-dl-charts">
<div class="visual-dl-chart-box">
</div>
<div class="visual-dl-chart-actions">
<san-button on-click="expandArea">
<san-icon size="20">settings_overscan</san-icon>
</san-button>
</div>
</div>
</template>
<script>
// components
import Button from 'san-mui/Button';
import Icon from 'san-mui/Icon';
// libs
import echarts from 'echarts';
import {originDataToChartData} from '../histogramHelper';
import {format, precisionRound} from 'd3-format';
// service
import {getPluginHistogramsHistograms} from '../../service';
const highlightLineColor = '#2f4554';
const defaultLineColor = '#fec42c';
const lineWidth = 1;
// the time to refresh chart data
const intervalTime = 30;
const p = Math.max(0, precisionRound(0.01, 1.01) - 1);
const yValueFormat = format('.' + p + 'e');
export default {
components: {
'san-button': Button,
'san-icon': Icon
},
computed: {
},
initData() {
return {
width: 400,
height: 300,
data: [
{
name: 'train',
value: []
}
]
};
},
inited() {
this.watch('originData', data => {
this.initChartChartOption();
});
this.watch('chartType', chartType => {
this.initChartChartOption();
});
},
attached() {
let tagInfo = this.data.get('tagInfo');
this.initCharts(tagInfo);
this.initeChartsEvent();
if (this.data.get('running')) {
this.startInterval();
}
this.watch('running', running => {
running ? this.startInterval() : this.stopInterval();
});
},
detached() {
this.stopInterval();
},
initCharts(tagInfo) {
this.createChart();
// this.setChartsOptions(tagInfo);
this.getOriginChartsData(tagInfo);
},
createChart() {
let el = this.el.getElementsByClassName('visual-dl-chart-box')[0];
this.myChart = echarts.init(el);
},
initChartChartOption() {
this.myChart.clear();
let data = this.data.get('originData');
let chartData = originDataToChartData(data);
let tagInfo = this.data.get('tagInfo');
let title = tagInfo.tag.displayName + '(' + tagInfo.run + ')';
let chartType = this.data.get('chartType');
this.setChartOptions(chartData, title, chartType);
},
setChartOptions(chartData, tag, chartType) {
let grid = {
left: '15%',
top: '20%',
right: '10%',
bottom: '20%'
};
let title = {
text: tag,
textStyle: {
fontSize: '12'
}
};
if (chartType === 'overlay') {
this.setOverlayChartOption(chartData, title, grid);
}
else if (chartType === 'offset') {
this.setOffsetChartOption(chartData, title, grid);
}
},
setOverlayChartOption({chartData, min, max}, title, grid) {
let seriesOption = chartData.map(({time, step, items}) => ({
name: 'step' + step,
type: 'line',
showSymbol: false,
hoverAnimation: false,
z: 0,
data: items,
animationDuration: 100,
lineStyle: {
normal: {
// opacity: originLinesOpacity,
width: lineWidth,
color: defaultLineColor
}
},
encode: {
x: [2],
y: [3]
}
})
);
let option = {
title: title,
axisPointer: {
link: {xAxisIndex: 'all'},
show: true,
snap: true,
triggerTooltip: true
},
grid: grid,
xAxis: {
type: 'value'
},
yAxis: {
type: 'value',
axisLabel: {
formatter(value, index) {
return yValueFormat(value);
}
},
axisPointer: {
label: {
formatter({value}) {
return yValueFormat(value);
}
}
}
},
series: seriesOption
};
this.myChart.setOption(option);
},
setOffsetChartOption({chartData, min, max}, title, grid) {
let rawData = [];
let minX = min;
let maxX = max;
let minZ = Infinity;
let maxZ = -Infinity;
grid.top = '60%';
chartData.forEach(({items}) => {
let lineData = [];
items.forEach(([time, step, x, y]) => {
minX = Math.min(minX, x);
maxX = Math.max(maxX, x);
minZ = Math.min(minZ, y);
maxZ = Math.max(maxZ, y);
lineData.push(x, step, y);
});
rawData.push(lineData);
});
// Max height in z axis.
let Z_HEIGHT = 100;
let option = {
title,
visualMap: {
type: 'continuous',
show: false,
min: 0,
max: 1000,
dimension: 1,
inRange: {
colorLightness: [0.3, 0.7]
}
},
xAxis: {
// min: minX - (maxX - minX) * 0.3,
// max: maxX + (maxX - minX) * 0.3,
min: minX,
max: maxX,
axisLine: {
onZero: false
},
splitLine: {
show: false
}
},
yAxis: {
position: 'right',
inverse: true,
splitLine: {
show: false
}
},
grid,
series: [{
type: 'custom',
dimensions: ['x', 'y'],
renderItem(params, api) {
let points = [];
for (let i = 0; i < rawData[params.dataIndex].length;) {
let x = api.value(i++);
let y = api.value(i++);
let z = api.value(i++);
let pt = api.coord([x, y]);
// Linear map in z axis
pt[1] -= (z - minZ) / (maxZ - minZ) * Z_HEIGHT;
points.push(pt);
}
return {
type: 'polygon',
shape: {
points
},
style: api.style({
stroke: '#bbb',
lineWidth: 1
})
};
},
data: rawData
}]
};
this.myChart.setOption(option);
},
// get origin data per 60 seconds
startInterval() {
this.getOringDataInterval = setInterval(() => {
let tagInfo = this.data.get('tagInfo');
this.getOriginChartsData(tagInfo);
}, intervalTime * 1000);
},
stopInterval() {
clearInterval(this.getOringDataInterval);
},
getOriginChartsData({run, tag}) {
let params = {
run,
tag: tag.displayName
};
getPluginHistogramsHistograms(params).then(({data}) => {
this.data.set('originData', data);
});
},
lightHoveredLine({seriesIndex}) {
let series = this.myChart.getOption().series;
let newSeries = series.map((item, index) => {
if (seriesIndex === index) {
item.lineStyle.normal.color = highlightLineColor;
item.zlevel = 1;
}
else {
item.lineStyle.normal.color = defaultLineColor;
item.zlevel = 0;
}
return item;
});
this.myChart.setOption({
series: newSeries
});
},
initeChartsEvent() {
this.myChart.on('mousemove', params => {
let chartType = this.data.get('chartType');
if (chartType === 'overlay') {
this.lightHoveredLine(params);
}
});
},
expandArea() {
let isExpand = this.data.get('isExpand');
if (!isExpand) {
let el = this.el.getElementsByClassName('visual-dl-chart-box')[0];
el.style.width = '800px';
el.style.height = '600px';
this.data.set('isExpand', true);
this.myChart.resize({
width: 800,
height: 600
});
}
else {
let el = this.el.getElementsByClassName('visual-dl-chart-box')[0];
el.style.width = '400px';
el.style.height = '300px';
this.data.set('isExpand', false);
this.myChart.resize({
width: 400,
height: 300
});
}
}
};
</script>
<style lang="stylus">
.visual-dl-charts
float left
margin-bottom 20px
.visual-dl-chart-box
width 400px;
height 300px;
.visual-dl-chart-actions
height 50px
margin-left 10%
.sm-form-item
float left
width 100px
margin-top 0px
display block
.sm-button
float left
display block
height 20px
line-height 20px
margin-top 10px
padding 0 10px
</style>
frontend/src/histogram/ui/chartPage.san
0 → 100644
浏览文件 @
2d61c8f8
<template>
<div class="visual-dl-chart-page">
<ui-expand-panel info="{{itemsLength}}" title="{{title}}">
<div san-for="tag in filteredPageList" class="visual-dl-chart-box">
<ui-chart
san-for="tag in tag.tagList"
tagInfo="{{tag}}"
runs="{{config.runs}}"
chartType="{{config.chartType}}"
runsItems="{{runsItems}}"
></ui-chart>
</div>
<ui-pagination
san-if="total > pageSize"
on-pageChange="handlePageChange($event)"
current="{{currentPage}}"
pageSize="{{pageSize}}"
total="{{total}}"
showSizeChanger="{{false}}"
/>
</ui-expand-panel>
</div>
</template>
<script>
import ExpandPanel from '../../common/component/ExpandPanel';
import Chart from './chart';
import Pagination from 'san-mui/Pagination';
import {cloneDeep} from 'lodash';
export default {
components: {
'ui-chart': Chart,
'ui-expand-panel': ExpandPanel,
'ui-pagination': Pagination
},
computed: {
filteredRunsList() {
let tagList = this.data.get('tagList') || [];
let runs = this.data.get('config.runs') || [];
let list = cloneDeep(tagList);
return list.slice().map(item => {
item.tagList = item.tagList.filter(one => runs.includes(one.run));
return item;
});
},
filteredPageList() {
let list = this.data.get('filteredRunsList');
let currentPage = this.data.get('currentPage');
let pageSize = this.data.get('pageSize');
return list.slice((currentPage - 1) * pageSize, currentPage * pageSize);
},
total() {
let list = this.data.get('filteredRunsList') || [];
return list.reduce((num, item) => {
let length = item.tagList.length;
return length ? num + 1 : num;
}, 0);
},
itemsLength() {
let list = this.data.get('filteredRunsList') || [];
return list.reduce((num, item) => {
let length = item.tagList.length;
return length + num;
}, 0);
}
},
initData() {
return {
// current page
currentPage: 1,
// item per page
pageSize: 4
};
},
handlePageChange({pageNum}) {
this.data.set('currentPage', pageNum);
}
};
</script>
<style lang="stylus">
@import '../../style/variables';
+prefix-classes('visual-dl-')
.chart-page
.chart-box
float left
.chart-box:after
content: "";
clear: both;
display: block;
</style>
frontend/src/histogram/ui/config.san
0 → 100644
浏览文件 @
2d61c8f8
<template>
<div class="visual-dl-scalar-config-com">
<san-text-field
hintText="input a tag group name to search"
label="Group name RegExp"
inputValue="{=config.groupNameReg=}"
/>
<ui-radio-group
label="Histogram mode"
value="{=config.chartType=}"
items="{{charTypeItems}}"
/>
<ui-radio-group
label="Horizontal"
value="{=config.horizontal=}"
items="{{horizontalItems}}"
/>
<ui-checkbox-group
value="{=config.runs=}"
label="Runs"
items="{{runsItems}}"
/>
<san-button
class="visual-dl-scalar-run-toggle"
variants="raised {{config.running ? 'secondery' : 'primary'}}"
on-click="toggleAllRuns"
>
{{config.running ? 'Running' : 'Stopped'}}
</san-button>
</div>
</template>
<script>
import TextField from 'san-mui/TextField';
import Slider from '../../common/component/Slider';
import RadioGroup from '../../common/component/RadioGroup';
import DropDownMenu from '../../common/component/DropDownMenu';
import CheckBoxGroup from '../../common/component/CheckBoxGroup';
import Button from 'san-mui/Button';
export default {
components: {
'san-text-field': TextField,
'ui-slider': Slider,
'ui-radio-group': RadioGroup,
'ui-dropdown-menu': DropDownMenu,
'ui-checkbox-group': CheckBoxGroup,
'san-button': Button
},
initData() {
return {
config: {
groupNameReg: '.*',
smoothing: '0.6',
horizontal: 'step',
sortingMethod: 'default',
downloadLink: [],
outlier: [],
running: true
},
horizontalItems: [
{
name: 'Step',
value: 'step'
},
{
name: 'Relative',
value: 'relative'
},
{
name: 'Wall',
value: 'wall'
}
],
runsItems: [],
charTypeItems: [
{
name: 'Overlay',
value: 'overlay'
},
{
name: 'Offset',
value: 'offset'
}
]
};
},
toggleAllRuns() {
let running = this.data.get('config.running');
this.data.set('config.running', !running);
this.fire('runningChange', running);
}
};
</script>
<style lang="stylus">
@import '../../style/variables';
+prefix-classes('visual-dl-scalar-')
.config-com
width 90%
margin 0 auto
.run-toggle
width 100%
margin-top 20px
</style>
frontend/src/home/index.js
浏览文件 @
2d61c8f8
...
...
@@ -4,6 +4,6 @@ import HomePage from './Home';
router
.
add
({
target
:
'
#content
'
,
rule
:
'
/
'
,
rule
:
'
/
welcome
'
,
Component
:
HomePage
});
frontend/src/images/Images.san
浏览文件 @
2d61c8f8
...
...
@@ -95,7 +95,6 @@ export default {
filteredConfig() {
let tansformArr = ['isActualImageSize'];
let config = this.data.get('config') || {};
console.log(config);
let filteredConfig = {};
Object.keys(config).forEach(key => {
let val = config[key];
...
...
frontend/src/images/ui/chartPage.san
浏览文件 @
2d61c8f8
...
...
@@ -38,7 +38,7 @@ export default {
filteredRunsList() {
let tagList = this.data.get('tagList') || [];
let runs = this.data.get('config.runs') || [];
let list = cloneDeep(tagList)
let list = cloneDeep(tagList)
;
return list.slice().map(item => {
item.tagList = item.tagList.filter(one => runs.includes(one.run));
return item;
...
...
@@ -47,14 +47,12 @@ export default {
filteredPageList() {
let list = this.data.get('filteredRunsList');
let runs = this.data.get('config.runs') || [];
let currentPage = this.data.get('currentPage');
let pageSize = this.data.get('pageSize');
return list.slice((currentPage - 1) * pageSize, currentPage * pageSize);
},
total() {
let list = this.data.get('filteredRunsList') || [];
console.log(list);
return list.reduce((num, item) => {
let length = item.tagList.length;
return length ? num + 1 : num;
...
...
@@ -64,7 +62,7 @@ export default {
let list = this.data.get('filteredRunsList') || [];
return list.reduce((num, item) => {
let length = item.tagList.length;
return length + num
;
return length + num;
}, 0);
}
},
...
...
frontend/src/index.js
浏览文件 @
2d61c8f8
...
...
@@ -5,6 +5,7 @@ import './common/component/ui-common.styl';
import
'
./home/index
'
;
import
'
./scalars/index
'
;
import
'
./images/index
'
;
import
'
./histogram/index
'
;
import
App
from
'
./App
'
;
new
App
({
...
...
frontend/src/scalars/Scalars.san
浏览文件 @
2d61c8f8
...
...
@@ -10,6 +10,7 @@
</div>
<div class="visual-dl-scalar-right">
<ui-chart-page
expand="{{true}}"
config="{{filteredConfig}}"
runsItems="{{runsItems}}"
tagList="{{filteredTagsList}}"
...
...
@@ -118,7 +119,7 @@ export default {
horizontal: 'step',
sortingMethod: 'default',
downloadLink: [],
outlier: [],
outlier: [
'yes'
],
runs: [],
running: true
}
...
...
frontend/src/scalars/index.js
浏览文件 @
2d61c8f8
...
...
@@ -2,8 +2,16 @@ import {router} from 'san-router';
import
Scalar
from
'
./Scalars
'
;
router
.
add
({
target
:
'
#content
'
,
rule
:
'
/
'
,
Component
:
Scalar
});
router
.
add
({
target
:
'
#content
'
,
rule
:
'
/scalars
'
,
Component
:
Scalar
});
frontend/src/scalars/ui/chartPage.san
浏览文件 @
2d61c8f8
<template>
<div class="visual-dl-chart-page">
<ui-expand-panel info="{{tagList.length}}" title="{{title}}">
<ui-expand-panel i
sShow="{{expand}}" i
nfo="{{tagList.length}}" title="{{title}}">
<div class="visual-dl-chart-box">
<ui-chart
san-for="tag in filteredTagList"
...
...
frontend/src/service.js
浏览文件 @
2d61c8f8
...
...
@@ -9,3 +9,8 @@ export const getPluginScalarsScalars = makeService('/data/plugin/scalars/scalars
export
const
getPluginImagesTags
=
makeService
(
'
/data/plugin/images/tags
'
);
export
const
getPluginImagesImages
=
makeService
(
'
/data/plugin/images/images
'
);
export
const
getPluginHistogramsTags
=
makeService
(
'
/data/plugin/histograms/tags
'
);
export
const
getPluginHistogramsHistograms
=
makeService
(
'
/data/plugin/histograms/histograms
'
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录