import {
|
G2PlotChartView,
|
G2PlotDrawOptions
|
} from '@/views/chart/components/js/panel/types/impl/g2plot'
|
import type { WordCloud as G2WordCloud, WordCloudOptions } from '@antv/g2plot/esm/plots/word-cloud'
|
import {
|
filterChartDataByRange,
|
flow,
|
getMaxAndMinValueByData,
|
parseJson
|
} from '@/views/chart/components/js/util'
|
import { getPadding } from '@/views/chart/components/js/panel/common/common_antv'
|
import { valueFormatter } from '@/views/chart/components/js/formatter'
|
import { useI18n } from '@/hooks/web/useI18n'
|
import { isEmpty } from 'lodash-es'
|
import { DEFAULT_MISC } from '@/views/chart/components/editor/util/chart'
|
|
const { t } = useI18n()
|
const DEFAULT_DATA = []
|
/**
|
* 词云图
|
*/
|
export class WordCloud extends G2PlotChartView<WordCloudOptions, G2WordCloud> {
|
properties: EditorProperty[] = [
|
'basic-style-selector',
|
'background-overall-component',
|
'border-style',
|
'title-selector',
|
'tooltip-selector',
|
'misc-selector',
|
'jump-set',
|
'linkage'
|
]
|
propertyInner: EditorPropertyInner = {
|
'background-overall-component': ['all'],
|
'border-style': ['all'],
|
'basic-style-selector': ['colors', 'alpha'],
|
'title-selector': [
|
'title',
|
'fontSize',
|
'color',
|
'hPosition',
|
'isItalic',
|
'isBolder',
|
'remarkShow',
|
'fontFamily',
|
'letterSpace',
|
'fontShadow'
|
],
|
'misc-selector': ['wordSizeRange', 'wordSpacing', 'wordCloudAxisValueRange'],
|
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'seriesTooltipFormatter', 'show']
|
}
|
axis: AxisType[] = ['xAxis', 'yAxis', 'filter']
|
axisConfig: AxisConfig = {
|
xAxis: {
|
name: `${t('chart.drag_block_word_cloud_label')} / ${t('chart.dimension_or_quota')}`,
|
type: 'd',
|
limit: 1
|
},
|
yAxis: {
|
name: `${t('chart.drag_block_word_cloud_size')} / ${t('chart.quota')}`,
|
type: 'q',
|
limit: 1
|
}
|
}
|
setDataRange = (action, maxValue, minValue) => {
|
action({
|
from: 'word-cloud',
|
data: {
|
max: maxValue,
|
min: minValue
|
}
|
})
|
}
|
async drawChart(drawOptions: G2PlotDrawOptions<G2WordCloud>): Promise<G2WordCloud> {
|
const { chart, container, action } = drawOptions
|
if (chart?.data) {
|
// data
|
let data = chart.data.data
|
const { misc } = parseJson(chart.customAttr)
|
let minValue = 0
|
let maxValue = 0
|
if (
|
!misc.wordCloudAxisValueRange?.auto &&
|
misc.wordCloudAxisValueRange?.fieldId === chart.yAxis[0].id
|
) {
|
minValue = misc.wordCloudAxisValueRange.min
|
maxValue = misc.wordCloudAxisValueRange.max
|
}
|
getMaxAndMinValueByData(data ?? [], 'value', maxValue, minValue, (max, min) => {
|
maxValue = max
|
minValue = min
|
})
|
data = filterChartDataByRange(data ?? [], maxValue, minValue)
|
// options
|
const initOptions: WordCloudOptions = {
|
data: data,
|
wordField: 'field',
|
weightField: 'value',
|
colorField: 'field',
|
wordStyle: {
|
fontFamily: chart.fontFamily ? chart.fontFamily : 'Verdana',
|
fontSize: (misc.wordSizeRange ?? DEFAULT_MISC.wordSizeRange) as [number, number],
|
rotation: [0, 0],
|
padding: misc.wordSpacing ?? DEFAULT_MISC.wordSpacing
|
},
|
random: () => 0.5,
|
appendPadding: getPadding(chart),
|
legend: false,
|
interactions: []
|
}
|
const options = this.setupOptions(chart, initOptions)
|
const { WordCloud: G2WordCloud } = await import('@antv/g2plot/esm/plots/word-cloud')
|
const newChart = new G2WordCloud(container, options)
|
newChart.on('click', () => {
|
this.setDataRange(action, maxValue, minValue)
|
})
|
newChart.on('afterrender', () => {
|
this.setDataRange(action, maxValue, minValue)
|
})
|
newChart.on('point:click', param => {
|
action({ x: param.x, y: param.y, data: { data: param.data.data.datum } })
|
})
|
return newChart
|
}
|
}
|
|
protected configTooltip(chart: Chart, options: WordCloudOptions): WordCloudOptions {
|
const customAttr: DeepPartial<ChartAttr> = parseJson(chart.customAttr)
|
const tooltipAttr = customAttr.tooltip
|
const yAxis = chart.yAxis
|
if (!tooltipAttr.show) {
|
return {
|
...options,
|
tooltip: false
|
}
|
}
|
const formatterMap = tooltipAttr.seriesTooltipFormatter
|
?.filter(i => i.show)
|
.reduce((pre, next) => {
|
pre[next.id] = next
|
return pre
|
}, {}) as Record<string, SeriesFormatter>
|
const tooltip: WordCloudOptions['tooltip'] = {
|
showTitle: true,
|
title: () => undefined,
|
customItems(originalItems) {
|
let tooltipItems = originalItems
|
if (tooltipAttr.seriesTooltipFormatter?.length) {
|
tooltipItems = originalItems.filter(item => formatterMap[item.data.datum.quotaList[0].id])
|
}
|
const result = []
|
const head = originalItems[0]
|
tooltipItems.forEach(item => {
|
const formatter = formatterMap[item.data.datum.quotaList[0].id] ?? yAxis[0]
|
const value = valueFormatter(item.value, formatter.formatterCfg)
|
const name = isEmpty(formatter.chartShowName) ? formatter.name : formatter.chartShowName
|
result.push({ ...item, name, value })
|
})
|
head.data.datum.dynamicTooltipValue?.forEach(item => {
|
const formatter = formatterMap[item.fieldId]
|
if (formatter) {
|
const value = valueFormatter(parseFloat(item.value), formatter.formatterCfg)
|
const name = isEmpty(formatter.chartShowName) ? formatter.name : formatter.chartShowName
|
result.push({ color: 'grey', name, value })
|
}
|
})
|
return result
|
}
|
}
|
return {
|
...options,
|
tooltip
|
}
|
}
|
|
protected setupOptions(chart: Chart, options: WordCloudOptions): WordCloudOptions {
|
return flow(this.configTheme, this.configTooltip)(chart, options)
|
}
|
|
constructor() {
|
super('word-cloud', DEFAULT_DATA)
|
}
|
}
|