提交 35ecf344 编写于 作者: J Jeff Wang 提交者: daminglu

Create text ui feature (#337)

上级 a6ec53ce
/**
* 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": {
"layer3/generated/animal": {
"displayName": "layer3/generated/animal",
"description": ""
}
},
"train": {
"layer3/generated/animal": {
"displayName": "layer3/generated/animal",
"description": ""
},
"layer3/generated/flower": {
"displayName": "layer3/generated/flower",
"description": ""
},
}
}
}
};
};
/**
* 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) {
if (queryParam.run === 'train') {
return {
// moock delay
_timeout: 0,
// mock http status
_status: 200,
// mock response data
_data: {
status: 0,
msg: 'SUCCESS',
data: [[1511842145.705075, 1, "Hello 1"], [1511842145.7388, 2, "Hello 2"], [1511842145.774563, 3, "Hello 3"], [1511842145.806828, 4, "Hello 4"], [1511842145.838082, 5, "Hello 5"], [1511842145.868955, 6, "Hello 6"], [1511842145.899323, 7, "Hello 7"], [1511842145.930518, 8, "Hello 8"], [1511842145.96089, 9, "Hello 7"], [1511842146.460557, 11, "Hello 11"], [1511842146.4952, 12, "Hello 12"], [1511842146.525936, 13, "Hello 13"], [1511842146.556059, 14, "Hello 14"], [1511842146.648703, 15, "Hello 15"], [1511842146.683295, 16, "Hello 16"], [1511842146.719782, 17, "Hello 17"], [1511842146.752392, 18, "Hello 18"]]
}
}
}
else {
return {
// moock delay
_timeout: 0,
// mock http status
_status: 200,
// mock response data
_data: {
status: 0,
msg: 'SUCCESS',
data: [[1511842145.514333, 0, "Hello 0"], [1511842146.427384, 10, "Hello 10"], [1511842147.260405, 20, "Hello 20"], [1511842148.019018, 30, "Hello 30 "], [1511842148.793569, 40, "Hello 40 "], [1511842149.610228, 50, "Hello 50 "], [1511842150.437095, 60, "Hello 60"], [1511842151.254679, 70, "Hello 70"], [1511842152.039353, 80, "Hello 80"], [1511842152.800043, 90, "Hello 90"]]
}
}
}
};
......@@ -41,6 +41,11 @@ export default {
url: '/graphs',
title: 'GRAPHS',
name: 'graphs'
},
{
url: '/texts',
title: 'TEXTS',
name: 'texts'
}
]
}
......
......@@ -5,6 +5,7 @@ import Scalars from '@/scalars/Scalars'
import Histogram from '@/histogram/Histogram'
import Images from '@/images/Images'
import Graph from '@/graph/Graph'
import Texts from '@/texts/Texts'
Vue.use(Router)
......@@ -30,5 +31,10 @@ export default new Router({
name: 'Graph',
component: Graph
},
{
path: '/texts',
name: 'Texts',
component: Texts
}
]
})
......@@ -15,3 +15,7 @@ export const getPluginHistogramsTags = makeService('/data/plugin/histograms/tags
export const getPluginHistogramsHistograms = makeService('/data/plugin/histograms/histograms');
export const getPluginGraphsGraph = makeService('/data/plugin/graphs/graph');
export const getPluginTextsTags = makeService('/data/plugin/texts/tags');
export const getPluginTextsTexts = makeService('/data/plugin/texts/texts');
<template>
<div class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-chart-page
:expand="true"
:config="filteredConfig"
:runsItems="runsItems"
:tagList="filteredTagsList"
:title="'Tags matching ' + config.groupNameReg"
></ui-chart-page>
<ui-chart-page
v-for="item in groupedTags"
:key="item.group"
:config="filteredConfig"
:runsItems="runsItems"
:tagList="item.tags"
:title="item.group"
></ui-chart-page>
</div>
<div class="visual-dl-page-right">
<div class="visual-dl-page-config-container">
<ui-config :runsItems="runsItems" :config="config"
></ui-config>
</div>
</div>
</div>
</template>
<script>
import {getPluginTextsTags, getRuns} from '../service';
import {debounce, flatten, uniq, isArray} from 'lodash';
import autoAdjustHeight from '../common/util/autoAdjustHeight';
import Config from './ui/Config'
import ChartPage from './ui/ChartPage';
export default {
name: 'Texts',
components: {
'ui-config': Config,
'ui-chart-page': ChartPage
},
data () {
return {
runsArray: [],
tags: [],
config: {
groupNameReg: '.*',
runs: [],
running: true
},
filteredTagsList: []
}
},
computed: {
runsItems() {
let runsArray = this.runsArray || [];
return runsArray.map(item => {
return {
name: item,
value: item
};
});
},
tagsList() {
let tags = this.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]
};
}).filter(item => item.tag !== undefined);
return {
tagList,
tag,
group: tag.split('/')[0]
};
});
},
groupedTags() {
let tagsList = this.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.config || {};
let filteredConfig = {};
Object.keys(config).forEach(key => {
let val = config[key];
filteredConfig[key] = val;
});
return filteredConfig;
}
},
created() {
getPluginTextsTags().then(({errno, data}) => {
this.tags = data;
// filter when inited
let groupNameReg = this.config.groupNameReg;
this.filterTagsList(groupNameReg);
});
getRuns().then(({errno, data}) => {
console.log(data);
this.runsArray = data;
this.config.runs = data;
});
},
mounted() {
autoAdjustHeight();
},
watch: {
'config.groupNameReg': function(val) {
this.throttledFilterTagsList()
}
},
methods:{
filterTagsList(groupNameReg) {
if (!groupNameReg) {
this.filteredTagsList = [];
return;
}
let tagsList = this.tagsList || [];
let regExp = new RegExp(groupNameReg);
this.filteredTagsList = tagsList.filter(item => regExp.test(item.tag));
},
throttledFilterTagsList: _.debounce(
function() {
this.filterTagsList(this.config.groupNameReg)
}, 300
),
}
};
</script>
<style lang="stylus">
</style>
import {router} from 'san-router';
import Texts from './Texts';
router.add({
target: '#content',
rule: '/texts',
Component: Texts
});
<template>
<v-card hover class="visual-dl-text">
<h3 class="visual-dl-text-title">{{tagInfo.tag.displayName}}
<span class="visual-dl-text-run-icon">{{tagInfo.run}}</span>
</h3>
<p>
<span>Step:</span>
<span>{{textData.step}};</span>
<span>{{textData.wall_time | formatTime}}</span>
</p>
<v-slider label="step"
:max="steps"
:min="slider.min"
:step="1"
v-model="currentIndex"
dark></v-slider>
<p> {{textData.message}} </p>
</v-card>
</template>
<script>
import {getPluginTextsTexts} from '../../service';
// the time to refresh chart data
const intervalTime = 30;
export default {
props: ['tagInfo', 'runs', 'running', 'runsItems'],
computed: {
steps() {
let data = this.data || [];
return data.length - 1;
}
},
filters: {
formatTime: function (value) {
if (!value) {
return;
}
let time = new Date();
time.setTime(value.toString().split('.')[0]);
return time;
}
},
data() {
return {
currentIndex: 0,
slider: {
value: '0',
label: '',
min: 0,
step: 1
},
textData: {},
data: [],
};
},
created() {
this.getOriginChartsData();
},
mounted() {
if (this.running) {
this.startInterval();
}
},
beforeDestroy() {
this.stopInterval();
},
watch: {
running: function (val) {
val ? this.startInterval() : this.stopInterval();
},
currentIndex: function(index) {
if (this.data && this.data[index]) {
let currentTextInfo = this.data ? this.data[index] : {};
let wall_time = currentTextInfo[0]
let step = currentTextInfo[1];
let message = currentTextInfo[2]
this.textData = {
step,
wall_time,
message,
}
}
}
},
methods: {
stopInterval() {
clearInterval(this.getOringDataInterval);
},
// get origin data per {{intervalTime}} seconds
startInterval() {
this.getOringDataInterval = setInterval(() => {
this.getOriginChartsData();
}, intervalTime * 1000);
},
getOriginChartsData() {
//let {run, tag} = this.tagInfo;
let run = this.tagInfo.run
let tag = this.tagInfo.tag
let {displayName, samples} = tag;
let params = {
run,
tag: displayName,
samples
};
getPluginTextsTexts(params).then(({status, data}) => {
if (status === 0) {
this.data = data;
this.currentIndex = data.length - 1;
}
});
}
}
};
</script>
<style lang="stylus">
.visual-dl-text
font-size 12px
width 420px
float left
margin 20px 30px 10px 0
background #fff
padding 10px
.visual-dl-text-title
font-size 14px
line-height 30px
.visual-dl-text-run-icon
background #e4e4e4
float right
margin-right 10px
padding 0 10px
border solid 1px #e4e4e4
border-radius 6px
line-height 20px
margin-top 4px
.visual-dl-chart-actions
.sm-form-item
width 300px
display inline-block
</style>
<template>
<div class="visual-dl-chart-page">
<ui-expand-panel :info="tagList.length" :title="title">
<div ref="chartPageBox" class="visual-dl-chart-page-box">
<ui-chart
v-for="(tagInfo, index) in filteredPageList"
:key="index"
:tagInfo="tagInfo"
:groupNameReg="config.groupNameReg"
:outlier="config.outlier"
:runs="config.runs"
:running="config.running"
:runsItems="runsItems"
></ui-chart>
</div>
<v-pagination
v-if="total > pageSize"
v-model="currentPage"
:length="pageLength"
/>
</ui-expand-panel>
</div>
</template>
<script>
import ExpandPanel from '../../common/component/ExpandPanel';
import Chart from './Chart';
import {cloneDeep, flatten} from 'lodash';
export default {
components: {
'ui-chart': Chart,
'ui-expand-panel': ExpandPanel,
},
props: ['config', 'runsItems', 'tagList', 'title'],
computed: {
filteredRunsList() {
let tagList = this.tagList || [];
let runs = this.config.runs || [];
let list = cloneDeep(tagList);
return flatten(list.slice().map(item => {
return item.tagList.filter(one => runs.includes(one.run));
}));
},
filteredPageList() {
let list = this.filteredRunsList || [];
return list.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize);
},
total() {
let tagList = this.tagList || [];
return tagList.length;
},
pageLength() {
return Math.ceil(this.total / this.pageSize)
}
},
data() {
return {
// current page
currentPage: 1,
// item per page
pageSize: 8
};
}
};
</script>
<style lang="stylus">
@import '~style/variables';
+prefix-classes('visual-dl-')
.chart-page
.chart-page-box:after
content: "";
clear: both;
display: block;
padding-bottom: 2%
</style>
<template>
<div class="visual-dl-page-config-com">
<v-text-field
label="Group name RegExp"
hint="input a tag group name"
v-model="config.groupNameReg"
dark
></v-text-field>
<label class="visual-dl-page-checkbox-group-label">Runs</label>
<v-checkbox v-for="item in runsItems"
:key="item.name"
:label="item.name"
:value="item.value"
v-model="config.runs"
dark
class="visual-dl-page-runs-checkbox"
></v-checkbox>
<v-btn :color="config.running ? 'primary' : 'error'"
v-model="config.running"
@click="toggleAllRuns"
class="visual-dl-page-run-toggle"
dark block
>
{{config.running ? 'Running' : 'Stopped'}}
</v-btn>
</div>
</template>
<script>
export default {
props: {
runsItems: Array,
config: Object
},
data() {
return {
};
},
methods: {
toggleAllRuns() {
this.config.running = !this.config.running;
}
}
};
</script>
<style lang="stylus">
+prefix-classes('visual-dl-page-')
.config-com
padding 20px
.slider-block
display flex
align-items center
.smoothing-slider
display inline
.slider-span
width 40px
.run-toggle
margin-top 20px
.config-selector
margin-top 12px
margin-bottom 20px
.checkbox-group-label
display flex
margin-top 20px
margin-bottom 10px
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册