Render SVG images on each point of gantt chart in highcharts - highcharts

I want to put some images as SVG on each point in Gantt chart, I've tried something like below:
function (chartt) { // on complete
chartt.renderer.image('imageURL.png',100,100,30,30)
.add();
}
But after running this code, the image will be shown on the corner of the page. I want to draw images on each point in the chart and set their position related to its point.
Live Demo: https://jsfiddle.net/meysamm22/x41wdu5z/

You need to use the right x and y attributes, calculate them based on plotX and plotY point's properties:
function(chartt) { // on complete
var points = chartt.series[0].points,
width = 30,
height = 30;
points.forEach(function(point) {
chartt.renderer.image(
'https://www.highcharts.com/images/employees2014/Torstein.jpg',
point.plotX + chartt.plotLeft + point.shapeArgs.width / 2 - width / 2,
point.plotY + chartt.plotTop - height / 2,
width,
height
)
.attr({
zIndex: 5
})
.add();
});
});
Live demo: https://jsfiddle.net/BlackLabel/r4ph3ykz/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#image

Related

How to move point's label and SVGs by moving a point graphic in highcharts gantt?

In this example, I tried to move the points by points.graphic.translate(0, -25), but it can't help to move point's label and SVGs. You can see the details in the example.
events: {
load() {
var chart = this,
series = chart.series[0];
series.points.forEach(function(point) {
point.graphic.translate(0, -25);
});
}
}
You need to move each element separately.
Label:
point.dataLabel.text.translate(0, -25)
And custom image just after rendering it:
points.forEach(function(point) {
point.customImg = chartt.renderer.image(
'https://www.highcharts.com/images/employees2014/Torstein.jpg',
point.plotX + chartt.plotLeft + point.shapeArgs.width / 2 - width / 2,
point.plotY + chartt.plotTop - height / 2,
width,
height
)
.attr({
zIndex: 5
})
.add();
point.customImg.translate(0, -25)
});
Demo: https://jsfiddle.net/BlackLabel/05hmufxa/

Highchart tooltip position to be fixed

I HV multi line chart, I want the shared tooltip to be at the top of the graph ( so that it doesn't covers up the space of graph) , but I want it to have fixed 'y'
And x coordinate to be Free.
So that user can hover over the graph and the tooltip comes at the top of that point ( x coordinate).
Is there a way where I can fix only the y coordinate of the tooltip position?
You can use the tooltip.positioner function. http://api.highcharts.com/highcharts/tooltip.positioner
tooltip: {
positioner: function (labelWidth, labelHeight, point) {
return { x: point.plotX, y: 15 };
},
shadow: false,
borderWidth: 0,
backgroundColor: 'rgba(255,255,255,0.8)'
},
http://jsfiddle.net/nt9x5tjj/
The callback receives a point object that contains plotX and plotY positions. Fix the y value to some number and return point.plotX as the x value.

Label position between series in Highcharts polar chart

I'm trying to position custom labels on the outside of a polar chart but can't figure out any way to do it. Please image below for what I'm trying to achieve.
Doesn't have to use the actual series labels but haven't found anything else that can be positioned relative to the actual chart (top level labels can be positioned anywhere but only using absolute left and top).
Have also tried changing the pointPlacement and tickmarkPlacement to "between" which sort of works but it rotates the actual chart so I get a diamond shape instead of a square, the effect I'm after would be more like rotating the labels and leaving the ticks in place.
IN such case custom labels can be positioned relative to grid line group.
Method for drawing the labels:
function drawLabels () {
let labels = this.customLabels,
bbox = this.xAxis[0].gridGroup.getBBox(),
positions = [
[bbox.x + bbox.width / 2, bbox.y],
[bbox.x + bbox.width, bbox.y + bbox.height / 2],
[bbox.x + bbox.width / 2, bbox.y + bbox.height],
[bbox.x, bbox.y + bbox.height / 2]
];
if (!labels) {
labels = this.customLabels = ['lab1', 'lab2', 'lab3', 'lab4'].map(text => this.renderer.label(text, 0, -9999).add().attr({zIndex: 4}));
}
labels.forEach((label, i) => {
label.align({
align: 'center',
verticalAlign: 'middle',
width: label.width,
height: label.height
}, null, {
x: positions[i][0],
y: positions[i][1],
width: 0,
height: 0
});
});
}
Draw labels on load/redraw:
Highcharts.chart('container', {
chart: {
polar: true,
type: 'line',
events: {
load: drawLabels,
redraw: drawLabels
}
},
example: http://jsfiddle.net/d6y1bn31/

How to calculate the height of bar chart

How can I calculate the height of a bar chart so that for different number of bars, highcharts always use the same height for a single bar. Without setting any height the size of the bars are to large for a minor number and to thin and missing labels for larger number of bars.
You can do it by dynamic change of height of your chart in dependence on your data length.
http://api.highcharts.com/highcharts#chart.height
chart: {
marginTop: 40,
marginBottom: 80,
height: data.length * 20 + 120 // 20px per data item plus top and bottom margins
}
jsFiddle made by Torstein Hønsi:
http://jsfiddle.net/highcharts/jMX8G/
Similar Topic:
https://highcharts.uservoice.com/forums/55896-highcharts-javascript-api/suggestions/3456724-size-height-of-bar-graph-based-on-contents-when-co
You can also see custom function I wrote. Inside it I am iterating over all of my series data and making a sum of all visible data. Then I am setting the height of my chart with width of my column (passed in function parameter), number of columns, marginBottom and plotTop of my chart.
at the end if this size is different than previous size of chart I am setting new size of chart with Chart.setSize():
http://api.highcharts.com/highcharts#Chart.setSize
example:
http://jsfiddle.net/izothep/d3ezek8t/1/
I have a similar set up that I use, I will post here for posterity:
http://jsfiddle.net/jlbriggs/kpu5d1qf/
Uses a set of variables to define the chart/bar sizing parameters, and works from there.
//count the data points
var barCount = chartData.length;
//specify chart properties that will be used to calculate the total height
var pointWidth = 20;
var marginTop = 60;
var marginRight = 10;
var marginBottom = 50;
var marginLeft = 100;
var groupPadding = 0;
var pointPadding = 0.3;
var chartHeight = marginTop
+ marginBottom
+ ((pointWidth * barCount) * (1 + groupPadding + pointPadding));
And in the chart options, for example:
chart: {
type : 'bar',
marginTop : marginTop,
marginRight : marginRight,
marginBottom : marginBottom,
marginLeft : marginLeft,
height : chartHeight
},
So you can edit all of the properties that might affect the height of the chart outside of the chart options, and all are accounted for when calculating the final height.

Highcharts tooltip always on right side of cursor

I want to show the tooltip on the right side of the cursor.
I looked in the documentation/examples but I can't find a way to force the tooltips to stay on the right side of the cursor.
Can anyone tell me how to do it?
With tooltip positioner I only can set a default position.
Tooltip positioner is much more than just default position. The function arguments contain info about your point position & tooltip dimensions, using which it should be fairly simple to position it to the right.
Highchart/stock allows you to define your alternate positioner as follows
tooltip:{
positioner:function(boxWidth, boxHeight, point){
...
}
}
Note that you have three arguments (boxWidth, boxHeight, point) at your disposal, these seem to be sufficient for most of the use cases to calculate a desired tooltip position. boxWidth and boxHeight are the width and height that your tooltip will require, hence you can use them for edge cases to adjust your tooltip and prevent it from spilling out of the chart or even worse getting clipped.
The default tooltip positioner that comes with highstock is as follows (Source)
/**
* Place the tooltip in a chart without spilling over
* and not covering the point it self.
*/
getPosition: function (boxWidth, boxHeight, point) {
// Set up the variables
var chart = this.chart,
plotLeft = chart.plotLeft,
plotTop = chart.plotTop,
plotWidth = chart.plotWidth,
plotHeight = chart.plotHeight,
distance = pick(this.options.distance, 12), // You can use a number directly here, as you may not be able to use pick, as its an internal highchart function
pointX = point.plotX,
pointY = point.plotY,
x = pointX + plotLeft + (chart.inverted ? distance : -boxWidth - distance),
y = pointY - boxHeight + plotTop + 15, // 15 means the point is 15 pixels up from the bottom of the tooltip
alignedRight;
// It is too far to the left, adjust it
if (x < 7) {
x = plotLeft + pointX + distance;
}
// Test to see if the tooltip is too far to the right,
// if it is, move it back to be inside and then up to not cover the point.
if ((x + boxWidth) > (plotLeft + plotWidth)) {
x -= (x + boxWidth) - (plotLeft + plotWidth);
y = pointY - boxHeight + plotTop - distance;
alignedRight = true;
}
// If it is now above the plot area, align it to the top of the plot area
if (y < plotTop + 5) {
y = plotTop + 5;
// If the tooltip is still covering the point, move it below instead
if (alignedRight && pointY >= y && pointY <= (y + boxHeight)) {
y = pointY + plotTop + distance; // below
}
}
// Now if the tooltip is below the chart, move it up. It's better to cover the
// point than to disappear outside the chart. #834.
if (y + boxHeight > plotTop + plotHeight) {
y = mathMax(plotTop, plotTop + plotHeight - boxHeight - distance); // below
}
return {x: x, y: y};
}
With all the above information, I think you have sufficient tools to implement your requirement by simply modifying the function to make float to right instead of the default left.
I will go ahead and give you the simplest implementation of positioning tooltip to right, you should be able to implement the edge cases based on the aftermentioned default tooltip positioner's code
tooltip: {
positioner: function(boxWidth, boxHeight, point) {
return {x:point.plotX + 20,y:point.plotY};
}
}
Read more # Customizing Highcharts - Tooltip positioning
The better solution to get your tooltip always on the right side of the cursor is the following:
function (labelWidth, labelHeight, point) {
return {
x: point.plotX + labelWidth / 2 + 20,
y: point.plotY + labelHeight / 2
};
}

Resources