support multiple widgets

This commit is contained in:
Qiuxia Fan 2022-07-06 15:12:48 +08:00
parent 437383d4b2
commit 21420e7395
6 changed files with 53 additions and 52 deletions

View File

@ -61,7 +61,7 @@ onMounted(async () => {
if (!instance) {
return;
}
instance.on("click", (params: any) => {
instance.on("click", (params: unknown) => {
emits("select", params);
});
}, 1000);

View File

@ -5,36 +5,8 @@
declare module '@vue/runtime-core' {
export interface GlobalComponents {
DateCalendar: typeof import('./../components/DateCalendar.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSlider: typeof import('element-plus/es')['ElSlider']
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
Graph: typeof import('./../components/Graph.vue')['default']
Icon: typeof import('./../components/Icon.vue')['default']
Loading: typeof import('element-plus/es')['ElLoadingDirective']
Radio: typeof import('./../components/Radio.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']

View File

@ -37,6 +37,7 @@ export interface LayoutConfig {
activedTabIndex?: number;
metricConfig?: MetricConfigOpt[];
id?: string;
associate?: { widgetIds: string }[];
}
export type MetricConfigOpt = {
@ -139,3 +140,15 @@ export interface TopologyConfig {
depth?: number;
showDepth?: boolean;
}
export type EventParams = {
componentType: string;
seriesType: string;
seriesIndex: number;
seriesName: string;
name: string;
dataIndex: number;
data: Record<string, unknown>;
dataType: string;
value: number | number[];
color: string;
};

View File

@ -16,12 +16,13 @@ limitations under the License. -->
<div class="item">
<span class="label">{{ t("widget") }}</span>
<Selector
:value="widgetId"
:multiple="true"
:value="widgetIds"
:options="widgets"
size="small"
placeholder="Select a widget"
@change="updateWidgetConfig({ associateWidget: $event[0].value })"
class="selectors"
@change="updateWidgetConfig"
/>
</div>
</template>
@ -31,13 +32,14 @@ import { useI18n } from "vue-i18n";
import { useDashboardStore } from "@/store/modules/dashboard";
import getDashboard from "@/hooks/useDashboardsSession";
import { LayoutConfig } from "@/types/dashboard";
import { Option } from "@/types/app";
const { t } = useI18n();
const dashboardStore = useDashboardStore();
const associate = dashboardStore.selectedGrid.associate || {};
const widgetId = ref<string>(associate.widgetId || "");
const widgetIds = ref<string[]>(associate.widgetIds || []);
const widgets = computed(() => {
const isLinear = ["Bar", "Line"].includes(
const isLinear = ["Bar", "Line", "Area"].includes(
dashboardStore.selectedGrid.graph && dashboardStore.selectedGrid.graph.type
);
const isRank = ["TopList"].includes(
@ -47,14 +49,14 @@ const widgets = computed(() => {
const items = widgets.filter(
(d: { value: string; label: string } & LayoutConfig) => {
if (dashboardStore.selectedGrid.id !== d.id) {
if (isLinear && d.widget) {
d.value = d.id || "";
d.label = d.widget.name || d.id || "";
if (isLinear && d.widget && d.id) {
d.value = d.id;
d.label = d.widget.name || d.id;
return d;
}
if (isRank && d.type !== "Widget" && d.widget) {
d.value = d.id || "";
d.label = d.widget.name || d.id || "";
if (isRank && d.type !== "Widget" && d.widget && d.id) {
d.value = d.id;
d.label = d.widget.name || d.id;
return d;
}
}
@ -62,17 +64,13 @@ const widgets = computed(() => {
);
return items;
});
function updateWidgetConfig(param: { [key: string]: string }) {
const key = Object.keys(param)[0];
if (!key) {
return;
}
const { selectedGrid } = dashboardStore;
function updateWidgetConfig(options: Option[]) {
const opt = options.map((d: Option) => d.value);
const widget = {
...dashboardStore.selectedGrid.widget,
[key]: decodeURIComponent(param[key]),
...dashboardStore.selectedGrid,
associate: { widgetIds: opt },
};
dashboardStore.selectWidget({ ...selectedGrid, widget });
dashboardStore.selectWidget({ ...widget });
}
</script>
<style lang="scss" scoped>

View File

@ -62,8 +62,10 @@ limitations under the License. -->
metricTypes: data.metricTypes || [''],
i: data.i,
metricConfig: data.metricConfig,
associate: data.associate || [],
}"
:needQuery="needQuery"
@click="clickHandle"
/>
</div>
<div v-else class="no-data">{{ t("noGraph") }}</div>
@ -84,6 +86,7 @@ import {
useGetMetricEntity,
} from "@/hooks/useProcessor";
import { EntityType, ListChartTypes } from "../data";
import { EventParams } from "@/types/dashboard";
const props = {
data: {
@ -93,6 +96,7 @@ const props = {
activeIndex: { type: String, default: "" },
needQuery: { type: Boolean, default: false },
};
export default defineComponent({
name: "Widget",
components: { ...graphs },
@ -156,6 +160,12 @@ export default defineComponent({
dashboardStore.activeGridItem(props.data.i);
}
}
function clickHandle(params: EventParams | any) {
console.log(params);
console.log(props.data.associate);
// for (const id of props.config.associate.widgetIds) {
// }
}
watch(
() => [props.data.metricTypes, props.data.metrics],
() => {
@ -221,6 +231,7 @@ export default defineComponent({
t,
graph,
widget,
clickHandle,
};
},
});

View File

@ -13,15 +13,16 @@ 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>
<Graph :option="option" />
<Graph :option="option" @select="clickEvent" />
</template>
<script lang="ts" setup>
import { computed } from "vue";
import type { PropType } from "vue";
import { Event } from "@/types/events";
import { LineConfig } from "@/types/dashboard";
import { LineConfig, EventParams } from "@/types/dashboard";
/*global defineProps */
/*global defineProps, defineEmits */
const emits = defineEmits(["click"]);
const props = defineProps({
data: {
type: Object as PropType<{ [key: string]: number[] }>,
@ -31,7 +32,9 @@ const props = defineProps({
theme: { type: String, default: "light" },
itemEvents: { type: Array as PropType<Event[]>, default: () => [] },
config: {
type: Object as PropType<LineConfig>,
type: Object as PropType<
LineConfig & { associate: { widgetIds: string[] } }
>,
default: () => ({
step: false,
smooth: false,
@ -215,4 +218,8 @@ function getOption() {
series: temp,
};
}
function clickEvent(params: EventParams) {
emits("click", params);
}
</script>