Highcharts. Pie chart. DataLabels formatter - javascript

I have a pie chart. And I need to format DataLabels in someway. So I use:
dataLabels: {
useHTML : true,
formatter: function () {
if(this.point.id == 'razr') {
return '<div><b>' + this.point.y + '</b></div><div style="left: -140px; text-align: center; position: absolute"><b>sum is:<br/>' + this.point.summ + ' </b></div>';
} else return '<b>' + this.point.y + '<b>';
}
}
And what I got:
My problem is here style="left: -140px;. The position is static. I can't find any way to position my sum label at the center of a green point of a chart. I've been searching the properties of a point (like plotX, graphic attr), nothing helps. If I remove style="left: -140px; datalabel will moves to the right. How can I get coordinates of my green point?

To be honest, it's not easy. I see two possible solutions:
1) Easy (but dirty workaround): create second pie chart under the first one with the same values, but render just one label. Then the second pie chart can have dataLabel inside the slice.
2) Hard (more generic solution): calculate required top/left offsets. It's hard because you don't know bounding box of the label. I suggest to set fixed width+height for that part of the label - so you can find center of that label's part. Then calculate position using series.center and point.labelPos arrays. These are inner options and can change between versions, so keep an eye on these options before upgrading. Example: http://jsfiddle.net/zwb5toe9/2/
dataLabels: {
useHTML: true,
formatter: function () {
var point = this.point,
width = 50,
height = 50,
series = point.series,
center = series.center, //center of the pie
startX = point.labelPos[4], //connector X starts here
endX = point.labelPos[0] + 5, //connector X ends here
left = -(endX - startX + width / 2), //center label over right edge
startY = point.labelPos[5], //connector Y starts here
endY = point.labelPos[1] - 5, //connector Y ends here
top = -(endY - startY + height / 2); //center label over right edge
// now move inside the slice:
left += (center[0] - startX)/2;
top += (center[1] - startY)/2;
if (point.id == 'razr') {
console.log(this);
return '<div><b>' + point.y + '</b></div><div style="width: ' + width + 'px; left:' + left + 'px;top:' + top + 'px; text-align: center; position: absolute"><b>sum is:<br/>' + point.summ + ' </b></div>';
} else return '<b>' + point.y + '<b>';
}
}

Related

Highcharts bar chart tooltip HTML positioning

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
};
}

HighCarts Tooltip position relative to mouse

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
};
} }

Custom tooltip for area stacked Highchart

I have used area stacked Highchart in my application.
This is my FIDDLE
I have converted the y axis values by place the below code in y axis - labels, but unable to format the tooltip to the same % values
formatter: function(){
return Math.round(100*this.value / $(this.axis.tickPositions).last()[0]) + '%';
}
But when I tried to apply the same for tool tip, the tooltip itself went invisible. How to apply the percentage to tool tip also. I have tried the below code.
tooltip: {
shared: false,
formatter: function() {
var text = '';
var pcnt = (this.y / dataSum) * 100;
text = this.x + ' : <b>'+ Highcharts.numberFormat(pcnt) +' M</b>';
return text;
}
},
Thanks in advance

Create div overlay for image based on xml attributes

I want to create a div overlay, set at 5% opacity, which creates a diagonal bounding box around each of the lines of text in this image. I have the coordinates of each of the four points I need to draw the bounding box, which are encoded as attributes in an XML element which contains the text of individual line as its data. It seems to me that since I have the x,y coordinates for the four corners, I should be able to create the overlay -- but I cannot figure out what the proper syntax would be to mark out the div. Someone suggested to me using the transform functions for CSS (which was the right call as I originally framed this question) but that sounds like I'd be basically writing eight separate pieces of css, one for each line -- which could get messy since there are potentially 118 pictures like this that I would be writing custom pieces of CSS for.
Am I wrong in thinking this can be done programmatically, and if not can someone point me at some methods for doing so?
Yes, it is possible this way, with simple html markup:
<div class="image_box" data-cords="20,50,210,50,50,250,240,250">I am the text inside the div, I can be in several lines. It is important for text stay vertical and it is important the text to follow boundary box.</div>
Than do some script magic:
$.fn.skewText = function () {
return this.each(function (i) {
var thisText = $(this);
var coords = thisText.data('cords').split(',');
/* Calculate degree */
var deg = Math.tan((coords[5] - coords[1]) / (coords[4] - coords[0])) * 57.2957795;
/* Skew pixels for calculations */
var skewVal = coords[4] - coords[0];
/* Calculate position */
var cssWidth = (coords[2] - coords[0] - skewVal) + 'px';
var cssHeight = (coords[5] - coords[1]) + 'px';
var cssTop = coords[1] + 'px';
var cssLeft = (coords[0] * 1 + skewVal) + 'px'; /* Add a half of skew */
/* Wrapp and apply styles */
thisText.wrapInner('<div class="skew_padding" />').wrapInner('<div class="skew_text" />');
var skewText = thisText.find('.skew_text');
skewText.css({
'transform': 'skew(' + deg + 'deg)',
'top': cssTop,
'left': cssLeft,
'width': cssWidth,
'height': cssHeight,
'background': 'none rgba(0,0,0,.5)'
});
/* Now skew back each letter inside */
var skewPadding = skewText.find('.skew_padding');
var letters = skewPadding.text().split(' ');
var newText = '<span>' + letters.join('</span> <span>') + '</span>';
skewPadding.html(newText);
skewPadding.find('span').css({
'display': 'inline-block',
'transform': 'skew(' + (-deg) + 'deg)'
});
});
};
$('[data-cords]').skewText();
That is possible with this css:
.image_box {
position: relative;
width: 300px;
height: 300px;
background: yellow;
}
.skew_text {
position: absolute;
}
.skew_padding {
padding: 10px;
}

Get x,y coord of a div when rotation is 0

Hi I need some help with math for my problem. I have a situation where I need to access the left,top coord of a div whenever a touchstart event is fired. But I need to get it based on the rotation of the div being 0 degree.
I have attached a fiddle which shows my condition. Right now when you press the button, the value is 'x:169, y:195'. But I am looking for some formula to get 'x: 208, y: 234'
document.querySelectorAll('input')[0].addEventListener('click',function() {
var x = Math.round(document.querySelectorAll('#knob')[0].getBoundingClientRect().left),
y = Math.round(document.querySelectorAll('#knob')[0].getBoundingClientRect().top)
alert('x: '+x+', y: '+y);
/*
* Alerts x: 208, y: 234 when angle is 0.
* Need to get this value all the time irrespective of the rotation.
*/
});
Is that possible? I did a lot of search but couldn't find the apt answer. And my math isn't good enough to modify the formulas for the other answers in SO.
Note that the centre of the red square will not change when rotated. So we can find its coordinates first (by taking averages), then figure out the top left corner (based off the fact that the size of the red square is given beforehand; in this case, it was 256x256). Here's a simple implementation:
document.querySelectorAll('input')[0].addEventListener('click',function() {
var left = Math.round(document.querySelectorAll('#knob')[0].getBoundingClientRect().left),
right = Math.round(document.querySelectorAll('#knob')[0].getBoundingClientRect().right),
top = Math.round(document.querySelectorAll('#knob')[0].getBoundingClientRect().top),
bottom = Math.round(document.querySelectorAll('#knob')[0].getBoundingClientRect().bottom),
x_mid = (left+right)/2.0,
y_mid = (top+bottom)/2.0,
x = x_mid - 256/2, // Subtract by half the knob's width.
y = y_mid - 256/2 // Subtract by half the knob's height.
alert('left: '+left+', right: '+right+', top: '+top+', bottom: '+bottom+'\n'
+'centre: ('+x_mid+', '+y_mid+')\n'
+'x: '+x+', y: '+y);
//Alerts x: 208, y: 234 when angle is 0. Need to get this value all the time irrespective of the rotation.
});
Use this code for any figure
document.querySelectorAll('input')[0].addEventListener('click', function () {
var left = Math.round(document.querySelectorAll('#knob')[0].getBoundingClientRect().left),
right = Math.round(document.querySelectorAll('#knob')[0].getBoundingClientRect().right),
top = Math.round(document.querySelectorAll('#knob')[0].getBoundingClientRect().top),
bottom = Math.round(document.querySelectorAll('#knob')[0].getBoundingClientRect().bottom),
width = Math.round(document.querySelectorAll('#knob')[0].offsetWidth),
height = Math.round(document.querySelectorAll('#knob')[0].offsetHeight),
x_mid = (left + right) / 2.0,
y_mid = (top + bottom) / 2.0,
x = x_mid - width / 2, // Subtract by half the knob's width.
y = y_mid - height / 2 // Subtract by half the knob's height.
alert('left: ' + left + ', right: ' + right + ', top: ' + top + ', bottom: ' + bottom + '\n' + 'centre: (' + x_mid + ', ' + y_mid + ')\n' +'dimen; w:' +width + ',h:'+ height + 'x: ' + x + ', y: ' + y);
});

Categories