536 lines
15 KiB
Java
536 lines
15 KiB
Java
import { cos, sin } from '@/utils/translate'
|
|
import {
|
|
DEFAULT_COLOR_CASE,
|
|
DEFAULT_COLOR_CASE_DARK
|
|
} from '@/views/chart/components/editor/util/chart'
|
|
|
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
|
import { useEmitt } from '@/hooks/web/useEmitt'
|
|
import { merge } from 'lodash-es'
|
|
const dvMainStore = dvMainStoreWithOut()
|
|
|
|
export const LIGHT_THEME_COLOR_MAIN = '#000000'
|
|
export const LIGHT_THEME_COLOR_SLAVE1 = '#CCCCCC'
|
|
export const LIGHT_THEME_DASHBOARD_BACKGROUND = '#f5f6f7'
|
|
export const LIGHT_THEME_COMPONENT_BACKGROUND = '#FFFFFF'
|
|
|
|
export const DARK_THEME_COLOR_MAIN = '#FFFFFF'
|
|
export const DARK_THEME_COLOR_SLAVE1 = '#858383'
|
|
export const DARK_THEME_DASHBOARD_BACKGROUND = '#030B2E'
|
|
export const DARK_THEME_COMPONENT_BACKGROUND = '#131E42'
|
|
export const DARK_THEME_COMPONENT_BACKGROUND_BACK = '#5a5c62'
|
|
|
|
export function getStyle(style, filter = []) {
|
|
const needUnit = [
|
|
'fontSize',
|
|
'width',
|
|
'height',
|
|
'top',
|
|
'left',
|
|
'borderWidth',
|
|
'letterSpacing',
|
|
'borderRadius',
|
|
'margin',
|
|
'padding'
|
|
]
|
|
|
|
const result = {}
|
|
Object.keys(style).forEach(key => {
|
|
if (!filter.includes(key)) {
|
|
if (key !== 'rotate') {
|
|
result[key] = style[key]
|
|
if (key) {
|
|
if (key === 'backgroundColor') {
|
|
result[key] = colorRgb(style[key], style.opacity)
|
|
}
|
|
if (key === 'fontSize' && result[key] < 12) {
|
|
result[key] = 12
|
|
}
|
|
if (needUnit.includes(key)) {
|
|
result[key] += 'px'
|
|
}
|
|
}
|
|
} else {
|
|
result['transform'] = key + '(' + style[key] + 'deg)'
|
|
}
|
|
}
|
|
})
|
|
if (result['backgroundColor'] && (result['opacity'] || result['opacity'] === 0)) {
|
|
delete result['opacity']
|
|
}
|
|
return result
|
|
}
|
|
|
|
// 获取一个组件旋转 rotate 后的样式
|
|
export function getComponentRotatedStyle(style) {
|
|
style = { ...style }
|
|
if (style.rotate !== 0) {
|
|
const newWidth = style.width * cos(style.rotate) + style.height * sin(style.rotate)
|
|
const diffX = (style.width - newWidth) / 2 // 旋转后范围变小是正值,变大是负值
|
|
style.left += diffX
|
|
style.right = style.left + newWidth
|
|
|
|
const newHeight = style.height * cos(style.rotate) + style.width * sin(style.rotate)
|
|
const diffY = (newHeight - style.height) / 2 // 始终是正
|
|
style.top -= diffY
|
|
style.bottom = style.top + newHeight
|
|
|
|
style.width = newWidth
|
|
style.height = newHeight
|
|
} else {
|
|
style.bottom = style.top + style.height
|
|
style.right = style.left + style.width
|
|
}
|
|
|
|
return style
|
|
}
|
|
|
|
export function colorRgb(color, opacity) {
|
|
const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
|
|
let sColor = color
|
|
if (sColor && reg.test(sColor)) {
|
|
sColor = sColor.toLowerCase()
|
|
if (sColor.length === 4) {
|
|
let sColorNew = '#'
|
|
for (let i = 1; i < 4; i += 1) {
|
|
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
|
|
}
|
|
sColor = sColorNew
|
|
}
|
|
// 处理六位的颜色值
|
|
const sColorChange = []
|
|
for (let i = 1; i < 7; i += 2) {
|
|
sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)))
|
|
}
|
|
if (opacity || opacity === 0) {
|
|
return 'rgba(' + sColorChange.join(',') + ',' + opacity + ')'
|
|
} else {
|
|
return 'rgba(' + sColorChange.join(',') + ')'
|
|
}
|
|
} else {
|
|
return sColor
|
|
}
|
|
}
|
|
|
|
export const customAttrTrans = {
|
|
basicStyle: ['barWidth', 'lineWidth', 'lineSymbolSize'],
|
|
tableHeader: ['tableTitleFontSize', 'tableTitleHeight'],
|
|
tableCell: ['tableItemFontSize', 'tableItemHeight'],
|
|
misc: [
|
|
'nameFontSize',
|
|
'valueFontSize',
|
|
'spaceSplit', // 间隔
|
|
'scatterSymbolSize', // 气泡大小,散点图
|
|
'radarSize', // 雷达占比
|
|
'wordSizeRange',
|
|
'wordSpacing'
|
|
],
|
|
label: {
|
|
fontSize: '',
|
|
seriesLabelFormatter: ['fontSize']
|
|
},
|
|
tooltip: {
|
|
fontSize: '',
|
|
seriesTooltipFormatter: ['fontSize']
|
|
},
|
|
indicator: ['fontSize', 'suffixFontSize'],
|
|
indicatorName: ['fontSize', 'nameValueSpacing']
|
|
}
|
|
export const customStyleTrans = {
|
|
text: ['fontSize'],
|
|
legend: ['fontSize'],
|
|
xAxis: {
|
|
fontSize: 'fontSize',
|
|
axisLabel: ['fontSize'],
|
|
splitLine: {
|
|
lineStyle: ['width']
|
|
}
|
|
},
|
|
yAxis: {
|
|
fontSize: 'fontSize',
|
|
axisLabel: ['fontSize'],
|
|
splitLine: {
|
|
lineStyle: ['width']
|
|
}
|
|
},
|
|
yAxisExt: {
|
|
fontSize: 'fontSize',
|
|
axisLabel: ['fontSize'],
|
|
splitLine: {
|
|
lineStyle: ['width']
|
|
}
|
|
},
|
|
misc: {
|
|
fontSize: 'fontSize',
|
|
axisLine: {
|
|
lineStyle: ['width']
|
|
},
|
|
axisTick: {
|
|
lineStyle: ['width']
|
|
},
|
|
axisLabel: ['margin', 'fontSize'],
|
|
splitLine: {
|
|
lineStyle: ['width']
|
|
}
|
|
}
|
|
}
|
|
|
|
export const THEME_STYLE_TRANS_MAIN_BACK = {
|
|
legend: {
|
|
textStyle: ['color']
|
|
},
|
|
xAxis: {
|
|
nameTextStyle: ['color'],
|
|
axisLabel: ['color'],
|
|
splitLine: {
|
|
lineStyle: ['color']
|
|
}
|
|
},
|
|
yAxis: {
|
|
nameTextStyle: ['color'],
|
|
axisLabel: ['color'],
|
|
splitLine: {
|
|
lineStyle: ['color']
|
|
}
|
|
},
|
|
yAxisExt: {
|
|
nameTextStyle: ['color'],
|
|
axisLabel: ['color'],
|
|
splitLine: {
|
|
lineStyle: ['color']
|
|
}
|
|
},
|
|
split: {
|
|
name: ['color'],
|
|
axisLine: {
|
|
lineStyle: ['color']
|
|
},
|
|
axisTick: {
|
|
lineStyle: ['color']
|
|
},
|
|
axisLabel: ['color'],
|
|
splitLine: {
|
|
lineStyle: ['color']
|
|
}
|
|
}
|
|
}
|
|
|
|
export const THEME_STYLE_TRANS_MAIN = {
|
|
legend: ['color'],
|
|
xAxis: {
|
|
// 一级属性直接字符串
|
|
color: 'color',
|
|
axisLabel: ['color']
|
|
},
|
|
yAxis: {
|
|
color: '',
|
|
axisLabel: ['color']
|
|
},
|
|
yAxisExt: {
|
|
color: '',
|
|
axisLabel: ['color']
|
|
},
|
|
misc: {
|
|
color: 'color',
|
|
axisTick: {
|
|
lineStyle: ['color']
|
|
},
|
|
axisLabel: ['color']
|
|
}
|
|
}
|
|
|
|
export const THEME_STYLE_TRANS_SLAVE1 = {
|
|
xAxis: {
|
|
splitLine: {
|
|
lineStyle: ['color']
|
|
}
|
|
},
|
|
yAxis: {
|
|
splitLine: {
|
|
lineStyle: ['color']
|
|
}
|
|
},
|
|
yAxisExt: {
|
|
splitLine: {
|
|
lineStyle: ['color']
|
|
}
|
|
},
|
|
misc: {
|
|
splitLine: {
|
|
lineStyle: ['color']
|
|
},
|
|
axisLine: {
|
|
lineStyle: ['color']
|
|
}
|
|
}
|
|
}
|
|
|
|
export const THEME_ATTR_TRANS_MAIN = {
|
|
label: ['color'],
|
|
tooltip: ['color'],
|
|
indicatorName: ['color']
|
|
}
|
|
|
|
export const THEME_ATTR_TRANS_MAIN_SYMBOL = {
|
|
label: ['color']
|
|
}
|
|
|
|
export const THEME_ATTR_TRANS_SLAVE1_BACKGROUND = {
|
|
tooltip: ['backgroundColor']
|
|
}
|
|
|
|
// 移动端特殊属性
|
|
export const mobileSpecialProps = {
|
|
lineWidth: 2, // 线宽固定值
|
|
lineSymbolSize: 8 // 折点固定值
|
|
}
|
|
|
|
export function getScaleValue(propValue, scale) {
|
|
if (propValue instanceof Array) {
|
|
propValue.forEach((v, i) => {
|
|
const val = Math.round(v * scale)
|
|
propValue[i] = val > 1 ? val : 1
|
|
})
|
|
return propValue
|
|
}
|
|
const propValueTemp = Math.round(propValue * scale)
|
|
return propValueTemp > 1 ? propValueTemp : 1
|
|
}
|
|
export const THEME_ATTR_TRANS_ARR_MAIN = {
|
|
label: {
|
|
seriesLabelFormatter: {
|
|
isArray: []
|
|
}
|
|
}
|
|
}
|
|
|
|
export function seriesAdaptor(template, color) {
|
|
template.label?.seriesLabelFormatter?.forEach(series => {
|
|
series['color'] = color
|
|
})
|
|
|
|
template.label?.seriesTooltipFormatter?.forEach(series => {
|
|
series['color'] = color
|
|
})
|
|
}
|
|
|
|
export function recursionTransObj(template, infoObj, scale, terminal) {
|
|
for (const templateKey in template) {
|
|
// 如果是数组 进行赋值计算
|
|
if (template[templateKey] instanceof Array) {
|
|
// 词云图的大小区间,不需要缩放
|
|
template[templateKey]
|
|
.filter(field => field !== 'wordSizeRange')
|
|
.forEach(templateProp => {
|
|
if (
|
|
infoObj[templateKey] &&
|
|
(infoObj[templateKey][templateProp] || infoObj[templateKey].length)
|
|
) {
|
|
// 移动端特殊属性值设置
|
|
if (terminal === 'mobile' && mobileSpecialProps[templateProp] !== undefined) {
|
|
infoObj[templateKey][templateProp] = mobileSpecialProps[templateProp]
|
|
} else {
|
|
// 数组依次设置
|
|
if (infoObj[templateKey] instanceof Array) {
|
|
infoObj[templateKey].forEach(v => {
|
|
v[templateProp] = getScaleValue(v[templateProp], scale)
|
|
})
|
|
} else {
|
|
infoObj[templateKey][templateProp] = getScaleValue(
|
|
infoObj[templateKey][templateProp],
|
|
scale
|
|
)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
} else if (typeof template[templateKey] === 'string') {
|
|
// 一级字段为字符串直接赋值
|
|
infoObj[templateKey] = getScaleValue(infoObj[templateKey], scale)
|
|
} else {
|
|
// 如果是对象 继续进行递归
|
|
if (infoObj[templateKey]) {
|
|
recursionTransObj(template[templateKey], infoObj[templateKey], scale, terminal)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export function recursionThemTransObj(template, infoObj, color) {
|
|
for (const templateKey in template) {
|
|
// 如果是数组 进行赋值计算
|
|
if (template[templateKey] instanceof Array) {
|
|
template[templateKey].forEach(templateProp => {
|
|
if (infoObj[templateKey]) {
|
|
infoObj[templateKey][templateProp] = color
|
|
}
|
|
})
|
|
} else if (typeof template[templateKey] === 'string') {
|
|
// 一级字段为字符串直接赋值
|
|
infoObj[templateKey] = color
|
|
} else {
|
|
// 如果是对象 继续进行递归
|
|
if (infoObj[templateKey]) {
|
|
recursionThemTransObj(template[templateKey], infoObj[templateKey], color)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export function componentScalePublic(chartInfo, heightScale, widthScale) {
|
|
const scale = Math.min(heightScale, widthScale)
|
|
// attr 缩放转换
|
|
recursionTransObj(this.customAttrTrans, chartInfo.customAttr, scale, null)
|
|
// style 缩放转换
|
|
recursionTransObj(this.customStyleTrans, chartInfo.customStyle, scale, null)
|
|
return chartInfo
|
|
}
|
|
|
|
export function adaptCurTheme(customStyle, customAttr) {
|
|
const canvasStyle = dvMainStore.canvasStyleData
|
|
const themeColor = canvasStyle.dashboard.themeColor
|
|
if (themeColor === 'light') {
|
|
recursionThemTransObj(THEME_STYLE_TRANS_MAIN, customStyle, LIGHT_THEME_COLOR_MAIN)
|
|
recursionThemTransObj(THEME_STYLE_TRANS_SLAVE1, customStyle, LIGHT_THEME_COLOR_SLAVE1)
|
|
recursionThemTransObj(THEME_ATTR_TRANS_MAIN, customAttr, LIGHT_THEME_COLOR_MAIN)
|
|
recursionThemTransObj(
|
|
THEME_ATTR_TRANS_SLAVE1_BACKGROUND,
|
|
customAttr,
|
|
LIGHT_THEME_COMPONENT_BACKGROUND
|
|
)
|
|
seriesAdaptor(customAttr, LIGHT_THEME_COLOR_MAIN)
|
|
merge(customAttr, DEFAULT_COLOR_CASE, canvasStyle.component.chartColor)
|
|
} else {
|
|
recursionThemTransObj(THEME_STYLE_TRANS_MAIN, customStyle, DARK_THEME_COLOR_MAIN)
|
|
recursionThemTransObj(THEME_STYLE_TRANS_SLAVE1, customStyle, DARK_THEME_COLOR_SLAVE1)
|
|
recursionThemTransObj(THEME_ATTR_TRANS_MAIN, customAttr, DARK_THEME_COLOR_MAIN)
|
|
recursionThemTransObj(
|
|
THEME_ATTR_TRANS_SLAVE1_BACKGROUND,
|
|
customAttr,
|
|
DARK_THEME_COMPONENT_BACKGROUND_BACK
|
|
)
|
|
seriesAdaptor(customAttr, DARK_THEME_COLOR_MAIN)
|
|
merge(customAttr, DEFAULT_COLOR_CASE_DARK, canvasStyle.component.chartColor)
|
|
}
|
|
customStyle['text'] = {
|
|
...canvasStyle.component.chartTitle,
|
|
title: customStyle['text']['title'],
|
|
show: customStyle['text']['show'],
|
|
remarkShow: customStyle['text']['remarkShow'],
|
|
remark: customStyle['text']['remark']
|
|
}
|
|
}
|
|
|
|
export function adaptCurThemeCommonStyle(component) {
|
|
if (['DeTabs'].includes(component.component)) {
|
|
component.commonBackground['innerPadding'] = 0
|
|
}
|
|
// 背景融合-Begin 如果是大屏['CanvasBoard', 'CanvasIcon', 'Picture']组件不需要设置背景
|
|
if (
|
|
dvMainStore.dvInfo.type === 'dataV' &&
|
|
['CanvasBoard', 'CanvasIcon', 'Picture', 'Group', 'SvgTriangle', 'SvgStar'].includes(
|
|
component.component
|
|
)
|
|
) {
|
|
component.commonBackground['backgroundColorSelect'] = false
|
|
component.commonBackground['innerPadding'] = 0
|
|
} else {
|
|
const commonStyle = dvMainStore.canvasStyleData.component.chartCommonStyle
|
|
for (const key in commonStyle) {
|
|
component.commonBackground[key] = commonStyle[key]
|
|
}
|
|
}
|
|
// 背景融合-End
|
|
// 通用样式-Begin
|
|
if (component.style.color) {
|
|
if (dvMainStore.canvasStyleData.dashboard.themeColor === 'light') {
|
|
component.style.color = LIGHT_THEME_COLOR_MAIN
|
|
} else {
|
|
component.style.color = DARK_THEME_COLOR_MAIN
|
|
}
|
|
}
|
|
if (component.component === 'UserView') {
|
|
// 图表-Begin
|
|
const curViewInfo = dvMainStore.canvasViewInfo[component.id]
|
|
adaptCurTheme(curViewInfo.customStyle, curViewInfo.customAttr)
|
|
useEmitt().emitter.emit('renderChart-' + component.id, curViewInfo)
|
|
// 图表-Begin
|
|
} else if (component.component === 'Group') {
|
|
component.propValue.forEach(groupItem => {
|
|
adaptCurThemeCommonStyle(groupItem)
|
|
})
|
|
} else if (component.component === 'DeTabs') {
|
|
if (dvMainStore.canvasStyleData.dashboard.themeColor === 'light') {
|
|
component.style.headFontColor = LIGHT_THEME_COLOR_MAIN
|
|
component.style.headFontActiveColor = LIGHT_THEME_COLOR_MAIN
|
|
} else {
|
|
component.style.headFontColor = DARK_THEME_COLOR_MAIN
|
|
component.style.headFontActiveColor = DARK_THEME_COLOR_MAIN
|
|
}
|
|
component.propValue.forEach(tabItem => {
|
|
tabItem.componentData.forEach(tabComponent => {
|
|
adaptCurThemeCommonStyle(tabComponent)
|
|
})
|
|
})
|
|
} else if (component.component === 'VQuery') {
|
|
const viewInfo = dvMainStore.canvasViewInfo[component.id]
|
|
if (viewInfo) {
|
|
adaptCurThemeFilterStyleAllKeyComponent(viewInfo)
|
|
}
|
|
}
|
|
|
|
return component
|
|
}
|
|
|
|
export function adaptCurThemeCommonStyleAll() {
|
|
const componentData = dvMainStore.componentData
|
|
componentData.forEach(item => {
|
|
adaptCurThemeCommonStyle(item)
|
|
})
|
|
}
|
|
|
|
interface CanvasViewInfo {
|
|
type: string
|
|
customStyle: {
|
|
component: object
|
|
}
|
|
}
|
|
|
|
const colors = ['labelColor', 'borderColor', 'text', 'bgColor']
|
|
const colorsSwitch = ['borderShow', 'textColorShow', 'bgColorShow']
|
|
|
|
export function adaptCurThemeFilterStyleAllKeyComponent(component) {
|
|
if (isFilterComponent(component.type)) {
|
|
const filterStyle = dvMainStore.canvasStyleData.component.filterStyle
|
|
colors.forEach(styleKey => {
|
|
component.customStyle.component[styleKey] = filterStyle[styleKey]
|
|
const index = colors.indexOf(styleKey)
|
|
if (index !== -1) {
|
|
component.customStyle.component[colorsSwitch[index]] = true
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
export function adaptCurThemeFilterStyleAll(styleKey) {
|
|
const componentViewData = Object.values(dvMainStore.canvasViewInfo) as CanvasViewInfo[]
|
|
const filterStyle = dvMainStore.canvasStyleData.component.filterStyle
|
|
componentViewData.forEach(item => {
|
|
if (isFilterComponent(item.type)) {
|
|
item.customStyle.component[styleKey] = filterStyle[styleKey]
|
|
const index = colors.indexOf(styleKey)
|
|
if (index !== -1) {
|
|
item.customStyle.component[colorsSwitch[index]] = true
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
export function isFilterComponent(component) {
|
|
return ['VQuery'].includes(component)
|
|
}
|
|
|
|
export function isTabComponent(component) {
|
|
return ['DeTabs'].includes(component)
|
|
}
|