mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-01 22:04:30 +00:00
feat: Implement Text control and update Topology (#37)
This commit is contained in:
parent
4380a874de
commit
99e23c33dc
@ -125,6 +125,7 @@ const msg = {
|
|||||||
kubernetesService: "Service",
|
kubernetesService: "Service",
|
||||||
kubernetesCluster: "Cluster",
|
kubernetesCluster: "Cluster",
|
||||||
kubernetes: "Kubernetes",
|
kubernetes: "Kubernetes",
|
||||||
|
textUrl: "Text Hyperlink",
|
||||||
hourTip: "Select Hour",
|
hourTip: "Select Hour",
|
||||||
minuteTip: "Select Minute",
|
minuteTip: "Select Minute",
|
||||||
secondTip: "Select Second",
|
secondTip: "Select Second",
|
||||||
|
@ -125,6 +125,7 @@ const msg = {
|
|||||||
kubernetesService: "服务",
|
kubernetesService: "服务",
|
||||||
kubernetesCluster: "集群",
|
kubernetesCluster: "集群",
|
||||||
kubernetes: "Kubernetes",
|
kubernetes: "Kubernetes",
|
||||||
|
textUrl: "文本超链接",
|
||||||
hourTip: "选择小时",
|
hourTip: "选择小时",
|
||||||
minuteTip: "选择分钟",
|
minuteTip: "选择分钟",
|
||||||
secondTip: "选择秒数",
|
secondTip: "选择秒数",
|
||||||
|
@ -22,10 +22,17 @@ export const NewControl = {
|
|||||||
i: "0",
|
i: "0",
|
||||||
type: "Widget",
|
type: "Widget",
|
||||||
widget: {
|
widget: {
|
||||||
title: "Title",
|
title: "",
|
||||||
},
|
},
|
||||||
graph: {},
|
graph: {},
|
||||||
standard: {},
|
standard: {},
|
||||||
metrics: [""],
|
metrics: [""],
|
||||||
metricTypes: [""],
|
metricTypes: [""],
|
||||||
};
|
};
|
||||||
|
export const TextConfig = {
|
||||||
|
fontColor: "white",
|
||||||
|
backgroundColor: "green",
|
||||||
|
content: "Text",
|
||||||
|
fontSize: 14,
|
||||||
|
textAlign: "left",
|
||||||
|
};
|
||||||
|
@ -22,7 +22,7 @@ import query from "@/graphql/fetch";
|
|||||||
import { DashboardItem } from "@/types/dashboard";
|
import { DashboardItem } from "@/types/dashboard";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
import { useSelectorStore } from "@/store/modules/selectors";
|
import { useSelectorStore } from "@/store/modules/selectors";
|
||||||
import { NewControl } from "../data";
|
import { NewControl, TextConfig } from "../data";
|
||||||
import { Duration } from "@/types/app";
|
import { Duration } from "@/types/app";
|
||||||
import { AxiosResponse } from "axios";
|
import { AxiosResponse } from "axios";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
@ -112,6 +112,10 @@ export const dashboardStore = defineStore({
|
|||||||
if (type === "Trace" || type === "Profile" || type === "Log") {
|
if (type === "Trace" || type === "Profile" || type === "Log") {
|
||||||
newItem.h = 36;
|
newItem.h = 36;
|
||||||
}
|
}
|
||||||
|
if (type === "Text") {
|
||||||
|
newItem.h = 6;
|
||||||
|
newItem.graph = TextConfig;
|
||||||
|
}
|
||||||
this.activedGridItem = newItem.i;
|
this.activedGridItem = newItem.i;
|
||||||
this.selectedGrid = newItem;
|
this.selectedGrid = newItem;
|
||||||
this.layout = this.layout.map((d: LayoutConfig) => {
|
this.layout = this.layout.map((d: LayoutConfig) => {
|
||||||
@ -158,6 +162,10 @@ export const dashboardStore = defineStore({
|
|||||||
if (type === "Trace" || type === "Profile" || type === "Log") {
|
if (type === "Trace" || type === "Profile" || type === "Log") {
|
||||||
newItem.h = 32;
|
newItem.h = 32;
|
||||||
}
|
}
|
||||||
|
if (type === "Text") {
|
||||||
|
newItem.h = 6;
|
||||||
|
newItem.graph = TextConfig;
|
||||||
|
}
|
||||||
if (this.layout[idx].children) {
|
if (this.layout[idx].children) {
|
||||||
const items = children.map((d: LayoutConfig) => {
|
const items = children.map((d: LayoutConfig) => {
|
||||||
d.y = d.y + newItem.h;
|
d.y = d.y + newItem.h;
|
||||||
@ -171,10 +179,9 @@ export const dashboardStore = defineStore({
|
|||||||
activeGridItem(index: string) {
|
activeGridItem(index: string) {
|
||||||
this.activedGridItem = index;
|
this.activedGridItem = index;
|
||||||
},
|
},
|
||||||
setActiveTabIndex(index: number) {
|
setActiveTabIndex(index: number, target?: number) {
|
||||||
const idx = this.layout.findIndex(
|
const m = target || this.activedGridItem;
|
||||||
(d: LayoutConfig) => d.i === this.activedGridItem
|
const idx = this.layout.findIndex((d: LayoutConfig) => d.i === m);
|
||||||
);
|
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,14 @@ export interface CardConfig {
|
|||||||
textAlign?: "center" | "right" | "left";
|
textAlign?: "center" | "right" | "left";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TextConfig {
|
||||||
|
fontSize: number;
|
||||||
|
backgroundColor: string;
|
||||||
|
textAlign: string;
|
||||||
|
fontColor: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TableConfig {
|
export interface TableConfig {
|
||||||
type?: string;
|
type?: string;
|
||||||
showTableValues: boolean;
|
showTableValues: boolean;
|
||||||
|
@ -13,7 +13,7 @@ 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>
|
||||||
<Edit v-if="dashboardStore.currentDashboard" />
|
<Dashboard v-if="dashboardStore.currentDashboard" />
|
||||||
<div v-else class="no-root">
|
<div v-else class="no-root">
|
||||||
{{ t("noRoot") }} {{ dashboardStore.layerId }}
|
{{ t("noRoot") }} {{ dashboardStore.layerId }}
|
||||||
</div>
|
</div>
|
||||||
@ -24,7 +24,7 @@ import { ref } from "vue";
|
|||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { EntityType } from "./dashboard/data";
|
import { EntityType } from "./dashboard/data";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import Edit from "./dashboard/Edit.vue";
|
import Dashboard from "./dashboard/Edit.vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
|
|
||||||
@ -52,7 +52,6 @@ getDashboard();
|
|||||||
|
|
||||||
async function getDashboard() {
|
async function getDashboard() {
|
||||||
layer.value = routesMap[String(route.name)];
|
layer.value = routesMap[String(route.name)];
|
||||||
console.log(layer.value);
|
|
||||||
dashboardStore.setLayer(layer.value);
|
dashboardStore.setLayer(layer.value);
|
||||||
dashboardStore.setEntity(EntityType[1].value);
|
dashboardStore.setEntity(EntityType[1].value);
|
||||||
dashboardStore.setMode(false);
|
dashboardStore.setMode(false);
|
||||||
|
@ -28,30 +28,31 @@ limitations under the License. -->
|
|||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
@closed="dashboardStore.setConfigPanel(false)"
|
@closed="dashboardStore.setConfigPanel(false)"
|
||||||
>
|
>
|
||||||
<TopologyConfig v-if="dashboardStore.selectedGrid.type === 'Topology'" />
|
<component :is="dashboardStore.selectedGrid.type" />
|
||||||
<WidgetConfig v-else />
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts">
|
||||||
import { ref } from "vue";
|
import { ref, defineComponent } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import GridLayout from "./panel/Layout.vue";
|
import GridLayout from "./panel/Layout.vue";
|
||||||
import Tool from "./panel/Tool.vue";
|
import Tool from "./panel/Tool.vue";
|
||||||
import TopologyConfig from "./configuration/Topology.vue";
|
|
||||||
import WidgetConfig from "./configuration/Widget.vue";
|
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
|
import Configuration from "./configuration";
|
||||||
|
|
||||||
const dashboardStore = useDashboardStore();
|
export default defineComponent({
|
||||||
const appStore = useAppStoreWithOut();
|
name: "Dashboard",
|
||||||
const { t } = useI18n();
|
components: { ...Configuration, GridLayout, Tool },
|
||||||
const p = useRoute().params;
|
setup() {
|
||||||
const layoutKey = ref<string>(`${p.layerId}_${p.entity}_${p.name}`);
|
const dashboardStore = useDashboardStore();
|
||||||
|
const appStore = useAppStoreWithOut();
|
||||||
setTemplate();
|
const { t } = useI18n();
|
||||||
async function setTemplate() {
|
const p = useRoute().params;
|
||||||
|
const layoutKey = ref<string>(`${p.layerId}_${p.entity}_${p.name}`);
|
||||||
|
setTemplate();
|
||||||
|
async function setTemplate() {
|
||||||
await dashboardStore.setDashboards();
|
await dashboardStore.setDashboards();
|
||||||
|
|
||||||
if (!p.entity) {
|
if (!p.entity) {
|
||||||
@ -76,15 +77,22 @@ async function setTemplate() {
|
|||||||
isRoot: layout.isRoot,
|
isRoot: layout.isRoot,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function handleClick(e: any) {
|
||||||
function handleClick(e: any) {
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (e.target.className === "ds-main") {
|
if (e.target.className === "ds-main") {
|
||||||
dashboardStore.activeGridItem("");
|
dashboardStore.activeGridItem("");
|
||||||
dashboardStore.selectWidget(null);
|
dashboardStore.selectWidget(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
t,
|
||||||
|
handleClick,
|
||||||
|
dashboardStore,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.ds-main {
|
.ds-main {
|
||||||
|
149
src/views/dashboard/configuration/Text.vue
Normal file
149
src/views/dashboard/configuration/Text.vue
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
<!-- 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. -->
|
||||||
|
<template>
|
||||||
|
<div class="item">
|
||||||
|
<span class="label">{{ t("textUrl") }}</span>
|
||||||
|
<el-input
|
||||||
|
class="input"
|
||||||
|
v-model="url"
|
||||||
|
size="small"
|
||||||
|
@change="changeConfig({ url })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="label">{{ t("content") }}</span>
|
||||||
|
<el-input
|
||||||
|
class="input"
|
||||||
|
v-model="content"
|
||||||
|
size="small"
|
||||||
|
@change="changeConfig({ content })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="label">{{ t("backgroundColors") }}</span>
|
||||||
|
<Selector
|
||||||
|
:value="backgroundColor"
|
||||||
|
:options="Colors"
|
||||||
|
size="small"
|
||||||
|
placeholder="Select a color"
|
||||||
|
class="input"
|
||||||
|
@change="changeConfig({ backgroundColor: $event[0].value })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="label">{{ t("fontSize") }}</span>
|
||||||
|
<el-slider
|
||||||
|
class="slider"
|
||||||
|
v-model="fontSize"
|
||||||
|
show-input
|
||||||
|
input-size="small"
|
||||||
|
:min="12"
|
||||||
|
:max="30"
|
||||||
|
:step="1"
|
||||||
|
@change="changeConfig({ fontSize })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="label">{{ t("fontColors") }}</span>
|
||||||
|
<Selector
|
||||||
|
:value="fontColor"
|
||||||
|
:options="Colors"
|
||||||
|
size="small"
|
||||||
|
placeholder="Select a color"
|
||||||
|
class="input"
|
||||||
|
@change="changeConfig({ fontColor: $event[0].value })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<el-button size="small" @click="cancelConfig">
|
||||||
|
{{ t("cancel") }}
|
||||||
|
</el-button>
|
||||||
|
<el-button size="small" type="primary" @click="applyConfig">
|
||||||
|
{{ t("apply") }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
const { t } = useI18n();
|
||||||
|
const dashboardStore = useDashboardStore();
|
||||||
|
const originConfig = dashboardStore.selectedGrid;
|
||||||
|
const url = ref(originConfig.graph.url || "");
|
||||||
|
const backgroundColor = ref(originConfig.graph.backgroundColor || "green");
|
||||||
|
const fontColor = ref(originConfig.graph.fontColor || "white");
|
||||||
|
const content = ref<string>(originConfig.graph.content || "");
|
||||||
|
const fontSize = ref<number>(originConfig.graph.fontSize || 12);
|
||||||
|
const Colors = [
|
||||||
|
{
|
||||||
|
label: "Green",
|
||||||
|
value: "green",
|
||||||
|
},
|
||||||
|
{ label: "Blue", value: "blue" },
|
||||||
|
{ label: "Red", value: "red" },
|
||||||
|
{ label: "Grey", value: "grey" },
|
||||||
|
{ label: "White", value: "white" },
|
||||||
|
{ label: "Black", value: "black" },
|
||||||
|
{ label: "Orange", value: "orange" },
|
||||||
|
];
|
||||||
|
function changeConfig(param: { [key: string]: unknown }) {
|
||||||
|
const { selectedGrid } = dashboardStore;
|
||||||
|
const graph = {
|
||||||
|
...selectedGrid.graph,
|
||||||
|
...param,
|
||||||
|
};
|
||||||
|
dashboardStore.selectWidget({ ...selectedGrid, graph });
|
||||||
|
}
|
||||||
|
function applyConfig() {
|
||||||
|
dashboardStore.setConfigPanel(false);
|
||||||
|
dashboardStore.setConfigs(dashboardStore.selectedGrid);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelConfig() {
|
||||||
|
dashboardStore.selectWidget(originConfig);
|
||||||
|
dashboardStore.setConfigPanel(false);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.slider {
|
||||||
|
width: 500px;
|
||||||
|
margin-top: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: right;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
@ -90,7 +90,6 @@ import configs from "./widget/graph-styles";
|
|||||||
import WidgetOptions from "./widget/WidgetOptions.vue";
|
import WidgetOptions from "./widget/WidgetOptions.vue";
|
||||||
import StandardOptions from "./widget/StandardOptions.vue";
|
import StandardOptions from "./widget/StandardOptions.vue";
|
||||||
import MetricOptions from "./widget/MetricOptions.vue";
|
import MetricOptions from "./widget/MetricOptions.vue";
|
||||||
import { ListChartTypes } from "../data";
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "ConfigEdit",
|
name: "ConfigEdit",
|
||||||
|
26
src/views/dashboard/configuration/index.ts
Normal file
26
src/views/dashboard/configuration/index.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Text from "./Text.vue";
|
||||||
|
import Widget from "./Widget.vue";
|
||||||
|
import Topology from "./Topology.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
Text,
|
||||||
|
Widget,
|
||||||
|
Topology,
|
||||||
|
};
|
@ -121,6 +121,7 @@ import Widget from "./Widget.vue";
|
|||||||
import Trace from "./Trace.vue";
|
import Trace from "./Trace.vue";
|
||||||
import Profile from "./Profile.vue";
|
import Profile from "./Profile.vue";
|
||||||
import Log from "./Log.vue";
|
import Log from "./Log.vue";
|
||||||
|
import Text from "./Text.vue";
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
data: {
|
data: {
|
||||||
@ -131,7 +132,7 @@ const props = {
|
|||||||
};
|
};
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "Tab",
|
name: "Tab",
|
||||||
components: { Topology, Widget, Trace, Profile, Log },
|
components: { Topology, Widget, Trace, Profile, Log, Text },
|
||||||
props,
|
props,
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@ -149,6 +150,7 @@ export default defineComponent({
|
|||||||
dashboardStore.setCurrentTabItems(
|
dashboardStore.setCurrentTabItems(
|
||||||
dashboardStore.layout[l].children[activeTabIndex.value].children
|
dashboardStore.layout[l].children[activeTabIndex.value].children
|
||||||
);
|
);
|
||||||
|
dashboardStore.setActiveTabIndex(activeTabIndex.value, props.data.i);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickTabs(e: Event, idx: number) {
|
function clickTabs(e: Event, idx: number) {
|
||||||
|
129
src/views/dashboard/controls/Text.vue
Normal file
129
src/views/dashboard/controls/Text.vue
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<!-- 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. -->
|
||||||
|
<template>
|
||||||
|
<div class="topology">
|
||||||
|
<div class="header">
|
||||||
|
<el-popover
|
||||||
|
placement="bottom"
|
||||||
|
trigger="click"
|
||||||
|
:width="100"
|
||||||
|
v-if="dashboardStore.editMode"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<span>
|
||||||
|
<Icon iconName="ellipsis_v" size="middle" class="operation" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<div class="tools" @click="editConfig">
|
||||||
|
<span>{{ t("edit") }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="tools" @click="removeTopo">
|
||||||
|
<span>{{ t("delete") }}</span>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="body"
|
||||||
|
:style="{ backgroundColor: TextColors[data.graph.backgroundColor] }"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
color: TextColors[data.graph.fontColor],
|
||||||
|
fontSize: data.graph.fontSize + 'px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<a :href="data.graph.url" target="_blank">
|
||||||
|
{{ data.graph.content }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { PropType } from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
import { TextColors } from "@/views/dashboard/data";
|
||||||
|
|
||||||
|
/*global defineProps */
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object as PropType<any>,
|
||||||
|
default: () => ({ graph: {} }),
|
||||||
|
},
|
||||||
|
activeIndex: { type: String, default: "" },
|
||||||
|
});
|
||||||
|
const { t } = useI18n();
|
||||||
|
const dashboardStore = useDashboardStore();
|
||||||
|
|
||||||
|
function removeTopo() {
|
||||||
|
dashboardStore.removeControls(props.data);
|
||||||
|
}
|
||||||
|
function editConfig() {
|
||||||
|
dashboardStore.setConfigPanel(true);
|
||||||
|
dashboardStore.selectWidget(props.data);
|
||||||
|
}
|
||||||
|
function viewText() {
|
||||||
|
const path = props.data.graph.url;
|
||||||
|
console.log(path);
|
||||||
|
if (!path) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.open(path, "_blank");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.topology {
|
||||||
|
font-size: 12px;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operation {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #333;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
-webkit-box-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools {
|
||||||
|
padding: 5px 0;
|
||||||
|
color: #999;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #409eff;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -20,5 +20,6 @@ import Widget from "./Widget.vue";
|
|||||||
import Trace from "./Trace.vue";
|
import Trace from "./Trace.vue";
|
||||||
import Profile from "./Profile.vue";
|
import Profile from "./Profile.vue";
|
||||||
import Log from "./Log.vue";
|
import Log from "./Log.vue";
|
||||||
|
import Text from "./Text.vue";
|
||||||
|
|
||||||
export default { Tab, Widget, Trace, Topology, Profile, Log };
|
export default { Tab, Widget, Trace, Topology, Profile, Log, Text };
|
||||||
|
@ -23,10 +23,10 @@ export const ChartTypes = [
|
|||||||
{ label: "Bar", value: "Bar" },
|
{ label: "Bar", value: "Bar" },
|
||||||
{ label: "Line", value: "Line" },
|
{ label: "Line", value: "Line" },
|
||||||
{ label: "Area", value: "Area" },
|
{ label: "Area", value: "Area" },
|
||||||
// { label: "Pie", value: "Pie" },
|
|
||||||
{ label: "Card", value: "Card" },
|
{ label: "Card", value: "Card" },
|
||||||
{ label: "Top List", value: "TopList" },
|
{ label: "Top List", value: "TopList" },
|
||||||
{ label: "Table", value: "Table" },
|
{ label: "Table", value: "Table" },
|
||||||
|
{ label: "Text", value: "Text" },
|
||||||
{ label: "Heatmap", value: "Heatmap" },
|
{ label: "Heatmap", value: "Heatmap" },
|
||||||
{ label: "Service List", value: "ServiceList" },
|
{ label: "Service List", value: "ServiceList" },
|
||||||
{ label: "Endpoint List", value: "EndpointList" },
|
{ label: "Endpoint List", value: "EndpointList" },
|
||||||
@ -169,6 +169,7 @@ export const SortOrder = [
|
|||||||
export const AllTools = [
|
export const AllTools = [
|
||||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||||
|
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||||
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
||||||
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
||||||
{ name: "assignment", content: "Add Log", id: "addLog" },
|
{ name: "assignment", content: "Add Log", id: "addLog" },
|
||||||
@ -177,6 +178,7 @@ export const AllTools = [
|
|||||||
export const ServiceTools = [
|
export const ServiceTools = [
|
||||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||||
|
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||||
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
||||||
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
||||||
{ name: "timeline", content: "Add Profile", id: "addProfile" },
|
{ name: "timeline", content: "Add Profile", id: "addProfile" },
|
||||||
@ -186,6 +188,7 @@ export const ServiceTools = [
|
|||||||
export const InstanceTools = [
|
export const InstanceTools = [
|
||||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||||
|
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||||
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
||||||
{ name: "assignment", content: "Add Log", id: "addLog" },
|
{ name: "assignment", content: "Add Log", id: "addLog" },
|
||||||
{ name: "save", content: "Apply", id: "apply" },
|
{ name: "save", content: "Apply", id: "apply" },
|
||||||
@ -193,6 +196,7 @@ export const InstanceTools = [
|
|||||||
export const EndpointTools = [
|
export const EndpointTools = [
|
||||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||||
|
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||||
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
||||||
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
{ name: "merge", content: "Add Trace", id: "addTrace" },
|
||||||
{ name: "assignment", content: "Add Log", id: "addLog" },
|
{ name: "assignment", content: "Add Log", id: "addLog" },
|
||||||
@ -201,6 +205,7 @@ export const EndpointTools = [
|
|||||||
export const ServiceRelationTools = [
|
export const ServiceRelationTools = [
|
||||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||||
|
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||||
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
||||||
{ name: "save", content: "Apply", id: "apply" },
|
{ name: "save", content: "Apply", id: "apply" },
|
||||||
];
|
];
|
||||||
@ -208,11 +213,13 @@ export const ServiceRelationTools = [
|
|||||||
export const EndpointRelationTools = [
|
export const EndpointRelationTools = [
|
||||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||||
|
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||||
{ name: "save", content: "Apply", id: "apply" },
|
{ name: "save", content: "Apply", id: "apply" },
|
||||||
];
|
];
|
||||||
export const InstanceRelationTools = [
|
export const InstanceRelationTools = [
|
||||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||||
|
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||||
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
{ name: "device_hub", content: "Add Topology", id: "addTopology" },
|
||||||
{ name: "save", content: "Apply", id: "apply" },
|
{ name: "save", content: "Apply", id: "apply" },
|
||||||
];
|
];
|
||||||
@ -248,3 +255,12 @@ export const QueryOrders = [
|
|||||||
{ label: "Start Time", value: "BY_START_TIME" },
|
{ label: "Start Time", value: "BY_START_TIME" },
|
||||||
{ label: "Duration", value: "BY_DURATION" },
|
{ label: "Duration", value: "BY_DURATION" },
|
||||||
];
|
];
|
||||||
|
export const TextColors: { [key: string]: string } = {
|
||||||
|
green: "#67C23A",
|
||||||
|
blue: "#409EFF",
|
||||||
|
red: "#F56C6C",
|
||||||
|
grey: "#909399",
|
||||||
|
white: "#fff",
|
||||||
|
black: "#000",
|
||||||
|
orange: "#E6A23C",
|
||||||
|
};
|
||||||
|
@ -59,6 +59,9 @@ export default defineComponent({
|
|||||||
function clickGrid(item: LayoutConfig) {
|
function clickGrid(item: LayoutConfig) {
|
||||||
dashboardStore.activeGridItem(item.i);
|
dashboardStore.activeGridItem(item.i);
|
||||||
dashboardStore.selectWidget(item);
|
dashboardStore.selectWidget(item);
|
||||||
|
if (item.type === "Tab") {
|
||||||
|
dashboardStore.setActiveTabIndex(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
dashboardStore.setLayout([]);
|
dashboardStore.setLayout([]);
|
||||||
|
@ -367,6 +367,9 @@ function setTabControls(id: string) {
|
|||||||
case "addTopology":
|
case "addTopology":
|
||||||
dashboardStore.addTabControls("Topology");
|
dashboardStore.addTabControls("Topology");
|
||||||
break;
|
break;
|
||||||
|
case "addText":
|
||||||
|
dashboardStore.addTabControls("Text");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ElMessage.info("Don't support this control");
|
ElMessage.info("Don't support this control");
|
||||||
break;
|
break;
|
||||||
@ -393,6 +396,9 @@ function setControls(id: string) {
|
|||||||
case "addTopology":
|
case "addTopology":
|
||||||
dashboardStore.addControl("Topology");
|
dashboardStore.addControl("Topology");
|
||||||
break;
|
break;
|
||||||
|
case "addText":
|
||||||
|
dashboardStore.addControl("Text");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dashboardStore.addControl("Widget");
|
dashboardStore.addControl("Widget");
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ limitations under the License. -->
|
|||||||
class="inputs"
|
class="inputs"
|
||||||
:value="depth"
|
:value="depth"
|
||||||
:options="DepthList"
|
:options="DepthList"
|
||||||
placeholder="Select a option"
|
|
||||||
@change="changeDepth"
|
@change="changeDepth"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
@ -377,10 +376,12 @@ async function handleInspect() {
|
|||||||
topologyStore.setNode(null);
|
topologyStore.setNode(null);
|
||||||
topologyStore.setLink(null);
|
topologyStore.setLink(null);
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const resp = await topologyStore.getServicesTopology([id]);
|
const resp = await topologyStore.getDepthServiceTopology(
|
||||||
|
[id],
|
||||||
|
Number(depth.value)
|
||||||
|
);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
if (resp && resp.errors) {
|
||||||
if (resp.errors) {
|
|
||||||
ElMessage.error(resp.errors);
|
ElMessage.error(resp.errors);
|
||||||
}
|
}
|
||||||
await init();
|
await init();
|
||||||
@ -555,17 +556,18 @@ watch(
|
|||||||
|
|
||||||
.operations-list {
|
.operations-list {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 10px;
|
|
||||||
color: #333;
|
color: #333;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
padding: 10px 0;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
display: block;
|
display: block;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
text-align: center;
|
text-align: left;
|
||||||
|
padding: 0 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
span:hover {
|
span:hover {
|
||||||
|
@ -324,7 +324,7 @@ watch(
|
|||||||
|
|
||||||
.operations-list {
|
.operations-list {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 10px;
|
padding: 10px 0;
|
||||||
color: #333;
|
color: #333;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
@ -335,7 +335,8 @@ watch(
|
|||||||
height: 30px;
|
height: 30px;
|
||||||
width: 140px;
|
width: 140px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
text-align: center;
|
text-align: left;
|
||||||
|
padding: 0 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
span:hover {
|
span:hover {
|
||||||
|
@ -23,6 +23,7 @@ limitations under the License. -->
|
|||||||
placeholder="Please input a dashboard name for calls"
|
placeholder="Please input a dashboard name for calls"
|
||||||
@change="changeLinkDashboard"
|
@change="changeLinkDashboard"
|
||||||
class="inputs"
|
class="inputs"
|
||||||
|
:clearable="true"
|
||||||
/>
|
/>
|
||||||
<div class="label">{{ t("linkServerMetrics") }}</div>
|
<div class="label">{{ t("linkServerMetrics") }}</div>
|
||||||
<Selector
|
<Selector
|
||||||
@ -86,7 +87,6 @@ limitations under the License. -->
|
|||||||
<span>
|
<span>
|
||||||
<Icon
|
<Icon
|
||||||
class="cp mr-5"
|
class="cp mr-5"
|
||||||
v-show="items.length > 1"
|
|
||||||
iconName="remove_circle_outline"
|
iconName="remove_circle_outline"
|
||||||
size="middle"
|
size="middle"
|
||||||
@click="deleteItem(index)"
|
@click="deleteItem(index)"
|
||||||
@ -144,7 +144,6 @@ limitations under the License. -->
|
|||||||
iconName="remove_circle_outline"
|
iconName="remove_circle_outline"
|
||||||
size="middle"
|
size="middle"
|
||||||
@click="deleteMetric(index)"
|
@click="deleteMetric(index)"
|
||||||
v-show="legend.metric.length > 1"
|
|
||||||
/>
|
/>
|
||||||
<Icon
|
<Icon
|
||||||
class="cp"
|
class="cp"
|
||||||
@ -196,6 +195,10 @@ const { t } = useI18n();
|
|||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
const topologyStore = useTopologyStore();
|
const topologyStore = useTopologyStore();
|
||||||
const { selectedGrid } = dashboardStore;
|
const { selectedGrid } = dashboardStore;
|
||||||
|
const nodeDashboard =
|
||||||
|
selectedGrid.nodeDashboard && selectedGrid.nodeDashboard.length
|
||||||
|
? selectedGrid.nodeDashboard
|
||||||
|
: "";
|
||||||
const isService = [EntityType[0].value, EntityType[1].value].includes(
|
const isService = [EntityType[0].value, EntityType[1].value].includes(
|
||||||
dashboardStore.entity
|
dashboardStore.entity
|
||||||
);
|
);
|
||||||
@ -204,7 +207,7 @@ const items = reactive<
|
|||||||
scope: string;
|
scope: string;
|
||||||
dashboard: string;
|
dashboard: string;
|
||||||
}[]
|
}[]
|
||||||
>((isService && selectedGrid.nodeDashboard) || [{ scope: "", dashboard: "" }]);
|
>(isService && nodeDashboard ? nodeDashboard : [{ scope: "", dashboard: "" }]);
|
||||||
const states = reactive<{
|
const states = reactive<{
|
||||||
linkDashboard: string;
|
linkDashboard: string;
|
||||||
nodeDashboard: {
|
nodeDashboard: {
|
||||||
@ -229,9 +232,12 @@ const states = reactive<{
|
|||||||
linkDashboards: [],
|
linkDashboards: [],
|
||||||
nodeDashboards: [],
|
nodeDashboards: [],
|
||||||
});
|
});
|
||||||
|
const l = selectedGrid.legend && selectedGrid.legend.length;
|
||||||
const legend = reactive<{
|
const legend = reactive<{
|
||||||
metric: { name: string; condition: string; value: string }[];
|
metric: { name: string; condition: string; value: string }[];
|
||||||
}>({ metric: selectedGrid.legend || [{ name: "", condition: "", value: "" }] });
|
}>({
|
||||||
|
metric: l ? selectedGrid.legend : [{ name: "", condition: "", value: "" }],
|
||||||
|
});
|
||||||
|
|
||||||
getMetricList();
|
getMetricList();
|
||||||
async function getMetricList() {
|
async function getMetricList() {
|
||||||
@ -335,6 +341,9 @@ function addItem() {
|
|||||||
items.push({ scope: "", dashboard: "" });
|
items.push({ scope: "", dashboard: "" });
|
||||||
}
|
}
|
||||||
function deleteItem(index: number) {
|
function deleteItem(index: number) {
|
||||||
|
if (items.length === 1) {
|
||||||
|
items.push({ scope: "", dashboard: "" });
|
||||||
|
}
|
||||||
items.splice(index, 1);
|
items.splice(index, 1);
|
||||||
updateSettings();
|
updateSettings();
|
||||||
}
|
}
|
||||||
@ -384,6 +393,10 @@ async function changeNodeMetrics(options: Option[] | any) {
|
|||||||
topologyStore.queryNodeMetrics(states.nodeMetrics);
|
topologyStore.queryNodeMetrics(states.nodeMetrics);
|
||||||
}
|
}
|
||||||
function deleteMetric(index: number) {
|
function deleteMetric(index: number) {
|
||||||
|
if (legend.metric.length === 1) {
|
||||||
|
legend.metric = [{ name: "", condition: "", value: "" }];
|
||||||
|
return;
|
||||||
|
}
|
||||||
legend.metric.splice(index, 1);
|
legend.metric.splice(index, 1);
|
||||||
}
|
}
|
||||||
function addMetric() {
|
function addMetric() {
|
||||||
|
@ -40,14 +40,15 @@ export default class ListGraph {
|
|||||||
constructor(el: HTMLDivElement, handleSelectSpan: (i: Trace) => void) {
|
constructor(el: HTMLDivElement, handleSelectSpan: (i: Trace) => void) {
|
||||||
this.handleSelectSpan = handleSelectSpan;
|
this.handleSelectSpan = handleSelectSpan;
|
||||||
this.el = el;
|
this.el = el;
|
||||||
this.width = el.clientWidth - 20;
|
this.width = el.clientWidth - 10;
|
||||||
this.height = el.clientHeight;
|
this.height = el.clientHeight;
|
||||||
this.svg = d3
|
this.svg = d3
|
||||||
.select(this.el)
|
.select(this.el)
|
||||||
.append("svg")
|
.append("svg")
|
||||||
.attr("class", "trace-list-dowanload")
|
.attr("class", "trace-list-dowanload")
|
||||||
.attr("width", this.width)
|
.attr("width", this.width)
|
||||||
.attr("height", this.height);
|
.attr("height", this.height)
|
||||||
|
.attr("transform", `translate(-5, 0)`);
|
||||||
this.tip = (d3tip as any)()
|
this.tip = (d3tip as any)()
|
||||||
.attr("class", "d3-tip")
|
.attr("class", "d3-tip")
|
||||||
.offset([-8, 0])
|
.offset([-8, 0])
|
||||||
@ -220,7 +221,7 @@ export default class ListGraph {
|
|||||||
nodeEnter
|
nodeEnter
|
||||||
.transition()
|
.transition()
|
||||||
.duration(400)
|
.duration(400)
|
||||||
.attr("transform", (d: any) => `translate(${d.y},${d.x})`)
|
.attr("transform", (d: any) => `translate(${d.y + 5},${d.x})`)
|
||||||
.style("opacity", 1);
|
.style("opacity", 1);
|
||||||
nodeEnter
|
nodeEnter
|
||||||
.append("circle")
|
.append("circle")
|
||||||
@ -243,7 +244,7 @@ export default class ListGraph {
|
|||||||
node
|
node
|
||||||
.transition()
|
.transition()
|
||||||
.duration(400)
|
.duration(400)
|
||||||
.attr("transform", (d: any) => `translate(${d.y},${d.x})`)
|
.attr("transform", (d: any) => `translate(${d.y + 5},${d.x})`)
|
||||||
.style("opacity", 1)
|
.style("opacity", 1)
|
||||||
.select("circle")
|
.select("circle")
|
||||||
.attr("fill", (d: any) =>
|
.attr("fill", (d: any) =>
|
||||||
@ -273,8 +274,9 @@ export default class ListGraph {
|
|||||||
.attr("fill", "rgba(0,0,0,0)")
|
.attr("fill", "rgba(0,0,0,0)")
|
||||||
.attr("stroke", "rgba(0, 0, 0, 0.1)")
|
.attr("stroke", "rgba(0, 0, 0, 0.1)")
|
||||||
.attr("stroke-width", 2)
|
.attr("stroke-width", 2)
|
||||||
|
.attr("transform", `translate(5, 0)`)
|
||||||
.attr("d", () => {
|
.attr("d", () => {
|
||||||
const o = { x: source.x0 + 35, y: source.y0 };
|
const o = { x: source.x0 + 40, y: source.y0 };
|
||||||
return this.diagonal({ source: o, target: o });
|
return this.diagonal({ source: o, target: o });
|
||||||
})
|
})
|
||||||
.transition()
|
.transition()
|
||||||
|
Loading…
Reference in New Issue
Block a user