未验证 提交 db62d42b 编写于 作者: J Jeff Wang 提交者: GitHub

Use ESlint to format the Javascript and Vue files. (#365)

* Use ESlint to format the Javascript and Vue files.
Strongly recommended rules applied.

* Add google format package
上级 32ef4f9e
module.exports = {
extends: [
'google',
'plugin:vue/base',
'plugin:vue/essential',
'plugin:vue/strongly-recommended',
],
rules: {
// override/add rules settings here, such as:
'vue/no-unused-vars': 'warn',
'max-len': ["warn", 120],
}
}
......@@ -49,6 +49,9 @@
"copy-webpack-plugin": "^4.0.1",
"cross-env": "^4.0.0",
"css-loader": "^0.28.0",
"eslint": "^4.19.1",
"eslint-config-google": "^0.9.1",
"eslint-plugin-vue": "^4.4.0",
"express": "^4.16.2",
"extract-text-webpack-plugin": "^2.1.0",
"fecs": "1.5.2",
......
<template>
<div id="app">
<v-app>
<AppMenu :initialRoute="initialRoute">
</AppMenu>
<router-view></router-view>
</v-app>
</div>
<div id="app">
<v-app>
<AppMenu :initial-route="initialRoute"/>
<router-view/>
</v-app>
</div>
</template>
<script>
import AppMenu from './common/component/AppMenu'
import AppMenu from './common/component/AppMenu';
export default {
name: 'App',
components: {
AppMenu
AppMenu,
},
data() {
return {
initialRoute: "scalars"
}
initialRoute: 'scalars',
};
},
created() {
if (location.hash && location.hash != '#/') {
this.initialRoute = /(\#\/)(\w*)([?|&]{0,1})/.exec(location.hash)[2];
}
else {
} else {
location.hash = '#/scalars';
}
}
}
},
};
</script>
<style lang="stylus">
......
<template>
<div class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-audio-container
:expand="true"
:config="filteredConfig"
:runsItems="runsItems"
:tagList="filteredTagsList"
:title="'Tags matching ' + config.groupNameReg"
></ui-audio-container>
<ui-audio-container
v-for="item in groupedTags"
:key="item.group"
:config="filteredConfig"
:runsItems="runsItems"
:tagList="item.tags"
:title="item.group"
></ui-audio-container>
</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 class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-audio-container
:expand="true"
:config="filteredConfig"
:runs-items="runsItems"
:tag-list="filteredTagsList"
:title="'Tags matching ' + config.groupNameReg"
/>
<ui-audio-container
v-for="item in groupedTags"
:key="item.group"
:config="filteredConfig"
:runs-items="runsItems"
:tag-list="item.tags"
:title="item.group"
/>
</div>
<div class="visual-dl-page-right">
<div class="visual-dl-page-config-container">
<ui-config
:runs-items="runsItems"
:config="config"
/>
</div>
</div>
</div>
</template>
<script>
......@@ -32,16 +34,16 @@ import {getPluginAudioTags, getRuns} from '../service';
import {debounce, flatten, uniq, isArray} from 'lodash';
import autoAdjustHeight from '../common/util/autoAdjustHeight';
import Config from './ui/Config'
import Config from './ui/Config';
import AudioPanelContainer from './ui/AudioPanelContainer';
export default {
name: 'Images',
components: {
'ui-config': Config,
'ui-audio-container': AudioPanelContainer
'ui-audio-container': AudioPanelContainer,
},
data () {
data() {
return {
runsArray: [],
tags: [],
......@@ -49,18 +51,18 @@ export default {
groupNameReg: '.*',
isActualImageSize: false,
runs: [],
running: true
running: true,
},
filteredTagsList: []
}
filteredTagsList: [],
};
},
computed: {
runsItems() {
let runsArray = this.runsArray || [];
return runsArray.map(item => {
return runsArray.map((item) => {
return {
name: item,
value: item
value: item,
};
});
},
......@@ -68,21 +70,21 @@ export default {
let tags = this.tags;
let runs = Object.keys(tags);
let tagsArray = runs.map(run => Object.keys(tags[run]));
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 allUniqTags.map((tag) => {
let tagList = runs.map((run) => {
return {
run,
tag: tags[run][tag]
tag: tags[run][tag],
};
}).filter(item => item.tag !== undefined);
}).filter((item) => item.tag !== undefined);
return {
tagList,
tag,
group: tag.split('/')[0]
group: tag.split('/')[0],
};
});
},
......@@ -90,35 +92,34 @@ export default {
let tagsList = this.tagsList || [];
// put data in group
let groupData = {};
tagsList.forEach(item => {
tagsList.forEach((item) => {
let group = item.group;
if (groupData[group] === undefined) {
groupData[group] = [];
groupData[group].push(item);
}
else {
} else {
groupData[group].push(item);
}
});
// to array
let groups = Object.keys(groupData);
return groups.map(group => {
return groups.map((group) => {
return {
group,
tags: groupData[group]
tags: groupData[group],
};
});
},
filteredConfig() {
let config = this.config || {};
let filteredConfig = {};
Object.keys(config).forEach(key => {
Object.keys(config).forEach((key) => {
let val = config[key];
filteredConfig[key] = val;
});
return filteredConfig;
}
},
},
created() {
getPluginAudioTags().then(({errno, data}) => {
......@@ -139,10 +140,10 @@ export default {
},
watch: {
'config.groupNameReg': function(val) {
this.throttledFilterTagsList()
}
this.throttledFilterTagsList();
},
},
methods:{
methods: {
filterTagsList(groupNameReg) {
if (!groupNameReg) {
this.filteredTagsList = [];
......@@ -150,14 +151,14 @@ export default {
}
let tagsList = this.tagsList || [];
let regExp = new RegExp(groupNameReg);
this.filteredTagsList = tagsList.filter(item => regExp.test(item.tag));
this.filteredTagsList = tagsList.filter((item) => regExp.test(item.tag));
},
throttledFilterTagsList: _.debounce(
function() {
this.filterTagsList(this.config.groupNameReg)
this.filterTagsList(this.config.groupNameReg);
}, 300
),
}
},
};
</script>
......
......@@ -5,5 +5,5 @@ import Audio from './Audio';
router.add({
target: '#content',
rule: '/audio',
Component: Audio
Component: Audio,
});
<template>
<v-card hover class="visual-dl-audio">
<h3 class="visual-dl-audio-title">{{tagInfo.tag.displayName}}
<span class="visual-dl-audio-run-icon">{{tagInfo.run}}</span>
</h3>
<p>
<span>Step:</span>
<span>{{audioData.step}}</span>
<span class="visual-del-audio-time">{{audioData.wall_time | formatTime}}</span>
</p>
<v-slider :max="steps"
:min="slider.min"
:step="1"
v-model="currentIndex"
></v-slider>
<v-card
hover
class="visual-dl-audio">
<h3 class="visual-dl-audio-title">{{ tagInfo.tag.displayName }}
<span class="visual-dl-audio-run-icon">{{ tagInfo.run }}</span>
</h3>
<p>
<span>Step:</span>
<span>{{ audioData.step }}</span>
<span class="visual-del-audio-time">{{ audioData.wall_time | formatTime }}</span>
</p>
<v-slider
:max="steps"
:min="slider.min"
:step="1"
v-model="currentIndex"
/>
<audio controls :src="audioData.audioSrc">
Your browser does not support the audio element.
</audio>
</v-card>
<audio
controls
:src="audioData.audioSrc">
Your browser does not support the audio element.
</audio>
</v-card>
</template>
<script>
import {getPluginAudioAudio} from '../../service';
......@@ -31,21 +36,21 @@ export default {
steps() {
let data = this.data || [];
return data.length - 1;
}
},
},
filters: {
formatTime: function (value) {
formatTime: function(value) {
if (!value) {
return;
}
// The value was made in seconds, must convert it to milliseconds
let time = new Date(value * 1000);
var options = {
weekday: "short", year: "numeric", month: "short",
day: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit"
let options = {
weekday: 'short', year: 'numeric', month: 'short',
day: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit',
};
return time.toLocaleDateString("en-US", options);
}
return time.toLocaleDateString('en-US', options);
},
},
data() {
return {
......@@ -54,7 +59,7 @@ export default {
value: '0',
label: '',
min: 0,
step: 1
step: 1,
},
audioData: {},
data: [],
......@@ -74,7 +79,7 @@ export default {
},
watch: {
running: function (val) {
running: function(val) {
val ? this.startInterval() : this.stopInterval();
},
currentIndex: function(index) {
......@@ -86,10 +91,10 @@ export default {
this.audioData = {
audioSrc,
step,
wall_time
}
wall_time,
};
}
}
},
},
methods: {
stopInterval() {
......@@ -102,14 +107,14 @@ export default {
}, intervalTime * 1000);
},
getOriginAudioData() {
//let {run, tag} = this.tagInfo;
let run = this.tagInfo.run
let tag = this.tagInfo.tag
// 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
samples,
};
getPluginAudioAudio(params).then(({status, data}) => {
if (status === 0) {
......@@ -117,8 +122,8 @@ export default {
this.currentIndex = data.length - 1;
}
});
}
}
},
},
};
</script>
<style lang="stylus">
......
<template>
<div class="visual-dl-chart-page">
<ui-expand-panel :info="total" :title="title">
<ui-audio
class="visual-dl-chart-audio"
v-for="(tagInfo, index) in filteredPageList"
:key="index"
:tagInfo="tagInfo"
:runs="config.runs"
:running="config.running"
:runsItems="runsItems"
></ui-audio>
<div class="visual-dl-chart-page">
<ui-expand-panel
:info="total"
:title="title">
<ui-audio
class="visual-dl-chart-audio"
v-for="(tagInfo, index) in filteredPageList"
:key="index"
:tag-info="tagInfo"
:runs="config.runs"
:running="config.running"
:runs-items="runsItems"
/>
<v-pagination class="visual-dl-sm-pagination"
v-if="total > pageSize"
v-model="currentPage"
:length="pageLength"
></v-pagination>
</ui-expand-panel>
</div>
<v-pagination
class="visual-dl-sm-pagination"
v-if="total > pageSize"
v-model="currentPage"
:length="pageLength"
/>
</ui-expand-panel>
</div>
</template>
<script>
import ExpandPanel from '../../common/component/ExpandPanel';
......@@ -36,8 +39,8 @@ export default {
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));
return flatten(list.slice().map((item) => {
return item.tagList.filter((one) => runs.includes(one.run));
}));
},
......@@ -50,15 +53,15 @@ export default {
return list.length;
},
pageLength() {
return Math.ceil(this.total / this.pageSize)
}
return Math.ceil(this.total / this.pageSize);
},
},
data() {
return {
// current page
currentPage: 1,
// item per page
pageSize: 8
pageSize: 8,
};
},
};
......
<template>
<div class="visual-dl-page-config-com">
<v-text-field
label="Group name RegExp"
hint="input a tag group name to search"
v-model="config.groupNameReg"
dark
></v-text-field>
<div class="visual-dl-page-config-com">
<v-text-field
label="Group name RegExp"
hint="input a tag group name to search"
v-model="config.groupNameReg"
dark
/>
<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
></v-checkbox>
<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
/>
<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>
<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
config: Object,
},
data() {
return {
......@@ -40,8 +43,8 @@ export default {
methods: {
toggleAllRuns() {
this.config.running = !this.config.running;
}
}
},
},
};
</script>
......
<template>
<div>
<div class="visual-dl-app-menu">
<v-toolbar color="primary" dark>
<v-toolbar-title class="appbar-menu-title"></v-toolbar-title>
<v-toolbar-items>
<v-btn v-for="item in items" :key="item.name"
flat dark :class="selected === item.name ? 'menu-item-selected': 'menu-item'"
@click="handleItemClick(item)"
>{{ item.title}}</v-btn>
</v-toolbar-items>
</v-toolbar>
</div>
<div>
<div class="visual-dl-app-menu">
<v-toolbar
color="primary"
dark>
<v-toolbar-title class="appbar-menu-title"/>
<v-toolbar-items>
<v-btn
v-for="item in items"
:key="item.name"
flat
dark
:class="selected === item.name ? 'menu-item-selected': 'menu-item'"
@click="handleItemClick(item)"
>{{ item.title }}</v-btn>
</v-toolbar-items>
</v-toolbar>
</div>
</div>
</template>
<script>
export default {
props: ['initialRoute'],
name: 'AppMenu',
data () {
data() {
return {
selected: this.initialRoute,
items: [
{
url: '/scalars',
title: 'SCALARS',
name: 'scalars'
name: 'scalars',
},
{
url: '/images',
title: 'IMAGES',
name: 'images'
name: 'images',
},
{
url: '/audio',
title: 'AUDIO',
name: 'audio'
name: 'audio',
},
{
url: '/histograms',
title: 'HISTOGRAMS',
name: 'histograms'
name: 'histograms',
},
{
url: '/graphs',
title: 'GRAPHS',
name: 'graphs'
name: 'graphs',
},
{
url: '/texts',
title: 'TEXTS',
name: 'texts'
name: 'texts',
},
/* // Hide the top menu
{
......@@ -59,16 +65,16 @@ export default {
name: 'HighDimensional'
}
*/
]
}
],
};
},
methods: {
handleItemClick: function (item) {
this.selected = item.name
this.$router.push(item.url)
}
}
}
handleItemClick: function(item) {
this.selected = item.name;
this.$router.push(item.url);
},
},
};
</script>
<style scoped lang="stylus">
......
<template>
<div class="visual-dl-expand-panel">
<h3
class="visual-dl-expand-head"
@click="isShow = !isShow"
>
<span>{{title}}</span>
<span class="visual-dl-expand-head-info">
<v-icon class="visual-dl-expand-head-arrow" size="20">{{iconName}}</v-icon>
<span class="visual-dl-expand-head-num">({{info}})</span>
</span>
</h3>
<div
v-if="isShow"
class="visual-dl-expand-panel-content"
>
<slot></slot>
</div>
<div class="visual-dl-expand-panel">
<h3
class="visual-dl-expand-head"
@click="isShow = !isShow"
>
<span>{{ title }}</span>
<span class="visual-dl-expand-head-info">
<v-icon
class="visual-dl-expand-head-arrow"
size="20">{{ iconName }}</v-icon>
<span class="visual-dl-expand-head-num">({{ info }})</span>
</span>
</h3>
<div
v-if="isShow"
class="visual-dl-expand-panel-content"
>
<slot/>
</div>
</div>
</template>
<script>
export default {
props: {
title: String,
info: Number
info: Number,
},
computed: {
iconName() {
return this.isShow ? 'expand_less' : 'expand_more';
}
},
},
data() {
return {
isShow: true
isShow: true,
};
}
},
};
</script>
<style lang="stylus">
......
......@@ -23,7 +23,7 @@ function calcTopDist(topDist = 16) {
* @param {Object} options options
* @return {NotificationItem} instance
*/
const notification = function (options = {}) {
const notification = function(options = {}) {
options.top = calcTopDist(options.offset);
const {onClose, onClick} = options;
delete options.onClick;
......@@ -31,9 +31,9 @@ const notification = function (options = {}) {
delete options.offset;
const instance = {
vm: new NotificationItem({
data: options
data: options,
}),
id: `notification_${seed++}`
id: `notification_${seed++}`,
};
if (typeof onClick === 'function') {
......@@ -54,7 +54,7 @@ const notification = function (options = {}) {
* @param {string} id instance id
* @param {Function} onClose cusmtom func
*/
notification.close = function (id, onClose) {
notification.close = function(id, onClose) {
let index;
let removedHeight;
let len = instances.length;
......@@ -79,15 +79,14 @@ notification.close = function (id, onClose) {
instances[i].vm.el.style.top = `${parseInt(instances[i].vm.el.style.top, 10) - removedHeight - 16}px`;
}
}
};
// fout type func
['success', 'warning', 'info', 'error'].forEach(type => {
notification[type] = options => {
['success', 'warning', 'info', 'error'].forEach((type) => {
notification[type] = (options) => {
if (typeof options === 'string') {
options = {
message: options
message: options,
};
}
options = options || {};
......
......@@ -25,17 +25,17 @@ function s2ab(s) {
* @param {Array} data the data for the xlsx
* @param {string} name filename
*/
export const generateXLSXandAutoDownload = function (data, name) {
export const generateXLSXandAutoDownload = function(data, name) {
let wopts = {
bookType: 'xlsx',
bookSST: false,
type: 'binary'
type: 'binary',
};
let ws = aoaToSheet(data);
let wb = {
SheetNames: ['Export'],
Sheets: {},
Props: {}
Props: {},
};
wb.Sheets.Export = ws;
let wbout = XLSX.write(wb, wopts);
......@@ -43,7 +43,7 @@ export const generateXLSXandAutoDownload = function (data, name) {
new Blob(
[s2ab(wbout)],
{
type: 'application/octet-stream'
type: 'application/octet-stream',
}
),
name + '.xlsx' || 'sheetjs.xlsx'
......@@ -57,12 +57,12 @@ export const generateXLSXandAutoDownload = function (data, name) {
* @param {Array} data the data for the xlsx
* @param {string} name filename
*/
export const generateJsonAndDownload = function (data, name) {
export const generateJsonAndDownload = function(data, name) {
saveAs(
new Blob(
[s2ab(JSON.stringify(data, null, ' '))],
{
type: 'application/octet-stream'
type: 'application/octet-stream',
}
),
name + '.json' || 'json.json'
......
......@@ -7,11 +7,11 @@ const STATUSINFO = 'msg';
const instance = axios.create({
baseURL: '/',
timeout: 30000
timeout: 30000,
});
// for better ux, don't send the error msg because there will be too mutch error
const responseErrorStatus = response => {
const responseErrorStatus = (response) => {
const data = response.data;
// if (data[STATUS] !== 0) {
// Notification.error(data[STATUSINFO]);
......@@ -21,7 +21,7 @@ const responseErrorStatus = response => {
};
// for better ux, don't send the error msg because there will be too mutch error
const responseNetError = error => {
const responseNetError = (error) => {
// Notification.error('net error');
return Promise.reject(error);
};
......@@ -30,11 +30,11 @@ const responseNetError = error => {
const formInstance = axios.create({
baseURL: '/',
timeout: 3000,
transformRequest: [data => qs.stringify(data)],
transformRequest: [(data) => qs.stringify(data)],
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json,application/vnd.ms-excel'
}
'Accept': 'application/json,application/vnd.ms-excel',
},
});
......
import quantile from './quantile';
export {
quantile
quantile,
};
export default function (x) {
export default function(x) {
return x === null ? NaN : +x;
}
import number from './number';
export default function (values, p, valueof) {
export default function(values, p, valueof) {
if (valueof == null) {
return valueof = number;
}
......
import {router} from 'san-router';
export function routeTo(url, params = {}) {
let paramsArr = Object.keys(params).map(key => `${key}=${params[key]}`);
let paramsArr = Object.keys(params).map((key) => `${key}=${params[key]}`);
let urlParams = (url.indexOf('?') > -1 ? '&' : '?') + paramsArr.join('&');
router.locator.redirect(urlParams.length > 1 ? `${url}${urlParams}` : url);
......
<template>
<div class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-chart
:fitScreen="fitScreen"
:download="download"
:scale="config.scale"
:curNode="curNode"
@curNodeUpdated="curNode = $event"
></ui-chart>
</div>
<div class="visual-dl-page-right">
<div class="visual-dl-page-config-container">
<ui-config
:config="config"
:curNode="curNode"
@fitScreen="handleFitScreen"
@download="handleDownload"
></ui-config>
</div>
</div>
<div class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-chart
:fit-screen="fitScreen"
:download="download"
:scale="config.scale"
:cur-node="curNode"
@curNodeUpdated="curNode = $event"
/>
</div>
<div class="visual-dl-page-right">
<div class="visual-dl-page-config-container">
<ui-config
:config="config"
:cur-node="curNode"
@fitScreen="handleFitScreen"
@download="handleDownload"
/>
</div>
</div>
</div>
</template>
<script>
import autoAdjustHeight from '../common/util/autoAdjustHeight';
import Config from './ui/Config'
import Config from './ui/Config';
import Chart from './ui/Chart';
export default {
components: {
'ui-config': Config,
'ui-chart': Chart
'ui-chart': Chart,
},
name: 'Graph',
data () {
data() {
return {
config: {
scale: 0.5
scale: 0.5,
},
fitScreen: {fitScreen: false},
download: {download: false},
curNode: {}
}
curNode: {},
};
},
mounted() {
autoAdjustHeight();
......@@ -54,8 +54,8 @@ export default {
},
handleDownload() {
this.download = {fitScreen: true};
}
}
},
},
};
</script>
......
......@@ -5,5 +5,5 @@ import Graph from './Graph';
router.add({
target: '#content',
rule: '/graphs',
Component: Graph
Component: Graph,
});
<template>
<div class="visual-dl-graph-charts">
<svg class="visual-dl-page-left">
<g/>
</svg>
</div>
<div class="visual-dl-graph-charts">
<svg class="visual-dl-page-left">
<g/>
</svg>
</div>
</template>
<script>
// libs
......@@ -11,7 +11,7 @@
import {
dragMovelHandler,
tansformElement,
relativeMove
relativeMove,
} from './dragHelper';
// service
import {getPluginGraphsGraph} from '../../service';
......@@ -20,8 +20,8 @@
import interact from 'interactjs';
// for d3 drawing
import * as d3 from "d3";
import * as dagre from "dagre";
import * as d3 from 'd3';
import * as dagre from 'dagre';
export default {
props: ['fitScreen', 'download', 'scale', 'curNode'],
......@@ -29,7 +29,7 @@
computedWidth() {
let scale = this.scale;
return Math.floor(scale * 2 * 700);
}
},
},
data() {
return {
......@@ -49,25 +49,27 @@
aEl.download = 'graph.png';
aEl.click();
}
}
},
},
mounted() {
this.getOriginChartsData();
let chartScope = this;
getPluginGraphsGraph().then(({errno, data}) => {
var raw_data = data.data;
let raw_data = data.data;
var data = raw_data;
// d3 svg drawing
var g = new dagreD3.graphlib.Graph()
let g = new dagreD3.graphlib.Graph()
.setGraph({})
.setDefaultEdgeLabel(function() { return {}; });
var render = new dagreD3.render();
var nodeKeys = [];
.setDefaultEdgeLabel(function() {
return {};
});
let render = new dagreD3.render();
let nodeKeys = [];
var buildInputNodeLabel = function(inputNode) {
let buildInputNodeLabel = function(inputNode) {
// TODO(daming-lu): need more complex compound node
var nodeLabel = 'id: ' + inputNode['name'] + '\n'
let nodeLabel = 'id: ' + inputNode['name'] + '\n'
+ 'type: ' + inputNode['data_type'] + '\n'
+ 'dims: ' + inputNode['shape'].join(' x ');
return nodeLabel;
......@@ -75,13 +77,13 @@
// add input nodes
for (var i=0; i<data['input'].length; ++i) {
var curInputNode = data['input'][i];
let curInputNode = data['input'][i];
var nodeKey = curInputNode['name'];
g.setNode(
nodeKey,
{
label: buildInputNodeLabel(curInputNode),
class: "input"
class: 'input',
}
);
nodeKeys.push(nodeKey);
......@@ -89,65 +91,65 @@
// add operator nodes then add edges from inputs to operator and from operator to output
for (var i=0; i<data['node'].length; ++i) {
var curOperatorNode = data['node'][i];
let curOperatorNode = data['node'][i];
var nodeKey = 'opNode_' + i;
// add operator node
var curOpLabel = curOperatorNode['opType'];
let curOpLabel = curOperatorNode['opType'];
g.setNode(
nodeKey,
{
label: curOpLabel + ' '.repeat(Math.floor(curOpLabel.length/5)),
class: "operator"
class: 'operator',
}
);
nodeKeys.push(nodeKey);
// add output node
var outputNodeKey = curOperatorNode['output'][0];
let outputNodeKey = curOperatorNode['output'][0];
g.setNode(
outputNodeKey,
{
label: outputNodeKey + ' '.repeat(Math.floor(outputNodeKey.length/5)),
class: "output"
class: 'output',
}
);
nodeKeys.push(outputNodeKey);
// add edges from inputs to node and from node to output
for (var e=0; e<curOperatorNode['input'].length; ++e) {
for (let e=0; e<curOperatorNode['input'].length; ++e) {
g.setEdge(curOperatorNode['input'][e], nodeKey);
}
g.setEdge(nodeKey, curOperatorNode['output'][0]);
}
// TODO(daming-lu): add prettier styles to diff nodes
var svg = d3.select("svg")
.attr("font-family", "sans-serif")
.attr("font-size", "28px");
let svg = d3.select('svg')
.attr('font-family', 'sans-serif')
.attr('font-size', '28px');
render(d3.select("svg g"), g);
render(d3.select('svg g'), g);
// adjust viewBox so that the whole graph can be shown, with scroll bar
svg.attr('viewBox', '0 0 ' + g.graph().width + ' ' + g.graph().height);
svg.attr('viewBox', '0 0 ' + g.graph().width + ' ' + g.graph().height);
svg.selectAll(".node").on("click", function(d, i){
svg.selectAll('.node').on('click', function(d, i) {
this.curNode = g.node(d);
var nodeType = this.curNode.class;
var nodeInfo = null;
if (nodeType === "operator") {
var opIndex = d.slice(7); // remove prefix "opNode_"
let nodeType = this.curNode.class;
let nodeInfo = null;
if (nodeType === 'operator') {
let opIndex = d.slice(7); // remove prefix "opNode_"
nodeInfo = data.node[opIndex];
} else if (nodeType === "input") {
} else if (nodeType === 'input') {
nodeInfo = data.input[d-1];
} else {
nodeInfo = "output";
nodeInfo = 'output';
}
chartScope.$emit('curNodeUpdated',
{
'nodeType': nodeType,
'nodeInfo': nodeInfo
'nodeInfo': nodeInfo,
});
});
});
......@@ -182,15 +184,15 @@
},
getBigImgEl() {
return this.$refs.draggable
return this.$refs.draggable;
},
getSmallImgEl() {
return this.$refs.small_img
return this.$refs.small_img;
},
getSmallImgDragHandler() {
return this.$refs.screen_handler
return this.$refs.screen_handler;
},
addDragEventForImg() {
......@@ -210,7 +212,7 @@
relativeMove({triggerEl, x, y}, relativeEl);
});
}
},
});
interact('.screen-handler').draggable({
......@@ -224,8 +226,8 @@
top: 0,
left: 0,
bottom: 1,
right: 1
}
right: 1,
},
},
// call this function on every dragmove event
onmove(event) {
......@@ -237,10 +239,10 @@
relativeMove({triggerEl, x, y}, relativeEl);
});
}
},
});
}
}
},
},
};
</script>
<style lang="stylus">
......
<template>
<div class="visual-dl-graph-config-com">
<div class="graph-config-upper">
<v-btn
class="visual-dl-graph-config-button"
color="primary"
@click="handleFitScreen"
dark>
<v-icon style="margin-right: 6px" size="20">fullscreen</v-icon>
Fit &nbsp; to &nbsp; screen
</v-btn>
<div class="visual-dl-graph-config-com">
<div class="graph-config-upper">
<v-btn
class="visual-dl-graph-config-button"
color="primary"
@click="handleFitScreen"
dark>
<v-icon
style="margin-right: 6px"
size="20">fullscreen</v-icon>
Fit &nbsp; to &nbsp; screen
</v-btn>
<v-btn
class="visual-dl-graph-config-button"
color="primary"
@click="handleDownload"
dark>
<v-icon style="margin-right: 6px">file_download</v-icon>
Download image
</v-btn>
<v-btn
class="visual-dl-graph-config-button"
color="primary"
@click="handleDownload"
dark>
<v-icon style="margin-right: 6px">file_download</v-icon>
Download image
</v-btn>
<v-slider
label="Scale"
max="1"
min="0.1"
step="0.1"
v-model="config.scale"
dark></v-slider>
</div>
<div class="node-info">
<h3>Node Info: </h3>
<div v-if="curNode.nodeType === 'input'">
<div>Node Type: {{ curNode.nodeType }}</div>
<div>Name: {{curNode.nodeInfo.name}}</div>
<div>Shape: {{curNode.nodeInfo.shape}}</div>
<div>Data Type: {{curNode.nodeInfo.data_type}}</div>
</div>
<div v-else-if="curNode.nodeType === 'output'">
<div>Node Type: {{ curNode.nodeType }}</div>
</div>
<div v-else-if="curNode.nodeType === 'operator'">
<div>Node Type: {{ curNode.nodeType }}</div>
<div>Input: {{curNode.nodeInfo.input}}</div>
<div>Operator Type: {{curNode.nodeInfo.opType}}</div>
<div>Output: {{curNode.nodeInfo.output}}</div>
</div>
<div v-else>
<v-slider
label="Scale"
max="1"
min="0.1"
step="0.1"
v-model="config.scale"
dark/>
</div>
<div class="node-info">
<h3>Node Info: </h3>
</div>
</div>
<div v-if="curNode.nodeType === 'input'">
<div>Node Type: {{ curNode.nodeType }}</div>
<div>Name: {{ curNode.nodeInfo.name }}</div>
<div>Shape: {{ curNode.nodeInfo.shape }}</div>
<div>Data Type: {{ curNode.nodeInfo.data_type }}</div>
</div>
<div v-else-if="curNode.nodeType === 'output'">
<div>Node Type: {{ curNode.nodeType }}</div>
</div>
<div v-else-if="curNode.nodeType === 'operator'">
<div>Node Type: {{ curNode.nodeType }}</div>
<div>Input: {{ curNode.nodeInfo.input }}</div>
<div>Operator Type: {{ curNode.nodeInfo.opType }}</div>
<div>Output: {{ curNode.nodeInfo.output }}</div>
</div>
<div v-else/>
</div>
</div>
</template>
<script>
export default {
props:['config', 'curNode'],
props: ['config', 'curNode'],
methods: {
handleFitScreen() {
this.$emit('fitScreen')
this.$emit('fitScreen');
},
handleDownload() {
this.$emit('download')
}
}
this.$emit('download');
},
},
};
</script>
<style lang="stylus">
......
<template>
<div class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-chart
:config="config"
:displayWordLabel="config.displayWordLabel"
:searchText="config.searchText"
:dimension="config.dimension"
:embedding_data="embedding_data"
></ui-chart>
</div>
<div class="visual-dl-page-right">
<div class="visual-dl-page-config-container">
<ui-config
:config="config"
></ui-config>
</div>
</div>
<div class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-chart
:config="config"
:display-word-label="config.displayWordLabel"
:search-text="config.searchText"
:dimension="config.dimension"
:embedding_data="embedding_data"
/>
</div>
<div class="visual-dl-page-right">
<div class="visual-dl-page-config-container">
<ui-config
:config="config"
/>
</div>
</div>
</div>
</template>
<script>
import {getHighDimensionalDatasets} from '../service';
import autoAdjustHeight from '../common/util/autoAdjustHeight';
import Config from './ui/Config'
import Config from './ui/Config';
import Chart from './ui/Chart';
export default {
......@@ -31,28 +31,28 @@ export default {
'ui-chart': Chart,
},
name: 'HighDimensional',
data () {
data() {
return {
config: {
searchText: '',
displayWordLabel: true,
dimension: "2",
reduction: "tsne",
running: true
dimension: '2',
reduction: 'tsne',
running: true,
},
embedding_data: []
}
embedding_data: [],
};
},
created() {
this.fetchDatasets()
this.fetchDatasets();
},
watch: {
'config.dimension': function(val) {
this.fetchDatasets()
this.fetchDatasets();
},
'config.reduction': function(val) {
this.fetchDatasets()
}
this.fetchDatasets();
},
},
mounted() {
autoAdjustHeight();
......@@ -62,20 +62,20 @@ export default {
// Fetch the data from the server. Passing dimension and reduction method
let params = {
dimension: this.config.dimension,
reduction: this.config.reduction
reduction: this.config.reduction,
};
getHighDimensionalDatasets(params).then(({errno, data}) => {
var vector_data = data.embedding;
var labels = data.labels;
let vector_data = data.embedding;
let labels = data.labels;
for ( var i = 0; i < vector_data.length; i ++) {
vector_data[i].push(labels[i])
for ( let i = 0; i < vector_data.length; i ++) {
vector_data[i].push(labels[i]);
}
this.embedding_data = vector_data
this.embedding_data = vector_data;
});
},
}
},
};
</script>
......
<template>
<v-card hover class="visual-dl-page-charts">
<div ref="chartBox" class="visual-dl-chart-box" :style="computedStyle">
</div>
</v-card>
<v-card
hover
class="visual-dl-page-charts">
<div
ref="chartBox"
class="visual-dl-chart-box"
:style="computedStyle"/>
</v-card>
</template>
<script>
......@@ -21,12 +25,12 @@ export default {
computedStyle() {
return 'height:' + this.height + 'px;' +
'width:' + this.width + 'px;';
}
},
},
created() {},
mounted() {
this.createChart();
this.myChart.showLoading()
this.myChart.showLoading();
this.set2DChartOptions();
this.setDisplayWordLabel();
......@@ -38,17 +42,17 @@ export default {
series: [{
// Grab the 'matched' series data
name: 'all',
data: val
}]
data: val,
}],
});
},
displayWordLabel: function(val) {
this.setDisplayWordLabel()
this.setDisplayWordLabel();
},
dimension: function(val) {
this.myChart.clear()
this.myChart.showLoading()
if (val === "2") {
this.myChart.clear();
this.myChart.showLoading();
if (val === '2') {
this.set2DChartOptions();
this.setDisplayWordLabel();
} else {
......@@ -58,13 +62,13 @@ export default {
},
searchText: function(val) {
// Filter the data that has the hasPrefix
var matched_words = []
let matched_words = [];
if (val != '') {
val = val.toLowerCase()
val = val.toLowerCase();
function hasPrefix(value) {
var word = value[value.length - 1]
return (typeof word == "string" && word.toLowerCase().startsWith(val))
let word = value[value.length - 1];
return (typeof word == 'string' && word.toLowerCase().startsWith(val));
}
matched_words = this.embedding_data.filter(hasPrefix);
......@@ -75,8 +79,8 @@ export default {
series: [{
// Grab the 'matched' series data
name: 'matched',
data: matched_words
}]
data: matched_words,
}],
});
},
},
......@@ -87,25 +91,25 @@ export default {
this.myChart = echarts.init(el);
},
set2DChartOptions() {
var typeD = "normal";
var option = {
let typeD = 'normal';
let option = {
xAxis: {},
yAxis: {},
series: [{
name: "all",
name: 'all',
symbolSize: 10,
data: this.embedding_data,
type: 'scatter',
},
{
name: "matched",
name: 'matched',
animation: false,
symbolSize: 10,
data: [],
itemStyle: {
normal: {
opacity: 1
}
opacity: 1,
},
},
label: {
normal: {
......@@ -113,37 +117,37 @@ export default {
formatter: function(param) {
return param.data[param.data.length - 1];
},
position: 'top'
}
position: 'top',
},
},
type: 'scatter'
}
]
type: 'scatter',
},
],
};
this.myChart.setOption(option);
},
set3DChartOptions() {
var symbolSize = 2.5;
var option3d = {
let symbolSize = 2.5;
let option3d = {
grid3D: {},
xAxis3D: {
type: 'category'
type: 'category',
},
yAxis3D: {},
xAxis3D: {},
zAxis3D: {},
dataset: {
source: this.embedding_data
source: this.embedding_data,
},
series: [
{
name: "all",
name: 'all',
type: 'scatter3D',
symbolSize: symbolSize,
data: []
data: [],
},
{
name: "matched",
name: 'matched',
animation: false,
symbolSize: symbolSize,
data: [],
......@@ -153,13 +157,13 @@ export default {
formatter: function(param) {
return param.data[param.data.length - 1];
},
position: 'top'
}
position: 'top',
},
},
type: 'scatter3D'
}
]
}
type: 'scatter3D',
},
],
};
this.myChart.setOption(option3d);
},
setDisplayWordLabel() {
......@@ -173,16 +177,16 @@ export default {
formatter: function(param) {
return param.data[param.data.length - 1];
},
position: 'top'
position: 'top',
},
emphasis: {
show: true,
}
}
}]
},
},
}],
});
},
}
},
};
</script>
......
<template>
<div class="visual-dl-page-config-com">
<div class="visual-dl-page-config-com">
<v-text-field
label="Search"
hint="Search by label"
v-model="config.searchText"
dark
></v-text-field>
<v-text-field
label="Search"
hint="Search by label"
v-model="config.searchText"
dark
/>
<v-checkbox class="visual-dl-page-config-checkbox"
label="Display All Labels"
v-model="config.displayWordLabel" dark></v-checkbox>
<v-checkbox
class="visual-dl-page-config-checkbox"
label="Display All Labels"
v-model="config.displayWordLabel"
dark/>
<v-radio-group label="Dimension" v-model="config.dimension" dark>
<v-radio label="2D" value="2"></v-radio>
<v-radio label="3D" value="3"></v-radio>
</v-radio-group>
<v-radio-group
label="Dimension"
v-model="config.dimension"
dark>
<v-radio
label="2D"
value="2"/>
<v-radio
label="3D"
value="3"/>
</v-radio-group>
<v-radio-group label="Reduction Method" v-model="config.reduction" dark>
<v-radio label="T-SNE" value="tsne"></v-radio>
<v-radio label="PCA" value="pca"></v-radio>
</v-radio-group>
<v-radio-group
label="Reduction Method"
v-model="config.reduction"
dark>
<v-radio
label="T-SNE"
value="tsne"/>
<v-radio
label="PCA"
value="pca"/>
</v-radio-group>
<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>
<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
config: Object,
},
data() {
return {
......@@ -47,8 +65,8 @@ export default {
methods: {
toggleAllRuns() {
this.config.running = !this.config.running;
}
}
},
},
};
</script>
......
<template>
<div class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-chart-page
:config="config"
:runsItems="runsItems"
:tagList="filteredTagsList"
:title="'Tags matching ' + config.groupNameReg"
></ui-chart-page>
<ui-chart-page
v-for="item in groupedTags"
:key="item.group"
:config="config"
: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 class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-chart-page
:config="config"
:runs-items="runsItems"
:tag-list="filteredTagsList"
:title="'Tags matching ' + config.groupNameReg"
/>
<ui-chart-page
v-for="item in groupedTags"
:key="item.group"
:config="config"
:runs-items="runsItems"
:tag-list="item.tags"
:title="item.group"
/>
</div>
<div class="visual-dl-page-right">
<div class="visual-dl-page-config-container">
<ui-config
:runs-items="runsItems"
:config="config"
/>
</div>
</div>
</div>
</template>
<script>
......@@ -37,15 +37,15 @@ import autoAdjustHeight from '../common/util/autoAdjustHeight';
export default {
components: {
'ui-config': Config,
'ui-chart-page': ChartPage
'ui-chart-page': ChartPage,
},
computed: {
runsItems() {
let runsArray = this.runsArray || [];
return runsArray.map(item => {
return runsArray.map((item) => {
return {
name: item,
value: item
value: item,
};
});
},
......@@ -53,21 +53,21 @@ export default {
let tags = this.tags;
let runs = Object.keys(tags);
let tagsArray = runs.map(run => Object.keys(tags[run]));
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 allUniqTags.map((tag) => {
let tagList = runs.map((run) => {
return {
run,
tag: tags[run][tag]
tag: tags[run][tag],
};
}).filter(item => item.tag !== undefined);
}).filter((item) => item.tag !== undefined);
return {
tagList,
tag,
group: tag.split('/')[0]
group: tag.split('/')[0],
};
});
},
......@@ -75,26 +75,25 @@ export default {
let tagsList = this.tagsList || [];
// put data in group
let groupData = {};
tagsList.forEach(item => {
tagsList.forEach((item) => {
let group = item.group;
if (groupData[group] === undefined) {
groupData[group] = [];
groupData[group].push(item);
}
else {
} else {
groupData[group].push(item);
}
});
// to array
let groups = Object.keys(groupData);
return groups.map(group => {
return groups.map((group) => {
return {
group,
tags: groupData[group]
tags: groupData[group],
};
});
}
},
},
data() {
return {
......@@ -105,21 +104,21 @@ export default {
horizontal: 'step',
chartType: 'offset',
runs: [],
running: true
running: true,
},
filteredTagsList: []
filteredTagsList: [],
};
},
created() {
getPluginHistogramsTags().then(({errno, data}) => {
this.tags = data
this.tags = data;
// filter when inited
let groupNameReg = this.config.groupNameReg;
this.filterTagsList(groupNameReg);
});
getRuns().then(({errno, data}) => {
this.runsArray = data
this.config.runs = data
this.runsArray = data;
this.config.runs = data;
});
},
......@@ -128,26 +127,26 @@ export default {
},
watch: {
'config.groupNameReg': function(val) {
this.throttledFilterTagsList()
}
this.throttledFilterTagsList();
},
},
methods: {
filterTagsList(groupNameReg) {
if (!groupNameReg) {
this.filteredTagsList = []
this.filteredTagsList = [];
return;
}
let tagsList = this.tagsList || [];
let regExp = new RegExp(groupNameReg);
let filtedTagsList = tagsList.filter(item => regExp.test(item.tag));
this.filteredTagsList = filtedTagsList
let filtedTagsList = tagsList.filter((item) => regExp.test(item.tag));
this.filteredTagsList = filtedTagsList;
},
throttledFilterTagsList: _.debounce(
function() {
this.filterTagsList(this.config.groupNameReg)
this.filterTagsList(this.config.groupNameReg);
}, 300
),
}
},
};
</script>
......
......@@ -7,7 +7,7 @@ export function tansformBackendData(histogramData) {
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}))
items: items.map(([left, right, count]) => ({left, right, count})),
};
}
......@@ -19,7 +19,7 @@ export function computeNewHistogram(histogram, min, max, binsNum = 30) {
}
let stepWidth = (max - min) / binsNum;
let itemIndex = 0;
return range(min, max, stepWidth).map(binLeft => {
return range(min, max, stepWidth).map((binLeft) => {
let binRight = binLeft + stepWidth;
let yValue = 0;
while (itemIndex < histogram.items.length) {
......@@ -41,7 +41,7 @@ export function computeNewHistogram(histogram, min, max, binsNum = 30) {
}
export function tansformToVisData(tempData, time, step) {
return tempData.map(function (dataItem) {
return tempData.map(function(dataItem) {
return [time, step, dataItem.x + dataItem.dx / 2, Math.floor(dataItem.y)];
});
}
......@@ -50,18 +50,18 @@ export function originDataToChartData(originData) {
let tempData = originData.map(tansformBackendData);
let globalMin = min(tempData.map(({min}) => min));
let globalMax = max(tempData.map(({max}) => max));
let chartData = tempData.map(function (item) {
let chartData = tempData.map(function(item) {
let histoBins = computeNewHistogram(item, globalMin, globalMax);
let {time, step} = item;
return {
time,
step,
items: tansformToVisData(histoBins, time, step)
items: tansformToVisData(histoBins, time, step),
};
});
return {
min: globalMin,
max: globalMax,
chartData
chartData,
};
}
......@@ -5,5 +5,5 @@ import Histogram from './Histogram';
router.add({
target: '#content',
rule: '/histograms',
Component: Histogram
Component: Histogram,
});
<template>
<v-card hover class="visual-dl-page-charts">
<div class="visual-dl-chart-box" ref="visual_dl_chart_box">
</div>
<div class="visual-dl-chart-actions">
<v-btn color="toolbox_icon" flat icon @click="isExpand = !isExpand" class="chart-toolbox-icons" >
<img v-if="!isExpand" src="../../assets/ic_fullscreen_off.svg"/>
<img v-if="isExpand" src="../../assets/ic_fullscreen_on.svg"/>
</v-btn>
</div>
</v-card>
<v-card
hover
class="visual-dl-page-charts">
<div
class="visual-dl-chart-box"
ref="visual_dl_chart_box"/>
<div class="visual-dl-chart-actions">
<v-btn
color="toolbox_icon"
flat
icon
@click="isExpand = !isExpand"
class="chart-toolbox-icons" >
<img
v-if="!isExpand"
src="../../assets/ic_fullscreen_off.svg">
<img
v-if="isExpand"
src="../../assets/ic_fullscreen_on.svg">
</v-btn>
</div>
</v-card>
</template>
<script>
// libs
......@@ -32,7 +44,7 @@ export default {
data() {
return {
originData: [],
isExpand: false
isExpand: false,
};
},
watch: {
......@@ -47,7 +59,7 @@ export default {
},
isExpand: function(val) {
this.expandArea(val);
}
},
},
mounted() {
let tagInfo = this.tagInfo;
......@@ -68,7 +80,7 @@ export default {
},
createChart() {
let el = this.$refs.visual_dl_chart_box
let el = this.$refs.visual_dl_chart_box;
this.myChart = echarts.init(el);
},
......@@ -77,7 +89,7 @@ export default {
let zr = this.myChart.getZr();
let hoverDots = zrDrawElement.hoverDots;
if (hoverDots != null && hoverDots.length !== 0) {
hoverDots.forEach(dot => zr.remove(dot));
hoverDots.forEach((dot) => zr.remove(dot));
}
let chartType = this.chartType;
let data = this.originData;
......@@ -92,19 +104,18 @@ export default {
left: 45,
top: 60,
right: 40,
bottom: 36
bottom: 36,
};
let title = {
text: tag,
textStyle: {
fontSize: '12',
fontWeight: 'normal'
}
fontWeight: 'normal',
},
};
if (chartType === 'overlay') {
this.setOverlayChartOption(visData, title, grid);
}
else if (chartType === 'offset') {
} else if (chartType === 'offset') {
this.setOffsetChartOption(visData, title, grid);
}
},
......@@ -121,13 +132,13 @@ export default {
lineStyle: {
normal: {
width: 1,
color: '#008c99'
}
color: '#008c99',
},
},
encode: {
x: [2],
y: [3]
}
y: [3],
},
})
);
let option = {
......@@ -136,40 +147,40 @@ export default {
link: {xAxisIndex: 'all'},
show: true,
snap: true,
triggerTooltip: true
triggerTooltip: true,
},
grid: grid,
xAxis: {
type: 'value'
type: 'value',
},
yAxis: {
type: 'value',
axisLine: {
onZero: false
onZero: false,
},
axisLabel: {
formatter(value, index) {
return yValueFormat(value);
}
},
},
axisPointer: {
label: {
formatter({value}) {
return yValueFormat(value);
}
}
}
},
},
},
},
series: seriesOption
series: seriesOption,
};
let zr1 = this.myChart.getZr();
zr1.on('mousemove', function (e) {
zr1.on('mousemove', function(e) {
zr1.remove(zrDrawElement.hoverLine);
zr1.remove(zrDrawElement.tooltip);
zr1.remove(zrDrawElement.tooltipX);
zr1.remove(zrDrawElement.tooltipY);
zrDrawElement.hoverDots.forEach(dot => zr1.remove(dot));
zrDrawElement.hoverDots.forEach((dot) => zr1.remove(dot));
zrDrawElement.hoverDots.length = 0;
});
......@@ -188,7 +199,7 @@ export default {
grid.top = 126;
grid.left = 16;
grid.right = 40;
chartData.forEach(function (dataItem) {
chartData.forEach(function(dataItem) {
let lineData = [];
maxStep = Math.max(dataItem.step, maxStep);
minStep = Math.min(dataItem.step, minStep);
......@@ -202,7 +213,7 @@ export default {
let option = {
textStyle: {
fontFamily: 'Merriweather Sans'
fontFamily: 'Merriweather Sans',
},
title,
color: ['#006069'],
......@@ -213,43 +224,43 @@ export default {
max: maxStep,
dimension: 1,
inRange: {
colorLightness: [0.2, 0.4]
}
colorLightness: [0.2, 0.4],
},
},
xAxis: {
min: minX,
max: maxX,
axisLine: {
onZero: false
onZero: false,
},
axisLabel: {
fontSize: '11',
formatter: function (value) {
formatter: function(value) {
return Math.round(value * 100) / 100;
}
},
},
splitLine: {
show: false
}
show: false,
},
},
yAxis: {
position: 'right',
axisLine: {
onZero: false
onZero: false,
},
inverse: true,
splitLine: {
show: false
show: false,
},
axisLabel: {
fontSize: '11'
}
fontSize: '11',
},
},
grid,
series: [{
type: 'custom',
dimensions: ['x', 'y'],
renderItem: function (params, api) {
renderItem: function(params, api) {
let points = makePolyPoints(
params.dataIndex,
api.value,
......@@ -260,16 +271,16 @@ export default {
type: 'polygon',
silent: true,
shape: {
points
points,
},
style: api.style({
stroke: '#bbb',
lineWidth: 1
})
lineWidth: 1,
}),
};
},
data: rawData
}]
data: rawData,
}],
};
function makePolyPoints(dataIndex, getValue, getCoord, yValueMapHeight) {
......@@ -296,29 +307,29 @@ export default {
if (zrDrawElement.hoverLine) {
zr.remove(zrDrawElement.hoverLine);
zr.remove(zrDrawElement.tooltip);
zrDrawElement.hoverDots.forEach(dot => zr.remove(dot));
zrDrawElement.hoverDots.forEach((dot) => zr.remove(dot));
zrDrawElement.hoverDots.length = 0;
zr.remove(zrDrawElement.tooltipX);
zr.remove(zrDrawElement.tooltipY);
}
}
zr.on('mouseout', e => {
zr.on('mouseout', (e) => {
removeTooltip();
});
zr.on('mousemove', e => {
zr.on('mousemove', (e) => {
removeTooltip();
let nearestIndex = findNearestValue(e.offsetX, e.offsetY);
if (nearestIndex) {
let getCoord = function (pt) {
let getCoord = function(pt) {
return ecChart.convertToPixel('grid', pt);
};
let gridRect = ecChart.getModel().getComponent('grid', 0).coordinateSystem.getRect();
let linePoints = makePolyPoints(
nearestIndex.itemIndex,
function (i) {
function(i) {
return rawData[nearestIndex.itemIndex][i];
},
getCoord,
......@@ -328,17 +339,17 @@ export default {
zr.add(zrDrawElement.hoverLine = new echarts.graphic.Polyline({
silent: true,
shape: {
points: linePoints
points: linePoints,
},
style: {
stroke: '#5c5c5c',
lineWidth: 2
lineWidth: 2,
},
z: 999
z: 999,
}));
let itemX;
rawData.forEach(dataItem => {
rawData.forEach((dataItem) => {
let binIndex = nearestIndex.binIndex;
let x = dataItem[binIndex * 3];
let y = dataItem[binIndex * 3 + 1];
......@@ -349,14 +360,14 @@ export default {
shape: {
cx: pt[0],
cy: pt[1],
r: 3
r: 3,
},
style: {
fill: '#000',
stroke: '#ccc',
lineWidth: 1
lineWidth: 1,
},
z: 1000
z: 1000,
});
zr.add(dot);
zrDrawElement.hoverDots.push(dot);
......@@ -375,16 +386,16 @@ export default {
textBorderWidth: 2,
textBorderRadius: 5,
textPadding: 10,
rich: {}
rich: {},
},
z: 2000
z: 2000,
});
zr.add(zrDrawElement.tooltip);
zrDrawElement.tooltipX = new echarts.graphic.Text({
position: [
itemX,
gridRect.y + gridRect.height
gridRect.y + gridRect.height,
],
style: {
fontFamily: 'Merriweather Sans',
......@@ -395,16 +406,16 @@ export default {
textBackgroundColor: '#333',
textBorderWidth: 2,
textPadding: [5, 7],
rich: {}
rich: {},
},
z: 2000
z: 2000,
});
zr.add(zrDrawElement.tooltipX);
zrDrawElement.tooltipY = new echarts.graphic.Text({
position: [
gridRect.x + gridRect.width,
linePoints[linePoints.length - 1][1]
linePoints[linePoints.length - 1][1],
],
style: {
fontFamily: 'Merriweather Sans',
......@@ -415,9 +426,9 @@ export default {
textBackgroundColor: '#333',
textBorderWidth: 2,
textPadding: [5, 7],
rich: {}
rich: {},
},
z: 2000
z: 2000,
});
zr.add(zrDrawElement.tooltipY);
}
......@@ -448,7 +459,7 @@ export default {
if (binIndex != null) {
return {
itemIndex: itemIndex,
binIndex: binIndex
binIndex: binIndex,
};
}
}
......@@ -469,11 +480,11 @@ export default {
},
getOriginChartData(tagInfo) {
let run = tagInfo.run
let tag = tagInfo.tag
let run = tagInfo.run;
let tag = tagInfo.tag;
let params = {
run,
tag: tag.displayName
tag: tag.displayName,
};
getPluginHistogramsHistograms(params).then(({status, data}) => {
if (status === 0) {
......@@ -484,7 +495,7 @@ export default {
expandArea(expand) {
let pageBoxWidth = document.getElementsByClassName('visual-dl-chart-page')[0].offsetWidth;
let width = pageBoxWidth * 0.96; //4% margin
let width = pageBoxWidth * 0.96; // 4% margin
if (expand) {
let el = this.$refs.visual_dl_chart_box;
el.style.width = width + 'px';
......@@ -492,21 +503,20 @@ export default {
this.isExpand = true;
this.myChart.resize({
width: width,
height: 600
height: 600,
});
}
else {
} else {
let el = this.$refs.visual_dl_chart_box;
el.style.width = '400px';
el.style.height = '300px';
this.isExpand = false;
this.myChart.resize({
width: 400,
height: 300
height: 300,
});
}
}
}
},
},
};
</script>
<style lang="stylus">
......
<template>
<!-- ClassName visual-dl-chart-page used in chart.san, change they all if you need!-->
<div class="visual-dl-chart-page">
<ui-expand-panel :info="total" :title="title">
<div class="visual-dl-chart-page-box">
<ui-chart
v-for="(tagInfo, index) in filteredPageList"
:key="index"
:tagInfo="tagInfo"
:runs="config.runs"
:chartType="config.chartType"
:running="config.running"
:runsItems="runsItems"
></ui-chart>
</div>
<v-pagination class="visual-dl-sm-pagination"
v-if="total > pageSize"
v-model="currentPage"
:length="pageLength"
></v-pagination>
</ui-expand-panel>
</div>
<!-- ClassName visual-dl-chart-page used in chart.san, change they all if you need!-->
<div class="visual-dl-chart-page">
<ui-expand-panel
:info="total"
:title="title">
<div class="visual-dl-chart-page-box">
<ui-chart
v-for="(tagInfo, index) in filteredPageList"
:key="index"
:tag-info="tagInfo"
:runs="config.runs"
:chart-type="config.chartType"
:running="config.running"
:runs-items="runsItems"
/>
</div>
<v-pagination
class="visual-dl-sm-pagination"
v-if="total > pageSize"
v-model="currentPage"
:length="pageLength"
/>
</ui-expand-panel>
</div>
</template>
<script>
import ExpandPanel from '../../common/component/ExpandPanel';
......@@ -39,8 +42,8 @@ export default {
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));
return flatten(list.slice().map((item) => {
return item.tagList.filter((one) => runs.includes(one.run));
}));
},
......@@ -55,23 +58,23 @@ export default {
return list.length;
},
pageLength() {
return Math.ceil(this.total / this.pageSize)
}
return Math.ceil(this.total / this.pageSize);
},
},
data() {
return {
// current page
currentPage: 1,
// item per page
pageSize: 4
pageSize: 4,
};
},
methods: {
handlePageChange({pageNum}) {
this.currentPage = pageNum;
}
}
},
},
};
</script>
<style lang="stylus">
......
<template>
<div class="visual-dl-page-config-com">
<v-text-field
label="Group name RegExp"
hint="input a tag group name to search"
v-model="config.groupNameReg"
dark
></v-text-field>
<div class="visual-dl-page-config-com">
<v-text-field
label="Group name RegExp"
hint="input a tag group name to search"
v-model="config.groupNameReg"
dark
/>
<v-radio-group label="Histogram mode" v-model="config.chartType" dark>
<v-radio v-for="mode in chartTypeItems" :key="mode.name"
:label="mode.name" :value="mode.value"></v-radio>
</v-radio-group>
<v-radio-group
label="Histogram mode"
v-model="config.chartType"
dark>
<v-radio
v-for="mode in chartTypeItems"
:key="mode.name"
:label="mode.name"
:value="mode.value"/>
</v-radio-group>
<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
></v-checkbox>
<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
/>
<v-btn class="visual-dl-page-run-toggle"
:color="config.running ? 'primary' : 'error'"
v-model="config.running"
@click="toggleAllRuns"
dark block
>
{{config.running ? 'Running' : 'Stopped'}}
</v-btn>
</div>
<v-btn
class="visual-dl-page-run-toggle"
:color="config.running ? 'primary' : 'error'"
v-model="config.running"
@click="toggleAllRuns"
dark
block
>
{{ config.running ? 'Running' : 'Stopped' }}
</v-btn>
</div>
</template>
<script>
export default {
......@@ -39,21 +48,21 @@ export default {
chartTypeItems: [
{
name: 'Overlay',
value: 'overlay'
value: 'overlay',
},
{
name: 'Offset',
value: 'offset'
}
]
value: 'offset',
},
],
};
},
methods: {
toggleAllRuns() {
let running = this.config.running;
this.config.running = !running;
}
}
},
},
};
</script>
<style lang="stylus">
......
<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 class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-chart-page
:expand="true"
:config="filteredConfig"
:runs-items="runsItems"
:tag-list="filteredTagsList"
:title="'Tags matching ' + config.groupNameReg"
/>
<ui-chart-page
v-for="item in groupedTags"
:key="item.group"
:config="filteredConfig"
:runs-items="runsItems"
:tag-list="item.tags"
:title="item.group"
/>
</div>
<div class="visual-dl-page-right">
<div class="visual-dl-page-config-container">
<ui-config
:runs-items="runsItems"
:config="config"
/>
</div>
</div>
</div>
</template>
<script>
......@@ -32,16 +34,16 @@ import {getPluginImagesTags, getRuns} from '../service';
import {debounce, flatten, uniq, isArray} from 'lodash';
import autoAdjustHeight from '../common/util/autoAdjustHeight';
import Config from './ui/Config'
import Config from './ui/Config';
import ChartPage from './ui/ChartPage';
export default {
name: 'Images',
components: {
'ui-config': Config,
'ui-chart-page': ChartPage
'ui-chart-page': ChartPage,
},
data () {
data() {
return {
runsArray: [],
tags: [],
......@@ -49,18 +51,18 @@ export default {
groupNameReg: '.*',
isActualImageSize: false,
runs: [],
running: true
running: true,
},
filteredTagsList: []
}
filteredTagsList: [],
};
},
computed: {
runsItems() {
let runsArray = this.runsArray || [];
return runsArray.map(item => {
return runsArray.map((item) => {
return {
name: item,
value: item
value: item,
};
});
},
......@@ -68,21 +70,21 @@ export default {
let tags = this.tags;
let runs = Object.keys(tags);
let tagsArray = runs.map(run => Object.keys(tags[run]));
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 allUniqTags.map((tag) => {
let tagList = runs.map((run) => {
return {
run,
tag: tags[run][tag]
tag: tags[run][tag],
};
}).filter(item => item.tag !== undefined);
}).filter((item) => item.tag !== undefined);
return {
tagList,
tag,
group: tag.split('/')[0]
group: tag.split('/')[0],
};
});
},
......@@ -90,23 +92,22 @@ export default {
let tagsList = this.tagsList || [];
// put data in group
let groupData = {};
tagsList.forEach(item => {
tagsList.forEach((item) => {
let group = item.group;
if (groupData[group] === undefined) {
groupData[group] = [];
groupData[group].push(item);
}
else {
} else {
groupData[group].push(item);
}
});
// to array
let groups = Object.keys(groupData);
return groups.map(group => {
return groups.map((group) => {
return {
group,
tags: groupData[group]
tags: groupData[group],
};
});
},
......@@ -114,12 +115,12 @@ export default {
let tansformArr = ['isActualImageSize'];
let config = this.config || {};
let filteredConfig = {};
Object.keys(config).forEach(key => {
Object.keys(config).forEach((key) => {
let val = config[key];
filteredConfig[key] = val;
});
return filteredConfig;
}
},
},
created() {
getPluginImagesTags().then(({errno, data}) => {
......@@ -140,10 +141,10 @@ export default {
},
watch: {
'config.groupNameReg': function(val) {
this.throttledFilterTagsList()
}
this.throttledFilterTagsList();
},
},
methods:{
methods: {
filterTagsList(groupNameReg) {
if (!groupNameReg) {
this.filteredTagsList = [];
......@@ -151,14 +152,14 @@ export default {
}
let tagsList = this.tagsList || [];
let regExp = new RegExp(groupNameReg);
this.filteredTagsList = tagsList.filter(item => regExp.test(item.tag));
this.filteredTagsList = tagsList.filter((item) => regExp.test(item.tag));
},
throttledFilterTagsList: _.debounce(
function() {
this.filterTagsList(this.config.groupNameReg)
this.filterTagsList(this.config.groupNameReg);
}, 300
),
}
},
};
</script>
......
......@@ -5,5 +5,5 @@ import Images from './Images';
router.add({
target: '#content',
rule: '/images',
Component: Images
Component: Images,
});
<template>
<div class="visual-dl-chart-page">
<ui-expand-panel :info="total" :title="title">
<ui-image
class="visual-dl-chart-image"
v-for="(tagInfo, index) in filteredPageList"
:key="index"
:tagInfo="tagInfo"
:isActualImageSize="config.isActualImageSize"
:runs="config.runs"
:running="config.running"
:runsItems="runsItems"
></ui-image>
<div class="visual-dl-chart-page">
<ui-expand-panel
:info="total"
:title="title">
<ui-image
class="visual-dl-chart-image"
v-for="(tagInfo, index) in filteredPageList"
:key="index"
:tag-info="tagInfo"
:is-actual-image-size="config.isActualImageSize"
:runs="config.runs"
:running="config.running"
:runs-items="runsItems"
/>
<v-pagination class="visual-dl-sm-pagination"
v-if="total > pageSize"
v-model="currentPage"
:length="pageLength"
></v-pagination>
</ui-expand-panel>
</div>
<v-pagination
class="visual-dl-sm-pagination"
v-if="total > pageSize"
v-model="currentPage"
:length="pageLength"
/>
</ui-expand-panel>
</div>
</template>
<script>
import ExpandPanel from '../../common/component/ExpandPanel';
......@@ -37,8 +40,8 @@ export default {
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));
return flatten(list.slice().map((item) => {
return item.tagList.filter((one) => runs.includes(one.run));
}));
},
......@@ -51,15 +54,15 @@ export default {
return list.length;
},
pageLength() {
return Math.ceil(this.total / this.pageSize)
}
return Math.ceil(this.total / this.pageSize);
},
},
data() {
return {
// current page
currentPage: 1,
// item per page
pageSize: 8
pageSize: 8,
};
},
};
......
<template>
<div class="visual-dl-page-config-com">
<v-text-field
label="Group name RegExp"
hint="input a tag group name to search"
v-model="config.groupNameReg"
dark
></v-text-field>
<div class="visual-dl-page-config-com">
<v-text-field
label="Group name RegExp"
hint="input a tag group name to search"
v-model="config.groupNameReg"
dark
/>
<v-checkbox label="Show actual image size" v-model="config.isActualImageSize" dark></v-checkbox>
<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
></v-checkbox>
<v-checkbox
label="Show actual image size"
v-model="config.isActualImageSize"
dark/>
<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>
<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
/>
<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
config: Object,
},
data() {
return {
......@@ -42,8 +48,8 @@ export default {
methods: {
toggleAllRuns() {
this.config.running = !this.config.running;
}
}
},
},
};
</script>
......
<template>
<v-card hover class="visual-dl-image">
<h3 class="visual-dl-image-title">{{tagInfo.tag.displayName}}
<span class="visual-dl-image-run-icon">{{tagInfo.run}}</span>
</h3>
<p>
<span>Step:</span>
<span>{{imgData.step}}</span>
<span class="visual-del-image-time">{{imgData.wall_time | formatTime}}</span>
</p>
<v-slider :max="steps"
:min="slider.min"
:step="1"
v-model="currentIndex"
></v-slider>
<v-card
hover
class="visual-dl-image">
<h3 class="visual-dl-image-title">{{ tagInfo.tag.displayName }}
<span class="visual-dl-image-run-icon">{{ tagInfo.run }}</span>
</h3>
<p>
<span>Step:</span>
<span>{{ imgData.step }}</span>
<span class="visual-del-image-time">{{ imgData.wall_time | formatTime }}</span>
</p>
<v-slider
:max="steps"
:min="slider.min"
:step="1"
v-model="currentIndex"
/>
<img :width="imageWidth" :height="imageHeight" :src="imgData.imgSrc" />
</v-card>
<img
:width="imageWidth"
:height="imageHeight"
:src="imgData.imgSrc" >
</v-card>
</template>
<script>
import {getPluginImagesImages} from '../../service';
......@@ -33,25 +39,25 @@ export default {
return data.length - 1;
},
imageWidth() {
return this.isActualImageSize ? this.imgData.width : defaultImgWidth
return this.isActualImageSize ? this.imgData.width : defaultImgWidth;
},
imageHeight() {
return this.isActualImageSize ? this.imgData.height : defaultImgHeight
}
return this.isActualImageSize ? this.imgData.height : defaultImgHeight;
},
},
filters: {
formatTime: function (value) {
formatTime: function(value) {
if (!value) {
return;
}
// The value was made in seconds, must convert it to milliseconds
let time = new Date(value * 1000);
var options = {
weekday: "short", year: "numeric", month: "short",
day: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit"
let options = {
weekday: 'short', year: 'numeric', month: 'short',
day: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit',
};
return time.toLocaleDateString("en-US", options);
}
return time.toLocaleDateString('en-US', options);
},
},
data() {
return {
......@@ -60,12 +66,12 @@ export default {
value: '0',
label: '',
min: 0,
step: 1
step: 1,
},
imgData: {},
data: [],
height: defaultImgHeight,
weight: defaultImgWidth
weight: defaultImgWidth,
};
},
created() {
......@@ -82,7 +88,7 @@ export default {
},
watch: {
running: function (val) {
running: function(val) {
val ? this.startInterval() : this.stopInterval();
},
currentIndex: function(index) {
......@@ -97,11 +103,11 @@ export default {
height,
width,
step,
wall_time
}
wall_time,
};
}
/* eslint-enable fecs-camelcase */
}
},
},
methods: {
stopInterval() {
......@@ -114,14 +120,14 @@ export default {
}, intervalTime * 1000);
},
getOriginChartsData() {
//let {run, tag} = this.tagInfo;
let run = this.tagInfo.run
let tag = this.tagInfo.tag
// 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
samples,
};
getPluginImagesImages(params).then(({status, data}) => {
if (status === 0) {
......@@ -129,8 +135,8 @@ export default {
this.currentIndex = data.length - 1;
}
});
}
}
},
},
};
</script>
<style lang="stylus">
......
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import Vuetify from 'vuetify'
import router from '@/router'
Vue.config.productionTip = false
import Vue from 'vue';
import App from './App';
import Vuetify from 'vuetify';
import router from '@/router';
Vue.config.productionTip = false;
Vue.use(Vuetify, {
theme: {
primary: '#008c99',
accent: '#008c99',
toolbox_icon: '#999999'
}
})
toolbox_icon: '#999999',
},
});
/* eslint-disable no-new */
new Vue({
......@@ -20,4 +20,4 @@ new Vue({
router,
components: {App},
template: '<App/>',
})
});
import Vue from 'vue'
import Router from 'vue-router'
import Vue from 'vue';
import Router from 'vue-router';
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'
import Audio from '@/audio/Audio'
import HighDimensional from '@/high-dimensional/HighDimensional'
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';
import Audio from '@/audio/Audio';
import HighDimensional from '@/high-dimensional/HighDimensional';
Vue.use(Router)
Vue.use(Router);
export default new Router({
routes: [
{
path: '/scalars',
name: 'Scalars',
component: Scalars
component: Scalars,
},
{
path: '/histograms',
name: 'Histograms',
component: Histogram
component: Histogram,
},
{
path: '/images',
name: 'Images',
component: Images
component: Images,
},
{
path: '/graphs',
name: 'Graph',
component: Graph
component: Graph,
},
{
path: '/texts',
name: 'Texts',
component: Texts
component: Texts,
},
{
path: '/audio',
name: 'Audio',
component: Audio
component: Audio,
},
{
path: '/HighDimensional',
name: 'HighDimensional',
component: HighDimensional
}
]
})
component: HighDimensional,
},
],
});
<template>
<div class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-chart-page
:config="config"
:runsItems="runsItems"
:tagList="filteredTagsList"
:title="'Tags matching' + config.groupNameReg"
></ui-chart-page>
<ui-chart-page
v-for="item in groupedTags"
:key="item.group"
:config="config"
:runsItems="runsItems"
:tagList="item.tags"
:title="item.group"
></ui-chart-page>
</div>
<div class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-chart-page
:config="config"
:runs-items="runsItems"
:tag-list="filteredTagsList"
:title="'Tags matching' + config.groupNameReg"
/>
<ui-chart-page
v-for="item in groupedTags"
:key="item.group"
:config="config"
:runs-items="runsItems"
:tag-list="item.tags"
:title="item.group"
/>
</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 class="visual-dl-page-right">
<div class="visual-dl-page-config-container">
<ui-config
:runs-items="runsItems"
:config="config"
/>
</div>
</div>
</div>
</template>
<script>
......@@ -33,13 +33,13 @@ import {getPluginScalarsTags, getRuns} from '../service';
import {debounce, flatten, uniq, isArray} from 'lodash';
import autoAdjustHeight from '../common/util/autoAdjustHeight';
import Config from './ui/Config'
import Config from './ui/Config';
import ChartPage from './ui/ChartPage';
export default {
components: {
'ui-config': Config,
'ui-chart-page': ChartPage
'ui-chart-page': ChartPage,
},
data() {
return {
......@@ -52,18 +52,18 @@ export default {
sortingMethod: 'default',
outlier: false,
runs: [],
running: true
running: true,
},
filteredTagsList: []
}
filteredTagsList: [],
};
},
computed: {
runsItems() {
let runsArray = this.runsArray || [];
return runsArray.map(item => {
return runsArray.map((item) => {
return {
name: item,
value: item
value: item,
};
});
},
......@@ -71,21 +71,21 @@ export default {
let tags = this.tags;
let runs = Object.keys(tags);
let tagsArray = runs.map(run => Object.keys(tags[run]));
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 allUniqTags.map((tag) => {
let tagList = runs.map((run) => {
return {
run,
tag: tags[run][tag]
tag: tags[run][tag],
};
}).filter(item => item.tag !== undefined);
}).filter((item) => item.tag !== undefined);
return {
tagList,
tag,
group: tag.split('/')[0]
group: tag.split('/')[0],
};
});
},
......@@ -93,23 +93,22 @@ export default {
let tagsList = this.tagsList || [];
// put data in group
let groupData = {};
tagsList.forEach(item => {
tagsList.forEach((item) => {
let group = item.group;
if (groupData[group] === undefined) {
groupData[group] = [];
groupData[group].push(item);
}
else {
} else {
groupData[group].push(item);
}
});
// to array
let groups = Object.keys(groupData);
return groups.map(group => {
return groups.map((group) => {
return {
group,
tags: groupData[group]
tags: groupData[group],
};
});
},
......@@ -133,8 +132,8 @@ export default {
},
watch: {
'config.groupNameReg': function(val) {
this.throttledFilterTagsList()
}
this.throttledFilterTagsList();
},
},
methods: {
filterTagsList(groupNameReg) {
......@@ -144,14 +143,14 @@ export default {
}
let tagsList = this.tagsList || [];
let regExp = new RegExp(groupNameReg);
this.filteredTagsList = tagsList.filter(item => regExp.test(item.tag));
this.filteredTagsList = tagsList.filter((item) => regExp.test(item.tag));
},
throttledFilterTagsList: _.debounce(
function() {
this.filterTagsList(this.config.groupNameReg)
this.filterTagsList(this.config.groupNameReg);
}, 300
),
}
},
};
</script>
......
......@@ -5,11 +5,11 @@ import Scalar from './Scalars';
router.add({
target: '#content',
rule: '/',
Component: Scalar
Component: Scalar,
});
router.add({
target: '#content',
rule: '/scalars',
Component: Scalar
Component: Scalar,
});
此差异已折叠。
<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 filteredTagList"
:key="index"
:tagInfo="tagInfo"
:groupNameReg="config.groupNameReg"
:smoothing="config.smoothing"
:horizontal="config.horizontal"
:sortingMethod="config.sortingMethod"
: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>
<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 filteredTagList"
:key="index"
:tag-info="tagInfo"
:group-name-reg="config.groupNameReg"
:smoothing="config.smoothing"
:horizontal="config.horizontal"
:sorting-method="config.sortingMethod"
:outlier="config.outlier"
:runs="config.runs"
:running="config.running"
:runs-items="runsItems"
/>
</div>
<v-pagination
v-if="total > pageSize"
v-model="currentPage"
:length="pageLength"
/>
</ui-expand-panel>
</div>
</template>
<script>
import ExpandPanel from '../../common/component/ExpandPanel';
......@@ -41,31 +45,31 @@ export default {
let tagList = this.tagList || [];
let runs = this.config.runs || [];
let list = cloneDeep(tagList);
return list.slice().map(item => {
item.tagList = item.tagList.filter(one => runs.includes(one.run));
return list.slice().map((item) => {
item.tagList = item.tagList.filter((one) => runs.includes(one.run));
return item;
});
},
filteredTagList() {
let tagList = this.filteredRunsList || [];
return tagList.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize);
return tagList.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)
}
return Math.ceil(this.total / this.pageSize);
},
},
data() {
return {
// current page
currentPage: 1,
// item per page
pageSize: 8
pageSize: 8,
};
}
},
};
</script>
<style lang="stylus">
......
<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>
<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
/>
<div class="visual-dl-page-slider-block">
<v-slider label="Smoothing"
:max="0.99"
:min="0"
:step="0.01"
v-model="smoothingValue"
class="visual-dl-page-smoothing-slider"
dark></v-slider>
<span class="visual-dl-page-slider-span">{{smoothingValue}}</span>
</div>
<div class="visual-dl-page-slider-block">
<v-slider
label="Smoothing"
:max="0.99"
:min="0"
:step="0.01"
v-model="smoothingValue"
class="visual-dl-page-smoothing-slider"
dark/>
<span class="visual-dl-page-slider-span">{{ smoothingValue }}</span>
</div>
<v-radio-group label="Horizontal" v-model="config.horizontal" dark>
<v-radio label="Step" value="step"></v-radio>
<v-radio label="Relative" value="relative"></v-radio>
<v-radio label="Wall" value="wall"></v-radio>
</v-radio-group>
<v-radio-group
label="Horizontal"
v-model="config.horizontal"
dark>
<v-radio
label="Step"
value="step"/>
<v-radio
label="Relative"
value="relative"/>
<v-radio
label="Wall"
value="wall"/>
</v-radio-group>
<v-select
:items="sortingMethodItems"
v-model="config.sortingMethod"
label="Tooltip sorting method"
class="visual-dl-page-config-selector"
dark dense
></v-select>
<v-select
:items="sortingMethodItems"
v-model="config.sortingMethod"
label="Tooltip sorting method"
class="visual-dl-page-config-selector"
dark
dense
/>
<v-checkbox class="visual-dl-page-config-checkbox" label="Ignore outliers in chart scaling" v-model="config.outlier" dark></v-checkbox>
<v-checkbox
class="visual-dl-page-config-checkbox"
label="Ignore outliers in chart scaling"
v-model="config.outlier"
dark/>
<label class="visual-dl-page-checkbox-group-label">Runs</label>
<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-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-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>
<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
config: Object,
},
data() {
return {
horizontalItems: [
{
name: 'Step',
value: 'step'
value: 'step',
},
{
name: 'Relative',
value: 'relative'
value: 'relative',
},
{
name: 'Wall',
value: 'wall'
}
value: 'wall',
},
],
sortingMethodItems: [
'default', 'descending', 'ascending', 'nearest'
'default', 'descending', 'ascending', 'nearest',
],
smoothingValue: this.config.smoothing
smoothingValue: this.config.smoothing,
};
},
watch: {
......@@ -89,13 +107,13 @@ export default {
function() {
this.config.smoothing = this.smoothingValue;
}, 50
)
),
},
methods: {
toggleAllRuns() {
this.config.running = !this.config.running;
}
}
},
},
};
</script>
......
<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 class="visual-dl-page-container">
<div class="visual-dl-page-left">
<ui-chart-page
:expand="true"
:config="filteredConfig"
:runs-items="runsItems"
:tag-list="filteredTagsList"
:title="'Tags matching ' + config.groupNameReg"
/>
<ui-chart-page
v-for="item in groupedTags"
:key="item.group"
:config="filteredConfig"
:runs-items="runsItems"
:tag-list="item.tags"
:title="item.group"
/>
</div>
<div class="visual-dl-page-right">
<div class="visual-dl-page-config-container">
<ui-config
:runs-items="runsItems"
:config="config"
/>
</div>
</div>
</div>
</template>
<script>
......@@ -32,34 +34,34 @@ import {getPluginTextsTags, getRuns} from '../service';
import {debounce, flatten, uniq, isArray} from 'lodash';
import autoAdjustHeight from '../common/util/autoAdjustHeight';
import Config from './ui/Config'
import Config from './ui/Config';
import ChartPage from './ui/ChartPage';
export default {
name: 'Texts',
components: {
'ui-config': Config,
'ui-chart-page': ChartPage
'ui-chart-page': ChartPage,
},
data () {
data() {
return {
runsArray: [],
tags: [],
config: {
groupNameReg: '.*',
runs: [],
running: true
running: true,
},
filteredTagsList: []
}
filteredTagsList: [],
};
},
computed: {
runsItems() {
let runsArray = this.runsArray || [];
return runsArray.map(item => {
return runsArray.map((item) => {
return {
name: item,
value: item
value: item,
};
});
},
......@@ -67,21 +69,21 @@ export default {
let tags = this.tags;
let runs = Object.keys(tags);
let tagsArray = runs.map(run => Object.keys(tags[run]));
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 allUniqTags.map((tag) => {
let tagList = runs.map((run) => {
return {
run,
tag: tags[run][tag]
tag: tags[run][tag],
};
}).filter(item => item.tag !== undefined);
}).filter((item) => item.tag !== undefined);
return {
tagList,
tag,
group: tag.split('/')[0]
group: tag.split('/')[0],
};
});
},
......@@ -89,35 +91,34 @@ export default {
let tagsList = this.tagsList || [];
// put data in group
let groupData = {};
tagsList.forEach(item => {
tagsList.forEach((item) => {
let group = item.group;
if (groupData[group] === undefined) {
groupData[group] = [];
groupData[group].push(item);
}
else {
} else {
groupData[group].push(item);
}
});
// to array
let groups = Object.keys(groupData);
return groups.map(group => {
return groups.map((group) => {
return {
group,
tags: groupData[group]
tags: groupData[group],
};
});
},
filteredConfig() {
let config = this.config || {};
let filteredConfig = {};
Object.keys(config).forEach(key => {
Object.keys(config).forEach((key) => {
let val = config[key];
filteredConfig[key] = val;
});
return filteredConfig;
}
},
},
created() {
getPluginTextsTags().then(({errno, data}) => {
......@@ -138,10 +139,10 @@ export default {
},
watch: {
'config.groupNameReg': function(val) {
this.throttledFilterTagsList()
}
this.throttledFilterTagsList();
},
},
methods:{
methods: {
filterTagsList(groupNameReg) {
if (!groupNameReg) {
this.filteredTagsList = [];
......@@ -149,14 +150,14 @@ export default {
}
let tagsList = this.tagsList || [];
let regExp = new RegExp(groupNameReg);
this.filteredTagsList = tagsList.filter(item => regExp.test(item.tag));
this.filteredTagsList = tagsList.filter((item) => regExp.test(item.tag));
},
throttledFilterTagsList: _.debounce(
function() {
this.filterTagsList(this.config.groupNameReg)
this.filterTagsList(this.config.groupNameReg);
}, 300
),
}
},
};
</script>
......
......@@ -5,5 +5,5 @@ import Texts from './Texts';
router.add({
target: '#content',
rule: '/texts',
Component: 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 class="visual-del-text-time">{{textData.wall_time | formatTime}}</span>
</p>
<v-slider :max="steps"
:min="slider.min"
:step="1"
v-model="currentIndex"
></v-slider>
<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 class="visual-del-text-time">{{ textData.wall_time | formatTime }}</span>
</p>
<v-slider
:max="steps"
:min="slider.min"
:step="1"
v-model="currentIndex"
/>
<p> {{textData.message}} </p>
</v-card>
<p> {{ textData.message }} </p>
</v-card>
</template>
<script>
......@@ -30,21 +33,21 @@ export default {
steps() {
let data = this.data || [];
return data.length - 1;
}
},
},
filters: {
formatTime: function (value) {
formatTime: function(value) {
if (!value) {
return;
}
// The value was made in seconds, must convert it to milliseconds
let time = new Date(value * 1000);
var options = {
weekday: "short", year: "numeric", month: "short",
day: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit",
let options = {
weekday: 'short', year: 'numeric', month: 'short',
day: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit',
};
return time.toLocaleDateString("en-US", options);
}
return time.toLocaleDateString('en-US', options);
},
},
data() {
return {
......@@ -53,7 +56,7 @@ export default {
value: '0',
label: '',
min: 0,
step: 1
step: 1,
},
textData: {},
data: [],
......@@ -73,23 +76,23 @@ export default {
},
watch: {
running: function (val) {
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 wall_time = currentTextInfo[0];
let step = currentTextInfo[1];
let message = currentTextInfo[2]
let message = currentTextInfo[2];
this.textData = {
step,
wall_time,
message,
}
};
}
}
},
},
methods: {
stopInterval() {
......@@ -102,14 +105,14 @@ export default {
}, intervalTime * 1000);
},
getOriginChartsData() {
//let {run, tag} = this.tagInfo;
let run = this.tagInfo.run
let tag = this.tagInfo.tag
// 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
samples,
};
getPluginTextsTexts(params).then(({status, data}) => {
if (status === 0) {
......@@ -117,8 +120,8 @@ export default {
this.currentIndex = data.length - 1;
}
});
}
}
},
},
};
</script>
<style lang="stylus">
......
<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>
<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"
:tag-info="tagInfo"
:group-name-reg="config.groupNameReg"
:outlier="config.outlier"
:runs="config.runs"
:running="config.running"
:runs-items="runsItems"
/>
</div>
<v-pagination
v-if="total > pageSize"
v-model="currentPage"
:length="pageLength"
/>
</ui-expand-panel>
</div>
</template>
<script>
import ExpandPanel from '../../common/component/ExpandPanel';
......@@ -37,8 +41,8 @@ export default {
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));
return flatten(list.slice().map((item) => {
return item.tagList.filter((one) => runs.includes(one.run));
}));
},
filteredPageList() {
......@@ -50,17 +54,17 @@ export default {
return tagList.length;
},
pageLength() {
return Math.ceil(this.total / this.pageSize)
}
return Math.ceil(this.total / this.pageSize);
},
},
data() {
return {
// current page
currentPage: 1,
// item per page
pageSize: 8
pageSize: 8,
};
}
},
};
</script>
<style lang="stylus">
......
<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>
<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
/>
<label class="visual-dl-page-checkbox-group-label">Runs</label>
<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-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-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>
<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
config: Object,
},
data() {
return {
......@@ -42,8 +45,8 @@ export default {
methods: {
toggleAllRuns() {
this.config.running = !this.config.running;
}
}
},
},
};
</script>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册