MultiValueTooltip
名稱:MultiValue Tooltip(MultiValue類別提示框)
說明:MultiValue資料類別使用的提示框(tooltip)
params$
型別:
Partial<MultiValueTooltipParams>
欄位:
名稱 說明 型別 backgroundColorType 底色顏色類別 ColorType
backgroundOpacity 底色透明度 number
strokeColorType 外框顏色類別 ColorType
textColorType 文字顏色類別 ColorType
offset 滑鼠游標相對位置 (x, y) [number, number]
padding 內部間距 number
renderFn 渲染函式,函式可回傳三種格式:
(1) 純文字字串 (string
)
(2) 以陣列字串顯示多行純文字 (string[]
)
(3) SVG標籤內容字串 (string
)(eventData: EventMultiValue, context: { styles: BaseTooltipStyle; utils: BaseTooltipUtils }) => string[] | string
詳細型別
type ColorType = 'none' | 'label' | 'labelContrast' | 'primary' | 'secondary' | 'background'
interface BaseTooltipStyle {
backgroundColor: string
backgroundOpacity: number
strokeColor: string
offset: [number, number]
padding: number
textColor: string
textSize: number | string // chartParams上的設定
textSizePx: number
seriesColors: string[]
}
interface BaseTooltipUtils {
measureTextWidth (text: string, size?: number): number
}
- 預設值:
{
backgroundColorType: 'background',
strokeColorType: 'primary',
backgroundOpacity: 0.8,
textColorType: 'primary',
offset: [20, 5],
padding: 10,
renderFn: (eventData, { styles, utils }) => {
const hasCategoryLabel = eventData.categoryLabel === '' ? false : true
const hasDatumLabel = eventData.datum == null || eventData.datum.label.slice(0, 11) === 'multiValue_' ? false : true
const bulletWidth = styles.textSizePx * 0.7
const offset = (styles.textSizePx / 2) - (bulletWidth / 2)
const categorySvg = hasCategoryLabel
? `<rect width="${bulletWidth}" height="${bulletWidth}" x="${offset}" y="${offset - 1}" rx="${bulletWidth / 2}" fill="${eventData.datum.color}"></rect>
<text x="${styles.textSizePx * 1.5}" font-size="${styles.textSizePx}" dominant-baseline="hanging" fill="${styles.textColor}">
<tspan>${eventData.categoryLabel}</tspan>
</text>`
: ''
const datumLabelSvg = hasDatumLabel
? `<text font-size="${styles.textSizePx}" dominant-baseline="hanging" fill="${styles.textColor}">
<tspan>${eventData.datum.label}</tspan>
</text>`
: ''
const maxTextWidth = (() => {
const categoryLabelTextWidth = utils.measureTextWidth(eventData.categoryLabel, styles.textSizePx)
const datumLabelTextWidth = hasDatumLabel ? utils.measureTextWidth(eventData.datum.label, styles.textSizePx) : 0
const valueDetailTextWidth = eventData.valueDetail.reduce((acc, detail) => {
const text = `${detail.valueLabel}${utils.toCurrency(detail.value)}`
const _maxTextWidth = utils.measureTextWidth(text, styles.textSizePx)
return _maxTextWidth > acc ? _maxTextWidth : acc
}, 0)
return Math.max(categoryLabelTextWidth, datumLabelTextWidth, valueDetailTextWidth)
})()
const valueDetailSvg = eventData.valueDetail.map((detail, i) => {
const y = (i * styles.textSizePx * 1.5) + (datumLabelSvg ? styles.textSizePx * 2 : 0)
const lineEndX = maxTextWidth + styles.textSizePx * 3
return `<text x="0" y="${y}" font-weight="bold" font-size="${styles.textSizePx}" dominant-baseline="hanging" fill="${styles.textColor}">
<tspan>${detail.valueLabel}</tspan>
<tspan text-anchor="end" x="${lineEndX}">${utils.toCurrency(detail.value)}</tspan>
</text>`
}).join('')
const datumDetailSvg = datumLabelSvg || valueDetailSvg
? `<g ${hasCategoryLabel ? `transform="translate(0, ${styles.textSizePx * 2})"` : ''}>
${datumLabelSvg}
${valueDetailSvg}
</g>`
: ''
return `${categorySvg}
${datumDetailSvg}`
}
}