Files
gr_bi_web/src/views/bigscreenDesigner/designer/widget/widget.vue
2026-02-10 07:32:43 +08:00

277 lines
8.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<avue-draggable
:data-widget-index="index"
:step="step"
:width="widgetsWidth"
:height="widgetsHeight"
:disabled="widgetDisabled"
:left="widgetsLeft"
:top="widgetsTop"
ref="draggable"
:index="index"
@focus="handleFocus"
@blur="handleBlur"
>
<!-- :z-index="-1" -->
<component
:is="type"
:widget-index="index"
:value="value"
@childActivated="handleChildActivated"
@innerDragStart="handleInnerDragStart"
@innerDragEnd="handleInnerDragEnd"
@tabsHeaderMouseDown="handleTabsHeaderMouseDown"
/>
</avue-draggable>
</template>
<script>
import widgetHref from "./texts/widgetHref.vue";
import widgetText from "./texts/widgetText.vue";
import widgetButton from './form/widgetButton.vue';
import widgetTabs from './form/widgetTabs.vue';
import WidgetMarquee from "./texts/widgetMarquee.vue";
import widgetTime from "./texts/widgetTime.vue";
import widgetImage from "./texts/widgetImage.vue";
import widgetSlider from "./texts/widgetSlider.vue";
import widgetVideo from "./texts/widgetVideo.vue";
import widgetVideoMonitor from "./texts/widgetVideoMonitor.vue";
import WidgetIframe from "./texts/widgetIframe.vue";
import widgetCalendar from "./texts/widgetCalendar.vue";
import widgetBarchart from "./bar/widgetBarchart.vue";
import widgetScatter from "./scatter/widgetScatter.vue";
import widgetGradientColorBarchart from "./bar/widgetGradientColorBarchart.vue";
import widgetLinechart from "./line/widgetLinechart.vue";
import widgetBarlinechart from "./barline/widgetBarlinechart";
import WidgetPiechart from "./pie/widgetPiechart.vue";
import WidgetFunnel from "./funnel/widgetFunnel.vue";
import WidgetGauge from "./percent/widgetGauge.vue";
import WidgetPieNightingaleRoseArea from "./pie/widgetPieNightingaleRose";
import widgetTable from "./texts/widgetTable.vue";
import widgetLineMap from "./map/widgetLineMap.vue";
import widgetPiePercentageChart from "./percent/widgetPiePercentageChart";
import widgetAirBubbleMap from "./map/widgetAirBubbleMap";
import widgetBarStackChart from "./bar/widgetBarStackChart";
import widgetLineStackChart from "./line/widgetLineStackChart";
import widgetBarCompareChart from "./bar/widgetBarCompareChart";
import widgetLineCompareChart from "./line/widgetLineCompareChart";
import widgetDecoratePieChart from "./styleWidget/widgetDecoratePieChart.vue";
import widgetMoreBarLineChart from "./barline/widgetMoreBarLineChart";
import widgetWordCloud from "./wordcloud/widgetWordCloud";
import widgetHeatmap from "./heatmap/widgetHeatmap";
import widgetRadar from "./radar/widgetRadar";
import widgetBarLineStackChart from "./barline/widgetBarLineStackChart";
import widgetSelect from "./form/widgetSelect";
import widgetInput from "./form/widgetInput.vue";
import widgetFormTime from "./form/widgetFormTime.vue";
import widgetScaleVertical from "./scale/widgetScaleVertical.vue";
import widgetScaleHorizontal from "./scale/widgetScaleHorizontal.vue";
import widgetBarDoubleYaxisChart from "./bar/widgetBarDoubleYaxisChart.vue";
import widgetBorder from "./styleWidget/widgetBorder.vue";
import widgetDecorateFlowLine from "./styleWidget/widgetDecorateFlowLine.vue";
import widgetDecoration from "./styleWidget/widgetDecoration.vue";
import widgetBarMap from "./map/widgetBarMap.vue";
import widgetChinaMap from "./map/widgetChinaMap.vue";
import widgetGlobalMap from "./map/widgetGlobalMap.vue";
import widgetBarStackMoreShowChart from "./bar/widgetBarStackMoreShowChart.vue";
import widgetBarLineSingleChart from "./barline/widgetBarLineSingleChart.vue";
export default {
name: "Widget",
components: {
widgetHref,
widgetText,
widgetButton,
widgetTabs,
widgetBorder,
widgetDecorateFlowLine,
widgetDecoration,
WidgetMarquee,
widgetTime,
widgetImage,
widgetSlider,
widgetVideo,
widgetVideoMonitor,
WidgetIframe,
widgetCalendar,
widgetBarchart,
widgetGradientColorBarchart,
widgetLinechart,
widgetBarlinechart,
WidgetPiechart,
WidgetFunnel,
WidgetGauge,
WidgetPieNightingaleRoseArea,
widgetTable,
widgetLineMap,
widgetPiePercentageChart,
widgetAirBubbleMap,
widgetBarStackChart,
widgetLineStackChart,
widgetBarCompareChart,
widgetLineCompareChart,
widgetDecoratePieChart,
widgetMoreBarLineChart,
widgetWordCloud,
widgetHeatmap,
widgetRadar,
widgetBarLineStackChart,
widgetScaleVertical,
widgetScaleHorizontal,
widgetSelect,
//widgetInput,
widgetFormTime,
widgetBarDoubleYaxisChart,
widgetBarMap,
widgetChinaMap,
widgetGlobalMap,
widgetScatter,
widgetBarStackMoreShowChart,
widgetBarLineSingleChart
},
model: {
prop: "value",
event: "input",
},
props: {
/*
widget-text widget-marquee widget-href widget-time widget-image widget-slider widget-video widget-table widget-iframe widget-universal
widget-linechart widget-barlinechart widget-piechart widget-hollow-piechart widget-funnel widget-gauge widget-china-map
*/
index: Number, // 当前组件在工作区变量widgetInWorkbench中的索引
type: String,
bigscreen: Object,
value: {
type: [Object],
default: () => {
},
},
step: Number,
},
data() {
return {
data: {
setup: {},
data: {},
position: {},
/* leftMargin: null,
topMargin: null*/
},
// 当 Tabs 内部拖拽子组件时,暂时禁用外层 avue-draggable防止整个 Tabs 被拖动
innerDragging: false,
};
},
computed: {
widgetsWidth() {
return this.value.position.width;
},
widgetsHeight() {
return this.value.position.height;
},
widgetsLeft() {
return this.value.position.left; // >= this.leftMargin ? this.leftMargin : this.value.position.left;
},
widgetsTop() {
return this.value.position.top; // >= this.topMargin ? this.topMargin : this.value.position.top;
},
widgetsZIndex() {
return this.value.position.zIndex || 1;
},
widgetDisabled() {
// Tabs 必须禁用外层拖拽内部子组件才能选中Tabs 整体拖动改由标题栏单独处理
if (this.type === 'widget-tabs') {
return true;
}
return this.value.position.disabled || this.innerDragging || false;
},
},
mounted() {
},
methods: {
handleFocus({index, left, top, width, height}) {
},
handleBlur({index, left, top, width, height}) {
this.$emit("onActivated", {index, left, top, width, height});
this.$refs.draggable.setActive(true);
// 处理widget超出workbench的问题
//this.handleBoundary({ index, left, top, width, height })
},
handleBoundary({index, left, top, width, height}) {
// 计算workbench的X轴边界值
// 组件距离左侧宽度 + 组件宽度 > 大屏总宽度时,右侧边界值 = (大屏宽度 - 组件宽度);左侧边界值 = 0
const {bigscreenWidth, bigscreenHeight} = this.bigscreen;
const xBoundaryValue =
left + width > bigscreenWidth
? bigscreenWidth - width
: left < 0
? 0
: left;
// 初始化X轴边界值
this.leftMargin = left;
// 计算Y轴边界值
const yBoundaryValue =
top + height > bigscreenHeight
? bigscreenHeight - height
: top < 0
? 0
: top;
// 初始化Y轴边界值
this.topMargin = top;
// 若位置超出边界值则重新设置位置
if (
this.leftMargin != xBoundaryValue ||
this.topMargin != yBoundaryValue
) {
this.$nextTick(() => {
this.leftMargin = xBoundaryValue;
this.topMargin = yBoundaryValue;
this.$emit("onActivated", {
index,
left: xBoundaryValue,
top: yBoundaryValue,
width,
height,
});
});
}
},
/**
* 接收 Tabs 内部子组件发出的激活事件,并转发给设计器主页面
*/
handleChildActivated(payload) {
const info = Object.assign({}, payload || {});
if (info.rootWidgetIndex === undefined || info.rootWidgetIndex === null) {
info.rootWidgetIndex = this.index;
}
this.$emit("onChildActivated", info);
},
// Tabs 内部开始拖拽/点击子组件时,暂时禁用外层拖拽
handleInnerDragStart() {
this.innerDragging = true;
},
handleInnerDragEnd() {
this.innerDragging = false;
},
handleTabsHeaderMouseDown(evt) {
this.$emit('onTabsHeaderMouseDown', { event: evt, rootWidgetIndex: this.index });
},
},
};
</script>
<style scoped lang="scss">
.vue-draggalbe {
position: absolute;
}
.widget-active {
cursor: move;
border: 1px dashed #09f;
background-color: rgba(115, 170, 229, 0.5);
}
.avue-draggable {
padding: 0 !important;
}
</style>