|
@@ -0,0 +1,5213 @@
|
|
|
|
+<!--
|
|
|
|
+ * @Author: LiZhiWei
|
|
|
|
+ * @Date: 2025-04-10 14:38:27
|
|
|
|
+ * @LastEditors: LiZhiWei
|
|
|
|
+ * @LastEditTime: 2025-04-16 10:42:01
|
|
|
|
+ * @Description:
|
|
|
|
+-->
|
|
|
|
+<template>
|
|
|
|
+ <div id="pptx-container" ref="pptxContainer" class="pptx-container"></div>
|
|
|
|
+</template>
|
|
|
|
+<script>
|
|
|
|
+export default {
|
|
|
|
+ name: 'PPT',
|
|
|
|
+ props: {
|
|
|
|
+ pptxJson: Object
|
|
|
|
+ },
|
|
|
|
+ data () {
|
|
|
|
+ return {}
|
|
|
|
+ },
|
|
|
|
+ mounted () {
|
|
|
|
+ this.renderSlides()
|
|
|
|
+ },
|
|
|
|
+ computed: {},
|
|
|
|
+ watch: {
|
|
|
|
+ pptxJson: {
|
|
|
|
+ handler () {
|
|
|
|
+ this.renderSlides()
|
|
|
|
+ },
|
|
|
|
+ deep: true
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ renderSlides () {
|
|
|
|
+ console.log('this.pptxJson', this.pptxJson)
|
|
|
|
+ if (!this.$refs.pptxContainer || !this.pptxJson) return
|
|
|
|
+
|
|
|
|
+ this.$refs.pptxContainer.innerHTML = ''
|
|
|
|
+ const { size, slides } = this.pptxJson
|
|
|
|
+
|
|
|
|
+ slides.forEach((slide, index) => {
|
|
|
|
+ const slideElement = this.createSlideElement(size.width, size.height)
|
|
|
|
+ this.applySlideBackground(slideElement, slide.fill)
|
|
|
|
+ if (slide.layoutElements && Array.isArray(slide.layoutElements)) {
|
|
|
|
+ this.processElements(slide.layoutElements, index + 1)
|
|
|
|
+ slide.layoutElements.forEach((element) => {
|
|
|
|
+ const el = this.createElementByType(element)
|
|
|
|
+ if (!el) return
|
|
|
|
+ slideElement.appendChild(el)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 渲染幻灯片元素
|
|
|
|
+ if (slide.elements && Array.isArray(slide.elements)) {
|
|
|
|
+ this.processElements(slide.elements, index + 1)
|
|
|
|
+ slide.elements.forEach((element) => {
|
|
|
|
+ const el = this.createElementByType(element)
|
|
|
|
+ if (!el) return
|
|
|
|
+ slideElement.appendChild(el)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加幻灯片到容器
|
|
|
|
+ this.$refs.pptxContainer.appendChild(slideElement)
|
|
|
|
+ })
|
|
|
|
+ // 为所有p标签应用样式
|
|
|
|
+ const pTags = this.$refs.pptxContainer.querySelectorAll('p')
|
|
|
|
+ pTags.forEach((p) => {
|
|
|
|
+ p.style.margin = '0px'
|
|
|
|
+ p.style.padding = '0px'
|
|
|
|
+ p.style.wordBreak = 'break-word'
|
|
|
|
+ p.style.lineHeight = '1'
|
|
|
|
+ })
|
|
|
|
+ const ulTags = this.$refs.pptxContainer.querySelectorAll('ul')
|
|
|
|
+ ulTags.forEach((ul) => {
|
|
|
|
+ ul.style.wordBreak = 'break-word'
|
|
|
|
+ ul.style.lineHeight = '1'
|
|
|
|
+ })
|
|
|
|
+ const olTags = this.$refs.pptxContainer.querySelectorAll('ol')
|
|
|
|
+ olTags.forEach((ol) => {
|
|
|
|
+ ol.style.margin = '0px'
|
|
|
|
+ ol.style.padding = 'auto 0px'
|
|
|
|
+ ol.style.wordBreak = 'break-word'
|
|
|
|
+ ol.style.lineHeight = '1'
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ // 创建幻灯片元素
|
|
|
|
+ createSlideElement (width, height) {
|
|
|
|
+ const slideElement = document.createElement('div')
|
|
|
|
+ slideElement.className = 'slide'
|
|
|
|
+ slideElement.style.position = 'relative'
|
|
|
|
+ slideElement.style.width = width + 'px'
|
|
|
|
+ slideElement.style.height = height + 'px'
|
|
|
|
+ slideElement.style.border = '1px solid #ccc'
|
|
|
|
+ slideElement.style.margin = '0px auto'
|
|
|
|
+ slideElement.style.marginBottom = '20px'
|
|
|
|
+ slideElement.style.overflow = 'hidden'
|
|
|
|
+ return slideElement
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 应用幻灯片背景
|
|
|
|
+ applySlideBackground (slideElement, fill) {
|
|
|
|
+ if (!fill) return
|
|
|
|
+
|
|
|
|
+ if (fill.type === 'gradient') {
|
|
|
|
+ const { colors, path, rot } = fill.value
|
|
|
|
+
|
|
|
|
+ if (colors && colors.length >= 2) {
|
|
|
|
+ const gradientType = path === 'rect' ? 'linear' : 'radial'
|
|
|
|
+ const gradientAngle =
|
|
|
|
+ gradientType === 'linear' ? (90 - (rot || 0)) % 360 : rot || 0
|
|
|
|
+
|
|
|
|
+ let gradientString = `${gradientType}-gradient(`
|
|
|
|
+ if (gradientType === 'linear') {
|
|
|
|
+ gradientString += `${gradientAngle}deg, `
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ colors.forEach((color, i) => {
|
|
|
|
+ gradientString += `${color.color} ${color.pos}${
|
|
|
|
+ i < colors.length - 1 ? ', ' : ''
|
|
|
|
+ }`
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ gradientString += ')'
|
|
|
|
+ slideElement.style.background = gradientString
|
|
|
|
+ }
|
|
|
|
+ } else if (fill.type === 'color') {
|
|
|
|
+ slideElement.style.backgroundColor = fill.value || '#FFFFFF'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 根据元素类型创建DOM元素
|
|
|
|
+ createElementByType (element) {
|
|
|
|
+ switch (element.type) {
|
|
|
|
+ case 'image':
|
|
|
|
+ return this.createImageElement(element)
|
|
|
|
+ case 'video':
|
|
|
|
+ return this.createVideoElement(element)
|
|
|
|
+ case 'audio':
|
|
|
|
+ return this.createAudioElement(element)
|
|
|
|
+ case 'shape':
|
|
|
|
+ return this.createShapeElement(element)
|
|
|
|
+ case 'table':
|
|
|
|
+ return this.createTableElement(element)
|
|
|
|
+ case 'chart':
|
|
|
|
+ return this.createChartElement(element)
|
|
|
|
+ case 'diagram':
|
|
|
|
+ return this.createDiagramElement(element)
|
|
|
|
+ case 'math':
|
|
|
|
+ return this.createMathElement(element)
|
|
|
|
+ case 'group':
|
|
|
|
+ return this.createGroupElement(element)
|
|
|
|
+ default:
|
|
|
|
+ return this.createTextElement(element)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ createGroupElement (element) {
|
|
|
|
+ // 创建组合容器
|
|
|
|
+ const groupContainer = document.createElement('div')
|
|
|
|
+ groupContainer.className = 'group-element'
|
|
|
|
+ groupContainer.style.position = 'absolute'
|
|
|
|
+ groupContainer.style.top = element.top + 'px'
|
|
|
|
+ groupContainer.style.left = element.left + 'px'
|
|
|
|
+ groupContainer.style.width = element.width + 'px'
|
|
|
|
+ groupContainer.style.height = element.height + 'px'
|
|
|
|
+ // 移除 overflow 限制,允许子元素超出容器
|
|
|
|
+ groupContainer.style.zIndex = element.order
|
|
|
|
+ groupContainer.style.transformOrigin = 'center center'
|
|
|
|
+
|
|
|
|
+ // 创建内部容器来处理子元素
|
|
|
|
+ const innerContainer = document.createElement('div')
|
|
|
|
+ innerContainer.style.position = 'relative'
|
|
|
|
+ innerContainer.style.width = '100%'
|
|
|
|
+ innerContainer.style.height = '100%'
|
|
|
|
+
|
|
|
|
+ // 应用旋转变换
|
|
|
|
+ if (element.rotate) {
|
|
|
|
+ groupContainer.style.transform = `rotate(${element.rotate}deg)`
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 应用其他样式属性
|
|
|
|
+ if (element.opacity !== undefined) {
|
|
|
|
+ groupContainer.style.opacity = element.opacity
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 递归渲染组内的所有子元素
|
|
|
|
+ if (element.elements && Array.isArray(element.elements)) {
|
|
|
|
+ element.elements.forEach((childElement) => {
|
|
|
|
+ const childCopy = JSON.parse(JSON.stringify(childElement))
|
|
|
|
+ const childEl = this.createElementByType(childCopy)
|
|
|
|
+ if (childEl) {
|
|
|
|
+ innerContainer.appendChild(childEl)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ groupContainer.appendChild(innerContainer)
|
|
|
|
+ return groupContainer
|
|
|
|
+ },
|
|
|
|
+ // 递归调整元素位置
|
|
|
|
+ adjustElementPosition (element, parentElement) {
|
|
|
|
+ // 创建深拷贝,但保留特殊属性的引用
|
|
|
|
+ const adjustedElement = JSON.parse(JSON.stringify(element))
|
|
|
|
+
|
|
|
|
+ // 调整位置为相对于父组合元素的位置
|
|
|
|
+ adjustedElement.top = element.top - parentElement.top
|
|
|
|
+ adjustedElement.left = element.left - parentElement.left
|
|
|
|
+
|
|
|
|
+ // 恢复特殊属性的引用
|
|
|
|
+ const specialProps = [
|
|
|
|
+ 'src',
|
|
|
|
+ 'blob',
|
|
|
|
+ 'fill',
|
|
|
|
+ 'text',
|
|
|
|
+ 'path',
|
|
|
|
+ 'elements',
|
|
|
|
+ 'borderColor',
|
|
|
|
+ 'borderWidth',
|
|
|
|
+ 'borderType'
|
|
|
|
+ ]
|
|
|
|
+ specialProps.forEach((prop) => {
|
|
|
|
+ if (element[prop] !== undefined) {
|
|
|
|
+ adjustedElement[prop] = element[prop]
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ // 如果是组合元素,递归处理其子元素
|
|
|
|
+ if (element.type === 'group' && element.elements) {
|
|
|
|
+ adjustedElement.elements = element.elements.map((childElement) =>
|
|
|
|
+ this.adjustElementPosition(childElement, {
|
|
|
|
+ top: element.top,
|
|
|
|
+ left: element.left
|
|
|
|
+ })
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return adjustedElement
|
|
|
|
+ },
|
|
|
|
+ // 创建图像元素
|
|
|
|
+ createImageElement (element) {
|
|
|
|
+ const img = document.createElement('img')
|
|
|
|
+ img.src = element.src
|
|
|
|
+ img.style.width = element.width + 'px'
|
|
|
|
+ img.style.height = element.height + 'px'
|
|
|
|
+ img.style.objectFit = 'cover' // 保持图像的宽高比并填充容器
|
|
|
|
+ img.style.position = 'absolute'
|
|
|
|
+ img.style.top = `${element.top}px`
|
|
|
|
+ img.style.left = `${element.left}px`
|
|
|
|
+ img.style.zIndex = element.order
|
|
|
|
+
|
|
|
|
+ // el.appendChild(img)
|
|
|
|
+ return img
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 创建视频元素
|
|
|
|
+ createVideoElement (element) {
|
|
|
|
+ const el = document.createElement('video')
|
|
|
|
+ el.src = element.blob
|
|
|
|
+ el.controls = true
|
|
|
|
+ el.style.width = element.width + 'px'
|
|
|
|
+ el.style.height = element.height + 'px'
|
|
|
|
+ el.style.position = 'absolute'
|
|
|
|
+ el.style.top = element.top + 'px'
|
|
|
|
+ el.style.left = element.left + 'px'
|
|
|
|
+ el.style.zIndex = element.order
|
|
|
|
+ return el
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 创建音频元素
|
|
|
|
+ createAudioElement (element) {
|
|
|
|
+ const el = document.createElement('audio')
|
|
|
|
+ el.src = element.blob
|
|
|
|
+ el.controls = true
|
|
|
|
+ el.style.height = element.height + 'px'
|
|
|
|
+ el.style.position = 'absolute'
|
|
|
|
+ el.style.top = element.top + 'px'
|
|
|
|
+ el.style.left = element.left + 'px'
|
|
|
|
+ el.style.zIndex = element.order
|
|
|
|
+ return el
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 创建形状元素
|
|
|
|
+ createShapeElement (element) {
|
|
|
|
+ const el = document.createElement('div')
|
|
|
|
+ el.style.position = 'absolute'
|
|
|
|
+ el.style.top = element.top + 'px'
|
|
|
|
+ el.style.left = element.left + 'px'
|
|
|
|
+ el.style.width = element.width + 'px'
|
|
|
|
+ el.style.height = element.height + 'px'
|
|
|
|
+ el.style.zIndex = element.order
|
|
|
|
+ el.style.overflow = 'visible'
|
|
|
|
+ if (element.height === 0) {
|
|
|
|
+ // 如果高度为0,直接在div上绘制边框
|
|
|
|
+ el.style.borderTop = `${element.borderWidth || 1}px ${
|
|
|
|
+ element.borderType || 'solid'
|
|
|
|
+ } ${element.borderColor || '#000'}`
|
|
|
|
+ }
|
|
|
|
+ // 使用SVG绘制形状
|
|
|
|
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
|
|
|
+ svg.setAttribute('width', '100%')
|
|
|
|
+ svg.setAttribute('height', '100%')
|
|
|
|
+ svg.setAttribute('viewBox', `0 0 ${element.width} ${element.height}`)
|
|
|
|
+ svg.style.overflow = 'visible'
|
|
|
|
+
|
|
|
|
+ // 根据形状类型创建不同的SVG元素
|
|
|
|
+ switch (element.shapType) {
|
|
|
|
+ case 'rect':
|
|
|
|
+ const rect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'rect'
|
|
|
|
+ )
|
|
|
|
+ rect.setAttribute('x', 0)
|
|
|
|
+ rect.setAttribute('y', 0)
|
|
|
|
+ rect.setAttribute('width', element.width)
|
|
|
|
+ rect.setAttribute('height', element.height)
|
|
|
|
+ if (element.fill && element.fill.type) {
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill.type === 'color') {
|
|
|
|
+ rect.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else if (element.fill.type === 'gradient') {
|
|
|
|
+ // 渐变填充
|
|
|
|
+ const { colors, path, rot } = element.fill.value
|
|
|
|
+
|
|
|
|
+ if (colors && colors.length >= 2) {
|
|
|
|
+ const gradientType = path === 'rect' ? 'linear' : 'radial'
|
|
|
|
+ const gradientAngle =
|
|
|
|
+ gradientType === 'linear'
|
|
|
|
+ ? (90 - (rot || 0)) % 360
|
|
|
|
+ : rot || 0
|
|
|
|
+
|
|
|
|
+ let gradientString = `${gradientType}-gradient(`
|
|
|
|
+ if (gradientType === 'linear') {
|
|
|
|
+ gradientString += `${gradientAngle}deg, `
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ colors.forEach((color, i) => {
|
|
|
|
+ gradientString += `${color.color} ${color.pos}${
|
|
|
|
+ i < colors.length - 1 ? ', ' : ''
|
|
|
|
+ }`
|
|
|
|
+ })
|
|
|
|
+ gradientString += ')'
|
|
|
|
+
|
|
|
|
+ // 创建渐变定义
|
|
|
|
+ const gradientDef = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'defs'
|
|
|
|
+ )
|
|
|
|
+ const gradientEl = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ gradientType === 'linear'
|
|
|
|
+ ? 'linearGradient'
|
|
|
|
+ : 'radialGradient'
|
|
|
|
+ )
|
|
|
|
+ const gradientId = `gradient-${Date.now()}-${Math.random()
|
|
|
|
+ .toString(36)
|
|
|
|
+ .substr(2, 9)}`
|
|
|
|
+ gradientEl.setAttribute('id', gradientId)
|
|
|
|
+
|
|
|
|
+ // 设置渐变属性
|
|
|
|
+ if (gradientType === 'linear') {
|
|
|
|
+ gradientEl.setAttribute(
|
|
|
|
+ 'gradientTransform',
|
|
|
|
+ `rotate(${gradientAngle})`
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加渐变色标
|
|
|
|
+ colors.forEach((color) => {
|
|
|
|
+ const stop = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'stop'
|
|
|
|
+ )
|
|
|
|
+ stop.setAttribute('offset', color.pos)
|
|
|
|
+ stop.setAttribute('stop-color', color.color)
|
|
|
|
+ gradientEl.appendChild(stop)
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ gradientDef.appendChild(gradientEl)
|
|
|
|
+ svg.appendChild(gradientDef)
|
|
|
|
+
|
|
|
|
+ // 应用渐变
|
|
|
|
+ rect.setAttribute('fill', `url(#${gradientId})`)
|
|
|
|
+ }
|
|
|
|
+ } else if (element.fill.type === 'image') {
|
|
|
|
+ // 创建图案填充
|
|
|
|
+ const pattern = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'pattern'
|
|
|
|
+ )
|
|
|
|
+ const patternId = `pattern-${Date.now()}-${Math.random()
|
|
|
|
+ .toString(36)
|
|
|
|
+ .substr(2, 9)}`
|
|
|
|
+ pattern.setAttribute('id', patternId)
|
|
|
|
+ pattern.setAttribute('patternUnits', 'userSpaceOnUse')
|
|
|
|
+ pattern.setAttribute('width', '100%')
|
|
|
|
+ pattern.setAttribute('height', '100%')
|
|
|
|
+
|
|
|
|
+ // 创建图片元素
|
|
|
|
+ const image = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'image'
|
|
|
|
+ )
|
|
|
|
+ image.setAttribute('width', '100%')
|
|
|
|
+ image.setAttribute('height', '100%')
|
|
|
|
+ image.setAttribute('preserveAspectRatio', 'xMidYMid slice')
|
|
|
|
+ image.setAttributeNS(
|
|
|
|
+ 'http://www.w3.org/1999/xlink',
|
|
|
|
+ 'href',
|
|
|
|
+ element.fill.value.picBase64
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ pattern.appendChild(image)
|
|
|
|
+
|
|
|
|
+ // 添加pattern到defs
|
|
|
|
+ const defs = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'defs'
|
|
|
|
+ )
|
|
|
|
+ defs.appendChild(pattern)
|
|
|
|
+ svg.appendChild(defs)
|
|
|
|
+
|
|
|
|
+ // 应用图案填充
|
|
|
|
+ rect.setAttribute('fill', `url(#${patternId})`)
|
|
|
|
+ } else {
|
|
|
|
+ console.log('element.fill', element.fill)
|
|
|
|
+ rect.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ rect.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ rect.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ rect.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ rect.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ rect.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(rect)
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+ case 'roundRect':
|
|
|
|
+ const radius = Math.min(element.width, element.height) * 0.1
|
|
|
|
+ const roundRect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'rect'
|
|
|
|
+ )
|
|
|
|
+ roundRect.setAttribute('x', 0)
|
|
|
|
+ roundRect.setAttribute('y', 0)
|
|
|
|
+ roundRect.setAttribute('width', element.width)
|
|
|
|
+ roundRect.setAttribute('height', element.height)
|
|
|
|
+ roundRect.setAttribute('rx', radius)
|
|
|
|
+ roundRect.setAttribute('ry', radius)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ roundRect.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ roundRect.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ roundRect.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ roundRect.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+ roundRect.setAttribute('stroke-linejoin', 'round') // 设置连接处为圆角
|
|
|
|
+ roundRect.setAttribute('vector-effect', 'non-scaling-stroke') // 防止边框宽度变形
|
|
|
|
+ roundRect.setAttribute('shape-rendering', 'geometricPrecision') // 提高渲染精度
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ roundRect.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ roundRect.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ roundRect.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(roundRect)
|
|
|
|
+ break
|
|
|
|
+ case 'snip1Rect':
|
|
|
|
+ // 使用path元素绘制剪去单角的矩形
|
|
|
|
+ const snip1Rect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算剪角的大小,通常为矩形较短边的20%
|
|
|
|
+ const snipSize = Math.min(element.width, element.height) * 0.35
|
|
|
|
+
|
|
|
|
+ // 绘制路径:从左上角开始,顺时针方向,右上角被剪去
|
|
|
|
+ snip1Rect.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,0 ` +
|
|
|
|
+ `L${element.width - snipSize},0 ` +
|
|
|
|
+ `L${element.width},${snipSize} ` +
|
|
|
|
+ `L${element.width},${element.height} ` +
|
|
|
|
+ `L0,${element.height} ` +
|
|
|
|
+ `Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ snip1Rect.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ snip1Rect.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ snip1Rect.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ snip1Rect.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ snip1Rect.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ snip1Rect.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ snip1Rect.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ svg.appendChild(snip1Rect)
|
|
|
|
+ break
|
|
|
|
+ case 'snip2SameRect':
|
|
|
|
+ // 使用path元素绘制剪去四个角的矩形
|
|
|
|
+ const snip2SameRect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算剪角的大小,通常为矩形较短边的20%
|
|
|
|
+ const snip2Size = Math.min(element.width, element.height) * 0.35
|
|
|
|
+
|
|
|
|
+ // 绘制路径:从左上角开始,顺时针方向,剪去四个角
|
|
|
|
+ snip2SameRect.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${snip2Size},0 ` +
|
|
|
|
+ `L${element.width - snip2Size},0 ` +
|
|
|
|
+ `L${element.width},${snip2Size} ` +
|
|
|
|
+ `L${element.width},${element.height - snip2Size} ` +
|
|
|
|
+ `L${element.width - snip2Size},${element.height} ` +
|
|
|
|
+ `L${snip2Size},${element.height} ` +
|
|
|
|
+ `L0,${element.height - snip2Size} ` +
|
|
|
|
+ `L0,${snip2Size} ` +
|
|
|
|
+ `Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ snip2SameRect.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ snip2SameRect.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ snip2SameRect.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ snip2SameRect.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ snip2SameRect.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ snip2SameRect.setAttribute('stroke-dasharray', '2, 2')
|
|
|
|
+ snip2SameRect.setAttribute('stroke-linecap', 'round')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ snip2SameRect.setAttribute('stroke-dasharray', '6, 3')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加这些属性以确保边框正确渲染
|
|
|
|
+ snip2SameRect.setAttribute('vector-effect', 'non-scaling-stroke')
|
|
|
|
+ snip2SameRect.setAttribute('shape-rendering', 'geometricPrecision')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(snip2SameRect)
|
|
|
|
+ break
|
|
|
|
+ case 'line':
|
|
|
|
+ // 创建直线连接符
|
|
|
|
+ const line = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'line'
|
|
|
|
+ )
|
|
|
|
+ // 设置SVG的最小高度为1px
|
|
|
|
+ const svgHeight = element.height > 0 ? element.height : 1
|
|
|
|
+ svg.setAttribute('height', svgHeight + 'px')
|
|
|
|
+
|
|
|
|
+ // 设置线条的起点和终点
|
|
|
|
+ line.setAttribute('x1', 0)
|
|
|
|
+ line.setAttribute('y1', 0)
|
|
|
|
+ line.setAttribute('x2', element.width)
|
|
|
|
+ line.setAttribute('y2', svgHeight)
|
|
|
|
+
|
|
|
|
+ // 确保边框颜色和宽度被正确设置
|
|
|
|
+ line.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ line.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线样式
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ line.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ line.setAttribute('stroke-dasharray', '2, 2')
|
|
|
|
+ line.setAttribute('stroke-linecap', 'round') // 添加圆角端点使点线更明显
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ line.setAttribute('stroke-dasharray', '6, 3')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 确保线条正确渲染
|
|
|
|
+ line.setAttribute('vector-effect', 'non-scaling-stroke') // 防止缩放影响线条宽度
|
|
|
|
+ svg.appendChild(line)
|
|
|
|
+ break
|
|
|
|
+ case 'snip2DiagRect':
|
|
|
|
+ // 使用path元素绘制剪去右上角和左下角的矩形
|
|
|
|
+ const snip2DiagRect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算剪角的大小,通常为矩形较短边的35%
|
|
|
|
+ const snipDiagSize = Math.min(element.width, element.height) * 0.35
|
|
|
|
+
|
|
|
|
+ // 绘制路径:从左上角开始,顺时针方向,右上角和左下角被剪去
|
|
|
|
+ snip2DiagRect.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,0 ` +
|
|
|
|
+ `L${element.width - snipDiagSize},0 ` +
|
|
|
|
+ `L${element.width},${snipDiagSize} ` +
|
|
|
|
+ `L${element.width},${element.height} ` +
|
|
|
|
+ `L${snipDiagSize},${element.height} ` +
|
|
|
|
+ `L0,${element.height - snipDiagSize} ` +
|
|
|
|
+ `Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ snip2DiagRect.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ snip2DiagRect.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ snip2DiagRect.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ snip2DiagRect.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ snip2DiagRect.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ snip2DiagRect.setAttribute('stroke-dasharray', '2, 2')
|
|
|
|
+ snip2DiagRect.setAttribute('stroke-linecap', 'round')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ snip2DiagRect.setAttribute('stroke-dasharray', '6, 3')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加这些属性以确保边框正确渲染
|
|
|
|
+ snip2DiagRect.setAttribute('vector-effect', 'non-scaling-stroke')
|
|
|
|
+ snip2DiagRect.setAttribute('shape-rendering', 'geometricPrecision')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(snip2DiagRect)
|
|
|
|
+ break
|
|
|
|
+ case 'snipRoundRect':
|
|
|
|
+ const snipRoundRect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ // 计算剪切大小和圆角大小
|
|
|
|
+ const snipSize2 = Math.min(element.width, element.height) * 0.4
|
|
|
|
+ const roundSize = Math.min(element.width, element.height) * 0.5
|
|
|
|
+
|
|
|
|
+ // 绘制路径:从左上角开始,顺时针方向,左上为圆角,右上为剪切角
|
|
|
|
+ snipRoundRect.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${roundSize},0 ` +
|
|
|
|
+ `L${element.width - snipSize2},0 ` +
|
|
|
|
+ `L${element.width},${snipSize2} ` +
|
|
|
|
+ `L${element.width},${element.height} ` +
|
|
|
|
+ `L0,${element.height} ` +
|
|
|
|
+ `L0,${roundSize} ` +
|
|
|
|
+ `A${roundSize},${roundSize} 0 0,1 ${roundSize},0 ` +
|
|
|
|
+ `Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色和边框属性
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ snipRoundRect.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ snipRoundRect.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ snipRoundRect.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ snipRoundRect.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ snipRoundRect.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ snipRoundRect.setAttribute('stroke-dasharray', '2, 2')
|
|
|
|
+ snipRoundRect.setAttribute('stroke-linecap', 'round')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ snipRoundRect.setAttribute('stroke-dasharray', '6, 3')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ snipRoundRect.setAttribute('vector-effect', 'non-scaling-stroke')
|
|
|
|
+ snipRoundRect.setAttribute('shape-rendering', 'geometricPrecision')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(snipRoundRect)
|
|
|
|
+ break
|
|
|
|
+ case 'round1Rect':
|
|
|
|
+ const round1Rect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ // 计算圆角大小
|
|
|
|
+ const round1Size = Math.min(element.width, element.height) * 0.5
|
|
|
|
+
|
|
|
|
+ // 绘制路径:从左上角开始,顺时针方向,右上角为圆角
|
|
|
|
+ round1Rect.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,0 ` +
|
|
|
|
+ `L${element.width - round1Size},0 ` +
|
|
|
|
+ `Q${element.width},0 ${element.width},${round1Size} ` +
|
|
|
|
+ `L${element.width},${element.height} ` +
|
|
|
|
+ `L0,${element.height} ` +
|
|
|
|
+ `Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ round1Rect.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ round1Rect.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ round1Rect.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ round1Rect.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ round1Rect.setAttribute('stroke-dasharray', '40,15,5,15')
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ round1Rect.setAttribute('stroke-dasharray', '2, 2')
|
|
|
|
+ round1Rect.setAttribute('stroke-linecap', 'round')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ round1Rect.setAttribute('stroke-dasharray', '6, 3')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ round1Rect.setAttribute('vector-effect', 'non-scaling-stroke')
|
|
|
|
+ round1Rect.setAttribute('shape-rendering', 'geometricPrecision')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(round1Rect)
|
|
|
|
+ break
|
|
|
|
+ case 'ellipse':
|
|
|
|
+ case 'circle':
|
|
|
|
+ const ellipse = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'ellipse'
|
|
|
|
+ )
|
|
|
|
+ ellipse.setAttribute('cx', element.width / 2)
|
|
|
|
+ ellipse.setAttribute('cy', element.height / 2)
|
|
|
|
+ ellipse.setAttribute('rx', element.width / 2)
|
|
|
|
+ ellipse.setAttribute('ry', element.height / 2)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ ellipse.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ ellipse.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ ellipse.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ ellipse.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ ellipse.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ ellipse.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ ellipse.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(ellipse)
|
|
|
|
+ break
|
|
|
|
+ case 'round2SameRect':
|
|
|
|
+ const round2SameRect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ // 计算圆角大小
|
|
|
|
+ const round2Size = Math.min(element.width, element.height) * 0.5
|
|
|
|
+
|
|
|
|
+ // 绘制路径:从左上角开始,顺时针方向,左上和右上为圆角
|
|
|
|
+ round2SameRect.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${round2Size},0 ` +
|
|
|
|
+ `L${element.width - round2Size},0 ` +
|
|
|
|
+ `Q${element.width},0 ${element.width},${round2Size} ` +
|
|
|
|
+ `L${element.width},${element.height} ` +
|
|
|
|
+ `L0,${element.height} ` +
|
|
|
|
+ `L0,${round2Size} ` +
|
|
|
|
+ `Q0,0 ${round2Size},0 ` +
|
|
|
|
+ `Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ round2SameRect.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ round2SameRect.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ round2SameRect.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ round2SameRect.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ round2SameRect.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ round2SameRect.setAttribute('stroke-dasharray', '2, 2')
|
|
|
|
+ round2SameRect.setAttribute('stroke-linecap', 'round')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ round2SameRect.setAttribute('stroke-dasharray', '6, 3')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ round2SameRect.setAttribute('vector-effect', 'non-scaling-stroke')
|
|
|
|
+ round2SameRect.setAttribute(
|
|
|
|
+ 'shape-rendering',
|
|
|
|
+ 'geometricPrecision'
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(round2SameRect)
|
|
|
|
+ break
|
|
|
|
+ case 'round2DiagRect':
|
|
|
|
+ const round2DiagRect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ // 计算圆角大小
|
|
|
|
+ const round2DiagSize = Math.min(element.width, element.height) * 0.5
|
|
|
|
+
|
|
|
|
+ // 绘制路径:从左上角开始,顺时针方向,左上和右下为圆角
|
|
|
|
+ round2DiagRect.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${round2DiagSize},0 ` +
|
|
|
|
+ `L${element.width},0 ` +
|
|
|
|
+ `L${element.width},${element.height - round2DiagSize} ` +
|
|
|
|
+ `Q${element.width},${element.height} ${
|
|
|
|
+ element.width - round2DiagSize
|
|
|
|
+ },${element.height} ` +
|
|
|
|
+ `L0,${element.height} ` +
|
|
|
|
+ `L0,${round2DiagSize} ` +
|
|
|
|
+ `Q0,0 ${round2DiagSize},0 ` +
|
|
|
|
+ `Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ round2DiagRect.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ round2DiagRect.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ round2DiagRect.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ round2DiagRect.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ round2DiagRect.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ round2DiagRect.setAttribute('stroke-dasharray', '2, 2')
|
|
|
|
+ round2DiagRect.setAttribute('stroke-linecap', 'round')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ round2DiagRect.setAttribute('stroke-dasharray', '6, 3')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ round2DiagRect.setAttribute('vector-effect', 'non-scaling-stroke')
|
|
|
|
+ round2DiagRect.setAttribute(
|
|
|
|
+ 'shape-rendering',
|
|
|
|
+ 'geometricPrecision'
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(round2DiagRect)
|
|
|
|
+ break
|
|
|
|
+ case 'triangle':
|
|
|
|
+ const triangle = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ triangle.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width / 2},0 ${element.width},${element.height} 0,${
|
|
|
|
+ element.height
|
|
|
|
+ }`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ triangle.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ triangle.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ triangle.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ triangle.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ triangle.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ triangle.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ triangle.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(triangle)
|
|
|
|
+ break
|
|
|
|
+ case 'custom':
|
|
|
|
+ const customPath = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 直接使用传入的 path 数据
|
|
|
|
+ customPath.setAttribute('d', element.path || '')
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ customPath.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ customPath.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ customPath.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ customPath.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ customPath.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ customPath.setAttribute('stroke-dasharray', '2, 2')
|
|
|
|
+ customPath.setAttribute('stroke-linecap', 'round')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ customPath.setAttribute('stroke-dasharray', '6, 3')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ customPath.setAttribute('vector-effect', 'non-scaling-stroke')
|
|
|
|
+ customPath.setAttribute('shape-rendering', 'geometricPrecision')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(customPath)
|
|
|
|
+ break
|
|
|
|
+ case 'teardrop':
|
|
|
|
+ const teardrop = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算泪珠形状的参数 - 调整为正确的泪滴形状
|
|
|
|
+ const tdCenterX = element.width / 2
|
|
|
|
+ const tdCenterY = element.height / 2
|
|
|
|
+ const tdRadiusX = element.width * 0.5
|
|
|
|
+ const tdRadiusY = element.height * 0.5
|
|
|
|
+
|
|
|
|
+ // 绘制泪珠形状:根据第二张图的正确形状
|
|
|
|
+ teardrop.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${tdCenterX},${element.height} ` +
|
|
|
|
+ `C${tdCenterX - tdRadiusX * 0.8},${element.height * 0.7} ` +
|
|
|
|
+ `${tdCenterX - tdRadiusX},${element.height * 0.4} ` +
|
|
|
|
+ `${tdCenterX},${element.height * 0.1} ` +
|
|
|
|
+ `C${tdCenterX + tdRadiusX},${element.height * 0.4} ` +
|
|
|
|
+ `${tdCenterX + tdRadiusX * 0.8},${element.height * 0.7} ` +
|
|
|
|
+ `${tdCenterX},${element.height} ` +
|
|
|
|
+ `Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ teardrop.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ teardrop.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ teardrop.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ teardrop.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ teardrop.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ teardrop.setAttribute('stroke-dasharray', '2, 2')
|
|
|
|
+ teardrop.setAttribute('stroke-linecap', 'round')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ teardrop.setAttribute('stroke-dasharray', '6, 3')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ teardrop.setAttribute('vector-effect', 'non-scaling-stroke')
|
|
|
|
+ teardrop.setAttribute('shape-rendering', 'geometricPrecision')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(teardrop)
|
|
|
|
+ break
|
|
|
|
+ case 'decagon':
|
|
|
|
+ const decagon = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算十边形的顶点
|
|
|
|
+ let decagonPoints = ''
|
|
|
|
+ for (let i = 0; i < 10; i++) {
|
|
|
|
+ const angle = (i * 2 * Math.PI) / 10 - Math.PI / 2 // 从顶部开始
|
|
|
|
+ const x = element.width / 2 + (element.width / 2) * Math.cos(angle)
|
|
|
|
+ const y =
|
|
|
|
+ element.height / 2 + (element.height / 2) * Math.sin(angle)
|
|
|
|
+ decagonPoints += `${x},${y} `
|
|
|
|
+ }
|
|
|
|
+ decagon.setAttribute('points', decagonPoints.trim())
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ decagon.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ decagon.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ decagon.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ decagon.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ decagon.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ decagon.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ decagon.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(decagon)
|
|
|
|
+ break
|
|
|
|
+ case 'pentagon':
|
|
|
|
+ const pentagon = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ pentagon.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width / 2},0 ${element.width},${
|
|
|
|
+ element.height * 0.38
|
|
|
|
+ } ` +
|
|
|
|
+ `${element.width * 0.82},${element.height} ${
|
|
|
|
+ element.width * 0.18
|
|
|
|
+ },${element.height} ` +
|
|
|
|
+ `0,${element.height * 0.38}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ pentagon.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ pentagon.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ pentagon.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ pentagon.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ pentagon.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ pentagon.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ pentagon.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(pentagon)
|
|
|
|
+ break
|
|
|
|
+ case 'pie':
|
|
|
|
+ const pie = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 使用提供的路径数据,但保留元素的宽高比例
|
|
|
|
+ const centerX = element.width / 2
|
|
|
|
+ const centerY = element.height / 2
|
|
|
|
+ const radius2 = Math.min(element.width, element.height) / 2
|
|
|
|
+
|
|
|
|
+ // 绘制饼图,使用类似提供的路径数据
|
|
|
|
+ pie.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${centerX},${centerY} ` +
|
|
|
|
+ `L${centerX * 1.85},${centerY * 1.52} ` +
|
|
|
|
+ `A${radius2},${radius2} 0 1,1 ${centerX * 1.56},${
|
|
|
|
+ centerY * 0.17
|
|
|
|
+ } ` +
|
|
|
|
+ `Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ pie.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ pie.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ pie.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ pie.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ pie.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ pie.setAttribute('stroke-dasharray', '2, 2')
|
|
|
|
+ pie.setAttribute('stroke-linecap', 'round')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ pie.setAttribute('stroke-dasharray', '6, 3')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pie.setAttribute('vector-effect', 'non-scaling-stroke')
|
|
|
|
+ pie.setAttribute('shape-rendering', 'geometricPrecision')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(pie)
|
|
|
|
+ break
|
|
|
|
+ case 'chord':
|
|
|
|
+ const chord = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算弦形的参数
|
|
|
|
+ const chordRadiusX = element.width * 0.4
|
|
|
|
+ const chordRadiusY = element.height * 0.4
|
|
|
|
+ // 绘制弦形 - 使用更大的圆弧和不同的起始/结束点
|
|
|
|
+ chord.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${element.width * 0.4},${element.height * 0.9} ` +
|
|
|
|
+ `A ${chordRadiusX} ${chordRadiusY} 0 1 1 ${element.width * 0.8},${
|
|
|
|
+ element.height * 0.5
|
|
|
|
+ } ` +
|
|
|
|
+ `Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ chord.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ chord.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ chord.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ chord.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ chord.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ chord.setAttribute('stroke-dasharray', '2, 2')
|
|
|
|
+ chord.setAttribute('stroke-linecap', 'round')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ chord.setAttribute('stroke-dasharray', '6, 3')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ chord.setAttribute('vector-effect', 'non-scaling-stroke')
|
|
|
|
+ chord.setAttribute('shape-rendering', 'geometricPrecision')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(chord)
|
|
|
|
+ break
|
|
|
|
+ case 'heptagon':
|
|
|
|
+ const heptagon = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算七边形的顶点
|
|
|
|
+ let heptagonPoints = ''
|
|
|
|
+ for (let i = 0; i < 7; i++) {
|
|
|
|
+ const angle = (i * 2 * Math.PI) / 7 - Math.PI / 2 // 从顶部开始
|
|
|
|
+ const x = element.width / 2 + (element.width / 2) * Math.cos(angle)
|
|
|
|
+ const y =
|
|
|
|
+ element.height / 2 + (element.height / 2) * Math.sin(angle)
|
|
|
|
+ heptagonPoints += `${x},${y} `
|
|
|
|
+ }
|
|
|
|
+ heptagon.setAttribute('points', heptagonPoints.trim())
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ heptagon.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ heptagon.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ heptagon.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ heptagon.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ heptagon.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ heptagon.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ heptagon.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(heptagon)
|
|
|
|
+ break
|
|
|
|
+ case 'hexagon':
|
|
|
|
+ const hexagon = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ hexagon.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width * 0.25},0 ${element.width * 0.75},0 ${
|
|
|
|
+ element.width
|
|
|
|
+ },${element.height * 0.5} ` +
|
|
|
|
+ `${element.width * 0.75},${element.height} ${
|
|
|
|
+ element.width * 0.25
|
|
|
|
+ },${element.height} 0,${element.height * 0.5}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ hexagon.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ hexagon.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ hexagon.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ hexagon.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ hexagon.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ hexagon.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ hexagon.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(hexagon)
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+ case 'octagon':
|
|
|
|
+ const octagon = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ octagon.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width * 0.3},0 ${element.width * 0.7},0 ${
|
|
|
|
+ element.width
|
|
|
|
+ },${element.height * 0.3} ` +
|
|
|
|
+ `${element.width},${element.height * 0.7} ${
|
|
|
|
+ element.width * 0.7
|
|
|
|
+ },${element.height} ` +
|
|
|
|
+ `${element.width * 0.3},${element.height} 0,${
|
|
|
|
+ element.height * 0.7
|
|
|
|
+ } 0,${element.height * 0.3}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ octagon.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ octagon.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ octagon.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ octagon.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ octagon.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ octagon.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ octagon.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(octagon)
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+ case 'trapezoid':
|
|
|
|
+ const trapezoid = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ trapezoid.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width * 0.2},0 ${element.width * 0.8},0 ${
|
|
|
|
+ element.width
|
|
|
|
+ },${element.height} 0,${element.height}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ trapezoid.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ trapezoid.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ trapezoid.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ trapezoid.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ trapezoid.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ trapezoid.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ trapezoid.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(trapezoid)
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+ case 'diamond':
|
|
|
|
+ const diamond = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ diamond.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width / 2},0 ${element.width},${element.height / 2} ${
|
|
|
|
+ element.width / 2
|
|
|
|
+ },${element.height} 0,${element.height / 2}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ diamond.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ diamond.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ diamond.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ diamond.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ diamond.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ diamond.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ diamond.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(diamond)
|
|
|
|
+ break
|
|
|
|
+ case 'dodecagon':
|
|
|
|
+ const dodecagon = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算十二边形的顶点
|
|
|
|
+ let dodecagonPoints = ''
|
|
|
|
+ for (let i = 0; i < 12; i++) {
|
|
|
|
+ const angle = (i * 2 * Math.PI) / 12 - Math.PI / 2 // 从顶部开始
|
|
|
|
+ const x = element.width / 2 + (element.width / 2) * Math.cos(angle)
|
|
|
|
+ const y =
|
|
|
|
+ element.height / 2 + (element.height / 2) * Math.sin(angle)
|
|
|
|
+ dodecagonPoints += `${x},${y} `
|
|
|
|
+ }
|
|
|
|
+ dodecagon.setAttribute('points', dodecagonPoints.trim())
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ dodecagon.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ dodecagon.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ dodecagon.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ dodecagon.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ dodecagon.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ dodecagon.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ dodecagon.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(dodecagon)
|
|
|
|
+ break
|
|
|
|
+ case 'halfFrame':
|
|
|
|
+ // 创建外框和内框
|
|
|
|
+ const outerRect2 = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ const innerRect2 = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算内框的边距
|
|
|
|
+ const frameWidth2 = element.width / 9
|
|
|
|
+
|
|
|
|
+ // 绘制外框的左边和上边
|
|
|
|
+ outerRect2.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,${element.height} L0,0 L${element.width},0`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 绘制内框的左边和上边,注意起点位置调整
|
|
|
|
+ innerRect2.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${frameWidth2},${element.height - frameWidth2} ` +
|
|
|
|
+ `L${frameWidth2},${frameWidth2} ` +
|
|
|
|
+ `L${element.width - frameWidth2},${frameWidth2}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ // 创建一个填充用的路径
|
|
|
|
+ const fillPath = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ fillPath.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${frameWidth2},${frameWidth2} ` +
|
|
|
|
+ `L${element.width - frameWidth2},${frameWidth2} ` +
|
|
|
|
+ `L${element.width},0 ` +
|
|
|
|
+ `L0,0 ` +
|
|
|
|
+ `L0,${element.height} ` +
|
|
|
|
+ `L${frameWidth2},${element.height - frameWidth2} Z`
|
|
|
|
+ )
|
|
|
|
+ fillPath.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ svg.appendChild(fillPath)
|
|
|
|
+
|
|
|
|
+ outerRect2.setAttribute('fill', 'none')
|
|
|
|
+ innerRect2.setAttribute('fill', 'none')
|
|
|
|
+ } else {
|
|
|
|
+ outerRect2.setAttribute('fill', 'none')
|
|
|
|
+ innerRect2.setAttribute('fill', 'none')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ const borderColor = element.borderColor || '#000'
|
|
|
|
+ const borderWidth = element.borderWidth || 1
|
|
|
|
+
|
|
|
|
+ outerRect2.setAttribute('stroke', borderColor)
|
|
|
|
+ outerRect2.setAttribute('stroke-width', borderWidth)
|
|
|
|
+ innerRect2.setAttribute('stroke', borderColor)
|
|
|
|
+ innerRect2.setAttribute('stroke-width', borderWidth)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ const dashArray = element.borderStrokeDasharray
|
|
|
|
+ outerRect2.setAttribute('stroke-dasharray', dashArray)
|
|
|
|
+ innerRect2.setAttribute('stroke-dasharray', dashArray)
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ outerRect2.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ innerRect2.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ outerRect2.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ innerRect2.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(outerRect2)
|
|
|
|
+ svg.appendChild(innerRect2)
|
|
|
|
+ break
|
|
|
|
+ case 'corner':
|
|
|
|
+ const corner = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ corner.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,0 ` +
|
|
|
|
+ `L0,${element.height} ` +
|
|
|
|
+ `L${element.width},${element.height} ` +
|
|
|
|
+ `L${element.width},${element.height * 0.6} ` +
|
|
|
|
+ `L${element.width * 0.4},${element.height * 0.6} ` +
|
|
|
|
+ `L${element.width * 0.4},0 Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ corner.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ corner.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ corner.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ corner.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ corner.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ corner.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ corner.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(corner)
|
|
|
|
+ break
|
|
|
|
+ case 'diagStripe':
|
|
|
|
+ const diagStripe = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 绘制斜纹路径
|
|
|
|
+ diagStripe.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${element.width * 0.4},0 ` +
|
|
|
|
+ `L${element.width},0 ` +
|
|
|
|
+ `L0,${element.height} ` +
|
|
|
|
+ `L0,${element.height * 0.4} Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ diagStripe.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ diagStripe.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ diagStripe.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ diagStripe.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+ diagStripe.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ diagStripe.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ diagStripe.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ diagStripe.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(diagStripe)
|
|
|
|
+ break
|
|
|
|
+ case 'plus':
|
|
|
|
+ const plus = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ plus.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width * 0.4},0 ` +
|
|
|
|
+ `${element.width * 0.6},0 ` +
|
|
|
|
+ `${element.width * 0.6},${element.height * 0.4} ` +
|
|
|
|
+ `${element.width},${element.height * 0.4} ` +
|
|
|
|
+ `${element.width},${element.height * 0.6} ` +
|
|
|
|
+ `${element.width * 0.6},${element.height * 0.6} ` +
|
|
|
|
+ `${element.width * 0.6},${element.height} ` +
|
|
|
|
+ `${element.width * 0.4},${element.height} ` +
|
|
|
|
+ `${element.width * 0.4},${element.height * 0.6} ` +
|
|
|
|
+ `0,${element.height * 0.6} ` +
|
|
|
|
+ `0,${element.height * 0.4} ` +
|
|
|
|
+ `${element.width * 0.4},${element.height * 0.4}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ plus.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ plus.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ plus.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ plus.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ plus.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ plus.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ plus.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(plus)
|
|
|
|
+ break
|
|
|
|
+ case 'can':
|
|
|
|
+ const can = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'g'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 创建圆柱体的主体部分
|
|
|
|
+ const cylinderBody = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ cylinderBody.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,${element.height * 0.15} ` +
|
|
|
|
+ `A${element.width / 2},${element.height * 0.15} 0 0 1 ${
|
|
|
|
+ element.width
|
|
|
|
+ },${element.height * 0.15} ` +
|
|
|
|
+ `V${element.height * 0.85} ` +
|
|
|
|
+ `A${element.width / 2},${element.height * 0.15} 0 0 1 0,${
|
|
|
|
+ element.height * 0.85
|
|
|
|
+ } Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 创建顶部椭圆
|
|
|
|
+ const topEllipse = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'ellipse'
|
|
|
|
+ )
|
|
|
|
+ topEllipse.setAttribute('cx', element.width / 2)
|
|
|
|
+ topEllipse.setAttribute('cy', element.height * 0.15)
|
|
|
|
+ topEllipse.setAttribute('rx', element.width / 2)
|
|
|
|
+ topEllipse.setAttribute('ry', element.height * 0.15)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ cylinderBody.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ topEllipse.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ cylinderBody.setAttribute('fill', 'transparent')
|
|
|
|
+ topEllipse.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ const borderColor = element.borderColor || '#000'
|
|
|
|
+ const borderWidth = element.borderWidth || 1
|
|
|
|
+
|
|
|
|
+ cylinderBody.setAttribute('stroke', borderColor)
|
|
|
|
+ cylinderBody.setAttribute('stroke-width', borderWidth)
|
|
|
|
+ topEllipse.setAttribute('stroke', borderColor)
|
|
|
|
+ topEllipse.setAttribute('stroke-width', borderWidth)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ const dashArray = element.borderStrokeDasharray
|
|
|
|
+ cylinderBody.setAttribute('stroke-dasharray', dashArray)
|
|
|
|
+ topEllipse.setAttribute('stroke-dasharray', dashArray)
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ cylinderBody.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ topEllipse.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ cylinderBody.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ topEllipse.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ can.appendChild(cylinderBody)
|
|
|
|
+ can.appendChild(topEllipse)
|
|
|
|
+ svg.appendChild(can)
|
|
|
|
+ break
|
|
|
|
+ case 'cube':
|
|
|
|
+ const cube = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'g'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算关键点坐标
|
|
|
|
+ const offset = element.width * 0.2
|
|
|
|
+ const frontX = offset
|
|
|
|
+ const frontY = offset
|
|
|
|
+ const frontW = element.width - offset
|
|
|
|
+ const frontH = element.height
|
|
|
|
+
|
|
|
|
+ // 设置立方体的三个面的路径
|
|
|
|
+ const frontFace = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ frontFace.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${frontX},${frontY} ` +
|
|
|
|
+ `L${frontW},${frontY} ` +
|
|
|
|
+ `L${frontW},${frontH} ` +
|
|
|
|
+ `L${frontX},${frontH} Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ const rightFace = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ rightFace.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${frontW},${frontY} ` +
|
|
|
|
+ `L${element.width},0 ` +
|
|
|
|
+ `L${element.width},${element.height - offset} ` +
|
|
|
|
+ `L${frontW},${frontH} Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ const topFace = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ topFace.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${frontX},${frontY} ` +
|
|
|
|
+ `L${frontW - offset - frontX},0 ` + // 修改这里:改为从(0,0)开始
|
|
|
|
+ `L${element.width - offset},0 ` + // 修改这里:使用 offset 来计算右上角的位置
|
|
|
|
+ `L${element.width},0 ` +
|
|
|
|
+ `L${frontW},${frontY} Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ const fillColor = element.fill.value || 'transparent'
|
|
|
|
+ frontFace.setAttribute('fill', fillColor)
|
|
|
|
+ rightFace.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ this.adjustBrightness(fillColor, 0.8)
|
|
|
|
+ )
|
|
|
|
+ topFace.setAttribute('fill', this.adjustBrightness(fillColor, 1.2))
|
|
|
|
+ } else {
|
|
|
|
+ frontFace.setAttribute('fill', 'transparent')
|
|
|
|
+ rightFace.setAttribute('fill', 'transparent')
|
|
|
|
+ topFace.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ const borderColor = element.borderColor || '#000'
|
|
|
|
+ const borderWidth = element.borderWidth || 1
|
|
|
|
+
|
|
|
|
+ frontFace.setAttribute('stroke', borderColor)
|
|
|
|
+ frontFace.setAttribute('stroke-width', borderWidth)
|
|
|
|
+ rightFace.setAttribute('stroke', borderColor)
|
|
|
|
+ rightFace.setAttribute('stroke-width', borderWidth)
|
|
|
|
+ topFace.setAttribute('stroke', borderColor)
|
|
|
|
+ topFace.setAttribute('stroke-width', borderWidth)
|
|
|
|
+
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ const dashArray =
|
|
|
|
+ element.borderStrokeDasharray ||
|
|
|
|
+ (element.borderType === 'dotted' ? '1, 3' : '5, 5')
|
|
|
|
+ frontFace.setAttribute('stroke-dasharray', dashArray)
|
|
|
|
+ rightFace.setAttribute('stroke-dasharray', dashArray)
|
|
|
|
+ topFace.setAttribute('stroke-dasharray', dashArray)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 按正确的顺序添加面(从后到前)
|
|
|
|
+ cube.appendChild(rightFace)
|
|
|
|
+ cube.appendChild(topFace)
|
|
|
|
+ cube.appendChild(frontFace)
|
|
|
|
+ svg.appendChild(cube)
|
|
|
|
+ break
|
|
|
|
+ case 'bevel':
|
|
|
|
+ const bevel = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'g'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算关键点坐标
|
|
|
|
+ const bevelOffset = element.width * 0.2
|
|
|
|
+ const smallRectX = bevelOffset
|
|
|
|
+ const smallRectY = bevelOffset
|
|
|
|
+ const smallRectW = element.width - 2 * bevelOffset
|
|
|
|
+ const smallRectH = element.height - 2 * bevelOffset
|
|
|
|
+
|
|
|
|
+ // 绘制顶部小矩形
|
|
|
|
+ const topRect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'rect'
|
|
|
|
+ )
|
|
|
|
+ topRect.setAttribute('x', smallRectX)
|
|
|
|
+ topRect.setAttribute('y', smallRectY)
|
|
|
|
+ topRect.setAttribute('width', smallRectW)
|
|
|
|
+ topRect.setAttribute('height', smallRectH)
|
|
|
|
+
|
|
|
|
+ // 绘制四个梯形
|
|
|
|
+ const topTrapezoid = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ topTrapezoid.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,0 L${element.width},0 L${
|
|
|
|
+ element.width - bevelOffset
|
|
|
|
+ },${bevelOffset} L${bevelOffset},${bevelOffset} Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ const bottomTrapezoid = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ bottomTrapezoid.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${bevelOffset},${element.height - bevelOffset} L${
|
|
|
|
+ element.width - bevelOffset
|
|
|
|
+ },${element.height - bevelOffset} L${element.width},${
|
|
|
|
+ element.height
|
|
|
|
+ } L0,${element.height} Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ const leftTrapezoid = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ leftTrapezoid.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,0 L${bevelOffset},${bevelOffset} L${bevelOffset},${
|
|
|
|
+ element.height - bevelOffset
|
|
|
|
+ } L0,${element.height} Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ const rightTrapezoid = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ rightTrapezoid.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${element.width},0 L${element.width},${element.height} L${
|
|
|
|
+ element.width - bevelOffset
|
|
|
|
+ },${element.height - bevelOffset} L${
|
|
|
|
+ element.width - bevelOffset
|
|
|
|
+ },${bevelOffset} Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ const fillColor = element.fill.value || 'transparent'
|
|
|
|
+ topRect.setAttribute('fill', fillColor)
|
|
|
|
+ topTrapezoid.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ this.adjustBrightness(fillColor, 1.2)
|
|
|
|
+ )
|
|
|
|
+ bottomTrapezoid.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ this.adjustBrightness(fillColor, 0.8)
|
|
|
|
+ )
|
|
|
|
+ leftTrapezoid.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ this.adjustBrightness(fillColor, 0.9)
|
|
|
|
+ )
|
|
|
|
+ rightTrapezoid.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ this.adjustBrightness(fillColor, 0.7)
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ topRect.setAttribute('fill', 'transparent')
|
|
|
|
+ topTrapezoid.setAttribute('fill', 'transparent')
|
|
|
|
+ bottomTrapezoid.setAttribute('fill', 'transparent')
|
|
|
|
+ leftTrapezoid.setAttribute('fill', 'transparent')
|
|
|
|
+ rightTrapezoid.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ const borderColor = element.borderColor || '#000'
|
|
|
|
+ const borderWidth = element.borderWidth || 1
|
|
|
|
+ const parts = [
|
|
|
|
+ topRect,
|
|
|
|
+ topTrapezoid,
|
|
|
|
+ bottomTrapezoid,
|
|
|
|
+ leftTrapezoid,
|
|
|
|
+ rightTrapezoid
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ parts.forEach((part) => {
|
|
|
|
+ part.setAttribute('stroke', borderColor)
|
|
|
|
+ part.setAttribute('stroke-width', borderWidth)
|
|
|
|
+
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ const dashArray =
|
|
|
|
+ element.borderStrokeDasharray ||
|
|
|
|
+ (element.borderType === 'dotted' ? '1, 3' : '5, 5')
|
|
|
|
+ part.setAttribute('stroke-dasharray', dashArray)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 按正确的顺序添加面(从后到前)
|
|
|
|
+ bevel.appendChild(bottomTrapezoid)
|
|
|
|
+ bevel.appendChild(leftTrapezoid)
|
|
|
|
+ bevel.appendChild(rightTrapezoid)
|
|
|
|
+ bevel.appendChild(topTrapezoid)
|
|
|
|
+ bevel.appendChild(topRect)
|
|
|
|
+ svg.appendChild(bevel)
|
|
|
|
+ break
|
|
|
|
+ case 'donut':
|
|
|
|
+ const donut = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'g'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 外圆
|
|
|
|
+ const outerCircle = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'circle'
|
|
|
|
+ )
|
|
|
|
+ outerCircle.setAttribute('cx', element.width / 2)
|
|
|
|
+ outerCircle.setAttribute('cy', element.height / 2)
|
|
|
|
+ outerCircle.setAttribute(
|
|
|
|
+ 'r',
|
|
|
|
+ Math.min(element.width, element.height) / 2
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 内圆
|
|
|
|
+ const innerCircle = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'circle'
|
|
|
|
+ )
|
|
|
|
+ innerCircle.setAttribute('cx', element.width / 2)
|
|
|
|
+ innerCircle.setAttribute('cy', element.height / 2)
|
|
|
|
+ innerCircle.setAttribute(
|
|
|
|
+ 'r',
|
|
|
|
+ Math.min(element.width, element.height) / 4
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ outerCircle.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ innerCircle.setAttribute('fill', 'white') // 内圆为白色,形成镂空效果
|
|
|
|
+ } else {
|
|
|
|
+ outerCircle.setAttribute('fill', 'transparent')
|
|
|
|
+ innerCircle.setAttribute('fill', 'white')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ const borderColor = element.borderColor || '#000'
|
|
|
|
+ const borderWidth = element.borderWidth || 1
|
|
|
|
+
|
|
|
|
+ outerCircle.setAttribute('stroke', borderColor)
|
|
|
|
+ outerCircle.setAttribute('stroke-width', borderWidth)
|
|
|
|
+ innerCircle.setAttribute('stroke', borderColor)
|
|
|
|
+ innerCircle.setAttribute('stroke-width', borderWidth)
|
|
|
|
+
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ const dashArray =
|
|
|
|
+ element.borderStrokeDasharray ||
|
|
|
|
+ (element.borderType === 'dotted' ? '1, 3' : '5, 5')
|
|
|
|
+ outerCircle.setAttribute('stroke-dasharray', dashArray)
|
|
|
|
+ innerCircle.setAttribute('stroke-dasharray', dashArray)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ donut.appendChild(outerCircle)
|
|
|
|
+ donut.appendChild(innerCircle)
|
|
|
|
+ svg.appendChild(donut)
|
|
|
|
+ break
|
|
|
|
+ case 'noSmoking':
|
|
|
|
+ const noSmoking = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'g'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 创建路径
|
|
|
|
+ const path = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ path.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ 'M0,70 A77,70 0 1,1 0,71 Z M123.80284467265982,99.39738105155146 A57.5386,50.5386 0 0 0 45.160427644134444,27.90427466198293 Z M30.197155327340184,40.602618948448544 A57.5386,50.5386 0 0 0 108.83957235586556,112.09572533801708 Z'
|
|
|
|
+ )
|
|
|
|
+ path.setAttribute('fill', 'rgba(255,217,102,1)')
|
|
|
|
+ path.setAttribute('stroke', 'rgba(23,44,81,1)')
|
|
|
|
+ path.setAttribute('stroke-width', '1px')
|
|
|
|
+ path.setAttribute('stroke-dasharray', '')
|
|
|
|
+ path.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ path.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ noSmoking.appendChild(path)
|
|
|
|
+ svg.appendChild(noSmoking)
|
|
|
|
+ break
|
|
|
|
+ case 'rightArrow':
|
|
|
|
+ const rightArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ rightArrow.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `0,${element.height * 0.3} ${element.width * 0.7},${
|
|
|
|
+ element.height * 0.3
|
|
|
|
+ } ` +
|
|
|
|
+ `${element.width * 0.7},0 ${element.width},${
|
|
|
|
+ element.height * 0.5
|
|
|
|
+ } ` +
|
|
|
|
+ `${element.width * 0.7},${element.height} ${
|
|
|
|
+ element.width * 0.7
|
|
|
|
+ },${element.height * 0.7} ` +
|
|
|
|
+ `0,${element.height * 0.7}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ rightArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ rightArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ rightArrow.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ rightArrow.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ rightArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ rightArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ rightArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(rightArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'leftArrow':
|
|
|
|
+ const leftArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ leftArrow.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width},${element.height * 0.3} ${element.width * 0.3},${
|
|
|
|
+ element.height * 0.3
|
|
|
|
+ } ` +
|
|
|
|
+ `${element.width * 0.3},0 0,${element.height * 0.5} ` +
|
|
|
|
+ `${element.width * 0.3},${element.height} ${
|
|
|
|
+ element.width * 0.3
|
|
|
|
+ },${element.height * 0.7} ` +
|
|
|
|
+ `${element.width},${element.height * 0.7}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ leftArrow.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ leftArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ leftArrow.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ leftArrow.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ leftArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ leftArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ leftArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(leftArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'upArrow':
|
|
|
|
+ const upArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ upArrow.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width * 0.3},${element.height} ${element.width * 0.3},${
|
|
|
|
+ element.height * 0.3
|
|
|
|
+ } ` +
|
|
|
|
+ `0,${element.height * 0.3} ${element.width * 0.5},0 ` +
|
|
|
|
+ `${element.width},${element.height * 0.3} ${
|
|
|
|
+ element.width * 0.7
|
|
|
|
+ },${element.height * 0.3} ` +
|
|
|
|
+ `${element.width * 0.7},${element.height}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ upArrow.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ upArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ upArrow.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ upArrow.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ upArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ upArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ upArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(upArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'downArrow':
|
|
|
|
+ const downArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ downArrow.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width * 0.3},0 ${element.width * 0.3},${
|
|
|
|
+ element.height * 0.7
|
|
|
|
+ } ` +
|
|
|
|
+ `0,${element.height * 0.7} ${element.width * 0.5},${
|
|
|
|
+ element.height
|
|
|
|
+ } ` +
|
|
|
|
+ `${element.width},${element.height * 0.7} ${
|
|
|
|
+ element.width * 0.7
|
|
|
|
+ },${element.height * 0.7} ` +
|
|
|
|
+ `${element.width * 0.7},0`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ downArrow.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ downArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ downArrow.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ downArrow.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ downArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ downArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ downArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(downArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'leftRightArrow':
|
|
|
|
+ const leftRightArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ leftRightArrow.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `0,${element.height * 0.5} ${element.width * 0.2},${
|
|
|
|
+ element.height * 0.2
|
|
|
|
+ } ` +
|
|
|
|
+ `${element.width * 0.2},${element.height * 0.4} ${
|
|
|
|
+ element.width * 0.8
|
|
|
|
+ },${element.height * 0.4} ` +
|
|
|
|
+ `${element.width * 0.8},${element.height * 0.2} ${
|
|
|
|
+ element.width
|
|
|
|
+ },${element.height * 0.5} ` +
|
|
|
|
+ `${element.width * 0.8},${element.height * 0.8} ${
|
|
|
|
+ element.width * 0.8
|
|
|
|
+ },${element.height * 0.6} ` +
|
|
|
|
+ `${element.width * 0.2},${element.height * 0.6} ${
|
|
|
|
+ element.width * 0.2
|
|
|
|
+ },${element.height * 0.8}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ leftRightArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ leftRightArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ leftRightArrow.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ leftRightArrow.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ leftRightArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ leftRightArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ leftRightArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(leftRightArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'upDownArrow':
|
|
|
|
+ const upDownArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ upDownArrow.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width * 0.5},0 ${element.width * 0.3},${
|
|
|
|
+ element.height * 0.2
|
|
|
|
+ } ` +
|
|
|
|
+ `${element.width * 0.4},${element.height * 0.2} ${
|
|
|
|
+ element.width * 0.4
|
|
|
|
+ },${element.height * 0.8} ` +
|
|
|
|
+ `${element.width * 0.3},${element.height * 0.8} ${
|
|
|
|
+ element.width * 0.5
|
|
|
|
+ },${element.height} ` +
|
|
|
|
+ `${element.width * 0.7},${element.height * 0.8} ${
|
|
|
|
+ element.width * 0.6
|
|
|
|
+ },${element.height * 0.8} ` +
|
|
|
|
+ `${element.width * 0.6},${element.height * 0.2} ${
|
|
|
|
+ element.width * 0.7
|
|
|
|
+ },${element.height * 0.2}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ upDownArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ upDownArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ upDownArrow.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ upDownArrow.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ upDownArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ upDownArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ upDownArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(upDownArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'quadArrow':
|
|
|
|
+ const quadArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算缩放比例
|
|
|
|
+ const scale = Math.min(element.width / 167, element.height / 121)
|
|
|
|
+ const offsetX = (element.width - 167 * scale) / 2
|
|
|
|
+ const offsetY = (element.height - 121 * scale) / 2
|
|
|
|
+
|
|
|
|
+ // 构建路径数据
|
|
|
|
+ const pathData = `
|
|
|
|
+ M${offsetX},${60.5 * scale + offsetY}
|
|
|
|
+ L${27.225 * scale + offsetX},${33.275 * scale + offsetY}
|
|
|
|
+ L${27.225 * scale + offsetX},${46.8875 * scale + offsetY}
|
|
|
|
+ L${69.8875 * scale + offsetX},${46.8875 * scale + offsetY}
|
|
|
|
+ L${69.8875 * scale + offsetX},${27.225 * scale + offsetY}
|
|
|
|
+ L${56.275 * scale + offsetX},${27.225 * scale + offsetY}
|
|
|
|
+ L${83.5 * scale + offsetX},${offsetY}
|
|
|
|
+ L${110.725 * scale + offsetX},${27.225 * scale + offsetY}
|
|
|
|
+ L${97.1125 * scale + offsetX},${27.225 * scale + offsetY}
|
|
|
|
+ L${97.1125 * scale + offsetX},${46.8875 * scale + offsetY}
|
|
|
|
+ L${139.775 * scale + offsetX},${46.8875 * scale + offsetY}
|
|
|
|
+ L${139.775 * scale + offsetX},${33.275 * scale + offsetY}
|
|
|
|
+ L${167 * scale + offsetX},${60.5 * scale + offsetY}
|
|
|
|
+ L${139.775 * scale + offsetX},${87.725 * scale + offsetY}
|
|
|
|
+ L${139.775 * scale + offsetX},${74.1125 * scale + offsetY}
|
|
|
|
+ L${97.1125 * scale + offsetX},${74.1125 * scale + offsetY}
|
|
|
|
+ L${97.1125 * scale + offsetX},${93.775 * scale + offsetY}
|
|
|
|
+ L${110.725 * scale + offsetX},${93.775 * scale + offsetY}
|
|
|
|
+ L${83.5 * scale + offsetX},${121 * scale + offsetY}
|
|
|
|
+ L${56.275 * scale + offsetX},${93.775 * scale + offsetY}
|
|
|
|
+ L${69.8875 * scale + offsetX},${93.775 * scale + offsetY}
|
|
|
|
+ L${69.8875 * scale + offsetX},${74.1125 * scale + offsetY}
|
|
|
|
+ L${27.225 * scale + offsetX},${74.1125 * scale + offsetY}
|
|
|
|
+ L${27.225 * scale + offsetX},${87.725 * scale + offsetY}
|
|
|
|
+ Z`
|
|
|
|
+
|
|
|
|
+ quadArrow.setAttribute('d', pathData)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ quadArrow.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ quadArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ quadArrow.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ quadArrow.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+ quadArrow.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ quadArrow.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ quadArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ quadArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ quadArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(quadArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'leftRightUpArrow':
|
|
|
|
+ const leftRightUpArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 计算缩放比例
|
|
|
|
+ const scale2 = Math.min(element.width / 167, element.height / 121)
|
|
|
|
+ const offsetX2 = (element.width - 167 * scale2) / 2
|
|
|
|
+ const offsetY2 = (element.height - 121 * scale2) / 2
|
|
|
|
+
|
|
|
|
+ // 构建路径数据
|
|
|
|
+ const pathData2 = `
|
|
|
|
+ M${offsetX2},${60.5 * scale2 + offsetY2}
|
|
|
|
+ L${27.225 * scale2 + offsetX2},${33.275 * scale2 + offsetY2}
|
|
|
|
+ L${27.225 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
|
|
|
|
+ L${69.8875 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
|
|
|
|
+ L${69.8875 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
|
|
|
|
+ L${56.275 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
|
|
|
|
+ L${83.5 * scale2 + offsetX2},${offsetY2}
|
|
|
|
+ L${110.725 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
|
|
|
|
+ L${97.1125 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
|
|
|
|
+ L${97.1125 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
|
|
|
|
+ L${139.775 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
|
|
|
|
+ L${139.775 * scale2 + offsetX2},${33.275 * scale2 + offsetY2}
|
|
|
|
+ L${167 * scale2 + offsetX2},${60.5 * scale2 + offsetY2}
|
|
|
|
+ L${139.775 * scale2 + offsetX2},${87.725 * scale2 + offsetY2}
|
|
|
|
+ L${139.775 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
|
|
|
|
+ L${97.1125 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
|
|
|
|
+ L${69.8875 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
|
|
|
|
+ L${27.225 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
|
|
|
|
+ L${27.225 * scale2 + offsetX2},${87.725 * scale2 + offsetY2}
|
|
|
|
+ Z`
|
|
|
|
+
|
|
|
|
+ leftRightUpArrow.setAttribute('d', pathData2)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ leftRightUpArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ leftRightUpArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ leftRightUpArrow.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ leftRightUpArrow.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+ leftRightUpArrow.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ leftRightUpArrow.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ leftRightUpArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ leftRightUpArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ leftRightUpArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(leftRightUpArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'bentArrow':
|
|
|
|
+ const bentArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 构建路径数据
|
|
|
|
+ const pathData3 = `
|
|
|
|
+ M0,${element.height * 0.88}
|
|
|
|
+ L0,${element.height * 0.495}
|
|
|
|
+ A${element.width * 0.385} ${element.height * 0.385} 0 0 1 ${
|
|
|
|
+ element.width * 0.385
|
|
|
|
+} ${element.height * 0.11}
|
|
|
|
+ L${element.width * 0.67},${element.height * 0.11}
|
|
|
|
+ L${element.width * 0.67},0
|
|
|
|
+ L${element.width * 0.89},${element.height * 0.22}
|
|
|
|
+ L${element.width * 0.67},${element.height * 0.44}
|
|
|
|
+ L${element.width * 0.67},${element.height * 0.33}
|
|
|
|
+ L${element.width * 0.385},${element.height * 0.33}
|
|
|
|
+ A${element.width * 0.165} ${element.height * 0.165} 0 0 0 ${
|
|
|
|
+ element.width * 0.22
|
|
|
|
+} ${element.height * 0.495}
|
|
|
|
+ L${element.width * 0.22},${element.height * 0.88}
|
|
|
|
+ Z`
|
|
|
|
+
|
|
|
|
+ bentArrow.setAttribute('d', pathData3)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ bentArrow.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ bentArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ bentArrow.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ bentArrow.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+ bentArrow.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ bentArrow.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ bentArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ bentArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ bentArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(bentArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'parallelogram':
|
|
|
|
+ const parallelogram = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ parallelogram.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width * 0.25},0 ${element.width},0 ${
|
|
|
|
+ element.width * 0.75
|
|
|
|
+ },${element.height} 0,${element.height}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ parallelogram.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ parallelogram.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ parallelogram.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ parallelogram.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ parallelogram.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ parallelogram.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ parallelogram.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(parallelogram)
|
|
|
|
+ break
|
|
|
|
+ case 'uturnArrow':
|
|
|
|
+ const uturnArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 构建路径数据
|
|
|
|
+ const pathDataUturn = `
|
|
|
|
+ M0,${element.height * 0.745}
|
|
|
|
+ L0,${element.height * 0.179375}
|
|
|
|
+ A${element.width * 0.179375} ${element.height * 0.179375} 0 0 1 ${
|
|
|
|
+ element.width * 0.179375
|
|
|
|
+},0
|
|
|
|
+ L${element.width * 0.179375},0
|
|
|
|
+ A${element.width * 0.179375} ${element.height * 0.179375} 0 0 1 ${
|
|
|
|
+ element.width * 0.359375
|
|
|
|
+},${element.height * 0.179375}
|
|
|
|
+ L${element.width * 0.359375},${element.height * 0.205}
|
|
|
|
+ L${element.width * 0.41},${element.height * 0.205}
|
|
|
|
+ L${element.width * 0.3075},${element.height * 0.3075}
|
|
|
|
+ L${element.width * 0.205},${element.height * 0.205}
|
|
|
|
+ L${element.width * 0.25625},${element.height * 0.205}
|
|
|
|
+ L${element.width * 0.25625},${element.height * 0.179375}
|
|
|
|
+ A${element.width * 0.076875} ${element.height * 0.076875} 0 0 0 ${
|
|
|
|
+ element.width * 0.179375
|
|
|
|
+},${element.height * 0.1025}
|
|
|
|
+ L${element.width * 0.179375},${element.height * 0.1025}
|
|
|
|
+ A${element.width * 0.076875} ${element.height * 0.076875} 0 0 0 ${
|
|
|
|
+ element.width * 0.1025
|
|
|
|
+},${element.height * 0.179375}
|
|
|
|
+ L${element.width * 0.1025},${element.height * 0.745}
|
|
|
|
+ Z`
|
|
|
|
+
|
|
|
|
+ uturnArrow.setAttribute('d', pathDataUturn)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ uturnArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ uturnArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ uturnArrow.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ uturnArrow.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+ uturnArrow.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ uturnArrow.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ uturnArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ uturnArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ uturnArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(uturnArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'leftUpArrow':
|
|
|
|
+ const leftUpArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 使用提供的路径数据
|
|
|
|
+ const pathDataLeftUp = `
|
|
|
|
+ M0,${element.height * 0.65}
|
|
|
|
+ L${element.width * 0.15},${element.height * 0.4}
|
|
|
|
+ L${element.width * 0.15},${element.height * 0.55}
|
|
|
|
+ L${element.width * 0.5},${element.height * 0.55}
|
|
|
|
+ L${element.width * 0.5},${element.height * 0.1}
|
|
|
|
+ L${element.width * 0.35},${element.height * 0.1}
|
|
|
|
+ L${element.width * 0.65},0
|
|
|
|
+ L${element.width * 0.85},${element.height * 0.1}
|
|
|
|
+ L${element.width * 0.75},${element.height * 0.1}
|
|
|
|
+ L${element.width * 0.75},${element.height * 0.85}
|
|
|
|
+ L${element.width * 0.15},${element.height * 0.85}
|
|
|
|
+ L${element.width * 0.15},${element.height * 1}
|
|
|
|
+ Z`
|
|
|
|
+
|
|
|
|
+ leftUpArrow.setAttribute('d', pathDataLeftUp)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ leftUpArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ leftUpArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ leftUpArrow.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ leftUpArrow.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+ leftUpArrow.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ leftUpArrow.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ leftUpArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ leftUpArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ leftUpArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(leftUpArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'bentUpArrow':
|
|
|
|
+ const bentUpArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 构建路径数据,去掉左侧箭头
|
|
|
|
+ // 使用提供的路径数据
|
|
|
|
+ const pathDataBentUp = `
|
|
|
|
+ M0,${element.height * 0.89}
|
|
|
|
+ L0,${element.height * 0.7}
|
|
|
|
+ L${element.width * 0.575},${element.height * 0.7}
|
|
|
|
+ L${element.width * 0.575},${element.height * 0.2}
|
|
|
|
+ L${element.width * 0.46},${element.height * 0.2}
|
|
|
|
+ L${element.width * 0.69},0
|
|
|
|
+ L${element.width * 0.92},${element.height * 0.2}
|
|
|
|
+ L${element.width * 0.805},${element.height * 0.2}
|
|
|
|
+ L${element.width * 0.805},${element.height * 0.89}
|
|
|
|
+ Z`
|
|
|
|
+
|
|
|
|
+ bentUpArrow.setAttribute('d', pathDataBentUp)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ bentUpArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ bentUpArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ bentUpArrow.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ bentUpArrow.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+ bentUpArrow.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ bentUpArrow.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ bentUpArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ bentUpArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ bentUpArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(bentUpArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'curvedRightArrow':
|
|
|
|
+ const curvedRightArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 使用提供的路径数据
|
|
|
|
+ const pathDataCurvedRight = `
|
|
|
|
+ M${element.width},0
|
|
|
|
+ A${element.width} ${element.height * 0.4} 0 0 0 0 ${
|
|
|
|
+ element.height * 0.4
|
|
|
|
+}
|
|
|
|
+ L0,${element.height * 0.5}
|
|
|
|
+ A${element.width} ${element.height * 0.4} 0 0 1 ${element.width} ${
|
|
|
|
+ element.height * 0.15
|
|
|
|
+}
|
|
|
|
+ Z
|
|
|
|
+ M0,${element.height * 0.4}
|
|
|
|
+ A${element.width} ${element.height * 0.4} 0 0 0 ${
|
|
|
|
+ element.width * 0.8
|
|
|
|
+} ${element.height * 0.8}
|
|
|
|
+ L${element.width * 0.8},${element.height * 0.75}
|
|
|
|
+ L${element.width},${element.height * 0.875}
|
|
|
|
+ L${element.width * 0.8},${element.height * 1}
|
|
|
|
+ L${element.width * 0.8},${element.height * 0.95}
|
|
|
|
+ A${element.width} ${element.height * 0.4} 0 0 1 0 ${
|
|
|
|
+ element.height * 0.5
|
|
|
|
+}
|
|
|
|
+ Z`
|
|
|
|
+
|
|
|
|
+ curvedRightArrow.setAttribute('d', pathDataCurvedRight)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ curvedRightArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ curvedRightArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ curvedRightArrow.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ curvedRightArrow.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+ curvedRightArrow.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ curvedRightArrow.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ curvedRightArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ curvedRightArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ curvedRightArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(curvedRightArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'curvedLeftArrow':
|
|
|
|
+ const curvedLeftArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 定义左弧形箭头的路径数据
|
|
|
|
+ const pathDataCurvedLeft = `
|
|
|
|
+ M0,0
|
|
|
|
+ A${element.width} ${element.height * 0.4} 0 0 1 ${element.width} ${
|
|
|
|
+ element.height * 0.4
|
|
|
|
+}
|
|
|
|
+ L${element.width},${element.height * 0.55}
|
|
|
|
+ A${element.width} ${element.height * 0.4} 0 0 0 0 ${
|
|
|
|
+ element.height * 0.15
|
|
|
|
+}
|
|
|
|
+ Z
|
|
|
|
+ M0,${element.height * 0.85}
|
|
|
|
+ L${element.width * 0.25},${element.height * 0.65}
|
|
|
|
+ L${element.width * 0.25},${element.height * 0.75}
|
|
|
|
+ A${element.width} ${element.height * 0.4} 0 0 0 ${element.width} ${
|
|
|
|
+ element.height * 0.4
|
|
|
|
+}
|
|
|
|
+ L${element.width},${element.height * 0.5}
|
|
|
|
+ L${element.width},${element.height * 0.5}
|
|
|
|
+ A${element.width} ${element.height * 0.4} 0 0 1 ${
|
|
|
|
+ element.width * 0.25
|
|
|
|
+} ${element.height * 0.9}
|
|
|
|
+ L${element.width * 0.25},${element.height}
|
|
|
|
+ Z`
|
|
|
|
+
|
|
|
|
+ curvedLeftArrow.setAttribute('d', pathDataCurvedLeft)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ curvedLeftArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ curvedLeftArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ curvedLeftArrow.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ curvedLeftArrow.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+ curvedLeftArrow.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ curvedLeftArrow.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ curvedLeftArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ curvedLeftArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ curvedLeftArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(curvedLeftArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'curvedUpArrow':
|
|
|
|
+ const curvedUpArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 定义上弧形箭头的路径数据
|
|
|
|
+ const pathDataCurvedUp = `
|
|
|
|
+ M${element.width * 0.905},0
|
|
|
|
+ L${element.width * 0.81},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.857},${element.height * 0.25}
|
|
|
|
+ A${element.width * 0.428} ${element.height} 0 0 1 ${
|
|
|
|
+ element.width * 0.428
|
|
|
|
+},${element.height}
|
|
|
|
+ L${element.width * 0.522},${element.height}
|
|
|
|
+ A${element.width * 0.428} ${element.height} 0 0 0 ${
|
|
|
|
+ element.width * 0.952
|
|
|
|
+},${element.height * 0.25}
|
|
|
|
+ L${element.width},${element.height * 0.25}
|
|
|
|
+ Z
|
|
|
|
+ M${element.width * 0.094},0
|
|
|
|
+ L0,0
|
|
|
|
+ A${element.width * 0.428} ${element.height} 0 0 0 ${
|
|
|
|
+ element.width * 0.428
|
|
|
|
+},${element.height}
|
|
|
|
+ L${element.width * 0.522},${element.height}
|
|
|
|
+ A${element.width * 0.428} ${element.height} 0 0 1 ${
|
|
|
|
+ element.width * 0.094
|
|
|
|
+},0
|
|
|
|
+ Z`
|
|
|
|
+
|
|
|
|
+ curvedUpArrow.setAttribute('d', pathDataCurvedUp)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ curvedUpArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ curvedUpArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ curvedUpArrow.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ curvedUpArrow.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+ curvedUpArrow.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ curvedUpArrow.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ curvedUpArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ curvedUpArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ curvedUpArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(curvedUpArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'curvedDownArrow':
|
|
|
|
+ const curvedDownArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 定义下弧形箭头的路径数据
|
|
|
|
+ const pathDataCurvedDown = `
|
|
|
|
+ M0,${element.height}
|
|
|
|
+ L${element.width * 0.16},${element.height}
|
|
|
|
+ A${element.width * 0.46} ${element.height} 0 0 1 ${
|
|
|
|
+ element.width * 0.62
|
|
|
|
+},0
|
|
|
|
+ L${element.width * 0.46},0
|
|
|
|
+ A${element.width * 0.46} ${element.height} 0 0 0 0,${element.height}
|
|
|
|
+ Z
|
|
|
|
+ M${element.width},${element.height}
|
|
|
|
+ L${element.width * 0.84},${element.height * 0.75}
|
|
|
|
+ L${element.width * 0.92},${element.height * 0.75}
|
|
|
|
+ A${element.width * 0.46} ${element.height} 0 0 0 ${
|
|
|
|
+ element.width * 0.46
|
|
|
|
+},0
|
|
|
|
+ L${element.width * 0.62},0
|
|
|
|
+ A${element.width * 0.46} ${element.height} 0 0 1 ${
|
|
|
|
+ element.width * 1.08
|
|
|
|
+},${element.height * 0.75}
|
|
|
|
+ L${element.width * 1.16},${element.height * 0.75}
|
|
|
|
+ Z`
|
|
|
|
+
|
|
|
|
+ curvedDownArrow.setAttribute('d', pathDataCurvedDown)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ curvedDownArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ curvedDownArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ curvedDownArrow.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ curvedDownArrow.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+ curvedDownArrow.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ curvedDownArrow.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ curvedDownArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ curvedDownArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ curvedDownArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(curvedDownArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'stripedRightArrow':
|
|
|
|
+ const stripedRightArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'g'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 主箭头部分
|
|
|
|
+ const mainArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ mainArrow.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${element.width * 0.062},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.8},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.8},0
|
|
|
|
+ L${element.width},${element.height * 0.5}
|
|
|
|
+ L${element.width * 0.8},${element.height}
|
|
|
|
+ L${element.width * 0.8},${element.height * 0.75}
|
|
|
|
+ L${element.width * 0.062},${element.height * 0.75}
|
|
|
|
+ Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 第一条尾部条纹
|
|
|
|
+ const stripe1 = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ stripe1.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.012},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.012},${element.height * 0.75}
|
|
|
|
+ L0,${element.height * 0.75}
|
|
|
|
+ Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 第二条尾部条纹
|
|
|
|
+ const stripe2 = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ stripe2.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${element.width * 0.025},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.049},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.049},${element.height * 0.75}
|
|
|
|
+ L${element.width * 0.025},${element.height * 0.75}
|
|
|
|
+ Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ mainArrow.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ stripe1.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ stripe2.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ mainArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ stripe1.setAttribute('fill', 'transparent')
|
|
|
|
+ stripe2.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ [mainArrow, stripe1, stripe2].forEach((path) => {
|
|
|
|
+ path.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ path.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+ path.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ path.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ path.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ path.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ path.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ stripedRightArrow.appendChild(mainArrow)
|
|
|
|
+ stripedRightArrow.appendChild(stripe1)
|
|
|
|
+ stripedRightArrow.appendChild(stripe2)
|
|
|
|
+ svg.appendChild(stripedRightArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'rightArrowCallout':
|
|
|
|
+ const rightArrowCallout = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ rightArrowCallout.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,0
|
|
|
|
+ L${element.width * 0.44},0
|
|
|
|
+ L${element.width * 0.44},${element.height * 0.375}
|
|
|
|
+ L${element.width * 0.79},${element.height * 0.375}
|
|
|
|
+ L${element.width * 0.79},${element.height * 0.25}
|
|
|
|
+ L${element.width},${element.height * 0.5}
|
|
|
|
+ L${element.width * 0.79},${element.height * 0.75}
|
|
|
|
+ L${element.width * 0.79},${element.height * 0.625}
|
|
|
|
+ L${element.width * 0.44},${element.height * 0.625}
|
|
|
|
+ L${element.width * 0.44},${element.height}
|
|
|
|
+ L0,${element.height}
|
|
|
|
+ Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ rightArrowCallout.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ rightArrowCallout.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ rightArrowCallout.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ rightArrowCallout.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+ rightArrowCallout.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ rightArrowCallout.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ rightArrowCallout.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ rightArrowCallout.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ rightArrowCallout.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(rightArrowCallout)
|
|
|
|
+ break
|
|
|
|
+ case 'leftRightArrowCallout':
|
|
|
|
+ const leftRightArrowCallout = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ leftRightArrowCallout.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,${element.height * 0.5}
|
|
|
|
+ L${element.width * 0.139},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.139},${element.height * 0.375}
|
|
|
|
+ L${element.width * 0.364},${element.height * 0.375}
|
|
|
|
+ L${element.width * 0.364},0
|
|
|
|
+ L${element.width * 0.636},0
|
|
|
|
+ L${element.width * 0.636},${element.height * 0.375}
|
|
|
|
+ L${element.width * 0.861},${element.height * 0.375}
|
|
|
|
+ L${element.width * 0.861},${element.height * 0.25}
|
|
|
|
+ L${element.width},${element.height * 0.5}
|
|
|
|
+ L${element.width * 0.861},${element.height * 0.75}
|
|
|
|
+ L${element.width * 0.861},${element.height * 0.625}
|
|
|
|
+ L${element.width * 0.636},${element.height * 0.625}
|
|
|
|
+ L${element.width * 0.636},${element.height}
|
|
|
|
+ L${element.width * 0.364},${element.height}
|
|
|
|
+ L${element.width * 0.364},${element.height * 0.625}
|
|
|
|
+ L${element.width * 0.139},${element.height * 0.625}
|
|
|
|
+ L${element.width * 0.139},${element.height * 0.75}
|
|
|
|
+ Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ leftRightArrowCallout.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ leftRightArrowCallout.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ leftRightArrowCallout.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ leftRightArrowCallout.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+ leftRightArrowCallout.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ leftRightArrowCallout.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ leftRightArrowCallout.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ leftRightArrowCallout.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ leftRightArrowCallout.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(leftRightArrowCallout)
|
|
|
|
+ break
|
|
|
|
+ case 'quadArrowCallout':
|
|
|
|
+ const quadArrowCallout = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ quadArrowCallout.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,${element.height * 0.5}
|
|
|
|
+ L${element.width * 0.096},${element.height * 0.315}
|
|
|
|
+ L${element.width * 0.096},${element.height * 0.407}
|
|
|
|
+ L${element.width * 0.26},${element.height * 0.407}
|
|
|
|
+ L${element.width * 0.26},${element.height * 0.259}
|
|
|
|
+ L${element.width * 0.453},${element.height * 0.259}
|
|
|
|
+ L${element.width * 0.453},${element.height * 0.185}
|
|
|
|
+ L${element.width * 0.405},${element.height * 0.185}
|
|
|
|
+ L${element.width * 0.5},0
|
|
|
|
+ L${element.width * 0.595},${element.height * 0.185}
|
|
|
|
+ L${element.width * 0.547},${element.height * 0.185}
|
|
|
|
+ L${element.width * 0.547},${element.height * 0.259}
|
|
|
|
+ L${element.width * 0.74},${element.height * 0.259}
|
|
|
|
+ L${element.width * 0.74},${element.height * 0.407}
|
|
|
|
+ L${element.width * 0.904},${element.height * 0.407}
|
|
|
|
+ L${element.width * 0.904},${element.height * 0.315}
|
|
|
|
+ L${element.width},${element.height * 0.5}
|
|
|
|
+ L${element.width * 0.904},${element.height * 0.685}
|
|
|
|
+ L${element.width * 0.904},${element.height * 0.593}
|
|
|
|
+ L${element.width * 0.74},${element.height * 0.593}
|
|
|
|
+ L${element.width * 0.74},${element.height * 0.741}
|
|
|
|
+ L${element.width * 0.547},${element.height * 0.741}
|
|
|
|
+ L${element.width * 0.547},${element.height * 0.815}
|
|
|
|
+ L${element.width * 0.595},${element.height * 0.815}
|
|
|
|
+ L${element.width * 0.5},${element.height}
|
|
|
|
+ L${element.width * 0.405},${element.height * 0.815}
|
|
|
|
+ L${element.width * 0.453},${element.height * 0.815}
|
|
|
|
+ L${element.width * 0.453},${element.height * 0.741}
|
|
|
|
+ L${element.width * 0.26},${element.height * 0.741}
|
|
|
|
+ L${element.width * 0.26},${element.height * 0.593}
|
|
|
|
+ L${element.width * 0.096},${element.height * 0.593}
|
|
|
|
+ L${element.width * 0.096},${element.height * 0.685}
|
|
|
|
+ Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ quadArrowCallout.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ quadArrowCallout.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ quadArrowCallout.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ quadArrowCallout.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+ quadArrowCallout.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ quadArrowCallout.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ quadArrowCallout.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ quadArrowCallout.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ quadArrowCallout.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(quadArrowCallout)
|
|
|
|
+ break
|
|
|
|
+ case 'leftArrowCallout':
|
|
|
|
+ const leftArrowCallout = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ leftArrowCallout.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,${element.height * 0.5}
|
|
|
|
+ L${element.width * 0.183},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.183},${element.height * 0.375}
|
|
|
|
+ L${element.width * 0.35},${element.height * 0.375}
|
|
|
|
+ L${element.width * 0.35},0
|
|
|
|
+ L${element.width},0
|
|
|
|
+ L${element.width},${element.height}
|
|
|
|
+ L${element.width * 0.35},${element.height}
|
|
|
|
+ L${element.width * 0.35},${element.height * 0.625}
|
|
|
|
+ L${element.width * 0.183},${element.height * 0.625}
|
|
|
|
+ L${element.width * 0.183},${element.height * 0.75}
|
|
|
|
+ Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ leftArrowCallout.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ leftArrowCallout.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ leftArrowCallout.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ leftArrowCallout.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+ leftArrowCallout.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ leftArrowCallout.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ leftArrowCallout.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ leftArrowCallout.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ leftArrowCallout.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(leftArrowCallout)
|
|
|
|
+ break
|
|
|
|
+ case 'upArrowCallout':
|
|
|
|
+ const upArrowCallout = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ upArrowCallout.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,${element.height * 0.35}
|
|
|
|
+ L${element.width * 0.41},${element.height * 0.35}
|
|
|
|
+ L${element.width * 0.41},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.32},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.5},0
|
|
|
|
+ L${element.width * 0.68},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.59},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.59},${element.height * 0.35}
|
|
|
|
+ L${element.width},${element.height * 0.35}
|
|
|
|
+ L${element.width},${element.height}
|
|
|
|
+ L0,${element.height}
|
|
|
|
+ Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ upArrowCallout.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ upArrowCallout.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ upArrowCallout.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ upArrowCallout.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+ upArrowCallout.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ upArrowCallout.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ upArrowCallout.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ upArrowCallout.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ upArrowCallout.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(upArrowCallout)
|
|
|
|
+ break
|
|
|
|
+ case 'notchedRightArrow':
|
|
|
|
+ const notchedRightArrow = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ notchedRightArrow.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.83},${element.height * 0.25}
|
|
|
|
+ L${element.width * 0.83},0
|
|
|
|
+ L${element.width},${element.height * 0.5}
|
|
|
|
+ L${element.width * 0.83},${element.height}
|
|
|
|
+ L${element.width * 0.83},${element.height * 0.75}
|
|
|
|
+ L0,${element.height * 0.75}
|
|
|
|
+ L${element.width * 0.086},${element.height * 0.5}
|
|
|
|
+ Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ notchedRightArrow.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ notchedRightArrow.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ notchedRightArrow.setAttribute(
|
|
|
|
+ 'stroke',
|
|
|
|
+ element.borderColor || '#000'
|
|
|
|
+ )
|
|
|
|
+ notchedRightArrow.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+ notchedRightArrow.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ notchedRightArrow.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ notchedRightArrow.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ notchedRightArrow.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ notchedRightArrow.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(notchedRightArrow)
|
|
|
|
+ break
|
|
|
|
+ case 'homePlate':
|
|
|
|
+ const homePlate = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ homePlate.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,0
|
|
|
|
+ L${element.width * 0.925},0
|
|
|
|
+ L${element.width},${element.height * 0.5}
|
|
|
|
+ L${element.width * 0.925},${element.height}
|
|
|
|
+ L0,${element.height}
|
|
|
|
+ Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ homePlate.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ homePlate.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ homePlate.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ homePlate.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+ homePlate.setAttribute('stroke-linecap', 'butt')
|
|
|
|
+ homePlate.setAttribute('stroke-linejoin', 'round')
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ homePlate.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ homePlate.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ homePlate.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(homePlate)
|
|
|
|
+ break
|
|
|
|
+ case 'rightTriangle':
|
|
|
|
+ const rightTriangle = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ rightTriangle.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `0,0 ${element.width},${element.height} 0,${element.height}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ rightTriangle.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ rightTriangle.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ rightTriangle.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ rightTriangle.setAttribute(
|
|
|
|
+ 'stroke-width',
|
|
|
|
+ element.borderWidth || 1
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ rightTriangle.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ rightTriangle.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ rightTriangle.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(rightTriangle)
|
|
|
|
+ break
|
|
|
|
+ case 'semiCircle':
|
|
|
|
+ const semiCircle = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ semiCircle.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M0,${element.height} A${element.width / 2},${
|
|
|
|
+ element.height
|
|
|
|
+ } 0 0,1 ${element.width},${element.height} Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ semiCircle.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ semiCircle.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ semiCircle.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ semiCircle.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ semiCircle.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ semiCircle.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ semiCircle.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(semiCircle)
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+ case 'star':
|
|
|
|
+ const star = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ const cx = element.width / 2
|
|
|
|
+ const cy = element.height / 2
|
|
|
|
+ const outerRadius = Math.min(element.width, element.height) / 2
|
|
|
|
+ const innerRadius = outerRadius * 0.4
|
|
|
|
+ let starPoints = ''
|
|
|
|
+
|
|
|
|
+ for (let i = 0; i < 10; i++) {
|
|
|
|
+ const radius = i % 2 === 0 ? outerRadius : innerRadius
|
|
|
|
+ const angle = (Math.PI * i) / 5
|
|
|
|
+ const x = cx + radius * Math.sin(angle)
|
|
|
|
+ const y = cy - radius * Math.cos(angle)
|
|
|
|
+ starPoints += `${x},${y} `
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ star.setAttribute('points', starPoints.trim())
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ star.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ star.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ star.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ star.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ star.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ star.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ star.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(star)
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+ case 'cross':
|
|
|
|
+ const cross = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ cross.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width * 0.35},0 ${element.width * 0.65},0 ${
|
|
|
|
+ element.width * 0.65
|
|
|
|
+ },${element.height * 0.35} ` +
|
|
|
|
+ `${element.width},${element.height * 0.35} ${element.width},${
|
|
|
|
+ element.height * 0.65
|
|
|
|
+ } ` +
|
|
|
|
+ `${element.width * 0.65},${element.height * 0.65} ${
|
|
|
|
+ element.width * 0.65
|
|
|
|
+ },${element.height} ` +
|
|
|
|
+ `${element.width * 0.35},${element.height} ${
|
|
|
|
+ element.width * 0.35
|
|
|
|
+ },${element.height * 0.65} ` +
|
|
|
|
+ `0,${element.height * 0.65} 0,${element.height * 0.35} ${
|
|
|
|
+ element.width * 0.35
|
|
|
|
+ },${element.height * 0.35}`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ cross.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ cross.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ cross.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ cross.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ cross.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ cross.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ cross.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(cross)
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+ case 'chevron':
|
|
|
|
+ const chevron = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'polygon'
|
|
|
|
+ )
|
|
|
|
+ chevron.setAttribute(
|
|
|
|
+ 'points',
|
|
|
|
+ `${element.width * 0.75},0 ${element.width},${
|
|
|
|
+ element.height * 0.5
|
|
|
|
+ } ${element.width * 0.75},${element.height} ` +
|
|
|
|
+ `0,${element.height} ${element.width * 0.25},${
|
|
|
|
+ element.height * 0.5
|
|
|
|
+ } 0,0`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ chevron.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ chevron.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ chevron.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ chevron.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ chevron.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ chevron.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ chevron.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(chevron)
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+ case 'frame':
|
|
|
|
+ // 创建外框和内框
|
|
|
|
+ const outerRect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'rect'
|
|
|
|
+ )
|
|
|
|
+ outerRect.setAttribute('x', 0)
|
|
|
|
+ outerRect.setAttribute('y', 0)
|
|
|
|
+ outerRect.setAttribute('width', element.width)
|
|
|
|
+ outerRect.setAttribute('height', element.height)
|
|
|
|
+
|
|
|
|
+ const innerRect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'rect'
|
|
|
|
+ )
|
|
|
|
+ const frameWidth = element.width / 10
|
|
|
|
+ innerRect.setAttribute('x', frameWidth)
|
|
|
|
+ innerRect.setAttribute('y', frameWidth)
|
|
|
|
+ innerRect.setAttribute('width', element.width - frameWidth * 2)
|
|
|
|
+ innerRect.setAttribute('height', element.height - frameWidth * 2)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ outerRect.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ innerRect.setAttribute('fill', 'white') // 内框为白色
|
|
|
|
+ } else {
|
|
|
|
+ outerRect.setAttribute('fill', 'transparent')
|
|
|
|
+ innerRect.setAttribute('fill', 'white')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ outerRect.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ outerRect.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ outerRect.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ outerRect.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ outerRect.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(outerRect)
|
|
|
|
+ svg.appendChild(innerRect)
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+ case 'cloud':
|
|
|
|
+ // 使用路径绘制云形
|
|
|
|
+ const cloud = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ const w = element.width
|
|
|
|
+ const h = element.height
|
|
|
|
+
|
|
|
|
+ cloud.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${w * 0.2},${h * 0.6} ` +
|
|
|
|
+ `C${w * 0.05},${h * 0.6} ${w * 0.05},${h * 0.3} ${w * 0.2},${
|
|
|
|
+ h * 0.3
|
|
|
|
+ } ` +
|
|
|
|
+ `C${w * 0.2},${h * 0.1} ${w * 0.45},${h * 0.1} ${w * 0.5},${
|
|
|
|
+ h * 0.3
|
|
|
|
+ } ` +
|
|
|
|
+ `C${w * 0.55},${h * 0.1} ${w * 0.8},${h * 0.1} ${w * 0.8},${
|
|
|
|
+ h * 0.3
|
|
|
|
+ } ` +
|
|
|
|
+ `C${w * 0.95},${h * 0.3} ${w * 0.95},${h * 0.6} ${w * 0.8},${
|
|
|
|
+ h * 0.6
|
|
|
|
+ } ` +
|
|
|
|
+ `L${w * 0.2},${h * 0.6} Z`
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ cloud.setAttribute('fill', element.fill.value || 'transparent')
|
|
|
|
+ } else {
|
|
|
|
+ cloud.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ cloud.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ cloud.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+
|
|
|
|
+ // 处理虚线边框
|
|
|
|
+ if (
|
|
|
|
+ element.borderType === 'dotted' ||
|
|
|
|
+ element.borderType === 'dashed'
|
|
|
|
+ ) {
|
|
|
|
+ if (element.borderStrokeDasharray) {
|
|
|
|
+ cloud.setAttribute(
|
|
|
|
+ 'stroke-dasharray',
|
|
|
|
+ element.borderStrokeDasharray
|
|
|
|
+ )
|
|
|
|
+ } else if (element.borderType === 'dotted') {
|
|
|
|
+ cloud.setAttribute('stroke-dasharray', '1, 3')
|
|
|
|
+ } else if (element.borderType === 'dashed') {
|
|
|
|
+ cloud.setAttribute('stroke-dasharray', '5, 5')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(cloud)
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ // 默认形状处理 - 使用矩形
|
|
|
|
+ const defaultRect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'rect'
|
|
|
|
+ )
|
|
|
|
+ defaultRect.setAttribute('x', 0)
|
|
|
|
+ defaultRect.setAttribute('y', 0)
|
|
|
|
+ defaultRect.setAttribute('width', element.width)
|
|
|
|
+ defaultRect.setAttribute('height', element.height)
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ if (element.fill && element.fill.type === 'color') {
|
|
|
|
+ defaultRect.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.fill.value || 'transparent'
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ defaultRect.setAttribute('fill', 'transparent')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (element.borderWidth > 0) {
|
|
|
|
+ defaultRect.setAttribute('stroke', element.borderColor || '#000')
|
|
|
|
+ defaultRect.setAttribute('stroke-width', element.borderWidth || 1)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ svg.appendChild(defaultRect)
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ // 应用翻转和旋转变换
|
|
|
|
+ const transformList = []
|
|
|
|
+ if (element.isFlipV) {
|
|
|
|
+ transformList.push(`scale(1, -1) translate(0, -${element.height})`)
|
|
|
|
+ }
|
|
|
|
+ if (element.isFlipH) {
|
|
|
|
+ transformList.push(`scale(-1, 1) translate(-${element.width}, 0)`)
|
|
|
|
+ }
|
|
|
|
+ if (element.rotate) {
|
|
|
|
+ transformList.push(
|
|
|
|
+ `rotate(${element.rotate}, ${element.width / 2}, ${
|
|
|
|
+ element.height / 2
|
|
|
|
+ })`
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ if (transformList.length > 0) {
|
|
|
|
+ svg.setAttribute('transform', transformList.join(' '))
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ el.appendChild(svg)
|
|
|
|
+
|
|
|
|
+ // 设置形状内容
|
|
|
|
+ if (element.content) {
|
|
|
|
+ const contentContainer = document.createElement('div')
|
|
|
|
+ contentContainer.innerHTML = this.convertPtToPxInContent(
|
|
|
|
+ element.content
|
|
|
|
+ )
|
|
|
|
+ contentContainer.style.position = 'absolute'
|
|
|
|
+ contentContainer.style.width = element.width + 'px'
|
|
|
|
+ contentContainer.style.height = element.height + 'px'
|
|
|
|
+ contentContainer.style.top = '0px'
|
|
|
|
+ contentContainer.style.left = '0px'
|
|
|
|
+ contentContainer.style.display = 'flex'
|
|
|
|
+ contentContainer.style.alignItems = 'center'
|
|
|
|
+ contentContainer.style.justifyContent = 'center'
|
|
|
|
+ contentContainer.style.zIndex = element.order
|
|
|
|
+ contentContainer.style.pointerEvents = 'none'
|
|
|
|
+
|
|
|
|
+ el.appendChild(contentContainer)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return el
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 创建表格元素
|
|
|
|
+ createTableElement (element) {
|
|
|
|
+ const el = document.createElement('div')
|
|
|
|
+ el.style.position = 'absolute'
|
|
|
|
+ el.style.top = element.top + 'px'
|
|
|
|
+ el.style.left = element.left + 'px'
|
|
|
|
+ el.style.width = element.width + 'px'
|
|
|
|
+ el.style.height = element.height + 'px'
|
|
|
|
+ el.style.zIndex = element.order
|
|
|
|
+
|
|
|
|
+ // 创建表格元素
|
|
|
|
+ const table = document.createElement('table')
|
|
|
|
+ table.style.width = element.width + 'px'
|
|
|
|
+ table.style.height = element.height + 'px'
|
|
|
|
+ table.style.borderCollapse = 'collapse'
|
|
|
|
+ table.style.tableLayout = 'fixed'
|
|
|
|
+ // 设置表格边框
|
|
|
|
+ if (element.borders) {
|
|
|
|
+ if (element.borders.all) {
|
|
|
|
+ const border = element.borders.all
|
|
|
|
+ table.style.border = `${border.borderWidth || 1}px ${
|
|
|
|
+ border.borderType || 'solid'
|
|
|
|
+ } ${border.borderColor || '#000'}`
|
|
|
|
+ } else {
|
|
|
|
+ // 分别设置四边边框
|
|
|
|
+ if (element.borders.top) {
|
|
|
|
+ table.style.borderTop = `${
|
|
|
|
+ element.borders.top.borderWidth || 1
|
|
|
|
+ }px ${element.borders.top.borderType || 'solid'} ${
|
|
|
|
+ element.borders.top.borderColor || '#000'
|
|
|
|
+ }`
|
|
|
|
+ }
|
|
|
|
+ if (element.borders.bottom) {
|
|
|
|
+ table.style.borderBottom = `${
|
|
|
|
+ element.borders.bottom.borderWidth || 1
|
|
|
|
+ }px ${element.borders.bottom.borderType || 'solid'} ${
|
|
|
|
+ element.borders.bottom.borderColor || '#000'
|
|
|
|
+ }`
|
|
|
|
+ }
|
|
|
|
+ if (element.borders.left) {
|
|
|
|
+ table.style.borderLeft = `${
|
|
|
|
+ element.borders.left.borderWidth || 1
|
|
|
|
+ }px ${element.borders.left.borderType || 'solid'} ${
|
|
|
|
+ element.borders.left.borderColor || '#000'
|
|
|
|
+ }`
|
|
|
|
+ }
|
|
|
|
+ if (element.borders.right) {
|
|
|
|
+ table.style.borderRight = `${
|
|
|
|
+ element.borders.right.borderWidth || 1
|
|
|
|
+ }px ${element.borders.right.borderType || 'solid'} ${
|
|
|
|
+ element.borders.right.borderColor || '#000'
|
|
|
|
+ }`
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 创建表格内容
|
|
|
|
+ const tbody = document.createElement('tbody')
|
|
|
|
+
|
|
|
|
+ // 处理表格数据
|
|
|
|
+ if (element.data && element.data.length > 0) {
|
|
|
|
+ element.data.forEach((rowData, rowIndex) => {
|
|
|
|
+ const tr = document.createElement('tr')
|
|
|
|
+
|
|
|
|
+ rowData.forEach((cell, colIndex) => {
|
|
|
|
+ // 跳过被合并的单元格
|
|
|
|
+ if (cell.hMerge) return
|
|
|
|
+
|
|
|
|
+ const td = document.createElement('td')
|
|
|
|
+
|
|
|
|
+ // 设置单元格内容
|
|
|
|
+ if (cell.text) {
|
|
|
|
+ td.innerHTML = this.convertPtToPxInContent(cell.text)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置单元格样式
|
|
|
|
+ td.style.padding = '0px'
|
|
|
|
+ td.style.verticalAlign = 'middle'
|
|
|
|
+
|
|
|
|
+ // 设置文本样式
|
|
|
|
+ if (cell.fontColor) td.style.color = cell.fontColor
|
|
|
|
+ if (cell.fontSize) td.style.fontSize = cell.fontSize
|
|
|
|
+ if (cell.fontFamily) td.style.fontFamily = cell.fontFamily
|
|
|
|
+ if (cell.bold) td.style.fontWeight = 'bold'
|
|
|
|
+ if (cell.italic) td.style.fontStyle = 'italic'
|
|
|
|
+ if (cell.underline) td.style.textDecoration = 'underline'
|
|
|
|
+ if (cell.align) td.style.textAlign = cell.align
|
|
|
|
+
|
|
|
|
+ // 设置背景色
|
|
|
|
+ if (cell.fillColor) td.style.backgroundColor = cell.fillColor
|
|
|
|
+
|
|
|
|
+ // 设置单元格边框
|
|
|
|
+ if (cell.borders) {
|
|
|
|
+ if (cell.borders.all) {
|
|
|
|
+ const border = cell.borders.all
|
|
|
|
+ td.style.border = `${border.borderWidth || 1}px ${
|
|
|
|
+ border.borderType || 'solid'
|
|
|
|
+ } ${border.borderColor || '#000'}`
|
|
|
|
+ } else {
|
|
|
|
+ // 分别设置四边边框
|
|
|
|
+ if (cell.borders.top) {
|
|
|
|
+ td.style.borderTop = `${
|
|
|
|
+ cell.borders.top.borderWidth || 1
|
|
|
|
+ }px ${cell.borders.top.borderType || 'solid'} ${
|
|
|
|
+ cell.borders.top.borderColor || '#000'
|
|
|
|
+ }`
|
|
|
|
+ }
|
|
|
|
+ if (cell.borders.bottom) {
|
|
|
|
+ td.style.borderBottom = `${
|
|
|
|
+ cell.borders.bottom.borderWidth || 1
|
|
|
|
+ }px ${cell.borders.bottom.borderType || 'solid'} ${
|
|
|
|
+ cell.borders.bottom.borderColor || '#000'
|
|
|
|
+ }`
|
|
|
|
+ }
|
|
|
|
+ if (cell.borders.left) {
|
|
|
|
+ td.style.borderLeft = `${
|
|
|
|
+ cell.borders.left.borderWidth || 1
|
|
|
|
+ }px ${cell.borders.left.borderType || 'solid'} ${
|
|
|
|
+ cell.borders.left.borderColor || '#000'
|
|
|
|
+ }`
|
|
|
|
+ }
|
|
|
|
+ if (cell.borders.right) {
|
|
|
|
+ td.style.borderRight = `${
|
|
|
|
+ cell.borders.right.borderWidth || 1
|
|
|
|
+ }px ${cell.borders.right.borderType || 'solid'} ${
|
|
|
|
+ cell.borders.right.borderColor || '#000'
|
|
|
|
+ }`
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ td.style.width = element.colWidths[colIndex] + 'px'
|
|
|
|
+ // 设置单元格合并
|
|
|
|
+ if (cell.colSpan && cell.colSpan > 1) {
|
|
|
|
+ td.colSpan = cell.colSpan
|
|
|
|
+ td.style.width =
|
|
|
|
+ element.colWidths[colIndex] * cell.colSpan + 'px'
|
|
|
|
+ }
|
|
|
|
+ if (cell.rowSpan && cell.rowSpan > 1) {
|
|
|
|
+ td.rowSpan = cell.rowSpan
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ tr.appendChild(td)
|
|
|
|
+ })
|
|
|
|
+ tr.style.height = element.rowHeights[rowIndex] + 'px'
|
|
|
|
+ tbody.appendChild(tr)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ table.appendChild(tbody)
|
|
|
|
+ el.appendChild(table)
|
|
|
|
+
|
|
|
|
+ return el
|
|
|
|
+ },
|
|
|
|
+ // 创建图表元素
|
|
|
|
+ createChartElement (element) {
|
|
|
|
+ // 1. 创建基础容器
|
|
|
|
+ const el = document.createElement('div')
|
|
|
|
+ el.style.position = 'absolute'
|
|
|
|
+ el.style.top = element.top + 'px'
|
|
|
|
+ el.style.left = element.left + 'px'
|
|
|
|
+ el.style.width = element.width + 'px'
|
|
|
|
+ el.style.height = element.height + 'px'
|
|
|
|
+ el.style.zIndex = element.order
|
|
|
|
+ // 2. 创建SVG画布
|
|
|
|
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
|
|
|
+ svg.setAttribute('width', element.width)
|
|
|
|
+ svg.setAttribute('height', element.height)
|
|
|
|
+ svg.setAttribute('viewBox', `0 0 ${element.width} ${element.height}`)
|
|
|
|
+
|
|
|
|
+ // 3. 设置图表内边距
|
|
|
|
+ const padding = {
|
|
|
|
+ top: 60, // 为图例留出空间
|
|
|
|
+ right: 40, // 右侧边距
|
|
|
|
+ bottom: 60, // X轴标签空间
|
|
|
|
+ left: 60 // Y轴标签空间
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 4. 计算实际绘图区域
|
|
|
|
+ const chartWidth = element.width - padding.left - padding.right
|
|
|
|
+ const chartHeight = element.height - padding.top - padding.bottom
|
|
|
|
+ // 处理不同图表类型
|
|
|
|
+ switch (element.chartType) {
|
|
|
|
+ case 'barChart':
|
|
|
|
+ // 绘制柱状图
|
|
|
|
+ this.drawBarChart(svg, element, {
|
|
|
|
+ padding,
|
|
|
|
+ chartWidth,
|
|
|
|
+ chartHeight,
|
|
|
|
+ barDir: element.barDir || 'col',
|
|
|
|
+ grouping: element.grouping || 'clustered'
|
|
|
|
+ })
|
|
|
|
+ break
|
|
|
|
+ case 'pieChart':
|
|
|
|
+ case 'doughnutChart':
|
|
|
|
+ this.drawDonutChart(svg, element, chartWidth, chartHeight)
|
|
|
|
+ break
|
|
|
|
+ default:
|
|
|
|
+ console.warn('Unsupported chart type:', element.chartType)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ el.appendChild(svg)
|
|
|
|
+ return el
|
|
|
|
+ },
|
|
|
|
+ drawDonutChart (svg, element, chartWidth, chartHeight) {
|
|
|
|
+ // 计算饼图中心点和半径
|
|
|
|
+ const cx = element.width / 2
|
|
|
|
+ const cy = element.height / 2
|
|
|
|
+ const radius = Math.min(chartWidth, chartHeight) / 2
|
|
|
|
+
|
|
|
|
+ // 计算所有数据总和
|
|
|
|
+ const total = element.data[0].values.reduce(
|
|
|
|
+ (sum, item) => sum + item.y,
|
|
|
|
+ 0
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 创建颜色数组
|
|
|
|
+ const colors = element.colors || [
|
|
|
|
+ '#5B9BD5',
|
|
|
|
+ '#ED7D31',
|
|
|
|
+ '#A5A5A5',
|
|
|
|
+ '#FFC000'
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ let startAngle = 0
|
|
|
|
+ element.data[0].values.forEach((item, index) => {
|
|
|
|
+ // 计算扇形角度
|
|
|
|
+ const angle = (item.y / total) * Math.PI * 2
|
|
|
|
+
|
|
|
|
+ // 计算扇形路径
|
|
|
|
+ const endAngle = startAngle + angle
|
|
|
|
+ const x1 = cx + radius * Math.cos(startAngle)
|
|
|
|
+ const y1 = cy + radius * Math.sin(startAngle)
|
|
|
|
+ const x2 = cx + radius * Math.cos(endAngle)
|
|
|
|
+ const y2 = cy + radius * Math.sin(endAngle)
|
|
|
|
+
|
|
|
|
+ // 创建扇形路径
|
|
|
|
+ const path = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ const largeArcFlag = angle > Math.PI ? 1 : 0
|
|
|
|
+
|
|
|
|
+ // 根据是否为环形图决定内圆半径
|
|
|
|
+ const innerRadius =
|
|
|
|
+ element.chartType === 'doughnutChart' ? radius * 0.6 : 0
|
|
|
|
+ if (element.chartType === 'doughnutChart') {
|
|
|
|
+ // 环形图路径
|
|
|
|
+ const ix1 = cx + innerRadius * Math.cos(startAngle)
|
|
|
|
+ const iy1 = cy + innerRadius * Math.sin(startAngle)
|
|
|
|
+ const ix2 = cx + innerRadius * Math.cos(endAngle)
|
|
|
|
+ const iy2 = cy + innerRadius * Math.sin(endAngle)
|
|
|
|
+
|
|
|
|
+ path.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `
|
|
|
|
+ M ${x1} ${y1}
|
|
|
|
+ A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2}
|
|
|
|
+ L ${ix2} ${iy2}
|
|
|
|
+ A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} 0 ${ix1} ${iy1}
|
|
|
|
+ Z
|
|
|
|
+ `
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ // 饼图路径
|
|
|
|
+ path.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `
|
|
|
|
+ M ${cx} ${cy}
|
|
|
|
+ L ${x1} ${y1}
|
|
|
|
+ A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2}
|
|
|
|
+ Z
|
|
|
|
+ `
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置填充色
|
|
|
|
+ path.setAttribute('fill', colors[index % colors.length])
|
|
|
|
+ path.setAttribute('stroke', '#fff')
|
|
|
|
+ path.setAttribute('stroke-width', '1')
|
|
|
|
+ svg.appendChild(path)
|
|
|
|
+
|
|
|
|
+ // 添加数值标签
|
|
|
|
+ const labelAngle = startAngle + angle / 2
|
|
|
|
+ const labelRadius = radius * 1.1
|
|
|
|
+ const labelX = cx + labelRadius * Math.cos(labelAngle)
|
|
|
|
+ const labelY = cy + labelRadius * Math.sin(labelAngle)
|
|
|
|
+
|
|
|
|
+ const label = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'text'
|
|
|
|
+ )
|
|
|
|
+ label.setAttribute('x', labelX)
|
|
|
|
+ label.setAttribute('y', labelY)
|
|
|
|
+ label.setAttribute('text-anchor', 'middle')
|
|
|
|
+ label.setAttribute('alignment-baseline', 'middle')
|
|
|
|
+ label.setAttribute('font-size', '12px')
|
|
|
|
+ label.textContent = `${((item.y / total) * 100).toFixed(1)}%`
|
|
|
|
+ svg.appendChild(label)
|
|
|
|
+
|
|
|
|
+ startAngle = endAngle
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ // 绘制柱状图
|
|
|
|
+ drawBarChart (svg, element, options) {
|
|
|
|
+ const { padding, chartWidth, chartHeight, barDir, grouping } = options
|
|
|
|
+ const series = element.data
|
|
|
|
+ const categories = series[0].xlabels
|
|
|
|
+ const categoryCount = Object.keys(categories).length
|
|
|
|
+
|
|
|
|
+ // 1. 计算最大值
|
|
|
|
+ let maxValue = 0
|
|
|
|
+ series.forEach((serie) => {
|
|
|
|
+ const seriesMax = Math.max(...serie.values.map((v) => v.y))
|
|
|
|
+ maxValue = Math.max(maxValue, seriesMax)
|
|
|
|
+ })
|
|
|
|
+ maxValue = maxValue * 1.2 // 增加20%空间
|
|
|
|
+
|
|
|
|
+ // 2. 计算柱子布局
|
|
|
|
+ const groupWidth = chartWidth / categoryCount
|
|
|
|
+ const barWidth =
|
|
|
|
+ grouping === 'clustered'
|
|
|
|
+ ? (groupWidth * 0.6) / series.length // 分组模式
|
|
|
|
+ : groupWidth * 0.6 // 堆叠模式
|
|
|
|
+ const barSpacing =
|
|
|
|
+ (groupWidth * 0.4) / (grouping === 'clustered' ? series.length + 1 : 2)
|
|
|
|
+
|
|
|
|
+ // 3. 绘制坐标轴
|
|
|
|
+ // X轴
|
|
|
|
+ const xAxisPath = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ xAxisPath.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${padding.left},${element.height - padding.bottom} L${
|
|
|
|
+ element.width - padding.right
|
|
|
|
+ },${element.height - padding.bottom}`
|
|
|
|
+ )
|
|
|
|
+ xAxisPath.setAttribute('stroke', '#000')
|
|
|
|
+ xAxisPath.setAttribute('stroke-width', '1')
|
|
|
|
+ svg.appendChild(xAxisPath)
|
|
|
|
+
|
|
|
|
+ // Y轴
|
|
|
|
+ const yAxisPath = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'path'
|
|
|
|
+ )
|
|
|
|
+ yAxisPath.setAttribute(
|
|
|
|
+ 'd',
|
|
|
|
+ `M${padding.left},${padding.top} L${padding.left},${
|
|
|
|
+ element.height - padding.bottom
|
|
|
|
+ }`
|
|
|
|
+ )
|
|
|
|
+ yAxisPath.setAttribute('stroke', '#000')
|
|
|
|
+ yAxisPath.setAttribute('stroke-width', '1')
|
|
|
|
+ svg.appendChild(yAxisPath)
|
|
|
|
+
|
|
|
|
+ // 4. 绘制Y轴刻度和网格线
|
|
|
|
+ const yTickCount = 5
|
|
|
|
+ for (let i = 0; i <= yTickCount; i++) {
|
|
|
|
+ const y = padding.top + (chartHeight * i) / yTickCount
|
|
|
|
+ const value = maxValue - (maxValue * i) / yTickCount
|
|
|
|
+
|
|
|
|
+ // 水平网格线
|
|
|
|
+ const gridLine = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'line'
|
|
|
|
+ )
|
|
|
|
+ gridLine.setAttribute('x1', padding.left)
|
|
|
|
+ gridLine.setAttribute('y1', y)
|
|
|
|
+ gridLine.setAttribute('x2', padding.left + chartWidth)
|
|
|
|
+ gridLine.setAttribute('y2', y)
|
|
|
|
+ gridLine.setAttribute('stroke', '#eee')
|
|
|
|
+ gridLine.setAttribute('stroke-width', '1')
|
|
|
|
+ svg.appendChild(gridLine)
|
|
|
|
+
|
|
|
|
+ // 刻度线
|
|
|
|
+ const tick = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'line'
|
|
|
|
+ )
|
|
|
|
+ tick.setAttribute('x1', padding.left - 6)
|
|
|
|
+ tick.setAttribute('y1', y)
|
|
|
|
+ tick.setAttribute('x2', padding.left)
|
|
|
|
+ tick.setAttribute('y2', y)
|
|
|
|
+ tick.setAttribute('stroke', '#000')
|
|
|
|
+ tick.setAttribute('stroke-width', '1')
|
|
|
|
+ svg.appendChild(tick)
|
|
|
|
+
|
|
|
|
+ // 刻度值
|
|
|
|
+ const label = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'text'
|
|
|
|
+ )
|
|
|
|
+ label.setAttribute('x', padding.left - 10)
|
|
|
|
+ label.setAttribute('y', y + 4)
|
|
|
|
+ label.setAttribute('text-anchor', 'end')
|
|
|
|
+ label.setAttribute('font-size', '12px')
|
|
|
|
+ label.textContent = value.toFixed(1)
|
|
|
|
+ svg.appendChild(label)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 5. 绘制数据条
|
|
|
|
+ series.forEach((serie, serieIndex) => {
|
|
|
|
+ serie.values.forEach((value, index) => {
|
|
|
|
+ const barHeight = (value.y / maxValue) * chartHeight
|
|
|
|
+ const x =
|
|
|
|
+ padding.left +
|
|
|
|
+ groupWidth * index +
|
|
|
|
+ (grouping === 'clustered'
|
|
|
|
+ ? barSpacing * (serieIndex + 1) + barWidth * serieIndex
|
|
|
|
+ : barSpacing)
|
|
|
|
+ const y = element.height - padding.bottom - barHeight
|
|
|
|
+
|
|
|
|
+ // 绘制柱子
|
|
|
|
+ const bar = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'rect'
|
|
|
|
+ )
|
|
|
|
+ bar.setAttribute('x', x)
|
|
|
|
+ bar.setAttribute('y', y)
|
|
|
|
+ bar.setAttribute('width', barWidth)
|
|
|
|
+ bar.setAttribute('height', barHeight)
|
|
|
|
+ bar.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.colors[serieIndex] || `hsl(${serieIndex * 60}, 70%, 50%)`
|
|
|
|
+ )
|
|
|
|
+ svg.appendChild(bar)
|
|
|
|
+
|
|
|
|
+ // 数值标签
|
|
|
|
+ if (element.marker) {
|
|
|
|
+ const label = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'text'
|
|
|
|
+ )
|
|
|
|
+ label.setAttribute('x', x + barWidth / 2)
|
|
|
|
+ label.setAttribute('y', y - 5)
|
|
|
|
+ label.setAttribute('text-anchor', 'middle')
|
|
|
|
+ label.setAttribute('font-size', '12px')
|
|
|
|
+ label.textContent = value.y.toFixed(1)
|
|
|
|
+ svg.appendChild(label)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ // 6. 绘制X轴类别标签
|
|
|
|
+ Object.values(categories).forEach((label, index) => {
|
|
|
|
+ const x = padding.left + groupWidth * (index + 0.5)
|
|
|
|
+ const text = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'text'
|
|
|
|
+ )
|
|
|
|
+ text.setAttribute('x', x)
|
|
|
|
+ text.setAttribute('y', element.height - padding.bottom + 20)
|
|
|
|
+ text.setAttribute('text-anchor', 'middle')
|
|
|
|
+ text.setAttribute('font-size', '12px')
|
|
|
|
+ text.textContent = label
|
|
|
|
+ svg.appendChild(text)
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ // 7. 绘制图例
|
|
|
|
+ series.forEach((serie, index) => {
|
|
|
|
+ const legendX = padding.left + index * 120
|
|
|
|
+ const legendY = 20
|
|
|
|
+
|
|
|
|
+ const rect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'rect'
|
|
|
|
+ )
|
|
|
|
+ rect.setAttribute('x', legendX)
|
|
|
|
+ rect.setAttribute('y', legendY)
|
|
|
|
+ rect.setAttribute('width', 15)
|
|
|
|
+ rect.setAttribute('height', 15)
|
|
|
|
+ rect.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ element.colors[index] || `hsl(${index * 60}, 70%, 50%)`
|
|
|
|
+ )
|
|
|
|
+ svg.appendChild(rect)
|
|
|
|
+
|
|
|
|
+ const text = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'text'
|
|
|
|
+ )
|
|
|
|
+ text.setAttribute('x', legendX + 25)
|
|
|
|
+ text.setAttribute('y', legendY + 12)
|
|
|
|
+ text.setAttribute('font-size', '12px')
|
|
|
|
+ text.textContent = serie.key
|
|
|
|
+ svg.appendChild(text)
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ // 绘制网格和刻度
|
|
|
|
+ drawGrid (svg, padding, width, height, maxValue) {
|
|
|
|
+ const yTickCount = 5
|
|
|
|
+ for (let i = 0; i <= yTickCount; i++) {
|
|
|
|
+ const y = padding.top + (height * i) / yTickCount
|
|
|
|
+ const value = maxValue - (maxValue * i) / yTickCount
|
|
|
|
+
|
|
|
|
+ // 刻度线
|
|
|
|
+ const tick = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'line'
|
|
|
|
+ )
|
|
|
|
+ tick.setAttribute('x1', padding.left - 5)
|
|
|
|
+ tick.setAttribute('x2', padding.left)
|
|
|
|
+ tick.setAttribute('y1', y)
|
|
|
|
+ tick.setAttribute('y2', y)
|
|
|
|
+ tick.setAttribute('stroke', '#000')
|
|
|
|
+ svg.appendChild(tick)
|
|
|
|
+
|
|
|
|
+ // 刻度值
|
|
|
|
+ const label = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'text'
|
|
|
|
+ )
|
|
|
|
+ label.setAttribute('x', padding.left - 8)
|
|
|
|
+ label.setAttribute('y', y + 4)
|
|
|
|
+ label.setAttribute('text-anchor', 'end')
|
|
|
|
+ label.setAttribute('font-size', '12px')
|
|
|
|
+ label.textContent = value.toFixed(1)
|
|
|
|
+ svg.appendChild(label)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 绘制类别标签
|
|
|
|
+ drawCategoryLabels (svg, categories, padding, groupWidth, barDir) {
|
|
|
|
+ Object.values(categories).forEach((label, index) => {
|
|
|
|
+ const text = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'text'
|
|
|
|
+ )
|
|
|
|
+ if (barDir === 'col') {
|
|
|
|
+ text.setAttribute('x', padding.left + groupWidth * (index + 0.5))
|
|
|
|
+ text.setAttribute(
|
|
|
|
+ 'y',
|
|
|
|
+ svg.height.baseVal.value - padding.bottom + 20
|
|
|
|
+ )
|
|
|
|
+ text.setAttribute('text-anchor', 'middle')
|
|
|
|
+ } else {
|
|
|
|
+ text.setAttribute('x', padding.left - 10)
|
|
|
|
+ text.setAttribute('y', padding.top + groupWidth * (index + 0.5))
|
|
|
|
+ text.setAttribute('text-anchor', 'end')
|
|
|
|
+ text.setAttribute('dominant-baseline', 'middle')
|
|
|
|
+ }
|
|
|
|
+ text.setAttribute('font-size', '12px')
|
|
|
|
+ text.textContent = label
|
|
|
|
+ svg.appendChild(text)
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ // 绘制图例
|
|
|
|
+ drawLegend (svg, series, colors, padding) {
|
|
|
|
+ series.forEach((serie, index) => {
|
|
|
|
+ const legendX = padding.left + index * 100
|
|
|
|
+ const legendY = 20
|
|
|
|
+
|
|
|
|
+ const rect = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'rect'
|
|
|
|
+ )
|
|
|
|
+ rect.setAttribute('x', legendX)
|
|
|
|
+ rect.setAttribute('y', legendY)
|
|
|
|
+ rect.setAttribute('width', 15)
|
|
|
|
+ rect.setAttribute('height', 15)
|
|
|
|
+ rect.setAttribute(
|
|
|
|
+ 'fill',
|
|
|
|
+ colors[index] || `hsl(${index * 60}, 70%, 50%)`
|
|
|
|
+ )
|
|
|
|
+ svg.appendChild(rect)
|
|
|
|
+
|
|
|
|
+ const text = document.createElementNS(
|
|
|
|
+ 'http://www.w3.org/2000/svg',
|
|
|
|
+ 'text'
|
|
|
|
+ )
|
|
|
|
+ text.setAttribute('x', legendX + 20)
|
|
|
|
+ text.setAttribute('y', legendY + 12)
|
|
|
|
+ text.setAttribute('font-size', '12px')
|
|
|
|
+ text.textContent = serie.key
|
|
|
|
+ svg.appendChild(text)
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ // 创建SmartArt图表元素
|
|
|
|
+ createDiagramElement (element) {
|
|
|
|
+ const el = document.createElement('div')
|
|
|
|
+ el.style.position = 'absolute'
|
|
|
|
+ el.style.top = element.top + 'px'
|
|
|
|
+ el.style.left = element.left + 'px'
|
|
|
|
+ el.style.width = element.width + 'px'
|
|
|
|
+ el.style.height = element.height + 'px'
|
|
|
|
+ el.style.zIndex = element.order
|
|
|
|
+ // 递归渲染SmartArt节点
|
|
|
|
+ const renderDiagramNode = (node) => {
|
|
|
|
+ const nodeEl = document.createElement('div')
|
|
|
|
+ nodeEl.style.position = 'absolute'
|
|
|
|
+ nodeEl.style.left = node.left + 'px'
|
|
|
|
+ nodeEl.style.top = node.top + 'px'
|
|
|
|
+ nodeEl.style.width = node.width + 'px'
|
|
|
|
+ nodeEl.style.height = node.height + 'px'
|
|
|
|
+
|
|
|
|
+ // 设置边框
|
|
|
|
+ if (node.borderWidth > 0) {
|
|
|
|
+ nodeEl.style.border = `${node.borderWidth}px ${node.borderType} ${node.borderColor}`
|
|
|
|
+ if (
|
|
|
|
+ node.borderStrokeDasharray &&
|
|
|
|
+ node.borderStrokeDasharray !== '0'
|
|
|
|
+ ) {
|
|
|
|
+ nodeEl.style.borderStyle = 'dashed'
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置背景填充
|
|
|
|
+ if (node.fill && node.fill.type === 'color') {
|
|
|
|
+ nodeEl.style.backgroundColor = node.fill.value
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置内容
|
|
|
|
+ if (node.content) {
|
|
|
|
+ nodeEl.innerHTML = this.convertPtToPxInContent(node.content)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置垂直对齐
|
|
|
|
+ if (node.vAlign === 'mid') {
|
|
|
|
+ nodeEl.style.display = 'flex'
|
|
|
|
+ nodeEl.style.alignItems = 'center'
|
|
|
|
+ nodeEl.style.justifyContent = 'center'
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置翻转
|
|
|
|
+ const transforms = []
|
|
|
|
+ if (node.isFlipV) {
|
|
|
|
+ transforms.push('scaleY(-1)')
|
|
|
|
+ }
|
|
|
|
+ if (node.isFlipH) {
|
|
|
|
+ transforms.push('scaleX(-1)')
|
|
|
|
+ }
|
|
|
|
+ if (transforms.length > 0) {
|
|
|
|
+ nodeEl.style.transform = transforms.join(' ')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nodeEl
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 按照 order 排序元素
|
|
|
|
+ const sortedElements = [...element.elements].sort(
|
|
|
|
+ (a, b) => a.order - b.order
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 渲染所有节点
|
|
|
|
+ sortedElements.forEach((node) => {
|
|
|
|
+ const nodeEl = renderDiagramNode(node)
|
|
|
|
+ el.appendChild(nodeEl)
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ return el
|
|
|
|
+ },
|
|
|
|
+ // 创建数学公式元素
|
|
|
|
+ createMathElement (element) {
|
|
|
|
+ const el = document.createElement('div')
|
|
|
|
+ el.style.position = 'absolute'
|
|
|
|
+ el.style.top = element.top + 'px'
|
|
|
|
+ el.style.left = element.left + 'px'
|
|
|
|
+ el.style.width = element.width + 'px'
|
|
|
|
+ el.style.height = element.height + 'px'
|
|
|
|
+
|
|
|
|
+ // 如果有公式图片,优先使用图片显示
|
|
|
|
+ if (element.picBase64) {
|
|
|
|
+ const img = document.createElement('img')
|
|
|
|
+ img.src = element.picBase64
|
|
|
|
+ img.style.width = '100%'
|
|
|
|
+ img.style.height = '100%'
|
|
|
|
+ img.style.objectFit = 'contain'
|
|
|
|
+ el.appendChild(img)
|
|
|
|
+ return el
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 如果有 LaTeX 表达式,使用 MathJax 渲染
|
|
|
|
+ if (element.latex) {
|
|
|
|
+ // 创建公式容器
|
|
|
|
+ const mathContainer = document.createElement('div')
|
|
|
|
+ mathContainer.style.width = '100%'
|
|
|
|
+ mathContainer.style.height = '100%'
|
|
|
|
+ mathContainer.style.display = 'flex'
|
|
|
|
+ mathContainer.style.alignItems = 'center'
|
|
|
|
+ mathContainer.style.justifyContent = 'center'
|
|
|
|
+
|
|
|
|
+ // 添加 LaTeX 公式
|
|
|
|
+ mathContainer.innerHTML = `\\[${element.latex}\\]`
|
|
|
|
+
|
|
|
|
+ // 如果 MathJax 不可用,显示原始 LaTeX
|
|
|
|
+ mathContainer.style.fontFamily = 'monospace'
|
|
|
|
+ mathContainer.style.whiteSpace = 'pre-wrap'
|
|
|
|
+ mathContainer.style.padding = '10px'
|
|
|
|
+ mathContainer.textContent = element.latex
|
|
|
|
+
|
|
|
|
+ el.appendChild(mathContainer)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return el
|
|
|
|
+ },
|
|
|
|
+ // 创建文本元素
|
|
|
|
+ createTextElement (element) {
|
|
|
|
+ const el = document.createElement('div')
|
|
|
|
+ if (element.content) {
|
|
|
|
+ // 转换内容中的pt单位为px单位
|
|
|
|
+ const convertedContent = this.convertPtToPxInContent(element.content)
|
|
|
|
+ el.innerHTML = convertedContent
|
|
|
|
+
|
|
|
|
+ // 设置文本样式
|
|
|
|
+ el.style.width = element.width + 'px'
|
|
|
|
+ el.style.height = element.height + 'px'
|
|
|
|
+ el.style.color = element.fontColor || '#000'
|
|
|
|
+ el.style.fontSize = element.fontSize
|
|
|
|
+ el.style.fontFamily = element.fontFamily || 'Arial'
|
|
|
|
+ el.style.textAlign = element.align || 'left'
|
|
|
|
+ el.style.fontWeight = element.bold ? 'bold' : 'normal'
|
|
|
|
+ el.style.fontStyle = element.italic ? 'italic' : 'normal'
|
|
|
|
+ el.style.textDecoration = element.underline ? 'underline' : 'none'
|
|
|
|
+ el.style.position = 'absolute'
|
|
|
|
+ el.style.top = element.top + 'px' || '0'
|
|
|
|
+ el.style.left = element.left + 'px' || '0'
|
|
|
|
+ el.style.whiteSpace = element.wrapText ? 'normal' : 'nowrap'
|
|
|
|
+ el.style.overflow = element.wrapText ? 'visible' : 'hidden'
|
|
|
|
+ el.style.textOverflow = element.wrapText ? 'ellipsis' : 'clip'
|
|
|
|
+ el.style.zIndex = element.order
|
|
|
|
+ el.style.whiteSpace = 'pre-wrap'
|
|
|
|
+ // 设置段落间距
|
|
|
|
+ el.style.lineHeight = element.lineHeight + 'px' || '1.2'
|
|
|
|
+ el.style.letterSpacing = element.charSpacing
|
|
|
|
+ ? `${element.charSpacing}px`
|
|
|
|
+ : 'normal'
|
|
|
|
+ }
|
|
|
|
+ return el
|
|
|
|
+ },
|
|
|
|
+ // 调整颜色明暗度
|
|
|
|
+ adjustBrightness (color, factor) {
|
|
|
|
+ if (color === 'transparent') return color
|
|
|
|
+ const hex = color.replace('#', '')
|
|
|
|
+ const r = Math.min(
|
|
|
|
+ 255,
|
|
|
|
+ Math.round(parseInt(hex.substr(0, 2), 16) * factor)
|
|
|
|
+ )
|
|
|
|
+ const g = Math.min(
|
|
|
|
+ 255,
|
|
|
|
+ Math.round(parseInt(hex.substr(2, 2), 16) * factor)
|
|
|
|
+ )
|
|
|
|
+ const b = Math.min(
|
|
|
|
+ 255,
|
|
|
|
+ Math.round(parseInt(hex.substr(4, 2), 16) * factor)
|
|
|
|
+ )
|
|
|
|
+ return `#${r.toString(16).padStart(2, '0')}${g
|
|
|
|
+ .toString(16)
|
|
|
|
+ .padStart(2, '0')}${b.toString(16).padStart(2, '0')}`
|
|
|
|
+ },
|
|
|
|
+ // 新增函数:转换内容中的pt单位为px单位
|
|
|
|
+ convertPtToPxInContent (content) {
|
|
|
|
+ if (!content) return content
|
|
|
|
+ // 使用正则表达式查找并替换
|
|
|
|
+ return content.replace(
|
|
|
|
+ /font-size:\s*(\d+)(pt|PT)/g,
|
|
|
|
+ (match, size, unit) => {
|
|
|
|
+ // 将pt转换为px
|
|
|
|
+ const pxSize = size
|
|
|
|
+ return `font-size: ${pxSize}px`
|
|
|
|
+ }
|
|
|
|
+ )
|
|
|
|
+ },
|
|
|
|
+ processElements (elements, slideIndex) {
|
|
|
|
+ if (!elements || !Array.isArray(elements)) return
|
|
|
|
+
|
|
|
|
+ // 使用 Map 存储原始顺序,避免多次排序
|
|
|
|
+ const orderMap = new Map(
|
|
|
|
+ elements.map((el, index) => [el, el.order || index])
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // 一次性排序
|
|
|
|
+ elements.sort((a, b) => orderMap.get(a) - orderMap.get(b))
|
|
|
|
+
|
|
|
|
+ const processElement = (element, baseOrder) => {
|
|
|
|
+ // 设置当前元素的 order
|
|
|
|
+ element.order = baseOrder
|
|
|
|
+
|
|
|
|
+ // 如果有子元素,递归处理
|
|
|
|
+ if (element.elements?.length > 0) {
|
|
|
|
+ element.elements
|
|
|
|
+ .sort((a, b) => (a.order || 0) - (b.order || 0))
|
|
|
|
+ .forEach((child, idx) => {
|
|
|
|
+ processElement(child, baseOrder * 10 + idx + 1)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 处理每个顶层元素
|
|
|
|
+ elements.forEach((element, index) => {
|
|
|
|
+ processElement(element, (slideIndex + 1) * 10 + index + 1)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</script>
|
|
|
|
+<style scoped lang="less">
|
|
|
|
+//滚动条
|
|
|
|
+.pptx-container {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ z-index: 99;
|
|
|
|
+}
|
|
|
|
+</style>
|