This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-rocketbot-ui.git
The following commit(s) were added to refs/heads/master by this push:
new a0ff494 display trace data in table (#129)
a0ff494 is described below
commit a0ff494b96b3d253a604ba3c7c09e13c2b80c8b2
Author: k3vin <[email protected]>
AuthorDate: Mon Aug 12 21:41:17 2019 +0800
display trace data in table (#129)
* add trace-detail display page with table
---
package-lock.json | 5 +
src/assets/index.ts | 1 +
src/assets/lang/en.ts | 1 +
src/assets/lang/zh.ts | 1 +
src/assets/svg/table.svg | 23 +++
src/store/modules/global/index.ts | 6 +
src/utils/tooltip.scss | 4 +
src/utils/tooltip.ts | 2 +
.../trace/trace-chart-table/collapse.gif | Bin 0 -> 846 bytes
.../components/trace/trace-chart-table/expand.gif | Bin 0 -> 851 bytes
.../trace/trace-chart-table/trace-container.vue | 63 +++++++
.../trace/trace-chart-table/trace-item.vue | 184 +++++++++++++++++++++
.../components/trace/trace-chart-table/trace.scss | 31 ++++
.../components/trace/trace-detail-chart-table.vue | 169 +++++++++++++++++++
.../components/trace/trace-detail-chart-tree.vue | 2 +-
src/views/components/trace/trace-detail.vue | 27 ++-
src/views/components/trace/trace-table.vue | 10 +-
17 files changed, 521 insertions(+), 8 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 7519b16..76d4816 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7343,6 +7343,11 @@
"integrity": "sha1-suHE3E98bVd0PfczpPWXjRhlBVk=",
"dev": true
},
+ "noty": {
+ "version": "3.2.0-beta",
+ "resolved": "https://registry.npmjs.org/noty/-/noty-3.2.0-beta.tgz",
+ "integrity":
"sha512-a1//Rth1MTQ/GCvGzwBXrZqCwOPyxiIKMdHT1TlcdrDYBYVfb7vzwsU0N4x+j/HeIQTi6/pbP8lRtY9gBz/d3Q=="
+ },
"npm-run-path": {
"version": "2.0.2",
"resolved":
"http://registry.npm.taobao.org/npm-run-path/download/npm-run-path-2.0.2.tgz",
diff --git a/src/assets/index.ts b/src/assets/index.ts
index 495b79b..c9856fd 100644
--- a/src/assets/index.ts
+++ b/src/assets/index.ts
@@ -28,6 +28,7 @@ import './svg/clear.svg';
import './svg/issue-child.svg';
import './svg/package.svg';
import './svg/list-bulleted.svg';
+import './svg/table.svg';
import './svg/earth.svg';
import './svg/epic.svg';
diff --git a/src/assets/lang/en.ts b/src/assets/lang/en.ts
index 3420a3d..7d36a8f 100644
--- a/src/assets/lang/en.ts
+++ b/src/assets/lang/en.ts
@@ -82,6 +82,7 @@ const m = {
tags: 'Tags',
logs: 'Logs',
component: 'Component',
+ table: 'Table',
list: 'List',
tree: 'Tree',
filterScope: 'Filter Scope',
diff --git a/src/assets/lang/zh.ts b/src/assets/lang/zh.ts
index 00c0c47..80ae5ed 100644
--- a/src/assets/lang/zh.ts
+++ b/src/assets/lang/zh.ts
@@ -82,6 +82,7 @@ const m = {
tags: '标记',
logs: '日志',
component: '组件',
+ table: '表格',
list: '列表',
tree: '树结构',
filterScope: '过滤范围',
diff --git a/src/assets/svg/table.svg b/src/assets/svg/table.svg
new file mode 100755
index 0000000..baa32eb
--- /dev/null
+++ b/src/assets/svg/table.svg
@@ -0,0 +1,23 @@
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License. -->
+
+
+<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <g id="table" stroke="none" stroke-width="1" fill="none"
fill-rule="evenodd">
+ <g id="list-bulleted" fill="#FFFFFF" fill-rule="nonzero">
+ <path d="M1,2 C0.44771525,2 0,1.55228475 0,1 C0,0.44771525
0.44771525,0 1,0 C1.55228475,0 2,0.44771525 2,1 C2,1.55228475 1.55228475,2 1,2
Z M11,2 C10.4477153,2 10,1.55228475 10,1 C10,0.44771525 10.4477153,0 11,0
C11.5522847,0 12,0.44771525 12,1 C12,1.55228475 11.5522847,2 11,2 Z M8,2
C7.44771525,2 7,1.55228475 7,1 C7,0.44771525 7.44771525,0 8,0 C8.55228475,0
9,0.44771525 9,1 C9,1.55228475 8.55228475,2 8,2 Z M4,2 C3.44771525,2
3,1.55228475 3,1 C3,0.44771525 3.44771525,0 4,0 C4 [...]
+ </g>
+ </g>
+</svg>
\ No newline at end of file
diff --git a/src/store/modules/global/index.ts
b/src/store/modules/global/index.ts
index 64b585e..f1f30cf 100644
--- a/src/store/modules/global/index.ts
+++ b/src/store/modules/global/index.ts
@@ -19,6 +19,7 @@ import { Commit, ActionTree, MutationTree, GetterTree, Getter
} from 'vuex';
import getLocalTime from '@/utils/localtime';
import { Duration, DurationTime } from '@/types/global';
import * as types from '@/store/mutation-types';
+import Vue from 'vue';
let timer: any = null;
@@ -76,6 +77,7 @@ export interface State {
edit: boolean;
lock: boolean;
utc: string | number;
+ eventHub: any;
}
const initState: State = {
@@ -89,10 +91,14 @@ const initState: State = {
edit: false,
lock: true,
utc: window.localStorage.getItem('utc') || -(new Date().getTimezoneOffset()
/ 60),
+ eventHub: new Vue(),
};
// getters
const getters = {
+ globalEventHub(state: State): any {
+ return state.eventHub;
+ },
duration(state: State): Duration {
return {
start: getLocalTime(parseInt(state.utc + '', 10),
state.durationRow.start),
diff --git a/src/utils/tooltip.scss b/src/utils/tooltip.scss
index 33e01b4..0f975e7 100644
--- a/src/utils/tooltip.scss
+++ b/src/utils/tooltip.scss
@@ -53,6 +53,10 @@ $tooltip-bg: #252a2f !default;
}
}
+.trace-detail-chart-table .rk-tooltip-popper .rk-tooltip-inner {
+ max-width: 500px;
+}
+
// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as
of v3.3.1
.rk-tooltip-popper {
&[x-placement^="top"] {
diff --git a/src/utils/tooltip.ts b/src/utils/tooltip.ts
index aaa158f..b6b4133 100644
--- a/src/utils/tooltip.ts
+++ b/src/utils/tooltip.ts
@@ -110,6 +110,8 @@ export default {
const $inner = document.createElement('div');
$inner.setAttribute('class', 'rk-tooltip-inner');
+
+
$content.appendChild($inner);
$popper.appendChild($content);
if (binding.value) {
diff --git a/src/views/components/trace/trace-chart-table/collapse.gif
b/src/views/components/trace/trace-chart-table/collapse.gif
new file mode 100644
index 0000000..01e6914
Binary files /dev/null and
b/src/views/components/trace/trace-chart-table/collapse.gif differ
diff --git a/src/views/components/trace/trace-chart-table/expand.gif
b/src/views/components/trace/trace-chart-table/expand.gif
new file mode 100644
index 0000000..1b24ef1
Binary files /dev/null and
b/src/views/components/trace/trace-chart-table/expand.gif differ
diff --git a/src/views/components/trace/trace-chart-table/trace-container.vue
b/src/views/components/trace/trace-chart-table/trace-container.vue
new file mode 100644
index 0000000..2f2c8c8
--- /dev/null
+++ b/src/views/components/trace/trace-chart-table/trace-container.vue
@@ -0,0 +1,63 @@
+<template>
+ <div class="trace">
+ <div class="trace-header">
+ <div class="method">
+ Method
+ </div>
+ <div class="start-time">
+ Start Time
+ </div>
+ <div class="gap">
+ Gap(ms)
+ </div>
+ <div class="exec-ms">
+ Exec(ms)
+ </div>
+ <div class="exec-percent">
+ Exec(%)
+ </div>
+ <div class="self">
+ Self(ms)
+ </div>
+ <div class="api">
+ API
+ </div>
+ <div class="application">
+ Service
+ </div>
+ </div>
+
+ <slot> </slot>
+ </div>
+</template>
+<style lang="scss" scoped>
+@import './trace.scss';
+.trace {
+ font-size: 12px;
+ height: 100%;
+ overflow: auto;
+ }
+ .trace-header {
+ display: flex;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+ }
+
+ .trace-header div {
+ padding: 0 4px;
+ border: 1px solid transparent;
+ border-right: 1px dotted silver;
+ line-height: 30px;
+ background-color: #f3f4f9;;
+ padding: 0 4px;
+ border: 1px solid transparent;
+ border-right: 1px dotted silver;
+ overflow: hidden;
+ line-height: 30px;
+ overflow:hidden;
+ text-overflow:ellipsis;
+ white-space:nowrap
+ }
+</style>
+
diff --git a/src/views/components/trace/trace-chart-table/trace-item.vue
b/src/views/components/trace/trace-chart-table/trace-item.vue
new file mode 100644
index 0000000..1cfc27c
--- /dev/null
+++ b/src/views/components/trace/trace-chart-table/trace-item.vue
@@ -0,0 +1,184 @@
+<template>
+ <div>
+ <div @click="showSelectSpan" :class="['trace-item', 'level'+( data.level
- 1)]">
+ <div :class="['method', 'level'+( data.level - 1)]"
:style="{'text-indent': (data.level - 1) * 10 + 'px' }">
+ <span
+ v-if="data.children && data.children.length > 0"
+ @click.stop="toggle"
+ :class="['trace-table-toggle', displayChildren? 'collapse':
'expand']">
+
+ </span>
+ <span v-tooltip:bottom="{content: data.endpointName, popperCls:
['trace-table-tooltip']}">
+ {{data.endpointName}}
+ </span>
+ </div>
+ <div class="start-time">
+ {{formatTime(data.startTime)}}
+ </div>
+ <div class="gap">
+ 0
+ </div>
+ <div class="exec-ms">
+ {{(data.endTime - data.startTime)?(data.endTime - data.startTime) :
'0'}}
+ </div>
+ <div class="exec-percent">
+ <div class="outer-progress_bar" :style="{width: outterPercent}">
+ <div class="inner-progress_bar" :style="{width:
innerPercent}"></div>
+ </div>
+ </div>
+ <div class="self">
+ {{data.dur ? data.dur + '' : '0'}}
+ </div>
+ <div class="api">
+ <span v-tooltip:bottom="data.component||'-'">{{data.component ||
'-'}}</span>
+ </div>
+ <div class="application">
+ <span
v-tooltip:bottom="data.serviceCode||'-'">{{data.serviceCode}}</span>
+ </div>
+ </div>
+ <div v-show="data.children && data.children.length > 0 && displayChildren"
class="children-trace">
+ <item v-for="(item, index) in data.children" :key="index"
:data="item"> </item>
+ </div>
+ </div>
+
+</template>
+<style lang="scss" scoped>
+ @import './trace.scss';
+ .trace-item.level0{
+ background: rgba(0, 0, 0, 0.04);;
+ color: #448dfe;
+ &:hover {
+ background: rgba(0, 0, 0, 0.04);;
+ color: #448dfe;
+ }
+ &::before{
+ position: absolute;
+ content: '';
+ width: 5px;
+ height: 100%;
+ background: #448dfe;
+ left: 0;
+ }
+ }
+
+ .trace-table-toggle {
+ cursor: pointer;
+ height: 12px;
+ width: 12px;
+ display: inline-block;
+ &.collapse {
+ background: url('./collapse.gif') no-repeat;
+ background-size: 12px 12px;
+ }
+
+ &.expand {
+ background: url('./expand.gif') no-repeat;
+ background-size: 12px 12px;
+ }
+ }
+
+ .trace-item {
+ display: flex;
+ position: relative;
+ }
+ .trace-item.selected {
+ background: rgba(0, 0, 0, 0.04);
+ }
+
+ .trace-item:not(.level0):hover {
+ background: rgba(0, 0, 0, 0.04);
+ }
+
+
+ .trace-item>div {
+ padding: 0 5px;
+ border: 1px solid transparent;
+ border-right: 1px dotted silver;
+ overflow: hidden;
+ line-height: 30px;
+ overflow:hidden;
+ text-overflow:ellipsis;
+ white-space:nowrap
+ }
+ .trace-item>div.method {
+ padding-left: 10px;
+ }
+ .trace-item div.exec-percent {
+ width: 10%;
+ padding-left: 8px;
+ padding-right: 8px;
+ .outer-progress_bar {
+ width: 100%;
+ height: 6px;
+ border-radius: 3px;
+ background: rgb(63, 177, 227);
+ position: relative;
+ margin-top: 11px;
+ border: none;
+ }
+ .inner-progress_bar {
+ position: absolute;
+ background: rgb(110, 64, 170);
+ height: 4px;
+ border-radius: 2px;
+ left: 0;
+ border:none;
+ top: 1px;
+ }
+ }
+
+
+</style>
+<script type="text/javascript">
+import moment from 'dayjs';
+import Popper from 'popper.js';
+export default {
+ name: 'item',
+ props: ['data'],
+ data() {
+ return {
+ displayChildren: true,
+ };
+ },
+ computed: {
+ selfTime() {
+ const {data} = this;
+ return data.dur ? data.dur : 0;
+ },
+ execTime() {
+ const {data} = this;
+ return (data.endTime - data.startTime) ? (data.endTime -
data.startTime) : 0;
+ },
+ outterPercent() {
+ if (this.data.level === 1) {
+ return '100%';
+ } else {
+ const data = this.data;
+ const exec = (data.endTime - data.startTime) ? (data.endTime -
data.startTime) : 0;
+ let result = (exec / data.totalExec * 100);
+ result = result > 100 ? 100 : result;
+ result = result.toFixed(4) + '%';
+ return result === '0.0000%' ? '0.9%' : result;
+ }
+ },
+ innerPercent() {
+ const result = (this.selfTime / this.execTime) * 100 .toFixed(4) + '%';
+ return result === '0.0000%' ? '0.9%' : result;
+ },
+ eventHub() {
+ return this.$store.getters.globalEventHub;
+ },
+ },
+ methods: {
+ toggle() {
+ this.displayChildren = ! this.displayChildren;
+ },
+ formatTime(timestamp) {
+ return moment(timestamp).format('HH:mm:ss SSS');
+ },
+ showSelectSpan() {
+ this.eventHub.$emit('HANDLE-SELECT-SPAN', this.data);
+ },
+ },
+};
+</script>
diff --git a/src/views/components/trace/trace-chart-table/trace.scss
b/src/views/components/trace/trace-chart-table/trace.scss
new file mode 100644
index 0000000..10d191b
--- /dev/null
+++ b/src/views/components/trace/trace-chart-table/trace.scss
@@ -0,0 +1,31 @@
+.method {
+ width: 45%;
+}
+.argument {
+ width: 15%;
+}
+.start-time {
+ width: 5%;
+ min-width: 100px;
+}
+.gap {
+ width: 5%;
+}
+.exec-ms {
+ width: 6%;
+}
+.exec-percent {
+ width: 10%;
+}
+.self {
+ width: 5%;
+}
+.api {
+ width: 10%;
+}
+.agent {
+ width: 15%;
+}
+.application {
+ width: 15%;
+}
\ No newline at end of file
diff --git a/src/views/components/trace/trace-detail-chart-table.vue
b/src/views/components/trace/trace-detail-chart-table.vue
new file mode 100644
index 0000000..d5f588b
--- /dev/null
+++ b/src/views/components/trace/trace-detail-chart-table.vue
@@ -0,0 +1,169 @@
+<template>
+
+ <div class="trace-detail-chart-table">
+ <TraceContainer>
+ <Item v-for="(item, index) in tableData" :data="item" :key="'key'+
index" />
+ </TraceContainer>
+ <rk-sidebox :show.sync="showDetail" :title="$t('spanInfo')">
+ <div class="rk-trace-detail">
+ <h5 class="mb-15">{{$t('tags')}}.</h5>
+ <div class="mb-10 clear"><span class="g-sm-4
grey">{{$t('endpoint')}}:</span><span class="g-sm-8
wba">{{this.currentSpan.label}}</span></div>
+ <div class="mb-10 clear"><span class="g-sm-4
grey">{{$t('spanType')}}:</span><span class="g-sm-8
wba">{{this.currentSpan.type}}</span></div>
+ <div class="mb-10 clear"><span class="g-sm-4
grey">{{$t('component')}}:</span><span class="g-sm-8
wba">{{this.currentSpan.component}}</span></div>
+ <div class="mb-10 clear"><span class="g-sm-4 grey">Peer:</span><span
class="g-sm-8 wba">{{this.currentSpan.peer||'No Peer'}}</span></div>
+ <div class="mb-10 clear"><span class="g-sm-4
grey">{{$t('error')}}:</span><span class="g-sm-8
wba">{{this.currentSpan.isError}}</span></div>
+ <div class="mb-10 clear" v-for="i in this.currentSpan.tags"
:key="i.key"><span class="g-sm-4 grey">{{i.key}}:</span><span class="g-sm-8
wba">{{i.value}}</span></div>
+ <h5 class="mb-10" v-if="this.currentSpan.logs"
v-show="this.currentSpan.logs.length">{{$t('logs')}}.</h5>
+ <div v-for="(i, index) in this.currentSpan.logs" :key="index">
+ <div class="mb-10 sm">
+ <span class="mr-10">{{$t('time')}}:</span>
+ <span class="grey">{{i.time | dateformat}}</span>
+ </div>
+ <div class="mb-15 clear" v-for="(_i, _index) in i.data"
:key="_index">
+ <div class="mb-10">{{_i.key}}:</div>
+ <pre class="g-sm-8 mt-0 mb-0 sm"
style="overflow:auto">{{_i.value}}</pre>
+ </div>
+ </div>
+ </div>
+ </rk-sidebox>
+ </div>
+</template>
+<style lang="scss">
+ .rk-tooltip-popper.trace-table-tooltip .rk-tooltip-inner{
+ max-width: 600px;
+ }
+</style>
+
+<script>
+import Item from './trace-chart-table/trace-item';
+import TraceContainer from './trace-chart-table/trace-container';
+/* eslint-disable */
+/* tslint:disable */
+export default {
+ components: {
+ Item,
+ TraceContainer,
+ },
+ props: ['data', 'traceId'],
+ watch: {
+ data(val, oldVal) {
+ if (!this.data.length) {
+ return;
+ }
+ this.tableData = this.formatData(this.changeTree());
+ },
+ },
+ data() {
+ return {
+ tableData: [],
+ diaplay: true,
+ // segmentId: [],
+ showDetail: false,
+ list: [],
+ currentSpan: [],
+ };
+ },
+ computed: {
+ eventHub() {
+ return this.$store.getters.globalEventHub
+ }
+ },
+ methods: {
+ // 给增加层级关系
+ formatData(arr, level = 1, totalExec = null) {
+ for (const item of arr) {
+ item.level = level;
+ totalExec = totalExec || (item.endTime - item.startTime);
+ item.totalExec = totalExec;
+ if (item.children && item.children.length > 0) {
+ this.formatData(item.children, level + 1, totalExec);
+ }
+ }
+ return arr;
+ },
+ traverseTree(node, spanId, segmentId, data) {
+ if (!node) {
+ return;
+ }
+ if (node.spanId === spanId && node.segmentId === segmentId) {
+ node.children.push(data);
+ return;
+ }
+ if (node.children && node.children.length > 0) {
+ for (const item of node.children) {
+ this.traverseTree(item, spanId, segmentId, data);
+ }
+ }
+ },
+ changeTree() {
+ if (this.data.length === 0) {
+ return [];
+ }
+ this.list = Array.from(new Set(this.data.map((i) => i.serviceCode)));
+ this.segmentId = [];
+ const segmentGroup = {};
+ const segmentIdGroup = [];
+ this.data.forEach((i) => {
+ i.label = i.endpointName || 'no operation name';
+ i.children = [];
+ if (segmentGroup[i.segmentId] === undefined) {
+ segmentIdGroup.push(i.segmentId);
+ segmentGroup[i.segmentId] = [];
+ segmentGroup[i.segmentId].push(i);
+ } else {
+ segmentGroup[i.segmentId].push(i);
+ }
+ });
+ segmentIdGroup.forEach((id) => {
+ const currentSegment = segmentGroup[id].sort((a, b) => b.parentSpanId
- a.parentSpanId);
+ currentSegment.forEach((s) => {
+ const index = currentSegment.findIndex((i) => i.spanId ===
s.parentSpanId);
+ if (index !== -1) {
+ currentSegment[index].children.push(s);
+ currentSegment[index].children.sort((a, b) => a.spanId - b.spanId
);
+ }
+ });
+ segmentGroup[id] = currentSegment[currentSegment.length - 1];
+ });
+ segmentIdGroup.forEach((id) => {
+ segmentGroup[id].refs.forEach((ref) => {
+ if (ref.traceId === this.traceId) {
+ this.traverseTree(segmentGroup[ref.parentSegmentId],
+ ref.parentSpanId,
+ ref.parentSegmentId,
+ segmentGroup[id]);
+ }
+ });
+ // if(segmentGroup[id].refs.length !==0 ) delete segmentGroup[id];
+ });
+ for (const i in segmentGroup) {
+ if (segmentGroup[i].refs.length === 0) {
+ this.segmentId.push(segmentGroup[i]);
+ }
+ }
+ this.segmentId.forEach((_, i) => {
+ this.collapse(this.segmentId[i]);
+ });
+ return this.segmentId;
+ },
+ collapse(d) {
+ if (d.children) {
+ let dur = d.endTime - d.startTime;
+ d.children.forEach((i) => {
+ dur -= (i.endTime - i.startTime);
+ });
+ d.dur = dur < 0 ? 0 : dur;
+ d.children.forEach((i) => this.collapse(i));
+ }
+ },
+ handleSelectSpan(data) {
+ this.currentSpan = data;
+ this.showDetail = true;
+ },
+ },
+ mounted() {
+ this.tableData = this.formatData(this.changeTree());
+ this.eventHub.$on('HANDLE-SELECT-SPAN', this.handleSelectSpan);
+ },
+};
+</script>
diff --git a/src/views/components/trace/trace-detail-chart-tree.vue
b/src/views/components/trace/trace-detail-chart-tree.vue
index 5f4353a..0f8a52b 100644
--- a/src/views/components/trace/trace-detail-chart-tree.vue
+++ b/src/views/components/trace/trace-detail-chart-tree.vue
@@ -214,4 +214,4 @@ export default {
fill: rgba(0,0,0,0.05)
}
}
-</style>
+</style>
\ No newline at end of file
diff --git a/src/views/components/trace/trace-detail.vue
b/src/views/components/trace/trace-detail.vue
index 2a309c8..f6c25b7 100644
--- a/src/views/components/trace/trace-detail.vue
+++ b/src/views/components/trace/trace-detail.vue
@@ -29,22 +29,32 @@
<option v-for="i in current.traceIds" :value="i"
:key="i">{{i}}</option>
</select>
</div>
- <a class="rk-btn sm r" :class="{'ghost':mode}" @click="mode = false">
+
+ <a class="rk-btn mr-5 sm r" :class="{'ghost':displayMode !== 'table'}"
@click="displayMode = 'table'">
+ <svg class="icon vm sm rk-trace-table_svg-icon">
+ <use xlink:href="#table"></use>
+ </svg>
+ {{$t('table')}}</a>
+ <a class="rk-btn mr-5 sm r" :class="{'ghost':displayMode !== 'tree'}"
@click="displayMode = 'tree'">
<svg class="icon vm sm">
<use xlink:href="#issue-child"></use>
</svg>
{{$t('tree')}}</a>
- <a class="rk-btn mr-5 sm r" :class="{'ghost':!mode}" @click="mode =
true">
+ <a class="rk-btn mr-5 sm r" :class="{'ghost':displayMode !== 'list'}"
@click="displayMode = 'list'">
<svg class="icon vm sm">
<use xlink:href="#list-bulleted"></use>
</svg>
{{$t('list')}}</a>
+
+
<div class="rk-tag mr-5">{{this.$t('start')}}</div><span class="mr-15
sm">{{parseInt(current.start) | dateformat}}</span>
<div class="rk-tag mr-5">{{this.$t('duration')}}</div><span class="mr-15
sm">{{current.duration}} ms</span>
<div class="rk-tag mr-5">{{this.$t('spans')}}</div><span
class="sm">{{spans.length}}</span>
</div>
- <TraceDetailChartList v-if="mode&¤t.endpointNames" :data="spans"
:traceId="current.traceIds[0]"/>
- <TraceDetailChartTree v-if="!mode&¤t.endpointNames" :data="spans"
:traceId="current.traceIds[0]"/>
+ <TraceDetailChartList v-if="displayMode == 'list'&¤t.endpointNames"
:data="spans" :traceId="current.traceIds[0]"/>
+ <TraceDetailChartTree v-if="displayMode == 'tree'&¤t.endpointNames"
:data="spans" :traceId="current.traceIds[0]"/>
+ <TraceDetailChartTable v-if="displayMode ==
'table'&¤t.endpointNames" :data="spans" :traceId="current.traceIds[0]"/>
+
<div v-if="!current.endpointNames" class="flex-h container">
<svg class="icon rk-icon-trace">
<use xlink:href="#unlink"></use>
@@ -57,16 +67,18 @@
import { Vue, Component, Prop } from 'vue-property-decorator';
import TraceDetailChartList from './trace-detail-chart-list.vue';
import TraceDetailChartTree from './trace-detail-chart-tree.vue';
+import TraceDetailChartTable from './trace-detail-chart-table.vue';
import { Trace, Span } from '@/types/trace';
import { Action, State } from 'vuex-class';
-@Component({ components: { TraceDetailChartList, TraceDetailChartTree } })
+@Component({ components: { TraceDetailChartList, TraceDetailChartTree,
TraceDetailChartTable } })
export default class Header extends Vue {
@State('rocketbot') private rocketbot: any;
@Action('rocketTrace/GET_TRACE_SPANS') private GET_TRACE_SPANS: any;
@Prop() private spans!: Span[];
@Prop() private current!: Trace;
private mode: boolean = true;
+ private displayMode: string = 'list';
}
</script>
@@ -75,6 +87,7 @@ export default class Header extends Vue {
flex-shrink: 0;
height: 100%;
width: 75%;
+ overflow-y:auto;
}
.rk-trace-detail-wrapper {
padding: 8px 30px;
@@ -101,4 +114,8 @@ export default class Header extends Vue {
margin: 0 auto;
fill: rgba(46, 47, 51, 0.15);
}
+.rk-trace-table_svg-icon {
+ width: 11px;
+ height: 11px;
+}
</style>
diff --git a/src/views/components/trace/trace-table.vue
b/src/views/components/trace/trace-table.vue
index ef68c95..9a7b029 100644
--- a/src/views/components/trace/trace-table.vue
+++ b/src/views/components/trace/trace-table.vue
@@ -31,7 +31,7 @@
</div>
<div class="rk-trace-t-wrapper scroll_hide">
<table class="rk-trace-t">
- <tr class="rk-trace-tr cp" v-for="i in rocketTrace.traceList"
@click="selectTrace(i)">
+ <tr class="rk-trace-tr cp" v-for="(i, index) in
rocketTrace.traceList" @click="selectTrace(i)" :key="index">
<td class="rk-trace-td" :class="{
'rk-trace-success':!i.isError,
'rk-trace-error':i.isError,
@@ -49,7 +49,7 @@
</template>
<script lang="ts">
-import { Component, Vue, Prop } from 'vue-property-decorator';
+import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
import { Action, Getter, Mutation, State } from 'vuex-class';
@Component
export default class Home extends Vue {
@@ -60,6 +60,12 @@ export default class Home extends Vue {
@Action('rocketTrace/GET_TRACELIST') private GET_TRACELIST: any;
@Action('rocketTrace/GET_TRACE_SPANS') private GET_TRACE_SPANS: any;
private loading: boolean = false;
+ @Watch('rocketTrace.traceList')
+ private onTraceListChange() {
+ if (this.rocketTrace.traceList && this.rocketTrace.traceList.length > 0) {
+ this.selectTrace(this.rocketTrace.traceList[0]);
+ }
+ }
private selectTrace(i: any) {
this.SET_CURRENT_TRACE(i);
if (i.traceIds.length) {