forked from github/dataease
feat(数据大屏): 增加图形组件
This commit is contained in:
parent
c15b098d46
commit
a85578ff7a
1
core/core-frontend/src/assets/svg/graphical-circular.svg
Normal file
1
core/core-frontend/src/assets/svg/graphical-circular.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1708249747987" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8596" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 64c60.5 0 119.2 11.8 174.4 35.2 53.3 22.6 101.3 54.9 142.4 96 41.2 41.2 73.5 89.1 96 142.4C948.2 392.8 960 451.5 960 512s-11.8 119.2-35.2 174.4c-22.6 53.3-54.9 101.3-96 142.4-41.2 41.2-89.1 73.5-142.4 96C631.2 948.2 572.5 960 512 960s-119.2-11.8-174.4-35.2c-53.3-22.6-101.3-54.9-142.4-96-41.2-41.2-73.5-89.1-96-142.4C75.8 631.2 64 572.5 64 512s11.8-119.2 35.2-174.4c22.6-53.3 54.9-101.3 96-142.4s89.1-73.5 142.4-96C392.8 75.8 451.5 64 512 64m0-64C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0z" p-id="8597"></path></svg>
|
After Width: | Height: | Size: 884 B |
1
core/core-frontend/src/assets/svg/graphical-rect.svg
Normal file
1
core/core-frontend/src/assets/svg/graphical-rect.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1708246996806" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4208" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M928 896H96a53.393333 53.393333 0 0 1-53.333333-53.333333V181.333333a53.393333 53.393333 0 0 1 53.333333-53.333333h832a53.393333 53.393333 0 0 1 53.333333 53.333333v661.333334a53.393333 53.393333 0 0 1-53.333333 53.333333zM96 170.666667a10.666667 10.666667 0 0 0-10.666667 10.666666v661.333334a10.666667 10.666667 0 0 0 10.666667 10.666666h832a10.666667 10.666667 0 0 0 10.666667-10.666666V181.333333a10.666667 10.666667 0 0 0-10.666667-10.666666z" p-id="4209"></path></svg>
|
After Width: | Height: | Size: 808 B |
1
core/core-frontend/src/assets/svg/graphical-triangle.svg
Normal file
1
core/core-frontend/src/assets/svg/graphical-triangle.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1708249769352" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9558" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M928.64 896a2.144 2.144 0 0 1-0.64 0H96a32.032 32.032 0 0 1-27.552-48.288l416-704c11.488-19.456 43.552-19.456 55.104 0l413.152 699.2A31.936 31.936 0 0 1 928.64 896z m-776.576-64h719.84L512 222.912 152.064 832z" p-id="9559"></path></svg>
|
After Width: | Height: | Size: 569 B |
1
core/core-frontend/src/assets/svg/icon_graphical.svg
Normal file
1
core/core-frontend/src/assets/svg/icon_graphical.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1708250676998" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10597" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M832 337.6 832 106.688C832 83.072 812.864 64 789.376 64L106.688 64C83.072 64 64 83.072 64 106.688l0 682.688C64 812.928 83.072 832 106.688 832l251.456 0c62.912 96.192 171.328 160 294.592 160 194.112 0 352-157.952 352-352C1004.736 511.424 935.232 399.04 832 337.6zM128 768 128 128l640 0 0 179.776C731.776 295.168 693.12 288 652.736 288 458.688 288 300.8 445.952 300.8 640c0 45.184 8.896 88.256 24.448 128L128 768zM652.736 928C494.016 928 364.8 798.784 364.8 640s129.216-288 287.936-288 288 129.216 288 288S811.52 928 652.736 928z" p-id="10598"></path></svg>
|
After Width: | Height: | Size: 889 B |
@ -60,6 +60,31 @@ export const CANVAS_MATERIAL = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
category: 'DeGraphical',
|
||||
title: '图形',
|
||||
span: 8,
|
||||
details: [
|
||||
{
|
||||
value: 'rect',
|
||||
type: 'graphical',
|
||||
title: '矩形',
|
||||
icon: 'graphical-rect'
|
||||
},
|
||||
{
|
||||
value: 'triangle',
|
||||
type: 'graphical',
|
||||
title: '三角形',
|
||||
icon: 'graphical-triangle'
|
||||
},
|
||||
{
|
||||
value: 'circular',
|
||||
type: 'graphical',
|
||||
title: '圆形',
|
||||
icon: 'graphical-circular'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
category: 'CanvasIcon',
|
||||
title: '图标',
|
||||
|
@ -86,7 +86,7 @@ const groupActiveChange = category => {
|
||||
:data-id="groupInfo.category + '&' + chartInfo.value"
|
||||
>
|
||||
<Icon
|
||||
v-if="chartInfo.type === 'outer_svg'"
|
||||
v-if="['outer_svg', 'graphical'].includes(chartInfo.type)"
|
||||
class-name="item-top-icon"
|
||||
:name="chartInfo.icon"
|
||||
/>
|
||||
|
@ -181,6 +181,26 @@ const list = [
|
||||
color: ''
|
||||
}
|
||||
},
|
||||
{
|
||||
component: 'DeGraphical',
|
||||
name: '图形',
|
||||
label: '图形',
|
||||
propValue: '',
|
||||
icon: 'icon_graphical',
|
||||
innerType: '',
|
||||
editing: false,
|
||||
canvasActive: false,
|
||||
x: 1,
|
||||
y: 1,
|
||||
sizeX: 15,
|
||||
sizeY: 15,
|
||||
style: {
|
||||
width: 300,
|
||||
height: 200,
|
||||
color: '#000000',
|
||||
board: 1
|
||||
}
|
||||
},
|
||||
{
|
||||
component: 'DeTabs',
|
||||
name: '选项卡',
|
||||
|
268
core/core-frontend/src/custom-component/de-graphical/Attr.vue
Normal file
268
core/core-frontend/src/custom-component/de-graphical/Attr.vue
Normal file
@ -0,0 +1,268 @@
|
||||
<script setup lang="ts">
|
||||
import CommonAttr from '@/custom-component/common/CommonAttr.vue'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ElIcon, ElMessage } from 'element-plus-secondary'
|
||||
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
|
||||
import { beforeUploadCheck, uploadFileResult } from '@/api/staticResource'
|
||||
import { imgUrlTrans } from '@/utils/imgUtils'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import ImgViewDialog from '@/custom-component/ImgViewDialog.vue'
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
themes?: EditorTheme
|
||||
}>(),
|
||||
{
|
||||
themes: 'dark'
|
||||
}
|
||||
)
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
|
||||
const { curComponent } = storeToRefs(dvMainStore)
|
||||
|
||||
const fileList = ref([])
|
||||
const dialogImageUrl = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const uploadDisabled = ref(false)
|
||||
const files = ref(null)
|
||||
const maxImageSize = 15000000
|
||||
|
||||
const handlePictureCardPreview = file => {
|
||||
dialogImageUrl.value = file.url
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleRemove = (_, fileList) => {
|
||||
uploadDisabled.value = false
|
||||
curComponent.value.propValue.url = null
|
||||
fileList.value = []
|
||||
snapshotStore.recordSnapshotCache()
|
||||
}
|
||||
async function upload(file) {
|
||||
uploadFileResult(file.file, fileUrl => {
|
||||
snapshotStore.recordSnapshotCache()
|
||||
curComponent.value.propValue.url = fileUrl
|
||||
})
|
||||
}
|
||||
|
||||
const goFile = () => {
|
||||
files.value.click()
|
||||
}
|
||||
|
||||
const reUpload = e => {
|
||||
const file = e.target.files[0]
|
||||
if (file.size > maxImageSize) {
|
||||
sizeMessage()
|
||||
}
|
||||
uploadFileResult(file, fileUrl => {
|
||||
snapshotStore.recordSnapshotCache()
|
||||
curComponent.value.propValue.url = fileUrl
|
||||
fileList.value = [{ url: imgUrlTrans(curComponent.value.propValue.url) }]
|
||||
})
|
||||
}
|
||||
|
||||
const sizeMessage = () => {
|
||||
ElMessage.success('图片大小不符合')
|
||||
}
|
||||
const init = () => {
|
||||
if (curComponent.value.propValue.url) {
|
||||
fileList.value = [{ url: imgUrlTrans(curComponent.value.propValue.url) }]
|
||||
} else {
|
||||
fileList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => curComponent.value.propValue.url,
|
||||
() => {
|
||||
init()
|
||||
}
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
eventBus.on('uploadImg', goFile)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
eventBus.off('uploadImg', goFile)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="attr-list de-collapse-style">
|
||||
<input
|
||||
id="input"
|
||||
ref="files"
|
||||
type="file"
|
||||
accept=".jpeg,.jpg,.png,.gif"
|
||||
hidden
|
||||
@click="
|
||||
e => {
|
||||
e.target.value = ''
|
||||
}
|
||||
"
|
||||
@change="reUpload"
|
||||
/>
|
||||
<CommonAttr
|
||||
:themes="themes"
|
||||
:element="curComponent"
|
||||
:background-color-picker-width="197"
|
||||
:background-border-select-width="197"
|
||||
>
|
||||
<el-collapse-item :effect="themes" title="图片" name="picture">
|
||||
<el-row class="img-area" :class="`img-area_${themes}`">
|
||||
<el-col style="width: 130px !important">
|
||||
<el-upload
|
||||
:themes="themes"
|
||||
action=""
|
||||
accept=".jpeg,.jpg,.png,.gif,.svg"
|
||||
class="avatar-uploader"
|
||||
list-type="picture-card"
|
||||
:class="{ disabled: uploadDisabled }"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="handleRemove"
|
||||
:before-upload="beforeUploadCheck"
|
||||
:http-request="upload"
|
||||
:file-list="fileList"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
<img-view-dialog v-model="dialogVisible" :image-url="dialogImageUrl"></img-view-dialog>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="margin-bottom: 16px">
|
||||
<span
|
||||
style="margin-top: 2px"
|
||||
v-if="!curComponent.propValue.url"
|
||||
class="image-hint"
|
||||
:class="`image-hint_${themes}`"
|
||||
>
|
||||
支持JPG、PNG、GIF
|
||||
</span>
|
||||
|
||||
<el-button
|
||||
size="small"
|
||||
style="margin: 8px 0 0 -4px"
|
||||
v-if="curComponent.propValue.url"
|
||||
text
|
||||
@click="goFile"
|
||||
>
|
||||
重新上传
|
||||
</el-button>
|
||||
</el-row>
|
||||
</el-collapse-item>
|
||||
</CommonAttr>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.de-collapse-style {
|
||||
:deep(.ed-collapse-item__header) {
|
||||
height: 36px !important;
|
||||
line-height: 36px !important;
|
||||
font-size: 12px !important;
|
||||
padding: 0 !important;
|
||||
font-weight: 500 !important;
|
||||
|
||||
.ed-collapse-item__arrow {
|
||||
margin: 0 6px 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ed-collapse-item__content) {
|
||||
padding: 16px 8px 0;
|
||||
}
|
||||
:deep(.ed-form-item) {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
:deep(.ed-form-item__label) {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.disabled :deep(.el-upload--picture-card) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.avatar-uploader :deep(.ed-upload) {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
line-height: 90px;
|
||||
}
|
||||
|
||||
.avatar-uploader :deep(.ed-upload-list li) {
|
||||
width: 80px !important;
|
||||
height: 80px !important;
|
||||
}
|
||||
|
||||
:deep(.ed-upload--picture-card) {
|
||||
background: #eff0f1;
|
||||
border: 1px dashed #dee0e3;
|
||||
border-radius: 4px;
|
||||
|
||||
.ed-icon {
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.ed-icon {
|
||||
color: #3370ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.img-area {
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
margin-top: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
&.img-area_dark {
|
||||
:deep(.ed-upload-list__item).is-success {
|
||||
border-color: #434343;
|
||||
}
|
||||
:deep(.ed-upload--picture-card) {
|
||||
background: #373737;
|
||||
border-color: #434343;
|
||||
.ed-icon {
|
||||
color: #ebebeb;
|
||||
}
|
||||
&:hover {
|
||||
.ed-icon {
|
||||
color: #3370ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.img-area_light {
|
||||
:deep(.ed-upload-list__item).is-success {
|
||||
border-color: #dee0e3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.image-hint {
|
||||
color: #8f959e;
|
||||
size: 14px;
|
||||
line-height: 22px;
|
||||
font-weight: 400;
|
||||
margin-top: 2px;
|
||||
&.image-hint_dark {
|
||||
color: #757575;
|
||||
}
|
||||
}
|
||||
|
||||
.re-update-span {
|
||||
cursor: pointer;
|
||||
color: #3370ff;
|
||||
size: 14px;
|
||||
line-height: 22px;
|
||||
font-weight: 400;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="rect-main">
|
||||
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="100%"
|
||||
height="100%"
|
||||
fill="transparent"
|
||||
:stroke="style.color"
|
||||
:stroke-width="style.fontSize"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, toRefs } from 'vue'
|
||||
const props = defineProps({
|
||||
element: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
style: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const { element } = toRefs(props)
|
||||
|
||||
const style = computed(() => element.value.style)
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.rect-main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
@ -13,6 +13,8 @@ import CanvasIcon from '@/custom-component/canvas-icon/Component.vue'
|
||||
import CanvasIconAttr from '@/custom-component/canvas-icon/Attr.vue'
|
||||
import DeTabs from '@/custom-component/de-tabs/Component.vue'
|
||||
import DeTabsAttr from '@/custom-component/de-tabs/Attr.vue'
|
||||
import DeGraphical from '@/custom-component/de-graphical/Component.vue'
|
||||
import DeGraphicalAttr from '@/custom-component/de-graphical/Attr.vue'
|
||||
|
||||
export const componentsMap = {
|
||||
VText: VText,
|
||||
@ -29,7 +31,9 @@ export const componentsMap = {
|
||||
CanvasIcon: CanvasIcon,
|
||||
CanvasIconAttr: CanvasIconAttr,
|
||||
DeTabs: DeTabs,
|
||||
DeTabsAttr: DeTabsAttr
|
||||
DeTabsAttr: DeTabsAttr,
|
||||
DeGraphical: DeGraphical,
|
||||
DeGraphicalAttr: DeGraphicalAttr
|
||||
}
|
||||
|
||||
export default function findComponent(key) {
|
||||
|
Loading…
Reference in New Issue
Block a user