diff --git a/core/frontend/src/lang/en.js b/core/frontend/src/lang/en.js index c54de4bd30..cdf0413b00 100644 --- a/core/frontend/src/lang/en.js +++ b/core/frontend/src/lang/en.js @@ -1534,6 +1534,7 @@ export default { value_formatter_thousand_separator: 'Thousand Separator', value_formatter_example: 'Example', value_suffix: 'Value Suffix', + axis_label_length_limit: 'Length limit', unit_none: 'None', unit_thousand: 'Thousand', unit_ten_thousand: 'Ten Thousand', diff --git a/core/frontend/src/lang/tw.js b/core/frontend/src/lang/tw.js index 96aeb97ac0..0fcf394508 100644 --- a/core/frontend/src/lang/tw.js +++ b/core/frontend/src/lang/tw.js @@ -1531,6 +1531,7 @@ export default { value_formatter_suffix: '單位後綴', value_formatter_thousand_separator: '千分符', value_formatter_example: '示例', + axis_label_length_limit: '長度限制', unit_none: '無', unit_thousand: '千', unit_ten_thousand: '萬', diff --git a/core/frontend/src/lang/zh.js b/core/frontend/src/lang/zh.js index 64bb247d4f..2e04769207 100644 --- a/core/frontend/src/lang/zh.js +++ b/core/frontend/src/lang/zh.js @@ -1531,6 +1531,7 @@ export default { value_formatter_suffix: '单位后缀', value_formatter_thousand_separator: '千分符', value_formatter_example: '示例', + axis_label_length_limit: '长度限制', unit_none: '无', unit_thousand: '千', unit_ten_thousand: '万', diff --git a/core/frontend/src/views/chart/chart/bar/bar_antv.js b/core/frontend/src/views/chart/chart/bar/bar_antv.js index c546873080..8b50cf617c 100644 --- a/core/frontend/src/views/chart/chart/bar/bar_antv.js +++ b/core/frontend/src/views/chart/chart/bar/bar_antv.js @@ -11,7 +11,8 @@ import { getAnalyse, setGradientColor, getMeta, - configPlotTooltipEvent + configPlotTooltipEvent, + configAxisLabelLengthLimit } from '@/views/chart/chart/common/common_antv' import { antVCustomColor, getColors, handleEmptyDataStrategy, hexColorToRGBA } from '@/views/chart/chart/util' import { cloneDeep, find } from 'lodash-es' @@ -251,8 +252,10 @@ export function hBaseBarOptionAntV(container, chart, action, isGroup, isStack) { const plot = new Bar(container, options) plot.on('interval:click', action) -// 处理 tooltip 被其他视图遮挡 + // 处理 tooltip 被其他视图遮挡 configPlotTooltipEvent(chart, plot) + // 处理纵轴标签长度限制 + configAxisLabelLengthLimit(chart, plot) return plot } diff --git a/core/frontend/src/views/chart/chart/chart.js b/core/frontend/src/views/chart/chart/chart.js index 731e0fa264..799e5ebeda 100644 --- a/core/frontend/src/views/chart/chart/chart.js +++ b/core/frontend/src/views/chart/chart/chart.js @@ -385,7 +385,8 @@ export const DEFAULT_YAXIS_STYLE = { color: '#333333', fontSize: '12', rotate: 0, - formatter: '{value}' + formatter: '{value}', + lengthLimit: 20 }, axisLine: { show: false, diff --git a/core/frontend/src/views/chart/chart/common/common_antv.js b/core/frontend/src/views/chart/chart/common/common_antv.js index b7e5d0794b..69938ef819 100644 --- a/core/frontend/src/views/chart/chart/common/common_antv.js +++ b/core/frontend/src/views/chart/chart/common/common_antv.js @@ -12,6 +12,10 @@ import { regressionPow, regressionQuad } from 'd3-regression/dist/d3-regression.esm' +import substitute from '@antv/util/esm/substitute' +import createDom from '@antv/dom-util/esm/create-dom' +import { assign } from 'lodash-es' + export function getPadding(chart) { if (chart.drill) { return [0, 10, 26, 10] @@ -849,7 +853,11 @@ export function getYAxis(chart) { return valueFormatter(value, a.axisLabelFormatter) } } else { - return value + const { lengthLimit } = a.axisLabel + if (!lengthLimit || value?.length <= lengthLimit) { + return value + } + return value?.slice(0, lengthLimit) + '...' } } } @@ -1275,6 +1283,19 @@ const REGRESSION_ALGO_MAP = { pow: regressionPow, loess: regressionLoess } +const AXIS_LABEL_TOOLTIP_STYLE = { + transition: 'left 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0s, top 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0s', + backgroundColor: 'rgb(255, 255, 255)', + boxShadow: 'rgb(174, 174, 174) 0px 0px 10px', + borderRadius: '3px', + padding: '8px 12px', + opacity: '0.95', + position: 'absolute', + visibility: 'visible' +} +const AXIS_LABEL_TOOLTIP_TPL = '
' + + '
{title}
' + + '
' export function configPlotTrendLine(chart, plot) { const senior = JSON.parse(chart.senior) if (!senior?.trendLine?.length || !chart.data?.data?.length) { @@ -1346,3 +1367,67 @@ export function configPlotTrendLine(chart, plot) { regLine.render() }) } +export function configAxisLabelLengthLimit(chart, plot) { + const customStyle = JSON.parse(chart.customStyle) + const { lengthLimit, fontSize, color, show } = customStyle.yAxis.axisLabel + if (!lengthLimit || !show) { + return + } + plot.on('axis-label:mouseenter', (e) => { + const field = e.target.cfg.delegateObject.component.cfg.field + // 先只处理竖轴 + if (field !== 'field') { + return + } + const realContent = e.target.attrs.text + if (realContent.length < lengthLimit || !(realContent?.slice(-3) === '...')) { + return + } + const { x, y } = e + const parentNode = e.event.target.parentNode + let labelTooltipDom = parentNode.getElementsByClassName('g2-axis-label-tooltip')?.[0] + if (!labelTooltipDom) { + const title = e.target.cfg.delegateObject.item.name + const domStr = substitute(AXIS_LABEL_TOOLTIP_TPL, { title }) + labelTooltipDom = createDom(domStr) + assign(labelTooltipDom.style, AXIS_LABEL_TOOLTIP_STYLE) + parentNode.appendChild(labelTooltipDom) + } else { + labelTooltipDom.getElementsByClassName('g2-tooltip-title')[0].innerHTML = e.target.cfg.delegateObject.item.name + labelTooltipDom.style.visibility = 'visible' + } + const { height, width } = parentNode.getBoundingClientRect() + const { offsetHeight, offsetWidth } = labelTooltipDom + if (offsetHeight > height || offsetWidth > width) { + labelTooltipDom.style.left = labelTooltipDom.style.top = `0px` + return + } + const initPosition = { left: x + 10, top: y + 15 } + if (initPosition.left + offsetWidth > width) { + initPosition.left = width - offsetWidth - 10 + } + if (initPosition.top + offsetHeight > height) { + initPosition.top -= (offsetHeight + 15) + } + labelTooltipDom.style.left = initPosition.left + 'px' + labelTooltipDom.style.top = initPosition.top + 'px' + labelTooltipDom.style.color = color + labelTooltipDom.style.fontSize = fontSize + }) + plot.on('axis-label:mouseleave', (e) => { + const field = e.target.cfg.delegateObject.component.cfg.field + // 先只处理竖轴 + if (field !== 'field') { + return + } + const realContent = e.target.attrs.text + if (realContent.length < lengthLimit || !(realContent?.slice(-3) === '...')) { + return + } + const parentNode = e.event.target.parentNode + let labelTooltipDom = parentNode.getElementsByClassName('g2-axis-label-tooltip')?.[0] + if (labelTooltipDom) { + labelTooltipDom.style.visibility = 'hidden' + } + }) +} diff --git a/core/frontend/src/views/chart/chart/util.js b/core/frontend/src/views/chart/chart/util.js index c204a09c55..274bb1c0b9 100644 --- a/core/frontend/src/views/chart/chart/util.js +++ b/core/frontend/src/views/chart/chart/util.js @@ -1082,7 +1082,8 @@ export const TYPE_CONFIGS = [ 'nameTextStyle', 'splitLine', 'axisForm', - 'axisLabel' + 'axisLabel', + 'axisLabelLength' ], 'title-selector-ant-v': [ 'show', @@ -1241,7 +1242,8 @@ export const TYPE_CONFIGS = [ 'nameTextStyle', 'splitLine', 'axisForm', - 'axisLabel' + 'axisLabel', + 'axisLabelLength' ], 'title-selector-ant-v': [ 'show', @@ -1317,7 +1319,8 @@ export const TYPE_CONFIGS = [ 'nameTextStyle', 'splitLine', 'axisForm', - 'axisLabel' + 'axisLabel', + 'axisLabelLength' ], 'title-selector-ant-v': [ 'show', diff --git a/core/frontend/src/views/chart/components/componentStyle/YAxisSelectorAntV.vue b/core/frontend/src/views/chart/components/componentStyle/YAxisSelectorAntV.vue index 3d5729df00..c5e4ad2b18 100644 --- a/core/frontend/src/views/chart/components/componentStyle/YAxisSelectorAntV.vue +++ b/core/frontend/src/views/chart/components/componentStyle/YAxisSelectorAntV.vue @@ -265,6 +265,20 @@ @change="changeYAxisStyle('axisLabel')" /> + + +