277 lines
8.8 KiB
Vue
277 lines
8.8 KiB
Vue
<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>
|