Highcharts, get point index when shared tooltip is shows/hides - javascript

I have a group of charts which have the same categories.
When user hover on the chart and the tooltip is shown, I need to set all charts's corresponding point state to hover to help user to compare the data.
Firstly I use mouseOver and mouseOut events and it almost meet my needs, but I use shared tooltip so sometimes the tooltip shows without mouse on the point, so the event is not fired.
So I guess I need an event that when the tooltip shows/hides, and I find this and try tooltipRefresh event but I can't find the exactly index of on which point the tooltip shows. I have tried:
tooltipRefresh: function(e) {
var index = this.hoverPoint.index; //No dependentable
}
Is that any way that I can get the index at the right event firing moment?

you can use Label which just like the tootip, show X, Y value on the Lable.
What i did is :
1.click on one chart === >
2.get X value ===>
3.fire a Event (click event of chart) === >
4.render Label on every other chart using X (get Y value in each chart by X)
when create chart, I set an click event
options.chart = $.extend(true, options.chart, {
renderTo: 'hChart_' + chartIndex,
type: 'spline',
events: {
click: function (event) {
if($scope.label.length > 0){
$scope.clearAllLabels();
}else{
var charts = $scope.ui.charts;
$.each(charts, function (index, chart) {
//render Label to chart
});
}
}
}
});
Below is add label in chart.
var label = chart.renderer.label(
moment(xAxis).format('dddd, MMM DD, HH:mm:ss') + '<br>' + kpiName + ': <b>' + Highcharts.numberFormat(yAxis, 2) + kpiUnit + '</b>',
120,
40)
.attr({
fill: Highcharts.getOptions().colors[0],
padding: 10,
r: 5,
zIndex: 8
})
.css({
lineHeight: '20%',
fontSize: '11px',
color: '#FFFFFF'
})
.add();
Hope it will help you.

Related

Echarts3 (baidu) colored round in tooltip

Echarts3 (baidu) colored round in tooltip
By default the tooltip has rounds of the same colour as graph, like this:
http://echarts.baidu.com/gallery/editor.html?c=candlestick-brush
But if I customize the tooltip it removes the colour coded round like in this example:
https://ecomfe.github.io/echarts/doc/example/tooltip.html#-en
Is there a way to use custom tooltip and put the colour round back.
Here is another way to explain it.
Go to this link
pie-simple
and you will find charts with no coloured round.
delete the following line:
formatter: "{a} <br/>{b} : {c} ({d}%)"
then press <运行> to refresh and you will see the round back.
Echarts already sends the marker html in params of each series with specific color. To create an original looking tooltip you can simply use that like this for line chart:
{
formatter : (args) => {
let tooltip = `<p>${args[0].axisValue}</p> `;
args.forEach(({ marker, seriesName, value }) => {
value = value || [0, 0];
tooltip += `<p>${marker} ${seriesName} — ${value[1]}</p>`;
});
return tooltip;
}
ECharts support user-defined tooltip, include the color you wanted.
For example you have a line chart demo like this, and you want to change the default tooltip, add % or something else after the tooltip without lose the default color.Just replace tooltip code with this code below.
tooltip : {
trigger: 'axis',
axisPointer: {
animation: true
},
formatter: function (params) {
var colorSpan = color => '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' + color + '"></span>';
let rez = '<p>' + params[0].axisValue + '</p>';
//console.log(params); //quite useful for debug
params.forEach(item => {
//console.log(item); //quite useful for debug
var xx = '<p>' + colorSpan(item.color) + ' ' + item.seriesName + ': ' + item.data + '%' + '</p>'
rez += xx;
});
return rez;
}
},
with this tooltip code, you will see the original tooltip color 邮件营销: 90 become color 邮件营销: 90%, we add self-defined % to tooltip.
One way to solve this is to return custom HTML in your tooltip formatter, for instance:
var formatTooltipLine = function(color){
return "<span style='display:inline-block;width:10px;height:10px;border-radius:50%;background-color:"+color+";margin-right:5px;'></span><span>line text</span>"
}
var formatter = function(){
// custom title
var lines = ["<b>2016</b>"];
// custom lines
["red", "orange"].forEach(function(color){
lines.push(formatTooltipLine(color));
});
return lines.join("<br>");
}
Example:
https://cdn.datamatic.io/runtime/echarts/3.3.0_61/view/index.html#id=117670017722819924657/0B3wq5VFn9PllSEVsQTJvcnVBZU0

c3.js - c3 graph that has a tooltip with a c3 graph inside

I have a c3.js line graph that represents the evolution of 2 values. I need that the tooltip of the line graph to be a pie chart (tooltip = another c3.js graph).
Here is what I succeeded:
http://jsfiddle.net/owhxgaqm/80/
// c3 - custom tooltip
function generateGraph(data1,data2) {
console.log(data1.name + '\t' + data1.value + '\t' + data2.name + '\t' + data2.value);
var chart1 = c3.generate(
{
bindto: "#t",
data: {columns : [[data1.name, data1.value],[data2.name, data2.value]],
type : 'pie'}
});
}
var chart = c3.generate({
data: {
columns: [
['data1', 1000, 200, 150, 300, 200],
['data2', 400, 500, 250, 700, 300], ]
},
tooltip: {
contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
generateGraph(d[0], d[1]);
var divt = document.getElementById("t");
return '';
}
}
});
As you can see I'm binding the "tooltip" with an already existing div so this is not really what I want from c3.js.
Any idea is welcome.
Thanks.
Adding a Chart inside a C3 Tooltip
You can use the tooltip element that c3 already has. In your contents function call the generateGraph function (see next step). Pass in the tooltip element available in this.tooltip in addition to the data.
...
tooltip: {
contents: function (d) {
// this creates a chart inside the tooltips
var content = generateGraph(this.tooltip, d[0], d[1])
// we don't return anything - see .html function below
}
}
...
Your generateGraph function basically creates a c3 chart in your tooltip element (bindto supports a d3 element). We do a bit of optimization (if the data is same, the chart is not recreated) and cleanup (when a chart is recreated it is destroyed and removed from the DOM)
function generateGraph(tooltip, data1, data2) {
// if the data is same as before don't regenrate the graph - this avoids flicker
if (tooltip.data1 &&
(tooltip.data1.name === data1.name) && (tooltip.data1.value === data1.value) &&
(tooltip.data2.name === data2.name) && (tooltip.data2.value === data2.value))
return;
tooltip.data1 = data1;
tooltip.data2 = data2;
// remove the existing chart
if (tooltip.chart) {
tooltip.chart = tooltip.chart.destroy();
tooltip.selectAll('*').remove();
}
// create new chart
tooltip.chart = c3.generate({
bindto: tooltip,
size: {
width: 200,
height: 200
},
data: {
columns: [[data1.name, data1.value], [data2.name, data2.value]],
type: 'pie'
}
});
// creating a chart on an element sets its position attribute to relative
// reset it to absolute (the tooltip was absolute originally) for proper positioning
tooltip.style('position', 'absolute');
}
Note that we set the chart size so that it's more like tooltip content instead of a subchart.
The last bit is a bit hacky - since c3 requires that we set a HTML (which we don't want to do) and because we don't have any other callbacks we can easily hitch onto after the content handler, we have to disable the function that c3 uses to set the html content on the tooltip (this will affect only this chart's tooltip) i.e. .tooltip.html
// MONKEY PATCHING (MAY break if library updates change the code that sets tooltip content)
// we override the html function for the tooltip to not do anything (since we've already created the tooltip content inside it)
chart.internal.tooltip.html = function () {
// this needs to return the tooltip - it's used for positioning the tooltip
return chart.internal.tooltip;
}
Fiddle - http://jsfiddle.net/muuqvf1a/
Tooltip Positioning
Instead of using c3's tooltip positioning you could also size and position the tooltip at the bottom of the chart. Just style .c3-tooltip-container.
Alternatives
Note that c3 also support subcharts (http://c3js.org/reference.html#subchart-show) and data.mouseover (http://c3js.org/reference.html#data-onmouseover) which could also be a cleaner avenues worth exploring.

Highcharts Pie Chart: How to ignore disabled legend items

Please see this JSFiddle.
In this example, you can see sum of all values at top left corner.
If you click on any legend item, it will be disabled, but the total value doesn't reflect it. The text should be updated to not include that disabled item. How can I do this?
While Ondkloss's answer works fine. But I have found a simpler solution, by using redraw event instead of load. JSFiddle
You can use the legendItemClick event to update the rendered text by keeping a reference to the Element. For example:
var totalText;
var chart = new Highcharts.Chart({
chart: {
events: {
load: function(event) {
totalText = this.renderer.text(
'Total: ' + total,
this.plotLeft,
this.plotTop - 20
).attr({
zIndex: 5
}).add()
}
}
}
//...
plotOptions: {
pie: {
point: {
events: {
legendItemClick: function(e) {
var newTotal = this.series.total + (this.visible ? -this.y : this.y);
totalText.attr({ text: 'Total: '+newTotal });
}
}
}
}
}
});
See this updated JSFiddle for a demonstration.

highstocks - legend position and refresh legend values on mousemove of multiple charts

Here is the scenario. I've multiple highstocks say 10 charts on a single page. Currently I've written 500 lines of code to position the legend, show tooltip and refresh the legend values on mousemove.
No. of legends vary per chart. On mousemove values of all the legends are updated. I need to optimize the code I am using highstocks v1.2.2.
Above screenshot shows 2 charts. Return, Basket, vs Basket Spread are legends and it's values are updated on every mousemove.
Please find this fiddle for example. In my case legends are positioned and updated values on mouse move with hundreds of lines of code. When I move the mouse the legend values of Return and Basket of first chart and the legend values of vs Basket Spread are updated. It's working fine but with lots of javascript code. So I need to optimize it less code or with highstocks built-in feature.
Update
User #wergeld has posted new fiddle. As I've shown in screenshot when cross-hair is being moved over any chart, the legend values of all the charts should be updated.
Is there anyway to implement the same functionality with less code or is there built-in feature available in highstocks ???
Using this as a reference.
Basic example would be to use the events.mouseover methods:
plotOptions: {
series: {
point: {
events: {
mouseOver: function () {
var theLegendList = $('#legend');
var theSeriesName = this.series.name;
var theYValue = this.y;
$('li', theLegendList).each(function (l) {
if (this.innerText.split(':')[0] == theSeriesName) {
this.innerText = theSeriesName + ': ' + theYValue;
}
});
}
}
}
}
}
This is assuming I have modded the <li> to be:
$('<li>')
.css('color', serie.color)
.text(serie.name + ': NA')
.click(function () {
toggleSeries(i);
})
.appendTo($legend);
You would then need to handle the mouseout event but I do not know what you want to do there.
Working example.
EDIT:
Here is a version using your reference OHLC chart to put the values in a different legend location when any point in the chart is hovered.
plotOptions: {
series: {
point: {
events: {
mouseOver: function () {
//using the ohlc and volumn data sets created at runtime.
var stockVal = ohlc[this.index][4]; // show close value
var stockVolume = volume[this.index][1];
var theChart = $('#container').highcharts();
var theLegendList = $('#legend');
$('li', theLegendList).each(function (l) {
var legendTitle = theChart.series[l].name;
if (l === 0) {
this.innerText = legendTitle + ': ' + stockVal;
}
if (l === 1) {
this.innerText = legendTitle + ': ' + stockVolume;
}
});
}
}
}
}
}

jqplot tooltip on bar chart

I'm using the jquery plugin jqplot for plotting some bar charts.
on hover, I'd like to display the tick for the bar and its value on a tooltip. I've tried
highlighter: { show: true,
showTooltip: true, // show a tooltip with data point values.
tooltipLocation: 'nw', // location of tooltip: n, ne, e, se, s, sw, w, nw.
tooltipAxes: 'both', // which axis values to display in the tooltip, x, y or both.
lineWidthAdjust: 2.5 // pixels to add to the size line stroking the data point marker
}
but it doesn't work. the bar visually gets lighter, and there's a small dot on the top (which would ideally go away--probably from line chart renderer stuff), but there is no tooltip anywhere. Anyone know how I can do this? I'll have lots of bars so the x-axis will be cluttered and kind of a mess if I show them down there only.
I go through jqplot.highlighter.js and find an undocumented property: tooltipContentEditor.
I use it to customize the tooltip to display x-axis label.
Use something like this:
highlighter:{
show:true,
tooltipContentEditor:tooltipContentEditor
},
function tooltipContentEditor(str, seriesIndex, pointIndex, plot) {
// display series_label, x-axis_tick, y-axis value
return plot.series[seriesIndex]["label"] + ", " + plot.data[seriesIndex][pointIndex];
}
nevermind, I did a roundabout way to create my own tooltip via jquery.
I left my highlighter settings as they were in my question (though you probably don't need the tooltip stuff).
In my js file after the bar chart is set up (after $.jqplot('chart', ...) I set up an on mouse hover binding, as some of the examples showed. I modified it like this:
$('#mychartdiv').bind('jqplotDataHighlight',
function (ev, seriesIndex, pointIndex, data ) {
var mouseX = ev.pageX; //these are going to be how jquery knows where to put the div that will be our tooltip
var mouseY = ev.pageY;
$('#chartpseudotooltip').html(ticks_array[pointIndex] + ', ' + data[1]);
var cssObj = {
'position' : 'absolute',
'font-weight' : 'bold',
'left' : mouseX + 'px', //usually needs more offset here
'top' : mouseY + 'px'
};
$('#chartpseudotooltip').css(cssObj);
}
);
$('#chartv').bind('jqplotDataUnhighlight',
function (ev) {
$('#chartpseudotooltip').html('');
}
);
explanation:
ticks_array is previously defined, containing the x axis tick strings. jqplot's data has the current data under your mouse as an [x-category-#, y-value] type array. pointIndex has the current highlighted bar #. Basically we will use this to get the tick string.
Then I styled the tooltip so that it appears close to where the mouse cursor is. You will probably need to subtract from mouseX and mouseY a bit if this div is in other positioned containers.
you can then style #chartpseudotooltip in your css. If you want the default styles you can just add it to .jqplot-highlighter-tooltip in the the jqplot.css.
hope this is helpful to others!
I am using the version of the highlighter plugin on the following link:
https://github.com/tryolabs/jqplot-highlighter
The parameters I am using:
highlighter: {
show:true,
tooltipLocation: 'n',
tooltipAxes: 'pieref', // exclusive to this version
tooltipAxisX: 20, // exclusive to this version
tooltipAxisY: 20, // exclusive to this version
useAxesFormatters: false,
formatString:'%s, %P',
}
The new parameters ensure a fixed location where the tooltip will appear. I prefer to place it on the upper left corner to avoid problems with resizing the container div.

Categories

Resources