Working with highcharts and I'm attempting to get the tooltip on a bar chart to hover directly above the right hand side of the bar. For example:
Currently I'm using the positioner function but I can't seem to figure out the math to get this to work. Currently when I attempt to use the point.plotX and point.plotY options the tooltip hovers in what appears to be a random spot, and I'm unable to find where you would get the right hand position of the bar. Here's the code I'm currently using
positioner: function(width, height, point) {
return {
x: point.plotX,
y: point.plotY,
};
},
and here's the output for how that looks:
It seems that you have a typo in your positioner function. You should use plotY insted of ploty property:
tooltip: {
positioner: function(width, height, point) {
return {
x: point.plotX,
y: point.plotY,
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/poxv4wq1/
API Reference: https://api.highcharts.com/highcharts/tooltip.positioner
EDIT:
The positioner function return a tooltip coordinates relative to the entire chart. The values point.plotX and point.plotY are relative to the plot area, so you need to add chart.plotTop and chart.plotLeft values:
positioner: function(width, height, point) {
var columnWidth = this.chart.series[0].options.pointWidth;
return {
x: point.plotX + this.chart.plotLeft,
y: point.plotY - columnWidth / 2 + this.chart.plotTop - height
};
}
Live demo: http://jsfiddle.net/BlackLabel/0cjftrsy/
ok, becouse of the label styles. The position of the toolTip is of.
This how i fixed it.
This example worked with http://jsfiddle.net/fqbkozpr/1/
return {
x: Math.max(point.plotX, width), // To the right.
y: point.plotY + height, // Make sure to be under the line
};
Related
I'm trying to increase the hover detection radius for scatter points in HighCharts, but I've found no official way of doing it.
Essentially, I want each point to have an invisible radius that triggers the hover effect when the mouse enters it.
I know stickyTracking exists, but in my case it feels a bit too sticky.
Turning it off, however, means having to be extremely precise before the tooltip shows up.
StickyTracking off: https://jsfiddle.net/wsxkLn25
StickyTracking on: https://jsfiddle.net/wsxkLn25/1/
Is there a way to trigger the hover effect on a point before the mouse enters the actual radius of the point without stickyTracking?
There is no such feature in Highcharts, but you can implement it by enabling sticky tracking and process the internal getHoverData method only if a hovered point is close enough to a mouse cursor. Example:
(function(H) {
H.wrap(H.Pointer.prototype, 'getHoverData', function(proceed, existingHoverPoint, existingHoverSeries, series, isDirectTouch, shared, e) {
var hoverData = proceed.apply(this, Array.prototype.slice.call(arguments, 1));
var RADIUS = 20;
var point = hoverData.hoverPoint;
var chart = this.chart;
var plotX;
var plotY;
if (point) {
plotX = point.plotX + chart.plotLeft;
plotY = point.plotY + chart.plotTop;
if (
plotX + RADIUS > e.chartX && plotX - RADIUS < e.chartX &&
plotY + RADIUS > e.chartY && plotY - RADIUS < e.chartY
) {
return hoverData;
} else if (chart.hoverPoint) {
chart.hoverPoint.setState('');
chart.tooltip.hide();
}
}
return {
hoverPoint: null,
hoverPoints: [],
hoverSeries: null
};
});
}(Highcharts));
Live demo: https://jsfiddle.net/BlackLabel/sb35j0ov/
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts
How could I get the width of a bar/box like in this snippet:
http://jsfiddle.net/zk9oc4c9/
to determine the y-postions of the bar?
In the Fiddle above version 1.x is used but this.chart.ctx.moveTo(0, this.scale.calculateY(lineHeight)); isn't possible in version 2.x.
With such kind of coordinates I want to draw a line into the chart. Drawing with static values (dummy data) works, but I need id dynamically.
So please see the screenshot how the chart looks like with static values for the line(s). The y-coordinates for the dashed line is easy - just the border of the chart. But I mean the red solid line.
So I wrote a plugin and this is the part where to draw the line(s) - this is just an excerpt:
Chart.plugins.register({
afterDatasetsDraw: function(chartInstance, easing) {
var coord = {
x: // this calculation is already done,
startY: 0,
endY: 0
};
// actually draw the line
ctx.beginPath();
ctx.moveTo(coord.x, coord.startY);
ctx.lineTo(coord.x, coord.endY);
ctx.stroke();
ctx.closePath();
}
});
Edit
I did some kind of solution. It's a bit a workaround, but it works:
Chart.plugins.register({
afterDatasetsDraw: function(chartInstance, easing) {
// get the meta from any dataset
var meta = chartInstance.getDatasetMeta(0);
var xScale = chartInstance.scales[meta.xAxisID];
var coord = {
x: xScale.getPixelForValue(<value for the line>);
startY: 0,
endY: 0
};
var yScale = chartInstance.scales[meta.yAxisID];
// get the height of the y-axis - subtract the top padding for the chart here
var height = yScale.bottom - yScale.top;
// get categoryPercentage & barPercentage from the chart's configuration
var catPerc = yScale.options.categoryPercentage;
var barPerc = yScale.options.barPercentage;
// calculate the each category height
var catHeight = (height * catPerc) / yScale.ticks.length;
// so calculate the height of a single bar
var barHeight = catHeight * barPerc;
var factor = barHeight / catHeight;
// padding between chat edge and the bar itself
var padding = (catHeight - barHeight) * factor;
// use the top value from which the chart itself is rendered + the padding
coord.startY = yScale.top + padding - 2;
coord.endY = coord.startY + barHeight + 3;
// actually draw the line
ctx.beginPath();
ctx.moveTo(coord.x, coord.startY);
ctx.lineTo(coord.x, coord.endY);
ctx.stroke();
ctx.closePath();
}
});
I am working with highcharts at the moment, I have a tooltip on by bar chart that is being cut off by a overflow:hidden setting, this is fine and understand I need that setting however the positioning of the tooltip is not overly intelligant, is there a way to position the tooltip relative to the width of the column, i.e if the tooltip is going cause a scrollbar can I decrease the offset? I don't have a code example, but I have attached an image of my problem,
Use tooltip positioner function in your tooltip. Adjust tooltipX and tooltipY accroding to your display requiremets :
positioner: function(labelWidth, labelHeight, point) {
var tooltipX, tooltipY;
if (point.plotX + labelWidth > this.chart.plotWidth) {
tooltipX = point.plotX + this.chart.plotLeft - labelWidth - 40;
} else {
tooltipX = point.plotX + this.chart.plotLeft + 40;
}
tooltipY = point.plotY + this.chart.plotTop - 20;
return {
x: tooltipX,
y: tooltipY
};
}
I am trying to create a funnel chart using the D3Funnel library . I am able to render the chart and display my data but since I am drawing it in a very small size widthwise, the text labels for the categories often overflow out of the funnel. Which doesn't look very pleasing. So now my idea is to display the labels in two lines; in the first line will be the cateogry and in the second line I want to display the amount.
To be able to do so, I tried following the various examples available here to text wrap the labels/text but I haven't been able to make any progress. So it will be great if someone can help me out here.
http://jsfiddle.net/NewMonk/s76oap3d/1/
I feel that the relevant place where I need to make the change is somewhere in the below part of the code but not able to figure out how shall I go about it:
{
key: '_addBlockLabel',
value: function _addBlockLabel(group, index) {
var paths = this.blockPaths[index];
var label = this._getBlockData(index)[0].formatted;
var fill = this.data[index][3] || this.label.fill;
var x = this.width / 2; // Center the text
var y = this._getTextY(paths);
group.append('text').text(label).attr({
'x': x,
'y': y,
'text-anchor': 'middle',
'dominant-baseline': 'middle',
'fill': fill,
'pointer-events': 'none'
}).style('font-size', this.label.fontSize);
}
/**
* Returns the y position of the given label's text. This is determined by
* taking the mean of the bases.
*
* #param {Array} paths
*
* #return {Number}
*/
}, {
key: '_getTextY',
value: function _getTextY(paths) {
if (this.isCurved) {
return (paths[2][1] + paths[3][1]) / 2 + this.curveHeight / this.data.length;
}
return (paths[1][1] + paths[2][1]) / 2;
}
}]);
Regards
You can append two text elements instead of one.
Playing with the code it seems that you have access to both the label and the value, so just need to append them separately, with a dy property in order to separate them vertically:
key: '_addBlockLabel',
value: function _addBlockLabel(group, index) {
var paths = this.blockPaths[index];
var text = this.blocks[index].label.raw;
var value = this.blocks[index].value;
var fill = this.blocks[index].label.color;
var x = this.width / 2; // Center the text
var y = this._getTextY(paths);
group.append('text').text(text).attr({
x: x,
y: y,
dy: -10,
fill: fill,
'text-anchor': 'middle',
'dominant-baseline': 'middle',
'pointer-events': 'none'
}).style('font-size', this.label.fontSize);
group.append('text').text(value).attr({
x: x,
y: y,
dy: 10,
fill: fill,
'text-anchor': 'middle',
'dominant-baseline': 'middle',
'pointer-events': 'none'
}).style('font-size', this.label.fontSize);
}
Working fiddle: http://jsfiddle.net/38kkctqh/
I am using highcharts to create graphics in my website, however this tooltip covers my bars, Is there a way to tell the tooltip todisplay on top of the bar instead that ‘ON’ it?
here is what I am seeing:
There are many s question around tool-tip positioning on StackOverflow ,The way I used in my chart was to show tooltip left or right on hover of column using positioner.
tooltip: {
positioner: function(labelWidth, labelHeight, point) {
var tooltipX, tooltipY;
if (point.plotX + labelWidth > this.chart.plotWidth) {
tooltipX = point.plotX + this.chart.plotLeft - labelWidth - 40;
} else {
tooltipX = point.plotX + this.chart.plotLeft + 40;
}
tooltipY = point.plotY + this.chart.plotTop - 20;
return {
x: tooltipX,
y: tooltipY
};
} }