39 lines
1.2 KiB
JavaScript
39 lines
1.2 KiB
JavaScript
import { createApp, h } from 'vue'
|
|
|
|
// Simple cache map to avoid re-rendering identical payloads.
|
|
const _cache = new Map()
|
|
|
|
function serializeKey(obj) {
|
|
try {
|
|
return JSON.stringify(obj, Object.keys(obj).sort())
|
|
} catch (e) {
|
|
return Math.random().toString(36)
|
|
}
|
|
}
|
|
|
|
// Factory returning template function for Unovis Crosshair.
|
|
// config: chart series configuration
|
|
// Component: Vue component to render
|
|
// extraProps: static props (e.g. labelKey, labelFormatter)
|
|
export function componentToString(config, Component, extraProps = {}) {
|
|
return function (_data, x) {
|
|
const row = _data && _data.data ? _data.data : _data
|
|
// Build series-only payload (exclude non-config fields like date/dateLabel)
|
|
const seriesPayload = {}
|
|
Object.keys(config).forEach(k => {
|
|
if (row && row[k] !== undefined) seriesPayload[k] = row[k]
|
|
})
|
|
const cacheKeyBase = { ...seriesPayload, __x: x }
|
|
const key = serializeKey(cacheKeyBase)
|
|
if (_cache.has(key)) return _cache.get(key)
|
|
|
|
const el = document.createElement('div')
|
|
const app = createApp(Component, { ...extraProps, payload: seriesPayload, config, x: row?.date ?? x })
|
|
app.mount(el)
|
|
const html = el.innerHTML
|
|
app.unmount()
|
|
_cache.set(key, html)
|
|
return html
|
|
}
|
|
}
|