There is a follow-up question. Often times im showing multiple series in a 'pane'. the current implementation concatenates the labels and then adds it as one element. The click event handler is attached to that one tooltip element (which may have multiple labels). So for example if we wanted to do this for the first pane in the example provided, which has 2 series. How would that be possible?
Is there any other element that supports a click event that we can use to draw the labels? for example i was looking at the legends, and they use the button element - wondering if that can be used such that we could add a click event for each.
As mentioned, i typically render multiple series in multiple panes...this is what my code looks like. After starting to add the event handler in this code, i realized that event handler handles the tooltip element as a whole, not the individual labels:
Code: Select all
function tooltip_formatter(tooltip) {
const chart = tooltip.chart;
const orig_fmt = tooltip.defaultFormatter.call(this, tooltip);
if(chart.hoverPoints.length > 0){
if (chart.extendedTooltips){
for(const e of chart.extendedTooltips)
e.destroy();
}
}
//used to store the tooltip labels we render
chart.extendedTooltips = []
//a map of panes to series labels. we can add attributes to as needed for a 'pane'. for example the top position where the labels for a pane should be rendered
let ext_tooltips = {}; //each element looks like: {tooltips:[{label: <span str>, index: <series index>}...]}, top: <series.yAxis.top>}
for(i=0; i < chart.hoverPoints.length; i++)
{
const point = chart.hoverPoints[i];
const pane = point.series.options.pane;
let color = point.chg < 0?'red':'green'
if (point.series.type == 'candlestick' || point.series.type == 'hollowcandlestick'){
orig_fmt[1] = `<span style="color:blue">●</span><b style="color:blue">`+point.series.name+': O:</b>'
+point.open.toFixed(2)+' <b style="color:blue">H:</b>'
+point.high.toFixed(2)+' <b style="color:blue">L:</b>'
+point.low.toFixed(2)+' <b style="color:blue">C:</b>'
+point.close.toFixed(2)+' <b style="color:blue">Chg:</b>'
+`<span style="color:${color}">`+point.chg.toFixed(2)+'</span> <b style="color:blue">%Chg:</b>'
+`<span style="color:${color}">`+point.chg_pct.toFixed(2)+'</span>';
}
//for additional series store series index, label and yAxis top where they will be rendered in dictionary
else if (pane > 0) {
let label = `<tspan style="color: ${point.series.color};">●</tspan> ${point.series.name}: ${point.y.toFixed(2)}`;
if (pane in ext_tooltips)
ext_tooltips[pane]['tooltip'].push({"series_idx":i, "label":label})
else
ext_tooltips[pane] = {'tooltip': [{"series_idx":i, "label":label}], 'top': point.series.yAxis.top }
}
}
//loop through the map, build the label, render and add to extendedToolTips, add event handler
for(const[k,v] of Object.entries(ext_tooltips)){
let labels = v['tooltip'].map((t)=>{return t['label']}).join('<br/>');
chart.extendedTooltips.push(chart.renderer.label(labels,chart.plotLeft, v['top'])
.attr({zIndex: 100})
.css({fontSize: `${chart.tooltip.options.style.fontSize}`})
.add());
//how do we add this handler to individual label elements as opposed to the tooltip element??
//chart.extendedTooltip.element.addEventListener('click', () => toggle_series(chart.extendedTooltip, 2));
}
return orig_fmt;
};