<template>
|
<div class="pic-main">
|
<chart-error v-if="isError" :err-msg="errMsg" />
|
<img
|
draggable="false"
|
v-else-if="state.showUrl"
|
:style="imageAdapter"
|
:src="imgUrlTrans(state.showUrl)"
|
/>
|
<template v-else>
|
<chart-empty-info :view-icon="view.type"></chart-empty-info>
|
</template>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import {
|
CSSProperties,
|
computed,
|
nextTick,
|
toRefs,
|
reactive,
|
ref,
|
PropType,
|
watch,
|
onBeforeMount
|
} from 'vue'
|
import { imgUrlTrans } from '@/utils/imgUtils'
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
import { getData } from '@/api/chart'
|
import { parseJson } from '@/views/chart/components/js/util'
|
import { mappingColorCustom } from '@/views/chart/components/js/panel/common/common_table'
|
import { storeToRefs } from 'pinia'
|
import ChartEmptyInfo from '@/views/chart/components/views/components/ChartEmptyInfo.vue'
|
import ChartError from '@/views/chart/components/views/components/ChartError.vue'
|
import { deepCopy } from '@/utils/utils'
|
const dvMainStore = dvMainStoreWithOut()
|
const { canvasViewInfo, mobileInPc, fullscreenFlag } = storeToRefs(dvMainStore)
|
const state = reactive({
|
emptyValue: '-',
|
data: null,
|
viewDataInfo: null,
|
showUrl: null,
|
firstRender: true,
|
previewFirstRender: true,
|
curImgList: []
|
})
|
const initReady = ref(true)
|
const props = defineProps({
|
element: {
|
type: Object,
|
default() {
|
return {
|
propValue: { urlList: [] }
|
}
|
}
|
},
|
showPosition: {
|
required: false,
|
type: String,
|
default: 'preview'
|
},
|
// 仪表板刷新计时器
|
searchCount: {
|
type: Number,
|
required: false,
|
default: 0
|
},
|
view: {
|
type: Object as PropType<ChartObj>,
|
default() {
|
return {
|
propValue: null
|
}
|
}
|
}
|
})
|
const isError = ref(false)
|
const errMsg = ref('')
|
const dataRowSelect = ref({})
|
const dataRowNameSelect = ref({})
|
const dataRowFiledName = ref([])
|
let carouselTimer = null
|
const { element, view, showPosition } = toRefs(props)
|
let innerRefreshTimer = null
|
let innerSearchCount = 0
|
const isEditMode = computed(
|
() => showPosition.value.includes('canvas') && !mobileInPc.value && !fullscreenFlag.value
|
)
|
|
watch([() => props.searchCount], () => {
|
// 内部计时器启动 忽略外部计时器
|
if (!innerRefreshTimer) {
|
calcData(view.value, () => {
|
// do searchCount
|
})
|
}
|
})
|
|
// 编辑状态下 不启动刷新
|
const buildInnerRefreshTimer = (
|
refreshViewEnable = false,
|
refreshUnit = 'minute',
|
refreshTime = 5
|
) => {
|
if (showPosition.value === 'preview' && !innerRefreshTimer && refreshViewEnable) {
|
innerRefreshTimer && clearInterval(innerRefreshTimer)
|
const timerRefreshTime = refreshUnit === 'second' ? refreshTime * 1000 : refreshTime * 60000
|
innerRefreshTimer = setInterval(() => {
|
calcData(view.value, () => {
|
// do innerRefreshTimer
|
})
|
innerSearchCount++
|
}, timerRefreshTime)
|
}
|
}
|
|
watch(
|
() => isEditMode.value,
|
() => {
|
initCarousel()
|
}
|
)
|
|
const initCarousel = () => {
|
carouselTimer && clearInterval(carouselTimer)
|
carouselTimer = null
|
const picLength = element.value.propValue.urlList?.length || 0
|
const { threshold } = parseJson(view.value.senior)
|
// 非编辑状态 未启用条件样式 存在图片 启用轮播
|
if (!isEditMode.value && !threshold.enable && picLength > 0 && element.value.carousel?.enable) {
|
const switchTime = (element.value.carousel.time || 5) * 1000
|
let switchCount = 1
|
// 轮播定时器
|
carouselTimer = setInterval(() => {
|
const nowIndex = switchCount % element.value.propValue.urlList.length
|
switchCount++
|
nextTick(() => {
|
state.showUrl = element.value.propValue.urlList[nowIndex].url
|
})
|
}, switchTime)
|
}
|
}
|
|
const imageAdapter = computed(() => {
|
const style = {
|
position: 'relative',
|
width: '100%',
|
height: '100%'
|
}
|
if (element.value.style.adaptation === 'original') {
|
style.width = 'auto'
|
style.height = 'auto'
|
} else if (element.value.style.adaptation === 'equiratio') {
|
style.height = 'auto'
|
}
|
return style as CSSProperties
|
})
|
|
const initCurFields = chartDetails => {
|
dataRowFiledName.value = []
|
dataRowSelect.value = {}
|
dataRowNameSelect.value = {}
|
if (chartDetails.data && chartDetails.data.sourceFields) {
|
const checkAllAxisStr =
|
JSON.stringify(chartDetails.xAxis) +
|
JSON.stringify(chartDetails.xAxisExt) +
|
JSON.stringify(chartDetails.yAxis) +
|
JSON.stringify(chartDetails.yAxisExt)
|
chartDetails.data.sourceFields.forEach(field => {
|
if (checkAllAxisStr.indexOf(field.id) > -1) {
|
dataRowFiledName.value.push(`[${field.name}]`)
|
}
|
})
|
if (checkAllAxisStr.indexOf('"记录数*"') > -1) {
|
dataRowFiledName.value.push(`[记录数*]`)
|
}
|
const sourceFieldNameIdMap = chartDetails.data.fields.reduce((pre, next) => {
|
pre[next['dataeaseName']] = next['name']
|
return pre
|
}, {})
|
const rowData = chartDetails.data.tableRow[0]
|
for (const key in rowData) {
|
dataRowNameSelect.value[sourceFieldNameIdMap[key]] = rowData[key]
|
}
|
}
|
conditionAdaptor(view.value)
|
}
|
|
const conditionAdaptor = (chart: Chart) => {
|
state.showUrl = null
|
if (!chart || !chart.senior) {
|
return
|
}
|
const { threshold } = parseJson(chart.senior)
|
if (!threshold.enable) {
|
return
|
}
|
const conditions = threshold.tableThreshold ?? []
|
if (conditions?.length > 0) {
|
for (let i = 0; i < conditions.length; i++) {
|
const field = deepCopy(conditions[i])
|
let defaultValueColor = null
|
field.conditions.sort((a, b) => {
|
const aIsDefault = a.term === 'default'
|
const bIsDefault = b.term === 'default'
|
|
if (aIsDefault && !bIsDefault) return 1
|
if (!aIsDefault && bIsDefault) return -1
|
return 0
|
})
|
const checkResult = mappingColorCustom(
|
dataRowNameSelect.value[field.field.name],
|
defaultValueColor,
|
field,
|
'url'
|
)
|
if (checkResult) {
|
state.showUrl = checkResult
|
}
|
}
|
}
|
}
|
|
const withInit = () => {
|
if (element.value.propValue['urlList'] && element.value.propValue['urlList'].length > 0) {
|
state.showUrl = element.value.propValue['urlList'][0].url
|
} else {
|
state.showUrl = null
|
}
|
|
initCarousel()
|
}
|
|
const calcData = (viewCalc: Chart, callback) => {
|
isError.value = false
|
const { threshold } = parseJson(viewCalc.senior)
|
if (!threshold.enable) {
|
withInit()
|
callback?.()
|
return
|
}
|
if (viewCalc.tableId || viewCalc['dataFrom'] === 'template') {
|
const v = JSON.parse(JSON.stringify(viewCalc))
|
v.type = 'table-info'
|
v.render = 'antv'
|
v.resultCount = 1
|
getData(v)
|
.then(res => {
|
if (res.code && res.code !== 0) {
|
isError.value = true
|
errMsg.value = res.msg
|
} else {
|
res.type = 'picture-group'
|
res.render = 'custom'
|
state.data = res?.data
|
state.viewDataInfo = res
|
state.totalItems = res?.totalItems
|
const curViewInfo = canvasViewInfo.value[element.value.id]
|
curViewInfo['curFields'] = res.data.fields
|
dvMainStore.setViewDataDetails(element.value.id, res)
|
initReady.value = true
|
initCurFields(res)
|
initCarousel()
|
}
|
callback?.()
|
nextTick(() => {
|
initReady.value = true
|
})
|
})
|
.catch(e => {
|
console.error(e)
|
nextTick(() => {
|
initReady.value = true
|
})
|
callback?.()
|
})
|
} else if (!viewCalc.tableId) {
|
initReady.value = true
|
withInit()
|
callback?.()
|
nextTick(() => {
|
initReady.value = true
|
})
|
} else {
|
withInit()
|
nextTick(() => {
|
initReady.value = true
|
})
|
callback?.()
|
}
|
}
|
|
// 初始化此处不必刷新
|
const renderChart = () => {
|
//do renderView
|
}
|
|
onBeforeMount(() => {
|
if (carouselTimer) {
|
clearInterval(carouselTimer)
|
carouselTimer = null
|
}
|
buildInnerRefreshTimer()
|
})
|
|
defineExpose({
|
calcData,
|
renderChart
|
})
|
</script>
|
|
<style lang="less" scoped>
|
.pic-main {
|
overflow: hidden;
|
width: 100%;
|
height: 100%;
|
cursor: pointer;
|
}
|
.pic-upload {
|
display: flex;
|
width: 100%;
|
height: 100%;
|
color: #5370af;
|
align-items: center;
|
justify-content: center;
|
}
|
</style>
|