faet(视图): AntV 折线图支持趋势线
This commit is contained in:
parent
599fb1d9e5
commit
12b33f2528
@ -1643,7 +1643,16 @@ export default {
|
||||
word_size_range: 'Word Size Range',
|
||||
word_spacing: 'Word Spacing',
|
||||
axis_multi_select_tip: 'Hold down the Ctrl/Cmd or Shift key and click to select more than one',
|
||||
needs_to_be_integer: 'Needs to be an integer'
|
||||
needs_to_be_integer: 'Needs to be an integer',
|
||||
regression_poly: 'Polynomial',
|
||||
regression_linear: 'Linear',
|
||||
regression_exp: 'Exponential',
|
||||
regression_log: 'Logarithmic',
|
||||
regression_quad: 'Quadratic',
|
||||
regression_pow: 'Power law',
|
||||
regression_loess: 'LOESS',
|
||||
regression_algo: 'Algorithm',
|
||||
trend_line: 'Trend Line'
|
||||
},
|
||||
dataset: {
|
||||
scope_edit: 'Effective only when editing',
|
||||
|
||||
@ -1635,7 +1635,16 @@ export default {
|
||||
word_size_range: '字號區間',
|
||||
word_spacing: '文字間隔',
|
||||
axis_multi_select_tip: '按住 Ctrl/Cmd 鍵或者 Shift 鍵再點擊可多選',
|
||||
needs_to_be_integer: '需要為整數'
|
||||
needs_to_be_integer: '需要為整數',
|
||||
regression_poly: '多項式',
|
||||
regression_linear: '線性',
|
||||
regression_exp: '指數',
|
||||
regression_log: '對數',
|
||||
regression_quad: '二次項',
|
||||
regression_pow: '冪函數',
|
||||
regression_loess: '局部加權',
|
||||
regression_algo: '算法',
|
||||
trend_line: '趨勢線'
|
||||
},
|
||||
dataset: {
|
||||
scope_edit: '僅編輯時生效',
|
||||
|
||||
@ -1635,7 +1635,16 @@ export default {
|
||||
word_size_range: '字号区间',
|
||||
word_spacing: '文字间隔',
|
||||
axis_multi_select_tip: '按住 Ctrl/Cmd 键或者 Shift 键再点击可多选',
|
||||
needs_to_be_integer: '需要为整数'
|
||||
needs_to_be_integer: '需要为整数',
|
||||
regression_poly: '多项式',
|
||||
regression_linear: '线性',
|
||||
regression_exp: '指数',
|
||||
regression_log: '对数',
|
||||
regression_quad: '二次项',
|
||||
regression_pow: '幂函数',
|
||||
regression_loess: '局部加权',
|
||||
regression_algo: '算法',
|
||||
trend_line: '趋势线'
|
||||
},
|
||||
dataset: {
|
||||
scope_edit: '仅编辑时生效',
|
||||
|
||||
@ -16,7 +16,7 @@ import {
|
||||
import { antVCustomColor, getColors, handleEmptyDataStrategy, hexColorToRGBA } from '@/views/chart/chart/util'
|
||||
import { cloneDeep, find } from 'lodash-es'
|
||||
|
||||
export function baseBarOptionAntV(plot, container, chart, action, isGroup, isStack) {
|
||||
export function baseBarOptionAntV(container, chart, action, isGroup, isStack) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -132,19 +132,15 @@ export function baseBarOptionAntV(plot, container, chart, action, isGroup, isSta
|
||||
}
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Column(container, options)
|
||||
const plot = new Column(container, options)
|
||||
|
||||
plot.off('interval:click')
|
||||
plot.on('interval:click', action)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
return plot
|
||||
}
|
||||
|
||||
export function hBaseBarOptionAntV(plot, container, chart, action, isGroup, isStack) {
|
||||
export function hBaseBarOptionAntV(container, chart, action, isGroup, isStack) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -252,20 +248,15 @@ export function hBaseBarOptionAntV(plot, container, chart, action, isGroup, isSt
|
||||
handleEmptyDataStrategy(emptyDataStrategy, chart, data, options)
|
||||
}
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Bar(container, options)
|
||||
const plot = new Bar(container, options)
|
||||
|
||||
plot.off('interval:click')
|
||||
plot.on('interval:click', action)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
return plot
|
||||
}
|
||||
|
||||
export function timeRangeBarOptionAntV(plot, container, chart, action) {
|
||||
export function timeRangeBarOptionAntV(container, chart, action) {
|
||||
const ifAggregate = !!chart.aggregate
|
||||
|
||||
// theme
|
||||
@ -446,11 +437,7 @@ export function timeRangeBarOptionAntV(plot, container, chart, action) {
|
||||
handleEmptyDataStrategy(emptyDataStrategy, chart, data, options)
|
||||
}
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Bar(container, options)
|
||||
const plot = new Bar(container, options)
|
||||
|
||||
plot.off('interval:click')
|
||||
plot.on('interval:click', action)
|
||||
@ -459,7 +446,7 @@ export function timeRangeBarOptionAntV(plot, container, chart, action) {
|
||||
return plot
|
||||
}
|
||||
|
||||
export function baseBidirectionalBarOptionAntV(plot, container, chart, action, isGroup, isStack) {
|
||||
export function baseBidirectionalBarOptionAntV(container, chart, action, isGroup, isStack) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -542,13 +529,8 @@ export function baseBidirectionalBarOptionAntV(plot, container, chart, action, i
|
||||
if (meta) {
|
||||
options.meta = meta
|
||||
}
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new BidirectionalBar(container, options)
|
||||
const plot = new BidirectionalBar(container, options)
|
||||
|
||||
plot.off('interval:click')
|
||||
plot.on('interval:click', action)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
|
||||
@ -3,7 +3,15 @@ import { formatterItem, valueFormatter } from '@/views/chart/chart/formatter'
|
||||
import { DEFAULT_XAXIS_STYLE, DEFAULT_YAXIS_EXT_STYLE, DEFAULT_YAXIS_STYLE } from '@/views/chart/chart/chart'
|
||||
import { equalsAny, includesAny } from '@/utils/StringUtils'
|
||||
import i18n from '@/lang'
|
||||
|
||||
import {
|
||||
regressionExp,
|
||||
regressionPoly,
|
||||
regressionLinear,
|
||||
regressionLoess,
|
||||
regressionLog,
|
||||
regressionPow,
|
||||
regressionQuad
|
||||
} from 'd3-regression/dist/d3-regression.esm'
|
||||
export function getPadding(chart) {
|
||||
if (chart.drill) {
|
||||
return [0, 10, 26, 10]
|
||||
@ -1258,3 +1266,82 @@ export const configTopN = (data, chart) => {
|
||||
}, initOtherItem)
|
||||
data.push(initOtherItem)
|
||||
}
|
||||
const REGRESSION_ALGO_MAP = {
|
||||
poly: regressionPoly,
|
||||
linear: regressionLinear,
|
||||
exp: regressionExp,
|
||||
log: regressionLog,
|
||||
quad: regressionQuad,
|
||||
pow: regressionPow,
|
||||
loess: regressionLoess
|
||||
}
|
||||
export function configPlotTrendLine(chart, plot) {
|
||||
const senior = JSON.parse(chart.senior)
|
||||
if (!senior?.trendLine?.length || !chart.data?.data?.length) {
|
||||
return
|
||||
}
|
||||
const originData = chart.data.data
|
||||
const originFieldDataMap = {}
|
||||
originData.forEach(item => {
|
||||
if (item.quotaList?.length) {
|
||||
const quota = item.quotaList[0]
|
||||
if (!originFieldDataMap[quota.id]) {
|
||||
originFieldDataMap[quota.id] = []
|
||||
}
|
||||
originFieldDataMap[quota.id].push(item.value)
|
||||
}
|
||||
})
|
||||
const trendResultData = {}
|
||||
const totalData = []
|
||||
const trendLineMap = senior.trendLine.reduce((p, n) => {
|
||||
const fieldData = originFieldDataMap[n.fieldId]
|
||||
if (!fieldData?.length) {
|
||||
return p
|
||||
}
|
||||
const regAlgo = REGRESSION_ALGO_MAP[n.algoType]()
|
||||
.x((_, i) => i)
|
||||
.y(d => d)
|
||||
const result = regAlgo(fieldData)
|
||||
trendResultData[n.fieldId] = result
|
||||
result.forEach(item => {
|
||||
totalData.push({ index: item[0], value: item[1], color: n.color, field: n.fieldId })
|
||||
})
|
||||
p[n.fieldId] = n
|
||||
return p
|
||||
}, {})
|
||||
if (!totalData.length) {
|
||||
return
|
||||
}
|
||||
const regLine = plot.chart.createView()
|
||||
plot.once('afterrender', () => {
|
||||
for (const fieldId in trendResultData) {
|
||||
const trendLine = trendLineMap[fieldId]
|
||||
const trendData = trendResultData[fieldId]
|
||||
regLine.annotation().text({
|
||||
content: trendLine.name,
|
||||
position: [0, trendData[0][1]],
|
||||
style: {
|
||||
textBaseline: 'bottom',
|
||||
fill: trendLine.color,
|
||||
fontSize: trendLine.fontSize ?? 20,
|
||||
fontWeight: 300
|
||||
},
|
||||
offsetY: 10
|
||||
})
|
||||
}
|
||||
regLine.axis(false);
|
||||
regLine.data(totalData);
|
||||
regLine.line()
|
||||
.position('index*value')
|
||||
.color('color', color => color)
|
||||
.style('field',field => {
|
||||
const trend = trendLineMap[field]
|
||||
return {
|
||||
stroke: trend?.color ?? 'grey',
|
||||
lineDash: trend?.lineType ? getLineDash(trend.lineType) : [0, 0]
|
||||
}
|
||||
})
|
||||
.tooltip(false)
|
||||
regLine.render()
|
||||
})
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
import { Funnel } from '@antv/g2plot'
|
||||
import { antVCustomColor } from '@/views/chart/chart/util'
|
||||
|
||||
export function baseFunnelOptionAntV(plot, container, chart, action) {
|
||||
export function baseFunnelOptionAntV(container, chart, action) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -53,13 +53,8 @@ export function baseFunnelOptionAntV(plot, container, chart, action) {
|
||||
// custom color
|
||||
options.color = antVCustomColor(chart)
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Funnel(container, options)
|
||||
const plot = new Funnel(container, options)
|
||||
|
||||
plot.off('interval:click')
|
||||
plot.on('interval:click', action)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
|
||||
@ -6,7 +6,7 @@ import { valueFormatter } from '@/views/chart/chart/formatter'
|
||||
|
||||
let labelFormatter = null
|
||||
|
||||
export function baseGaugeOptionAntV(plot, container, chart, action, scale = 1) {
|
||||
export function baseGaugeOptionAntV(container, chart, action, scale = 1) {
|
||||
let min, max, labelContent, startAngel, endAngel
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
@ -170,11 +170,5 @@ export function baseGaugeOptionAntV(plot, container, chart, action, scale = 1) {
|
||||
}
|
||||
}
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Gauge(container, options)
|
||||
|
||||
return plot
|
||||
return new Gauge(container, options)
|
||||
}
|
||||
|
||||
@ -10,12 +10,13 @@ import {
|
||||
getSlider,
|
||||
getAnalyse,
|
||||
setGradientColor,
|
||||
configPlotTooltipEvent
|
||||
configPlotTooltipEvent,
|
||||
configPlotTrendLine
|
||||
} from '@/views/chart/chart/common/common_antv'
|
||||
import { antVCustomColor, handleEmptyDataStrategy } from '@/views/chart/chart/util'
|
||||
import _ from 'lodash'
|
||||
|
||||
export function baseLineOptionAntV(plot, container, chart, action) {
|
||||
export function baseLineOptionAntV(container, chart, action) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -103,20 +104,17 @@ export function baseLineOptionAntV(plot, container, chart, action) {
|
||||
}
|
||||
handleEmptyDataStrategy(emptyDataStrategy, chart, data, options)
|
||||
}
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Line(container, options)
|
||||
const plot = new Line(container, options)
|
||||
|
||||
plot.off('point:click')
|
||||
plot.on('point:click', action)
|
||||
// 趋势线
|
||||
configPlotTrendLine(chart, plot)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
return plot
|
||||
}
|
||||
|
||||
export function baseAreaOptionAntV(plot, container, chart, action, isStack) {
|
||||
export function baseAreaOptionAntV(container, chart, action, isStack) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -214,13 +212,8 @@ export function baseAreaOptionAntV(plot, container, chart, action, isStack) {
|
||||
handleEmptyDataStrategy(emptyDataStrategy, chart, data, options)
|
||||
}
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Area(container, options)
|
||||
const plot = new Area(container, options)
|
||||
|
||||
plot.off('point:click')
|
||||
plot.on('point:click', action)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
|
||||
@ -5,7 +5,7 @@ import { valueFormatter } from '@/views/chart/chart/formatter'
|
||||
|
||||
let labelFormatter = null
|
||||
|
||||
export function baseLiquid(plot, container, chart) {
|
||||
export function baseLiquid(container, chart) {
|
||||
let value = 0
|
||||
const colors = []
|
||||
let max, radius, bgColor, shape, labelContent, liquidStyle, originVal = 0
|
||||
@ -80,11 +80,7 @@ export function baseLiquid(plot, container, chart) {
|
||||
bgColor = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha)
|
||||
}
|
||||
}
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Liquid(container, {
|
||||
return new Liquid(container, {
|
||||
theme: {
|
||||
styleSheet: {
|
||||
brandColor: colors[0],
|
||||
@ -101,5 +97,4 @@ export function baseLiquid(plot, container, chart) {
|
||||
},
|
||||
liquidStyle
|
||||
})
|
||||
return plot
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ import {
|
||||
import { Mix } from '@antv/g2plot'
|
||||
import { hexColorToRGBA } from '@/views/chart/chart/util'
|
||||
|
||||
export function baseMixOptionAntV(plot, container, chart, action) {
|
||||
export function baseMixOptionAntV(container, chart, action) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -98,15 +98,9 @@ export function baseMixOptionAntV(plot, container, chart, action) {
|
||||
tooltip: { shared: true }
|
||||
}
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Mix(container, options)
|
||||
const plot = new Mix(container, options)
|
||||
|
||||
plot.off('point:click')
|
||||
plot.on('point:click', action)
|
||||
plot.off('interval:click')
|
||||
plot.on('interval:click', action)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
|
||||
@ -11,7 +11,7 @@ import { Pie, Rose } from '@antv/g2plot'
|
||||
import { antVCustomColor } from '@/views/chart/chart/util'
|
||||
import { configTopN } from '@/views/chart/chart/common/common_antv'
|
||||
|
||||
export function basePieOptionAntV(plot, container, chart, action) {
|
||||
export function basePieOptionAntV(container, chart, action) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -85,20 +85,15 @@ export function basePieOptionAntV(plot, container, chart, action) {
|
||||
options.color = antVCustomColor(chart)
|
||||
// topN
|
||||
configTopN(data, chart)
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Pie(container, options)
|
||||
const plot = new Pie(container, options)
|
||||
|
||||
plot.off('interval:click')
|
||||
plot.on('interval:click', action)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
return plot
|
||||
}
|
||||
|
||||
export function basePieRoseOptionAntV(plot, container, chart, action) {
|
||||
export function basePieRoseOptionAntV(container, chart, action) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -163,13 +158,8 @@ export function basePieRoseOptionAntV(plot, container, chart, action) {
|
||||
// custom color
|
||||
options.color = antVCustomColor(chart)
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Rose(container, options)
|
||||
const plot = new Rose(container, options)
|
||||
|
||||
plot.off('interval:click')
|
||||
plot.on('interval:click', action)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
|
||||
@ -10,7 +10,7 @@ import { Radar } from '@antv/g2plot'
|
||||
import { antVCustomColor } from '@/views/chart/chart/util'
|
||||
import { minBy, maxBy } from 'lodash'
|
||||
|
||||
export function baseRadarOptionAntV(plot, container, chart, action) {
|
||||
export function baseRadarOptionAntV(container, chart, action) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -145,11 +145,7 @@ export function baseRadarOptionAntV(plot, container, chart, action) {
|
||||
// custom color
|
||||
options.color = antVCustomColor(chart)
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Radar(container, options)
|
||||
const plot = new Radar(container, options)
|
||||
|
||||
plot.off('point:click')
|
||||
plot.on('point:click', action)
|
||||
|
||||
@ -16,7 +16,7 @@ import {
|
||||
import { Scatter } from '@antv/g2plot'
|
||||
import { antVCustomColor } from '@/views/chart/chart/util'
|
||||
|
||||
export function baseScatterOptionAntV(plot, container, chart, action) {
|
||||
export function baseScatterOptionAntV(container, chart, action) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -87,11 +87,7 @@ export function baseScatterOptionAntV(plot, container, chart, action) {
|
||||
// custom color
|
||||
options.color = antVCustomColor(chart)
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Scatter(container, options)
|
||||
const plot = new Scatter(container, options)
|
||||
|
||||
plot.off('point:click')
|
||||
plot.on('point:click', action)
|
||||
|
||||
@ -8,7 +8,7 @@ import {
|
||||
} from '@/views/chart/chart/common/common_antv'
|
||||
import { Treemap } from '@antv/g2plot'
|
||||
|
||||
export function baseTreemapOptionAntV(plot, container, chart, action) {
|
||||
export function baseTreemapOptionAntV(container, chart, action) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -50,13 +50,8 @@ export function baseTreemapOptionAntV(plot, container, chart, action) {
|
||||
}
|
||||
]
|
||||
}
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Treemap(container, options)
|
||||
const plot = new Treemap(container, options)
|
||||
|
||||
plot.off('polygon:click')
|
||||
plot.on('polygon:click', action)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
|
||||
@ -3776,6 +3776,7 @@ export function handleEmptyDataStrategy(strategy, chart, data, options) {
|
||||
function handleBreakLineMultiDimension(chart, data) {
|
||||
const dimensionInfoMap = new Map()
|
||||
const subDimensionSet = new Set()
|
||||
const catQuotaMap = {}
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const item = data[i]
|
||||
const dimensionInfo = dimensionInfoMap.get(item.field)
|
||||
@ -3785,6 +3786,9 @@ function handleBreakLineMultiDimension(chart, data) {
|
||||
dimensionInfoMap.set(item.field, { set: new Set([item.category]), index: i })
|
||||
}
|
||||
subDimensionSet.add(item.category)
|
||||
if (!catQuotaMap[item.category]) {
|
||||
catQuotaMap[item.category] = item.quotaList
|
||||
}
|
||||
}
|
||||
// Map 是按照插入顺序排序的,所以插入索引往后推
|
||||
let insertCount = 0
|
||||
@ -3796,7 +3800,8 @@ function handleBreakLineMultiDimension(chart, data) {
|
||||
data.splice(dimensionInfo.index + insertCount + subInsertIndex, 0, {
|
||||
field,
|
||||
value: null,
|
||||
category: dimension
|
||||
category: dimension,
|
||||
quotaList: catQuotaMap[dimension]
|
||||
})
|
||||
}
|
||||
subInsertIndex++
|
||||
@ -3809,6 +3814,7 @@ function handleBreakLineMultiDimension(chart, data) {
|
||||
function handleSetZeroMultiDimension(chart, data) {
|
||||
const dimensionInfoMap = new Map()
|
||||
const subDimensionSet = new Set()
|
||||
const catQuotaMap = {}
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const item = data[i]
|
||||
if (item.value === null) {
|
||||
@ -3821,6 +3827,9 @@ function handleSetZeroMultiDimension(chart, data) {
|
||||
dimensionInfoMap.set(item.field, { set: new Set([item.category]), index: i })
|
||||
}
|
||||
subDimensionSet.add(item.category)
|
||||
if (!catQuotaMap[item.category]) {
|
||||
catQuotaMap[item.category] = item.quotaList
|
||||
}
|
||||
}
|
||||
let insertCount = 0
|
||||
dimensionInfoMap.forEach((dimensionInfo, field) => {
|
||||
@ -3831,7 +3840,8 @@ function handleSetZeroMultiDimension(chart, data) {
|
||||
data.splice(dimensionInfo.index + insertCount + subInsertIndex, 0, {
|
||||
field,
|
||||
value: 0,
|
||||
category: dimension
|
||||
category: dimension,
|
||||
quotaList: catQuotaMap[dimension]
|
||||
})
|
||||
}
|
||||
subInsertIndex++
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
import { Waterfall } from '@antv/g2plot'
|
||||
import { formatterItem, valueFormatter } from '@/views/chart/chart/formatter'
|
||||
|
||||
export function baseWaterfallOptionAntV(plot, container, chart, action) {
|
||||
export function baseWaterfallOptionAntV(container, chart, action) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -101,13 +101,8 @@ export function baseWaterfallOptionAntV(plot, container, chart, action) {
|
||||
}
|
||||
}
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new Waterfall(container, options)
|
||||
const plot = new Waterfall(container, options)
|
||||
|
||||
plot.off('interval:click')
|
||||
plot.on('interval:click', action)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
} from '@/views/chart/chart/common/common_antv'
|
||||
import { WordCloud } from '@antv/g2plot'
|
||||
|
||||
export function baseWordCloudOptionAntV(plot, container, chart, action) {
|
||||
export function baseWordCloudOptionAntV(container, chart, action) {
|
||||
// theme
|
||||
const theme = getTheme(chart)
|
||||
// attr
|
||||
@ -42,12 +42,7 @@ export function baseWordCloudOptionAntV(plot, container, chart, action) {
|
||||
]
|
||||
}
|
||||
|
||||
// 开始渲染
|
||||
if (plot) {
|
||||
plot.destroy()
|
||||
}
|
||||
plot = new WordCloud(container, options)
|
||||
plot.off('point:click')
|
||||
const plot = new WordCloud(container, options)
|
||||
plot.on('point:click', action)
|
||||
// 处理 tooltip 被其他视图遮挡
|
||||
configPlotTooltipEvent(chart, plot)
|
||||
|
||||
@ -119,7 +119,6 @@ export default {
|
||||
background: ''
|
||||
},
|
||||
title_show: true,
|
||||
antVRenderStatus: false,
|
||||
linkageActiveParam: null,
|
||||
linkageActiveHistory: false,
|
||||
remarkCfg: {
|
||||
@ -160,7 +159,7 @@ export default {
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.myChart.container) {
|
||||
if (this.myChart?.container) {
|
||||
if (typeof this.myChart.container.getAttribute === 'function') {
|
||||
clear(this.myChart.container)
|
||||
}
|
||||
@ -191,7 +190,7 @@ export default {
|
||||
methods: {
|
||||
reDrawView() {
|
||||
this.linkageActiveHistory = false
|
||||
this.myChart.render()
|
||||
this.myChart?.render()
|
||||
},
|
||||
linkageActivePre() {
|
||||
if (this.linkageActiveHistory) {
|
||||
@ -238,7 +237,6 @@ export default {
|
||||
},
|
||||
async drawView() {
|
||||
const chart = JSON.parse(JSON.stringify(this.chart))
|
||||
this.antVRenderStatus = true
|
||||
if (!chart.data || (!chart.data.data && !chart.data.series)) {
|
||||
chart.data = {
|
||||
data: [{}],
|
||||
@ -249,57 +247,53 @@ export default {
|
||||
]
|
||||
}
|
||||
}
|
||||
this.myChart?.destroy()
|
||||
if (chart.type === 'bar') {
|
||||
this.myChart = baseBarOptionAntV(this.myChart, this.chartId, chart, this.antVAction, true, false)
|
||||
this.myChart = baseBarOptionAntV(this.chartId, chart, this.antVAction, true, false)
|
||||
} else if (chart.type === 'bar-group') {
|
||||
this.myChart = baseBarOptionAntV(this.myChart, this.chartId, chart, this.antVAction, true, false)
|
||||
this.myChart = baseBarOptionAntV(this.chartId, chart, this.antVAction, true, false)
|
||||
} else if (equalsAny(chart.type, 'bar-stack', 'percentage-bar-stack')) {
|
||||
this.myChart = baseBarOptionAntV(this.myChart, this.chartId, chart, this.antVAction, false, true)
|
||||
this.myChart = baseBarOptionAntV(this.chartId, chart, this.antVAction, false, true)
|
||||
} else if (chart.type === 'bar-group-stack') {
|
||||
this.myChart = baseBarOptionAntV(this.myChart, this.chartId, chart, this.antVAction, true, true)
|
||||
this.myChart = baseBarOptionAntV(this.chartId, chart, this.antVAction, true, true)
|
||||
} else if (chart.type === 'bar-horizontal') {
|
||||
this.myChart = hBaseBarOptionAntV(this.myChart, this.chartId, chart, this.antVAction, true, false)
|
||||
this.myChart = hBaseBarOptionAntV(this.chartId, chart, this.antVAction, true, false)
|
||||
} else if (equalsAny(chart.type, 'bar-stack-horizontal', 'percentage-bar-stack-horizontal')) {
|
||||
this.myChart = hBaseBarOptionAntV(this.myChart, this.chartId, chart, this.antVAction, false, true)
|
||||
this.myChart = hBaseBarOptionAntV(this.chartId, chart, this.antVAction, false, true)
|
||||
} else if (equalsAny(chart.type, 'bar-time-range')) {
|
||||
this.myChart = timeRangeBarOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = timeRangeBarOptionAntV(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'line') {
|
||||
this.myChart = baseLineOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = baseLineOptionAntV(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'area') {
|
||||
this.myChart = baseAreaOptionAntV(this.myChart, this.chartId, chart, this.antVAction, false)
|
||||
this.myChart = baseAreaOptionAntV(this.chartId, chart, this.antVAction, false)
|
||||
} else if (chart.type === 'line-stack') {
|
||||
this.myChart = baseAreaOptionAntV(this.myChart, this.chartId, chart, this.antVAction, true)
|
||||
this.myChart = baseAreaOptionAntV(this.chartId, chart, this.antVAction, true)
|
||||
} else if (chart.type === 'scatter') {
|
||||
this.myChart = baseScatterOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = baseScatterOptionAntV(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'radar') {
|
||||
this.myChart = baseRadarOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = baseRadarOptionAntV(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'gauge') {
|
||||
this.myChart = baseGaugeOptionAntV(this.myChart, this.chartId, chart, this.antVAction, this.scale)
|
||||
this.myChart = baseGaugeOptionAntV(this.chartId, chart, this.antVAction, this.scale)
|
||||
} else if (chart.type === 'pie' || chart.type === 'pie-donut') {
|
||||
this.myChart = basePieOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = basePieOptionAntV(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'pie-rose' || chart.type === 'pie-donut-rose') {
|
||||
this.myChart = basePieRoseOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = basePieRoseOptionAntV(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'funnel') {
|
||||
this.myChart = baseFunnelOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = baseFunnelOptionAntV(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'treemap') {
|
||||
this.myChart = baseTreemapOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = baseTreemapOptionAntV(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'liquid') {
|
||||
this.myChart = baseLiquid(this.myChart, this.chartId, chart)
|
||||
this.myChart = baseLiquid(this.chartId, chart)
|
||||
} else if (chart.type === 'waterfall') {
|
||||
this.myChart = baseWaterfallOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = baseWaterfallOptionAntV(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'word-cloud') {
|
||||
this.myChart = baseWordCloudOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = baseWordCloudOptionAntV(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'chart-mix') {
|
||||
this.myChart = baseMixOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = baseMixOptionAntV(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'flow-map') {
|
||||
this.myChart = await baseFlowMapOption(this.myChart, this.chartId, chart, this.antVAction)
|
||||
this.myChart = await baseFlowMapOption(this.chartId, chart, this.antVAction)
|
||||
} else if (chart.type === 'bidirectional-bar') {
|
||||
this.myChart = baseBidirectionalBarOptionAntV(this.myChart, this.chartId, chart, this.antVAction)
|
||||
} else {
|
||||
if (this.myChart) {
|
||||
this.antVRenderStatus = false
|
||||
this.myChart.destroy()
|
||||
}
|
||||
this.myChart = baseBidirectionalBarOptionAntV(this.chartId, chart, this.antVAction)
|
||||
}
|
||||
|
||||
if (this.myChart && !equalsAny(chart.type, 'liquid', 'flow-map') && this.searchCount > 0) {
|
||||
@ -324,11 +318,9 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.antVRenderStatus) {
|
||||
this.myChart.render()
|
||||
if (this.linkageActiveHistory) {
|
||||
this.linkageActive()
|
||||
}
|
||||
this.myChart?.render()
|
||||
if (this.linkageActiveHistory) {
|
||||
this.linkageActive()
|
||||
}
|
||||
this.setBackGroundBorder()
|
||||
},
|
||||
|
||||
217
core/frontend/src/views/chart/components/senior/TrendLine.vue
Normal file
217
core/frontend/src/views/chart/components/senior/TrendLine.vue
Normal file
@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<div style="width: 100%;padding: 0 18px;">
|
||||
<el-col>
|
||||
<el-button
|
||||
:title="$t('chart.edit')"
|
||||
icon="el-icon-edit"
|
||||
type="text"
|
||||
size="small"
|
||||
style="width: 24px;margin-left: 4px;"
|
||||
@click="editLine"
|
||||
/>
|
||||
<el-col>
|
||||
<el-row
|
||||
v-for="(item,index) in trendLine"
|
||||
:key="index"
|
||||
class="line-style"
|
||||
>
|
||||
<el-col :span="8">
|
||||
<span :title="item.name">{{ item.name }}</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
{{ item.fieldName }}
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="8"
|
||||
>
|
||||
{{ $t(`chart.regression_${item.algoType}`)}}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-col>
|
||||
|
||||
<el-dialog
|
||||
v-if="editLineDialog"
|
||||
v-dialogDrag
|
||||
:title="$t('chart.trend_line')"
|
||||
:visible="editLineDialog"
|
||||
:show-close="false"
|
||||
width="1000px"
|
||||
class="dialog-css"
|
||||
>
|
||||
<trend-line-edit
|
||||
:line="trendLine"
|
||||
:quota-fields="quotaData"
|
||||
@onTrendLineChange="lineChange"
|
||||
/>
|
||||
<div
|
||||
slot="footer"
|
||||
class="dialog-footer"
|
||||
>
|
||||
<el-button
|
||||
size="mini"
|
||||
@click="closeEditLine"
|
||||
>{{ $t('chart.cancel') }}</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="changeLine"
|
||||
>{{ $t('chart.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TrendLineEdit from '@/views/chart/components/senior/dialog/TrendLineEdit'
|
||||
export default {
|
||||
name: 'TrendLine',
|
||||
components: { TrendLineEdit },
|
||||
props: {
|
||||
chart: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
quotaData: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
trendLine: [],
|
||||
editLineDialog: false,
|
||||
lineArr: [],
|
||||
quotaFields: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'chart': {
|
||||
handler: function() {
|
||||
this.initData()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initData()
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
const chart = JSON.parse(JSON.stringify(this.chart))
|
||||
if (chart.senior) {
|
||||
let senior = null
|
||||
if (Object.prototype.toString.call(chart.senior) === '[object Object]') {
|
||||
senior = JSON.parse(JSON.stringify(chart.senior))
|
||||
} else {
|
||||
senior = JSON.parse(chart.senior)
|
||||
}
|
||||
if (senior.trendLine) {
|
||||
this.trendLine.splice(0, this.trendLine.length, ...senior.trendLine)
|
||||
} else {
|
||||
this.trendLine.splice(0)
|
||||
}
|
||||
this.lineArr = JSON.parse(JSON.stringify(this.trendLine))
|
||||
}
|
||||
},
|
||||
changeTrendLine() {
|
||||
this.$emit('onTrendLineChange', this.trendLine)
|
||||
},
|
||||
lineChange(val) {
|
||||
this.lineArr = val
|
||||
},
|
||||
|
||||
editLine() {
|
||||
this.editLineDialog = true
|
||||
},
|
||||
closeEditLine() {
|
||||
this.editLineDialog = false
|
||||
},
|
||||
changeLine() {
|
||||
// check line config
|
||||
for (let i = 0; i < this.lineArr.length; i++) {
|
||||
const ele = this.lineArr[i]
|
||||
if (!ele.name) {
|
||||
this.$message({
|
||||
message: this.$t('chart.name_can_not_empty'),
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!ele.fieldId) {
|
||||
this.$message({
|
||||
message: this.$t('chart.field_not_empty'),
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
this.trendLine = JSON.parse(JSON.stringify(this.lineArr))
|
||||
this.changeTrendLine()
|
||||
this.closeEditLine()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.shape-item{
|
||||
padding: 6px;
|
||||
border: none;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.form-item-slider ::v-deep .el-form-item__label{
|
||||
font-size: 12px;
|
||||
line-height: 38px;
|
||||
}
|
||||
.form-item ::v-deep .el-form-item__label{
|
||||
font-size: 12px;
|
||||
}
|
||||
.el-select-dropdown__item{
|
||||
padding: 0 20px;
|
||||
}
|
||||
span{
|
||||
font-size: 12px
|
||||
}
|
||||
.el-form-item{
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.switch-style{
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
margin-top: -4px;
|
||||
}
|
||||
.color-picker-style{
|
||||
cursor: pointer;
|
||||
z-index: 1003;
|
||||
}
|
||||
|
||||
.line-style{
|
||||
|
||||
}
|
||||
.line-style ::v-deep span{
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.dialog-css ::v-deep .el-dialog__title {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.dialog-css ::v-deep .el-dialog__header {
|
||||
padding: 20px 20px 0;
|
||||
}
|
||||
|
||||
.dialog-css ::v-deep .el-dialog__body {
|
||||
padding: 10px 20px 20px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,297 @@
|
||||
<template>
|
||||
<el-col>
|
||||
<el-button
|
||||
icon="el-icon-plus"
|
||||
circle
|
||||
size="mini"
|
||||
style="margin-bottom: 10px;"
|
||||
@click="addLine"
|
||||
/>
|
||||
<div style="max-height: 50vh;overflow-y: auto;">
|
||||
<el-row
|
||||
v-for="(item,index) in lineArr"
|
||||
:key="index"
|
||||
class="line-item"
|
||||
>
|
||||
<el-col :span="4">
|
||||
<el-input
|
||||
v-model="item.name"
|
||||
class="value-item"
|
||||
style="width: 90% !important;"
|
||||
:placeholder="$t('chart.name')"
|
||||
size="mini"
|
||||
clearable
|
||||
@change="changeTrendLine"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-select
|
||||
v-model="item.fieldId"
|
||||
size="mini"
|
||||
class="select-item"
|
||||
:placeholder="$t('chart.field')"
|
||||
@change="changeTrendLineField(item)"
|
||||
>
|
||||
<el-option
|
||||
v-for="quota in quotaData"
|
||||
:key="quota.id"
|
||||
:label="quota.name"
|
||||
:value="quota.id"
|
||||
>
|
||||
<span style="float: left">
|
||||
<svg-icon
|
||||
v-if="quota.deType === 0"
|
||||
icon-class="field_text"
|
||||
class="field-icon-text"
|
||||
/>
|
||||
<svg-icon
|
||||
v-if="quota.deType === 1"
|
||||
icon-class="field_time"
|
||||
class="field-icon-time"
|
||||
/>
|
||||
<svg-icon
|
||||
v-if="quota.deType === 2 || quota.deType === 3"
|
||||
icon-class="field_value"
|
||||
class="field-icon-value"
|
||||
/>
|
||||
<svg-icon
|
||||
v-if="quota.deType === 5"
|
||||
icon-class="field_location"
|
||||
class="field-icon-location"
|
||||
/>
|
||||
</span>
|
||||
<span style="float: left; color: #8492a6; font-size: 12px">{{ quota.name }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-select
|
||||
v-model="item.algoType"
|
||||
size="mini"
|
||||
class="select-item"
|
||||
style="margin-left: 10px;"
|
||||
:placeholder="$t('chart.regression_algo')"
|
||||
@change="changeTrendLine"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in algoOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-select
|
||||
v-model="item.fontSize"
|
||||
size="mini"
|
||||
class="select-item"
|
||||
style="margin-left: 10px;"
|
||||
:placeholder="$t('chart.text_fontsize')"
|
||||
@change="changeTrendLine"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in fontSize"
|
||||
:key="option.value"
|
||||
:label="option.name"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-select
|
||||
v-model="item.lineType"
|
||||
size="mini"
|
||||
class="select-item"
|
||||
@change="changeTrendLine"
|
||||
>
|
||||
<el-option
|
||||
v-for="opt in lineOptions"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="1"
|
||||
style="text-align: center;"
|
||||
>
|
||||
<el-color-picker
|
||||
v-model="item.color"
|
||||
class="color-picker-style"
|
||||
:predefine="predefineColors"
|
||||
@change="changeTrendLine"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<el-button
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
circle
|
||||
style="float: right"
|
||||
@click="removeLine(index)"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { COLOR_PANEL } from '@/views/chart/chart/chart'
|
||||
|
||||
export default {
|
||||
name: 'TrendLineEdit',
|
||||
props: {
|
||||
line: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
quotaFields: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lineArr: [],
|
||||
lineObj: {
|
||||
name: '趋势线',
|
||||
algoType: 'poly',
|
||||
fieldId: '',
|
||||
fieldName: '',
|
||||
lineType: 'solid',
|
||||
color: '#ff0000',
|
||||
fontSize: 10
|
||||
},
|
||||
algoOptions: [
|
||||
{ label: this.$t('chart.regression_poly'), value: 'poly' },
|
||||
{ label: this.$t('chart.regression_linear'), value: 'linear' },
|
||||
{ label: this.$t('chart.regression_exp'), value: 'exp' },
|
||||
{ label: this.$t('chart.regression_log'), value: 'log' },
|
||||
{ label: this.$t('chart.regression_quad'), value: 'quad' },
|
||||
{ label: this.$t('chart.regression_pow'), value: 'pow' },
|
||||
{ label: this.$t('chart.regression_loess'), value: 'loess' },
|
||||
],
|
||||
lineOptions: [
|
||||
{ label: this.$t('chart.line_type_solid'), value: 'solid' },
|
||||
{ label: this.$t('chart.line_type_dashed'), value: 'dashed' },
|
||||
{ label: this.$t('chart.line_type_dotted'), value: 'dotted' }
|
||||
],
|
||||
predefineColors: COLOR_PANEL,
|
||||
quotaData: [],
|
||||
fontSize: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'quotaFields': function() {
|
||||
this.initField()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initField()
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
initField() {
|
||||
this.quotaData = this.quotaFields.filter(ele => !ele.chartId && ele.id !== 'count')
|
||||
},
|
||||
init() {
|
||||
this.lineArr = JSON.parse(JSON.stringify(this.line))
|
||||
for (let i = 10; i <= 60; i = i + 2) {
|
||||
this.fontSize.push({
|
||||
name: i + '',
|
||||
value: i
|
||||
})
|
||||
}
|
||||
},
|
||||
addLine() {
|
||||
const obj = {
|
||||
...this.lineObj,
|
||||
fieldId: this.quotaData ? this.quotaData[0]?.id : null,
|
||||
fieldName: this.quotaData ? this.quotaData[0]?.name : null
|
||||
}
|
||||
this.lineArr.push(JSON.parse(JSON.stringify(obj)))
|
||||
this.changeTrendLine()
|
||||
},
|
||||
removeLine(index) {
|
||||
this.lineArr.splice(index, 1)
|
||||
this.changeTrendLine()
|
||||
},
|
||||
|
||||
changeTrendLine() {
|
||||
this.$emit('onTrendLineChange', this.lineArr)
|
||||
},
|
||||
changeTrendLineField(item) {
|
||||
const curField = this.getQuotaField(item.fieldId)
|
||||
item.fieldName = curField.name
|
||||
this.changeTrendLine()
|
||||
},
|
||||
getQuotaField(id) {
|
||||
if (!id) {
|
||||
return {}
|
||||
}
|
||||
const fields = this.quotaData.filter(ele => {
|
||||
return ele.id === id
|
||||
})
|
||||
if (fields.length === 0) {
|
||||
return {}
|
||||
} else {
|
||||
return fields[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.line-item {
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #DCDFE6;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-item ::v-deep .el-form-item__label {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.value-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100px !important;
|
||||
}
|
||||
|
||||
.select-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100px !important;
|
||||
}
|
||||
|
||||
.el-select-dropdown__item {
|
||||
padding: 0 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.color-picker-style{
|
||||
cursor: pointer;
|
||||
z-index: 1003;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.color-picker-style ::v-deep .el-color-picker__trigger{
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
</style>
|
||||
@ -1344,6 +1344,18 @@
|
||||
@onThresholdChange="onThresholdChange"
|
||||
/>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item
|
||||
v-if="showTrendLineCfg"
|
||||
name="trend-line"
|
||||
:title="$t('chart.trend_line')"
|
||||
>
|
||||
<trend-line
|
||||
class="attr-selector"
|
||||
:chart="chart"
|
||||
:quota-data="view.yaxis"
|
||||
@onTrendLineChange="onTrendLineChange"
|
||||
/>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-row>
|
||||
|
||||
@ -1918,6 +1930,8 @@ import CalcChartFieldEdit from '@/views/chart/view/CalcChartFieldEdit'
|
||||
import { equalsAny, includesAny } from '@/utils/StringUtils'
|
||||
import PositionAdjust from '@/views/chart/view/PositionAdjust'
|
||||
import MarkMapDataEditor from '@/views/chart/components/map/MarkMapDataEditor'
|
||||
import TrendLine from '@/views/chart/components/senior/TrendLine'
|
||||
|
||||
export default {
|
||||
name: 'ChartEdit',
|
||||
components: {
|
||||
@ -1955,7 +1969,8 @@ export default {
|
||||
DrillPath,
|
||||
PluginCom,
|
||||
MapMapping,
|
||||
MarkMapDataEditor
|
||||
MarkMapDataEditor,
|
||||
TrendLine
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
@ -2021,6 +2036,7 @@ export default {
|
||||
senior: {
|
||||
functionCfg: DEFAULT_FUNCTION_CFG,
|
||||
assistLine: [],
|
||||
trendLine: [],
|
||||
threshold: DEFAULT_THRESHOLD
|
||||
},
|
||||
customFilter: {},
|
||||
@ -2166,6 +2182,9 @@ export default {
|
||||
showAssistLineCfg() {
|
||||
return includesAny(this.view.type, 'bar', 'line', 'area', 'mix') || this.view.type === 'scatter'
|
||||
},
|
||||
showTrendLineCfg() {
|
||||
return this.view.render === 'antv' && equalsAny(this.view.type, 'line')
|
||||
},
|
||||
showThresholdCfg() {
|
||||
if (this.view.type === 'bidirectional-bar') {
|
||||
return false
|
||||
@ -3040,12 +3059,15 @@ export default {
|
||||
this.view.senior.assistLine = val
|
||||
this.calcData()
|
||||
},
|
||||
onTrendLineChange(val) {
|
||||
this.view.senior.trendLine = val
|
||||
this.calcData()
|
||||
},
|
||||
|
||||
onThresholdChange(val) {
|
||||
this.view.senior.threshold = val
|
||||
this.calcData()
|
||||
},
|
||||
|
||||
onScrollChange(val) {
|
||||
this.view.senior.scrollCfg = val
|
||||
this.calcStyle()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user