components.push({
key: 'tooltip',
type: 'tooltip',
settings: {
filter: nodes => nodes.filter(node => node.key === 'p' && node.type === 'circle'),
extract: ({ node, resources }) => {
const formatterFn = resources.formatter({ type: 'd3-number', format: '.2s' });
const dataProps = Object.keys(node.data)
.filter(key => key !== 'value' && key !== 'label' && key !== 'source')
.map(key => ({
label: node.data[key].source.field,
value: isNaN(node.data[key].value) ? node.data[key].value : formatterFn(node.data[key].value)
}));
return {
title: node.data.value,
color: node.attrs.fill,
props: dataProps,
};
},
content: ({ h, data }) => {
const rows = [];
data.forEach(node => {
const title = h('th', {
colSpan: 2,
style: { fontWeight: 'bold', 'text-align': 'center', backgroundColor: node.color }
}, node.title);
rows.push(title);
node.props.forEach(prop => {
const cells = [
h('td', {}, `${prop.label}:`),
h('td', { style: { 'text-align': 'right' } }, prop.value)
];
rows.push(h('tr', {}, cells));
});
});
return h('div', { display: 'table' }, rows);
},
afterShow({ element }) {
element.children[0].style.opacity = 1;
element.children[1].style.opacity = 1;
},
onHide({ element }) {
element.children[0].style.opacity = 0;
element.children[1].style.opacity = 0;
},
placement: {
type: 'pointer',
area: 'target'
}
},
style: {
content: {
'border-spacing': '4px',
opacity: 0,
transition: 'opacity 150ms ease-in'
},
arrow: {
opacity: 0,
transition: 'opacity 150ms ease-in'
}
}
})