mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-12 15:52:57 +00:00
feat: update trace list
This commit is contained in:
parent
b56a503c66
commit
6b38ff6b2f
Binary file not shown.
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 259 B |
@ -26,3 +26,8 @@ export const Languages = [
|
|||||||
{ label: "Chinese", value: "zh" },
|
{ label: "Chinese", value: "zh" },
|
||||||
{ label: "Spanish", value: "es" },
|
{ label: "Spanish", value: "es" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export enum Themes {
|
||||||
|
Dark = "dark",
|
||||||
|
Light = "light",
|
||||||
|
}
|
||||||
|
@ -31,6 +31,7 @@ import { useEventListener } from "./useEventListener";
|
|||||||
import { useBreakpoint } from "./useBreakpoint";
|
import { useBreakpoint } from "./useBreakpoint";
|
||||||
import echarts from "@/utils/echarts";
|
import echarts from "@/utils/echarts";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
|
import { Themes } from "@/constants/data";
|
||||||
|
|
||||||
export type ECOption = echarts.ComposeOption<
|
export type ECOption = echarts.ComposeOption<
|
||||||
| BarSeriesOption
|
| BarSeriesOption
|
||||||
@ -47,7 +48,7 @@ export type ECOption = echarts.ComposeOption<
|
|||||||
export function useECharts(elRef: Ref<HTMLDivElement>, theme: "light" | "dark" | "default" = "default"): Indexable {
|
export function useECharts(elRef: Ref<HTMLDivElement>, theme: "light" | "dark" | "default" = "default"): Indexable {
|
||||||
const appStore = useAppStoreWithOut();
|
const appStore = useAppStoreWithOut();
|
||||||
const getDarkMode = computed(() => {
|
const getDarkMode = computed(() => {
|
||||||
return appStore.theme === "default" ? "light" : theme;
|
return appStore.theme === "default" ? Themes.Light : theme;
|
||||||
});
|
});
|
||||||
let chartInstance: Nullable<echarts.ECharts> = null;
|
let chartInstance: Nullable<echarts.ECharts> = null;
|
||||||
let resizeFn: Fn = resize;
|
let resizeFn: Fn = resize;
|
||||||
@ -57,7 +58,7 @@ export function useECharts(elRef: Ref<HTMLDivElement>, theme: "light" | "dark" |
|
|||||||
resizeFn = useDebounceFn(resize, 200);
|
resizeFn = useDebounceFn(resize, 200);
|
||||||
|
|
||||||
const getOptions = computed(() => {
|
const getOptions = computed(() => {
|
||||||
if (getDarkMode.value !== "dark") {
|
if (getDarkMode.value !== Themes.Dark) {
|
||||||
return cacheOptions.value as ECOption;
|
return cacheOptions.value as ECOption;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
@ -78,6 +78,7 @@ limitations under the License. -->
|
|||||||
import type { DashboardItem } from "@/types/dashboard";
|
import type { DashboardItem } from "@/types/dashboard";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { ArrowRight, Moon, Sunny } from "@element-plus/icons-vue";
|
import { ArrowRight, Moon, Sunny } from "@element-plus/icons-vue";
|
||||||
|
import { Themes } from "@/constants/data";
|
||||||
|
|
||||||
/*global Indexable */
|
/*global Indexable */
|
||||||
const { t, te } = useI18n();
|
const { t, te } = useI18n();
|
||||||
@ -98,13 +99,13 @@ limitations under the License. -->
|
|||||||
const root = document.documentElement;
|
const root = document.documentElement;
|
||||||
|
|
||||||
if (theme.value) {
|
if (theme.value) {
|
||||||
root.classList.add("dark");
|
root.classList.add(Themes.Dark);
|
||||||
root.classList.remove("light");
|
root.classList.remove(Themes.Light);
|
||||||
appStore.setTheme("dark");
|
appStore.setTheme(Themes.Dark);
|
||||||
} else {
|
} else {
|
||||||
root.classList.add("light");
|
root.classList.add(Themes.Light);
|
||||||
root.classList.remove("dark");
|
root.classList.remove(Themes.Dark);
|
||||||
appStore.setTheme("light");
|
appStore.setTheme(Themes.Light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import type { AxiosResponse } from "axios";
|
|||||||
import dateFormatStep, { dateFormatTime } from "@/utils/dateFormat";
|
import dateFormatStep, { dateFormatTime } from "@/utils/dateFormat";
|
||||||
import { TimeType } from "@/constants/data";
|
import { TimeType } from "@/constants/data";
|
||||||
import type { MenuOptions, SubItem } from "@/types/app";
|
import type { MenuOptions, SubItem } from "@/types/app";
|
||||||
|
import { Themes } from "@/constants/data";
|
||||||
/*global Nullable*/
|
/*global Nullable*/
|
||||||
interface AppState {
|
interface AppState {
|
||||||
durationRow: Recordable;
|
durationRow: Recordable;
|
||||||
@ -57,7 +58,7 @@ export const appStore = defineStore({
|
|||||||
isMobile: false,
|
isMobile: false,
|
||||||
reloadTimer: null,
|
reloadTimer: null,
|
||||||
allMenus: [],
|
allMenus: [],
|
||||||
theme: "dark",
|
theme: Themes.Dark,
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
duration(): Duration {
|
duration(): Duration {
|
||||||
|
@ -25,6 +25,7 @@ limitations under the License. -->
|
|||||||
import useLegendProcess from "@/hooks/useLegendProcessor";
|
import useLegendProcess from "@/hooks/useLegendProcessor";
|
||||||
import Legend from "./components/Legend.vue";
|
import Legend from "./components/Legend.vue";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
|
import { Themes } from "@/constants/data";
|
||||||
|
|
||||||
/*global defineProps, defineEmits */
|
/*global defineProps, defineEmits */
|
||||||
const emits = defineEmits(["click"]);
|
const emits = defineEmits(["click"]);
|
||||||
@ -93,11 +94,11 @@ limitations under the License. -->
|
|||||||
top: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
itemWidth: 12,
|
itemWidth: 12,
|
||||||
backgroundColor: appStore.theme === "dark" ? "#333" : "#fff",
|
backgroundColor: appStore.theme === Themes.Dark ? "#333" : "#fff",
|
||||||
borderColor: appStore.theme === "dark" ? "#333" : "#fff",
|
borderColor: appStore.theme === Themes.Dark ? "#333" : "#fff",
|
||||||
textStyle: {
|
textStyle: {
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: appStore.theme === "dark" ? "#eee" : "#333",
|
color: appStore.theme === Themes.Dark ? "#eee" : "#333",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
|
@ -32,6 +32,7 @@ limitations under the License. -->
|
|||||||
import useLegendProcess from "@/hooks/useLegendProcessor";
|
import useLegendProcess from "@/hooks/useLegendProcessor";
|
||||||
import { isDef } from "@/utils/is";
|
import { isDef } from "@/utils/is";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
|
import { Themes } from "@/constants/data";
|
||||||
|
|
||||||
/*global defineProps, defineEmits */
|
/*global defineProps, defineEmits */
|
||||||
const emits = defineEmits(["click"]);
|
const emits = defineEmits(["click"]);
|
||||||
@ -94,11 +95,11 @@ limitations under the License. -->
|
|||||||
const color: string[] = chartColors(keys);
|
const color: string[] = chartColors(keys);
|
||||||
const tooltip = {
|
const tooltip = {
|
||||||
trigger: "axis",
|
trigger: "axis",
|
||||||
backgroundColor: appStore.theme === "dark" ? "#333" : "#fff",
|
backgroundColor: appStore.theme === Themes.Dark ? "#333" : "#fff",
|
||||||
borderColor: appStore.theme === "dark" ? "#333" : "#fff",
|
borderColor: appStore.theme === Themes.Dark ? "#333" : "#fff",
|
||||||
textStyle: {
|
textStyle: {
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: appStore.theme === "dark" ? "#eee" : "#333",
|
color: appStore.theme === Themes.Dark ? "#eee" : "#333",
|
||||||
},
|
},
|
||||||
enterable: true,
|
enterable: true,
|
||||||
confine: true,
|
confine: true,
|
||||||
@ -111,11 +112,11 @@ limitations under the License. -->
|
|||||||
confine: true,
|
confine: true,
|
||||||
extraCssText: `height: 20px; padding:0 2px;`,
|
extraCssText: `height: 20px; padding:0 2px;`,
|
||||||
trigger: "axis",
|
trigger: "axis",
|
||||||
backgroundColor: appStore.theme === "dark" ? "#666" : "#eee",
|
backgroundColor: appStore.theme === Themes.Dark ? "#666" : "#eee",
|
||||||
borderColor: appStore.theme === "dark" ? "#666" : "#eee",
|
borderColor: appStore.theme === Themes.Dark ? "#666" : "#eee",
|
||||||
textStyle: {
|
textStyle: {
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: appStore.theme === "dark" ? "#eee" : "#333",
|
color: appStore.theme === Themes.Dark ? "#eee" : "#333",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -130,7 +131,7 @@ limitations under the License. -->
|
|||||||
left: 0,
|
left: 0,
|
||||||
itemWidth: 12,
|
itemWidth: 12,
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: appStore.theme === "dark" ? "#fff" : "#333",
|
color: appStore.theme === Themes.Dark ? "#fff" : "#333",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
|
@ -28,6 +28,7 @@ limitations under the License. -->
|
|||||||
import TreeGraph from "../../utils/d3-trace-tree";
|
import TreeGraph from "../../utils/d3-trace-tree";
|
||||||
import type { Span, Ref } from "@/types/trace";
|
import type { Span, Ref } from "@/types/trace";
|
||||||
import SpanDetail from "./SpanDetail.vue";
|
import SpanDetail from "./SpanDetail.vue";
|
||||||
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
|
|
||||||
/* global defineProps, Nullable, defineExpose,Recordable*/
|
/* global defineProps, Nullable, defineExpose,Recordable*/
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -35,6 +36,7 @@ limitations under the License. -->
|
|||||||
traceId: { type: String, default: "" },
|
traceId: { type: String, default: "" },
|
||||||
type: { type: String, default: "List" },
|
type: { type: String, default: "List" },
|
||||||
});
|
});
|
||||||
|
const appStore = useAppStoreWithOut();
|
||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
const showDetail = ref<boolean>(false);
|
const showDetail = ref<boolean>(false);
|
||||||
const fixSpansSize = ref<number>(0);
|
const fixSpansSize = ref<number>(0);
|
||||||
@ -289,6 +291,17 @@ limitations under the License. -->
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
watch(
|
||||||
|
() => appStore.theme,
|
||||||
|
() => {
|
||||||
|
tree.value.init({ label: "TRACE_ROOT", children: segmentId.value }, props.data, fixSpansSize.value);
|
||||||
|
tree.value.draw(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false;
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.d3-graph {
|
.d3-graph {
|
||||||
@ -301,12 +314,12 @@ limitations under the License. -->
|
|||||||
}
|
}
|
||||||
|
|
||||||
.trace-node-container {
|
.trace-node-container {
|
||||||
fill: rgba(0, 0, 0, 0);
|
fill: rgb(0 0 0 / 0%);
|
||||||
stroke-width: 5px;
|
stroke-width: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
fill: rgba(0, 0, 0, 0.05);
|
fill: rgb(0 0 0 / 5%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ import d3tip from "d3-tip";
|
|||||||
import type { Trace } from "@/types/trace";
|
import type { Trace } from "@/types/trace";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import icons from "@/assets/img/icons";
|
import icons from "@/assets/img/icons";
|
||||||
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
|
import { Themes } from "@/constants/data";
|
||||||
|
|
||||||
export default class ListGraph {
|
export default class ListGraph {
|
||||||
private barHeight = 48;
|
private barHeight = 48;
|
||||||
@ -127,6 +129,7 @@ export default class ListGraph {
|
|||||||
}
|
}
|
||||||
update(source: Recordable, callback: Function) {
|
update(source: Recordable, callback: Function) {
|
||||||
const t = this;
|
const t = this;
|
||||||
|
const appStore = useAppStoreWithOut();
|
||||||
const nodes = this.root.descendants();
|
const nodes = this.root.descendants();
|
||||||
let index = -1;
|
let index = -1;
|
||||||
this.root.eachBefore((n: Recordable) => {
|
this.root.eachBefore((n: Recordable) => {
|
||||||
@ -166,7 +169,7 @@ export default class ListGraph {
|
|||||||
.attr("width", 16)
|
.attr("width", 16)
|
||||||
.attr("height", 16)
|
.attr("height", 16)
|
||||||
.attr("x", 6)
|
.attr("x", 6)
|
||||||
.attr("y", -10)
|
.attr("y", -8)
|
||||||
.attr("xlink:href", (d: any) =>
|
.attr("xlink:href", (d: any) =>
|
||||||
d.data.type === "Entry" ? icons.ENTRY : d.data.type === "Exit" ? icons.EXIT : "",
|
d.data.type === "Entry" ? icons.ENTRY : d.data.type === "Exit" ? icons.EXIT : "",
|
||||||
)
|
)
|
||||||
@ -186,7 +189,7 @@ export default class ListGraph {
|
|||||||
.attr("width", 16)
|
.attr("width", 16)
|
||||||
.attr("height", 16)
|
.attr("height", 16)
|
||||||
.attr("x", 6)
|
.attr("x", 6)
|
||||||
.attr("y", -10)
|
.attr("y", -8)
|
||||||
.attr("xlink:href", (d: any) => {
|
.attr("xlink:href", (d: any) => {
|
||||||
const key = (d.data.refs || []).findIndex((d: { type: string }) => d.type === "CROSS_THREAD");
|
const key = (d.data.refs || []).findIndex((d: { type: string }) => d.type === "CROSS_THREAD");
|
||||||
return key > -1 ? icons.STREAM : "";
|
return key > -1 ? icons.STREAM : "";
|
||||||
@ -214,14 +217,14 @@ export default class ListGraph {
|
|||||||
.append("text")
|
.append("text")
|
||||||
.attr("x", 13)
|
.attr("x", 13)
|
||||||
.attr("y", 5)
|
.attr("y", 5)
|
||||||
.attr("fill", "#E54C17")
|
.attr("fill", appStore.theme === Themes.Dark ? "#666" : "#E54C17")
|
||||||
.html((d: Recordable) => (d.data.isError ? "◉" : ""));
|
.html((d: Recordable) => (d.data.isError ? "◉" : ""));
|
||||||
nodeEnter
|
nodeEnter
|
||||||
.append("text")
|
.append("text")
|
||||||
.attr("class", "node-text")
|
.attr("class", "node-text")
|
||||||
.attr("x", 35)
|
.attr("x", 35)
|
||||||
.attr("y", -6)
|
.attr("y", -6)
|
||||||
.attr("fill", "#333")
|
.attr("fill", appStore.theme === Themes.Dark ? "#eee" : "#333")
|
||||||
.html((d: Recordable) => {
|
.html((d: Recordable) => {
|
||||||
if (d.data.label === "TRACE_ROOT") {
|
if (d.data.label === "TRACE_ROOT") {
|
||||||
return "";
|
return "";
|
||||||
@ -242,7 +245,7 @@ export default class ListGraph {
|
|||||||
})
|
})
|
||||||
.attr("cy", -5)
|
.attr("cy", -5)
|
||||||
.attr("fill", "none")
|
.attr("fill", "none")
|
||||||
.attr("stroke", "#e66")
|
.attr("stroke", appStore.theme === Themes.Dark ? "#666" : "#e66")
|
||||||
.style("opacity", (d: Recordable) => {
|
.style("opacity", (d: Recordable) => {
|
||||||
const events = d.data.attachedEvents;
|
const events = d.data.attachedEvents;
|
||||||
if (events && events.length) {
|
if (events && events.length) {
|
||||||
@ -255,7 +258,7 @@ export default class ListGraph {
|
|||||||
.append("text")
|
.append("text")
|
||||||
.attr("x", 267)
|
.attr("x", 267)
|
||||||
.attr("y", -1)
|
.attr("y", -1)
|
||||||
.attr("fill", "#e66")
|
.attr("fill", appStore.theme === Themes.Dark ? "#666" : "#e66")
|
||||||
.style("font-size", "10px")
|
.style("font-size", "10px")
|
||||||
.text((d: Recordable) => {
|
.text((d: Recordable) => {
|
||||||
const events = d.data.attachedEvents;
|
const events = d.data.attachedEvents;
|
||||||
@ -270,7 +273,7 @@ export default class ListGraph {
|
|||||||
.attr("class", "node-text")
|
.attr("class", "node-text")
|
||||||
.attr("x", 35)
|
.attr("x", 35)
|
||||||
.attr("y", 12)
|
.attr("y", 12)
|
||||||
.attr("fill", "#ccc")
|
.attr("fill", appStore.theme === Themes.Dark ? "#777" : "#ccc")
|
||||||
.style("font-size", "11px")
|
.style("font-size", "11px")
|
||||||
.text(
|
.text(
|
||||||
(d: Recordable) =>
|
(d: Recordable) =>
|
||||||
@ -305,11 +308,15 @@ export default class ListGraph {
|
|||||||
.style("opacity", 1);
|
.style("opacity", 1);
|
||||||
nodeEnter
|
nodeEnter
|
||||||
.append("circle")
|
.append("circle")
|
||||||
.attr("r", 3)
|
.attr("r", appStore.theme === Themes.Dark ? 4 : 3)
|
||||||
.style("cursor", "pointer")
|
.style("cursor", "pointer")
|
||||||
.attr("stroke-width", 2.5)
|
.attr("stroke-width", appStore.theme === Themes.Dark ? 3 : 2.5)
|
||||||
.attr("fill", (d: Recordable) =>
|
.attr("fill", (d: Recordable) =>
|
||||||
d._children ? `${this.sequentialScale(this.list.indexOf(d.data.serviceCode))}` : "rbga(0,0,0,0)",
|
d._children
|
||||||
|
? `${this.sequentialScale(this.list.indexOf(d.data.serviceCode))}`
|
||||||
|
: appStore.theme === Themes.Dark
|
||||||
|
? "#eee"
|
||||||
|
: "rbga(0,0,0,0)",
|
||||||
)
|
)
|
||||||
.style("stroke", (d: Recordable) =>
|
.style("stroke", (d: Recordable) =>
|
||||||
d.data.label === "TRACE_ROOT" ? "" : `${this.sequentialScale(this.list.indexOf(d.data.serviceCode))}`,
|
d.data.label === "TRACE_ROOT" ? "" : `${this.sequentialScale(this.list.indexOf(d.data.serviceCode))}`,
|
||||||
@ -320,7 +327,7 @@ export default class ListGraph {
|
|||||||
node
|
node
|
||||||
.transition()
|
.transition()
|
||||||
.duration(400)
|
.duration(400)
|
||||||
.attr("transform", (d: Recordable) => `translate(${d.y + 5},${d.x})`)
|
.attr("transform", (d: Recordable) => `translate(${d.y + 3},${d.x})`)
|
||||||
.style("opacity", 1)
|
.style("opacity", 1)
|
||||||
.select("circle")
|
.select("circle")
|
||||||
.attr("fill", (d: Recordable) =>
|
.attr("fill", (d: Recordable) =>
|
||||||
@ -343,8 +350,8 @@ export default class ListGraph {
|
|||||||
.enter()
|
.enter()
|
||||||
.insert("path", "g")
|
.insert("path", "g")
|
||||||
.attr("class", "trace-link")
|
.attr("class", "trace-link")
|
||||||
.attr("fill", "rgba(0,0,0,0)")
|
.attr("fill", appStore.theme === Themes.Dark ? "rgba(244,244,244,0)" : "rgba(0,0,0,0)")
|
||||||
.attr("stroke", "rgba(0, 0, 0, 0.1)")
|
.attr("stroke", appStore.theme === Themes.Dark ? "rgba(244,244,244,0.4)" : "rgba(0, 0, 0, 0.1)")
|
||||||
.attr("stroke-width", 2)
|
.attr("stroke-width", 2)
|
||||||
.attr("transform", `translate(5, 0)`)
|
.attr("transform", `translate(5, 0)`)
|
||||||
.attr("d", () => {
|
.attr("d", () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user