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) { if (!instance) {
return; return;
} }
instance.on("click", (params: any) => { instance.on("click", (params: unknown) => {
emits("select", params); emits("select", params);
}); });
}, 1000); }, 1000);

View File

@ -5,36 +5,8 @@
declare module '@vue/runtime-core' { declare module '@vue/runtime-core' {
export interface GlobalComponents { export interface GlobalComponents {
DateCalendar: typeof import('./../components/DateCalendar.vue')['default'] 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'] Graph: typeof import('./../components/Graph.vue')['default']
Icon: typeof import('./../components/Icon.vue')['default'] Icon: typeof import('./../components/Icon.vue')['default']
Loading: typeof import('element-plus/es')['ElLoadingDirective']
Radio: typeof import('./../components/Radio.vue')['default'] Radio: typeof import('./../components/Radio.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']

View File

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

View File

@ -62,8 +62,10 @@ limitations under the License. -->
metricTypes: data.metricTypes || [''], metricTypes: data.metricTypes || [''],
i: data.i, i: data.i,
metricConfig: data.metricConfig, metricConfig: data.metricConfig,
associate: data.associate || [],
}" }"
:needQuery="needQuery" :needQuery="needQuery"
@click="clickHandle"
/> />
</div> </div>
<div v-else class="no-data">{{ t("noGraph") }}</div> <div v-else class="no-data">{{ t("noGraph") }}</div>
@ -84,6 +86,7 @@ import {
useGetMetricEntity, useGetMetricEntity,
} from "@/hooks/useProcessor"; } from "@/hooks/useProcessor";
import { EntityType, ListChartTypes } from "../data"; import { EntityType, ListChartTypes } from "../data";
import { EventParams } from "@/types/dashboard";
const props = { const props = {
data: { data: {
@ -93,6 +96,7 @@ const props = {
activeIndex: { type: String, default: "" }, activeIndex: { type: String, default: "" },
needQuery: { type: Boolean, default: false }, needQuery: { type: Boolean, default: false },
}; };
export default defineComponent({ export default defineComponent({
name: "Widget", name: "Widget",
components: { ...graphs }, components: { ...graphs },
@ -156,6 +160,12 @@ export default defineComponent({
dashboardStore.activeGridItem(props.data.i); 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( watch(
() => [props.data.metricTypes, props.data.metrics], () => [props.data.metricTypes, props.data.metrics],
() => { () => {
@ -221,6 +231,7 @@ export default defineComponent({
t, t,
graph, graph,
widget, 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 See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<Graph :option="option" /> <Graph :option="option" @select="clickEvent" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from "vue"; import { computed } from "vue";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { Event } from "@/types/events"; 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({ const props = defineProps({
data: { data: {
type: Object as PropType<{ [key: string]: number[] }>, type: Object as PropType<{ [key: string]: number[] }>,
@ -31,7 +32,9 @@ const props = defineProps({
theme: { type: String, default: "light" }, theme: { type: String, default: "light" },
itemEvents: { type: Array as PropType<Event[]>, default: () => [] }, itemEvents: { type: Array as PropType<Event[]>, default: () => [] },
config: { config: {
type: Object as PropType<LineConfig>, type: Object as PropType<
LineConfig & { associate: { widgetIds: string[] } }
>,
default: () => ({ default: () => ({
step: false, step: false,
smooth: false, smooth: false,
@ -215,4 +218,8 @@ function getOption() {
series: temp, series: temp,
}; };
} }
function clickEvent(params: EventParams) {
emits("click", params);
}
</script> </script>