feat: Move topology to widgets (#29)

This commit is contained in:
Fine0830
2022-03-20 19:45:31 +08:00
committed by GitHub
parent 597e98e291
commit 42d8e909f6
25 changed files with 279 additions and 348 deletions

View File

@@ -299,6 +299,14 @@ watch(
init();
}
);
watch(
() => appStore.durationTime,
() => {
if (dashboardStore.entity === EntityType[1].value) {
init();
}
}
);
</script>
<style lang="scss" scoped>
.inputs {

View File

@@ -56,9 +56,14 @@ import { useProfileStore } from "@/store/modules/profile";
import { useSelectorStore } from "@/store/modules/selectors";
import { ElMessage } from "element-plus";
import NewTask from "./components/NewTask.vue";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app";
import { EntityType } from "../../data";
const profileStore = useProfileStore();
const appStore = useAppStoreWithOut();
const selectorStore = useSelectorStore();
const dashboardStore = useDashboardStore();
const { t } = useI18n();
// const service = ref<any>({});
const endpointName = ref<string>("");
@@ -104,6 +109,14 @@ watch(
searchTasks();
}
);
watch(
() => appStore.durationTime,
() => {
if (dashboardStore.entity === EntityType[1].value) {
searchTasks();
}
}
);
</script>
<style lang="scss" scoped>
.header {

View File

@@ -13,18 +13,26 @@ 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>
<PodTopology v-if="isSankey" />
<Graph v-else />
<PodTopology :config="config" v-if="isSankey" />
<Graph :config="config" v-else />
</template>
<script lang="ts" setup>
import type { PropType } from "vue";
import { ref } from "vue";
import Graph from "./components/Graph.vue";
import PodTopology from "./components/PodTopology.vue";
import { EntityType } from "../../data";
import { useDashboardStore } from "@/store/modules/dashboard";
/*global defineProps */
defineProps({
config: {
type: Object as PropType<any>,
default: () => ({ graph: {} }),
},
});
const dashboardStore = useDashboardStore();
const isSankey = ref<boolean>(
[EntityType[2].value, EntityType[4].value].includes(dashboardStore.entity)
[EntityType[2].value, EntityType[3].value].includes(dashboardStore.entity)
);
</script>

View File

@@ -17,13 +17,14 @@ limitations under the License. -->
ref="chart"
class="micro-topo-chart"
v-loading="loading"
element-loading-background="rgba(0, 0, 0, 0)"
:style="`height: ${height}px`"
>
<div class="setting" v-show="showSetting">
<Settings @update="updateSettings" @updateNodes="freshNodes" />
</div>
<div class="tool">
<span v-show="dashboardStore.selectedGrid.showDepth">
<span v-show="config.graph.showDepth">
<span class="label">{{ t("currentDepth") }}</span>
<Selector
class="inputs"
@@ -63,7 +64,8 @@ limitations under the License. -->
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, reactive } from "vue";
import type { PropType } from "vue";
import { ref, onMounted, onBeforeUnmount, reactive, watch } from "vue";
import { useI18n } from "vue-i18n";
import * as d3 from "d3";
import d3tip from "d3-tip";
@@ -82,14 +84,22 @@ import { ElMessage } from "element-plus";
import Settings from "./Settings.vue";
import { Option } from "@/types/app";
import { Service } from "@/types/selector";
import { useAppStoreWithOut } from "@/store/modules/app";
/*global Nullable */
/*global Nullable, defineProps */
const props = defineProps({
config: {
type: Object as PropType<any>,
default: () => ({ graph: {} }),
},
});
const { t } = useI18n();
const selectorStore = useSelectorStore();
const topologyStore = useTopologyStore();
const dashboardStore = useDashboardStore();
const height = ref<number>(document.body.clientHeight - 90);
const width = ref<number>(document.body.clientWidth - 40);
const appStore = useAppStoreWithOut();
const height = ref<number>(100);
const width = ref<number>(100);
const loading = ref<boolean>(false);
const simulation = ref<any>(null);
const svg = ref<Nullable<any>>(null);
@@ -110,7 +120,7 @@ const items = ref<
{ id: "inspect", title: "Inspect", func: handleInspect },
{ id: "alarm", title: "Alarm", func: handleGoAlarm },
]);
const depth = ref<string>(dashboardStore.selectedGrid.depth || "2");
const depth = ref<number>(props.config.graph.depth || 2);
onMounted(async () => {
loading.value = true;
@@ -119,19 +129,23 @@ onMounted(async () => {
if (resp && resp.errors) {
ElMessage.error(resp.errors);
}
const dom = document.querySelector(".topology")?.getBoundingClientRect() || {
height: 40,
width: 0,
};
height.value = dom.height - 40;
width.value = dom.width;
window.addEventListener("resize", resize);
svg.value = d3
.select(chart.value)
.append("svg")
.attr("class", "topo-svg")
.attr("height", height.value)
.attr("width", width.value);
svg.value = d3.select(chart.value).append("svg").attr("class", "topo-svg");
await init();
update();
});
async function init() {
tip.value = (d3tip as any)().attr("class", "d3-tip").offset([-8, 0]);
graph.value = svg.value.append("g").attr("class", "topo-svg-graph");
graph.value = svg.value
.append("g")
.attr("class", "topo-svg-graph")
.attr("transform", `translate(0, -100)`);
graph.value.call(tip.value);
simulation.value = simulationInit(
d3,
@@ -410,8 +424,8 @@ function setConfig() {
showSetting.value = !showSetting.value;
}
function resize() {
height.value = document.body.clientHeight - 90;
width.value = document.body.clientWidth - 40;
height.value = document.body.clientHeight;
width.value = document.body.clientWidth;
svg.value.attr("height", height.value).attr("width", width.value);
}
function updateSettings(config: any) {
@@ -453,7 +467,7 @@ async function freshNodes() {
update();
}
async function changeDepth(opt: Option[]) {
async function changeDepth(opt: Option[] | any) {
depth.value = opt[0].value;
await getTopology();
freshNodes();
@@ -461,17 +475,40 @@ async function changeDepth(opt: Option[]) {
onBeforeUnmount(() => {
window.removeEventListener("resize", resize);
});
watch(
() => [selectorStore.currentService, selectorStore.currentDestService],
() => {
freshNodes();
}
);
watch(
() => appStore.durationTime,
() => {
if (dashboardStore.entity === EntityType[1].value) {
init();
}
}
);
</script>
<style lang="scss">
.topo-svg {
width: 100%;
height: calc(100% - 5px);
cursor: move;
}
.micro-topo-chart {
position: relative;
height: calc(100% - 30px);
overflow: auto;
margin-top: 30px;
.setting {
position: absolute;
top: 70px;
right: 0;
top: 80px;
right: 10px;
width: 400px;
height: 700px;
height: 600px;
background-color: #2b3037;
overflow: auto;
padding: 0 15px;
@@ -510,8 +547,8 @@ onBeforeUnmount(() => {
.tool {
position: absolute;
top: 22px;
right: 0;
top: 35px;
right: 10px;
}
.switch-icon {
@@ -524,11 +561,6 @@ onBeforeUnmount(() => {
border-radius: 3px;
}
.topo-svg {
display: block;
width: 100%;
}
.topo-line {
stroke-linecap: round;
stroke-width: 3px;

View File

@@ -16,8 +16,7 @@ limitations under the License. -->
<div class="tool">
<span
v-show="
dashboardStore.entity === EntityType[2].value &&
dashboardStore.selectedGrid.showDepth
dashboardStore.entity === EntityType[2].value && config.graph.showDepth
"
>
<span class="label">{{ t("currentDepth") }}</span>
@@ -47,6 +46,7 @@ limitations under the License. -->
class="sankey"
:style="`height:${height}px;width:${width}px;`"
v-loading="loading"
element-loading-background="rgba(0, 0, 0, 0)"
@click="handleClick"
>
<Sankey @click="selectNodeLink" />
@@ -72,36 +72,47 @@ limitations under the License. -->
</div>
</template>
<script lang="ts" setup>
import { watch } from "vue";
import type { PropType } from "vue";
import { useI18n } from "vue-i18n";
import { ref, onMounted, reactive } from "vue";
import { Option } from "@/types/app";
import { useTopologyStore } from "@/store/modules/topology";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useSelectorStore } from "@/store/modules/selectors";
import { useAppStoreWithOut } from "@/store/modules/app";
import { EntityType, DepthList } from "../../../data";
import { ElMessage } from "element-plus";
import Sankey from "./Sankey.vue";
import Settings from "./Settings.vue";
import router from "@/router";
/*global defineProps */
const props = defineProps({
config: {
type: Object as PropType<any>,
default: () => ({ graph: {} }),
},
});
const { t } = useI18n();
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
const topologyStore = useTopologyStore();
const appStore = useAppStoreWithOut();
const loading = ref<boolean>(false);
const height = ref<number>(document.body.clientHeight - 150);
const width = ref<number>(document.body.clientWidth - 40);
const height = ref<number>(100);
const width = ref<number>(100);
const showSettings = ref<boolean>(false);
const settings = ref<any>({});
const operationsPos = reactive<{ x: number; y: number }>({ x: NaN, y: NaN });
const depth = ref<string>(dashboardStore.selectedGrid.depth || "3");
const depth = ref<number>(props.config.graph.depth || 3);
const items = [
{ id: "inspect", title: "Inspect", func: inspect },
{ id: "dashboard", title: "View Dashboard", func: goDashboard },
{ id: "alarm", title: "View Alarm", func: goAlarm },
];
onMounted(async () => {
onMounted(() => {
loadTopology(selectorStore.currentPod && selectorStore.currentPod.id);
});
@@ -112,6 +123,12 @@ async function loadTopology(id: string) {
if (resp && resp.errors) {
ElMessage.error(resp.errors);
}
const dom = document.querySelector(".topology")?.getBoundingClientRect() || {
height: 70,
width: 5,
};
height.value = dom.height - 70;
width.value = dom.width - 5;
}
function inspect() {
@@ -176,7 +193,7 @@ function selectNodeLink(d: any) {
operationsPos.y = d.event.event.clientY;
}
async function changeDepth(opt: Option[]) {
async function changeDepth(opt: Option[] | any) {
depth.value = opt[0].value;
loadTopology(selectorStore.currentPod.id);
}
@@ -190,7 +207,7 @@ async function getTopology(id: string) {
Number(depth.value)
);
break;
case EntityType[4].value:
case EntityType[3].value:
resp = await topologyStore.getInstanceTopology();
break;
}
@@ -202,20 +219,36 @@ function handleClick(event: any) {
topologyStore.setLink(null);
}
}
watch(
() => [selectorStore.currentPod],
() => {
loadTopology(selectorStore.currentPod.id);
topologyStore.setNode(null);
topologyStore.setLink(null);
}
);
watch(
() => appStore.durationTime,
() => {
loadTopology(selectorStore.currentPod.id);
topologyStore.setNode(null);
topologyStore.setLink(null);
}
);
</script>
<style lang="scss" scoped>
.sankey {
margin-top: 10px;
background-color: #333840;
background-color: #333840 !important;
color: #ddd;
}
.settings {
position: absolute;
top: 40px;
right: 0;
top: 60px;
right: 10px;
width: 400px;
height: 700px;
height: 500px;
background-color: #2b3037;
overflow: auto;
padding: 0 15px;
@@ -228,7 +261,8 @@ function handleClick(event: any) {
.tool {
text-align: right;
margin-top: 10px;
margin-top: 40px;
margin-right: 10px;
position: relative;
}

View File

@@ -28,14 +28,14 @@ export default function topoLegend(
.attr("width", 30)
.attr("height", 30)
.attr("x", clientWidth - (item === "CUBEERROR" ? 340 : 440))
.attr("y", clientHeight - 50)
.attr("y", clientHeight + 50)
.attr("xlink:href", () =>
item === "CUBEERROR" ? icons.CUBEERROR : icons.CUBE
);
graph
.append("text")
.attr("x", clientWidth - (item === "CUBEERROR" ? 310 : 410))
.attr("y", clientHeight - 30)
.attr("y", clientHeight + 70)
.text(() => {
const l = config || [];
const str = l

View File

@@ -210,7 +210,16 @@ function updateTags(data: { tagsMap: Array<Option>; tagsList: string[] }) {
tagsMap.value = data.tagsMap;
}
watch(
() => selectorStore.currentService,
() => [selectorStore.currentPod],
() => {
if (dashboardStore.entity === EntityType[0].value) {
return;
}
init();
}
);
watch(
() => [selectorStore.currentService],
() => {
if (dashboardStore.entity !== EntityType[0].value) {
return;
@@ -218,6 +227,14 @@ watch(
init();
}
);
watch(
() => appStore.durationTime,
() => {
if (dashboardStore.entity === EntityType[1].value) {
init();
}
}
);
</script>
<style lang="scss" scoped>
.inputs {