mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-18 11:05:24 +00:00
vis stacks
This commit is contained in:
parent
68122c0a28
commit
cf46164337
31
package-lock.json
generated
31
package-lock.json
generated
@ -10,6 +10,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.24.0",
|
"axios": "^0.24.0",
|
||||||
"d3": "^7.3.0",
|
"d3": "^7.3.0",
|
||||||
|
"d3-flame-graph": "^4.1.3",
|
||||||
"d3-tip": "^0.9.1",
|
"d3-tip": "^0.9.1",
|
||||||
"echarts": "^5.2.2",
|
"echarts": "^5.2.2",
|
||||||
"element-plus": "^2.0.2",
|
"element-plus": "^2.0.2",
|
||||||
@ -9340,6 +9341,21 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/d3-flame-graph": {
|
||||||
|
"version": "4.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/d3-flame-graph/-/d3-flame-graph-4.1.3.tgz",
|
||||||
|
"integrity": "sha512-NijuhJZhaTMwobVgwGQ67x9PovqMMHXBbs0FMHEGJvsWZGuL4M7OsB03v8mHdyVyHhnQYGsYnb5w021e9+R+RQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"d3-array": "^3.1.1",
|
||||||
|
"d3-dispatch": "^3.0.1",
|
||||||
|
"d3-ease": "^3.0.1",
|
||||||
|
"d3-format": "^3.0.1",
|
||||||
|
"d3-hierarchy": "^3.0.1",
|
||||||
|
"d3-scale": "^4.0.2",
|
||||||
|
"d3-selection": "^3.0.0",
|
||||||
|
"d3-transition": "^3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/d3-force": {
|
"node_modules/d3-force": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
|
||||||
@ -36407,6 +36423,21 @@
|
|||||||
"d3-dsv": "1 - 3"
|
"d3-dsv": "1 - 3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"d3-flame-graph": {
|
||||||
|
"version": "4.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/d3-flame-graph/-/d3-flame-graph-4.1.3.tgz",
|
||||||
|
"integrity": "sha512-NijuhJZhaTMwobVgwGQ67x9PovqMMHXBbs0FMHEGJvsWZGuL4M7OsB03v8mHdyVyHhnQYGsYnb5w021e9+R+RQ==",
|
||||||
|
"requires": {
|
||||||
|
"d3-array": "^3.1.1",
|
||||||
|
"d3-dispatch": "^3.0.1",
|
||||||
|
"d3-ease": "^3.0.1",
|
||||||
|
"d3-format": "^3.0.1",
|
||||||
|
"d3-hierarchy": "^3.0.1",
|
||||||
|
"d3-scale": "^4.0.2",
|
||||||
|
"d3-selection": "^3.0.0",
|
||||||
|
"d3-transition": "^3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"d3-force": {
|
"d3-force": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.24.0",
|
"axios": "^0.24.0",
|
||||||
"d3": "^7.3.0",
|
"d3": "^7.3.0",
|
||||||
|
"d3-flame-graph": "^4.1.3",
|
||||||
"d3-tip": "^0.9.1",
|
"d3-tip": "^0.9.1",
|
||||||
"echarts": "^5.2.2",
|
"echarts": "^5.2.2",
|
||||||
"element-plus": "^2.0.2",
|
"element-plus": "^2.0.2",
|
||||||
|
11
src/types/ebpf.d.ts
vendored
11
src/types/ebpf.d.ts
vendored
@ -56,3 +56,14 @@ export type Process = {
|
|||||||
attributes: { name: string; value: string };
|
attributes: { name: string; value: string };
|
||||||
labels: string[];
|
labels: string[];
|
||||||
};
|
};
|
||||||
|
export type StackElement = {
|
||||||
|
id: string;
|
||||||
|
originId: string;
|
||||||
|
name: string;
|
||||||
|
parentId: string;
|
||||||
|
symbol: string;
|
||||||
|
dumpCount: number;
|
||||||
|
stackType: string;
|
||||||
|
value: number;
|
||||||
|
children?: StackElement[];
|
||||||
|
};
|
||||||
|
@ -82,13 +82,6 @@ const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
|
|||||||
|
|
||||||
function changeLabels(opt: any[]) {
|
function changeLabels(opt: any[]) {
|
||||||
const arr = opt.map((d) => d.value);
|
const arr = opt.map((d) => d.value);
|
||||||
|
|
||||||
// if (arr.includes("0")) {
|
|
||||||
// selectedLabels.value = labels.value.map((d: Option) => d.value);
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// selectedLabels.value = Array.from(new Set(arr));
|
|
||||||
selectedLabels.value = arr;
|
selectedLabels.value = arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,31 +13,95 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License. -->
|
limitations under the License. -->
|
||||||
<template>
|
<template>
|
||||||
<div>tree</div>
|
<div id="graph-stack" ref="graph"></div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { watch } from "vue";
|
import { ref, watch } from "vue";
|
||||||
|
import * as d3 from "d3";
|
||||||
|
import { flamegraph } from "d3-flame-graph";
|
||||||
import { useEbpfStore } from "@/store/modules/ebpf";
|
import { useEbpfStore } from "@/store/modules/ebpf";
|
||||||
|
import { StackElement } from "@/types/ebpf";
|
||||||
|
import { json } from "./json";
|
||||||
|
import "d3-flame-graph/dist/d3-flamegraph.css";
|
||||||
|
|
||||||
|
/*global Nullable*/
|
||||||
const ebpfStore = useEbpfStore();
|
const ebpfStore = useEbpfStore();
|
||||||
|
const stackTree = ref<Nullable<StackElement>>(null);
|
||||||
|
const graph = ref<Nullable<HTMLDivElement>>(null);
|
||||||
|
const flameChart = ref<any>(null);
|
||||||
|
|
||||||
function sortArr(arr: any[]) {
|
function drawGraph() {
|
||||||
|
if (flameChart.value) {
|
||||||
|
flameChart.value.destroy();
|
||||||
|
}
|
||||||
|
if (!ebpfStore.analyzeTrees.length) {
|
||||||
|
return (stackTree.value = null);
|
||||||
|
}
|
||||||
|
stackTree.value = processTree(ebpfStore.analyzeTrees);
|
||||||
|
|
||||||
|
const w = (graph.value && graph.value.getBoundingClientRect().width) || 10;
|
||||||
|
flameChart.value = flamegraph()
|
||||||
|
.width(w - 10)
|
||||||
|
.cellHeight(18)
|
||||||
|
.transitionDuration(750)
|
||||||
|
.minFrameSize(5)
|
||||||
|
.transitionEase(d3.easeCubic as any)
|
||||||
|
.sort(true)
|
||||||
|
.title("")
|
||||||
|
.onClick(onClick)
|
||||||
|
.selfValue(false)
|
||||||
|
.setColorMapper((d, originalColor) =>
|
||||||
|
d.highlight ? "#6aff8f" : originalColor
|
||||||
|
);
|
||||||
|
// stackTree.value = (json as any);
|
||||||
|
console.log(stackTree.value);
|
||||||
|
d3.select("#graph-stack")
|
||||||
|
.datum(stackTree.value)
|
||||||
|
.call(flameChart.value)
|
||||||
|
.call(invokeFind);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClick(d: any) {
|
||||||
|
console.info(`Clicked on ${d.data.name}, id: "${d.data.value}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetZoom() {
|
||||||
|
if (!flameChart.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flameChart.value.resetZoom();
|
||||||
|
}
|
||||||
|
|
||||||
|
function invokeFind() {
|
||||||
|
const searchId = parseInt(location.hash.substring(1), 10);
|
||||||
|
if (searchId) {
|
||||||
|
find(searchId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function find(id: number) {
|
||||||
|
var elem = flameChart.value.findById(id);
|
||||||
|
if (elem) {
|
||||||
|
flameChart.value.zoomTo(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processTree(arr: StackElement[]) {
|
||||||
const copyArr = JSON.parse(JSON.stringify(arr));
|
const copyArr = JSON.parse(JSON.stringify(arr));
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
const res = [];
|
let res = null;
|
||||||
for (const item of copyArr) {
|
for (const item of copyArr) {
|
||||||
obj[item.id] = item;
|
item.originId = item.id;
|
||||||
|
item.value = item.dumpCount;
|
||||||
|
item.name = item.symbol;
|
||||||
|
delete item.id;
|
||||||
|
obj[item.originId] = item;
|
||||||
}
|
}
|
||||||
for (const item of copyArr) {
|
for (const item of copyArr) {
|
||||||
if (item.parentId === "0") {
|
if (item.parentId === "0") {
|
||||||
item.name = item.symbol;
|
res = item;
|
||||||
item.value = item.dumpCount;
|
|
||||||
res.push(item);
|
|
||||||
}
|
}
|
||||||
for (const key in obj) {
|
for (const key in obj) {
|
||||||
if (item.id === obj[key].parentId) {
|
if (item.originId === obj[key].parentId) {
|
||||||
obj[key].name = obj[key].symbol;
|
|
||||||
obj[key].value = obj[key].dumpCount;
|
|
||||||
if (item.children) {
|
if (item.children) {
|
||||||
item.children.push(obj[key]);
|
item.children.push(obj[key]);
|
||||||
} else {
|
} else {
|
||||||
@ -46,13 +110,19 @@ function sortArr(arr: any[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(res);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
watch(
|
watch(
|
||||||
() => ebpfStore.analyzeTrees,
|
() => ebpfStore.analyzeTrees,
|
||||||
() => {
|
() => {
|
||||||
sortArr(ebpfStore.analyzeTrees);
|
drawGraph();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
<style>
|
||||||
|
#graph-stack {
|
||||||
|
width: 100%;
|
||||||
|
height: 350px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
2524
src/views/dashboard/related/ebpf/components/json.ts
Normal file
2524
src/views/dashboard/related/ebpf/components/json.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -88,7 +88,7 @@ limitations under the License. -->
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-button
|
<el-button
|
||||||
class="grey"
|
class="grey small"
|
||||||
:class="{ ghost: displayMode !== 'List' }"
|
:class="{ ghost: displayMode !== 'List' }"
|
||||||
@click="displayMode = 'List'"
|
@click="displayMode = 'List'"
|
||||||
>
|
>
|
||||||
@ -96,7 +96,7 @@ limitations under the License. -->
|
|||||||
{{ t("list") }}
|
{{ t("list") }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
class="grey"
|
class="grey small"
|
||||||
:class="{ ghost: displayMode !== 'Tree' }"
|
:class="{ ghost: displayMode !== 'Tree' }"
|
||||||
@click="displayMode = 'Tree'"
|
@click="displayMode = 'Tree'"
|
||||||
>
|
>
|
||||||
@ -104,7 +104,7 @@ limitations under the License. -->
|
|||||||
{{ t("tree") }}
|
{{ t("tree") }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
class="grey"
|
class="grey small"
|
||||||
:class="{ ghost: displayMode !== 'Table' }"
|
:class="{ ghost: displayMode !== 'Table' }"
|
||||||
@click="displayMode = 'Table'"
|
@click="displayMode = 'Table'"
|
||||||
>
|
>
|
||||||
@ -112,7 +112,7 @@ limitations under the License. -->
|
|||||||
{{ t("table") }}
|
{{ t("table") }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
class="grey"
|
class="grey small"
|
||||||
:class="{ ghost: displayMode !== 'Statistics' }"
|
:class="{ ghost: displayMode !== 'Statistics' }"
|
||||||
@click="displayMode = 'Statistics'"
|
@click="displayMode = 'Statistics'"
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user