UNPKG

zz-chart

Version:

Alauda Chart components by Alauda Frontend Team

184 lines 6.13 kB
import { StyleSheet, css } from 'aphrodite/no-important.js'; import { get, isArray, isElement, isFunction, isNil, isString, } from 'lodash-es'; import placement from 'placement.js'; import { ChartEvent, } from '../types/index.js'; import { NOT_AVAILABLE } from '../utils/constant.js'; import { generateName, template } from '../utils/index.js'; import { BaseComponent } from './base.js'; import { symbolStyle } from './styles.js'; const styles = StyleSheet.create({ overlay: { position: 'absolute', visibility: 'hidden', pointerEvents: 'none', padding: '12px', boxShadow: '0 2px 8px #00000029', margin: 8, zIndex: 999, transition: 'transform 0.1s ease-out 0s', // transition: // 'top 0.3s cubic-bezier(0.23, 1, 0.32, 1) 0s', fontSize: 12, }, 'tooltip-title': { marginBottom: 8, }, 'tooltip-list': { listStyle: 'none', padding: 0, margin: 0, }, 'tooltip-list-item': { listStyleType: 'none', padding: '2px 8px', display: 'flex', alignItems: 'center', }, 'tooltip-marker': { marginRight: 4, }, 'tooltip-name': { maxWidth: '197px', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', }, 'tooltip-value': { marginLeft: 30, flex: 1, textAlign: 'right', whiteSpace: 'nowrap', }, }); export class Tooltip extends BaseComponent { constructor() { super(...arguments); this.showTooltip = () => { this.container.style.visibility = 'visible'; this.container.style.background = this.ctrl.getTheme().tooltip.background; this.container.style.color = this.ctrl.getTheme().tooltip.color; }; this.hideTooltip = () => { if (this.container) { this.container.style.visibility = 'hidden'; } }; } get name() { return 'tooltip'; } render() { const opt = this.ctrl.getOption(); this.option = get(opt, this.name, {}); this.create(); } update() { this.option = get(this.ctrl.getOption(), this.name); this.createItem(); } create() { if (this.option) { if (!this.container) { const overlay = document.createElement('div'); overlay.className = `${generateName('tooltip')} ${css(styles.overlay)}`; (get(this.option, 'popupContainer') || document.body).append(overlay); overlay.style.visibility = 'hidden'; this.container = overlay; } this.createItem(); this.eventListener(); } } /** * 创建 tooltip item * @param title * @param values */ createItem(title, values) { const itemTpl = this.getTooltipItem(values); if (!itemTpl) { return; } const isEl = isElement(itemTpl); const list = `<ul class="${css(styles['tooltip-list'])}">${itemTpl}</ul>`; this.container.innerHTML = ` ${this.getTooltipTitle(title, values)} ${isEl ? '' : list} `; if (isEl) { this.container.remove(); this.container.append(itemTpl); } } getTooltipTitle(title, values) { const { showTitle, titleFormatter } = this.option; if (String(showTitle) === 'false' || !title) { return ''; } let tpl = title || NOT_AVAILABLE; if (isString(titleFormatter)) { tpl = template(titleFormatter, { title }); } if (isFunction(titleFormatter)) { tpl = titleFormatter(title, values); } return `<div class="${css(styles['tooltip-title'])}">${tpl}</div>`; } getTooltipItem(values) { if (!values || !values?.length) { return ''; } const { nameFormatter, valueFormatter, itemFormatter, sort } = this .option; let items = sort ? values.sort(sort) : values; if (itemFormatter) { const itemValue = itemFormatter(items); if (isString(itemValue)) { return itemValue; } if (isElement(itemValue)) { return itemValue.innerHTML; } if (isArray(itemValue)) { items = itemValue; } } return items ?.map(item => { const value = this.handleTemplateString(item.value, valueFormatter, item); const name = this.handleTemplateString(String(item.name), nameFormatter, item); return `<li class="${css(styles['tooltip-list-item'])}" style="background: ${item.activated ? this.ctrl.getTheme().tooltip.activeBg : 'unset'}"> <span class="${css(symbolStyle.symbol)} ${css(symbolStyle.line)}" style="background: ${item.color};"></span> <span class="${generateName('tooltip-name')} ${css(styles['tooltip-name'])}">${name || NOT_AVAILABLE}</span> <span class="${generateName('tooltip-value')} ${css(styles['tooltip-value'])}">${isNil(value) ? NOT_AVAILABLE : value}</span> </li>`; }) .join(''); } handleTemplateString(text, formatter, data) { let value = text; if (isString(formatter)) { value = template(formatter, { value: text }); } if (isFunction(formatter)) { value = formatter(value, data); } return value; } /** * 添加事件监听 */ eventListener() { // TODO: 是否纳管到 interaction this.ctrl.on(ChartEvent.U_PLOT_SET_CURSOR, ({ anchor, title, values, position }) => { if (values?.length) { // @ts-ignore placement(anchor, this.container, { placement: position || 'right', }); this.createItem(title, values); } }); } } //# sourceMappingURL=tooltip.js.map