How can I align Chart title with the bar dynamically? - javascript

How can I align Chart title with the bar in highcharts?
The bar length may vary because of the data, so I want my title to end where the bar is ending.
I want to implement something like this:

To adjust the title you can set tittle.attr in the events.redraw event. You need to remember that a bar chart is an inverted column chart and where you have an x-axis there will be a y-axis.
chart: {
events: {
render: function() {
let chart = this,
series = chart.series[0],
title = this.title,
point = series.points[0];
title.attr({
x: chart.plotTop + point.x,
y: chart.plotLeft + point.y
});
}
}
},
API References:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement
Demo: https://jsfiddle.net/BlackLabel/ud45prLg/

I would suggest adding a padding-right: ##px as you havent provided any code to work with. try applying the method via inspect element and add the code into your css after with the right amount of "px" needed.

Related

'Click anywhere' event in plotly

I am trying to implement a 'click anywhere' feature in plotly so that I can get the coordinates on user clicks anywhere on plotly charts. The current "official" plotly functionality only works when users click on a plotted data point, but I want to register clicks e.g. on the background white canvas.
Shiny click events for plots can do that, but surprisingly this doesn't seem to exist yet in plotly.
I made some research and found the following codepen implementation which comes close: https://codepen.io/tim-logan/pen/yLXgpyp
#JS
var d3 = Plotly.d3;
var gd = document.getElementById('graph');
Plotly.plot('graph', [{
y: [2, 1, 2]
}])
.then(attach);
function attach() {
var xaxis = gd._fullLayout.xaxis;
var yaxis = gd._fullLayout.yaxis;
var l = gd._fullLayout.margin.l;
var t = gd._fullLayout.margin.t;
gd.addEventListener('mousemove', function(evt) {
var xInDataCoord = xaxis.p2c(evt.x - l);
var yInDataCoord = yaxis.p2c(evt.y - t);
console.log(evt.x, l)
Plotly.relayout(gd, 'title', ['x: ' + xInDataCoord, 'y : ' + yInDataCoord].join('<br>'));
});
}
# HTML
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div style="padding-left: 100px; margin-left: 100px">
<div id="graph"></div>
</div>
</body>
However, as the creator of the codepen pointed out, the click coordinates are not precises as they don't take into account the padding / margin:
One issue with the example workaround is that it doesn't account for padding/margin in parent objects.
I've taken the example and added a parent div that has both padding and margin on the left side, this then skews the value of the x-axis value, and is clearly something that would need to be handled in such a solution as is suggested here.
According to the flot documentation this should be possible for plot objects by subtracting the plot offset from the coordinates:
https://github.com/flot/flot/blob/master/API.md#plot-methods
See e.g. the following excerpt:
Various things are stuffed inside an axis object, e.g. you could use getAxes().xaxis.ticks to find out what the ticks are for the xaxis. Two other useful attributes are p2c and c2p, functions for transforming from data point space to the canvas plot space and back. Both returns values that are offset with the plot offset.
or:
offset()
Returns the offset of the plotting area inside the grid relative to the document, useful for instance for calculating mouse positions (event.pageX/Y minus this offset is the pixel position inside the plot).
I tried to implement a workaround based on offset(), but since my js knownledge is not too good I couldn't get a working version of the code.
Would somebody be able to provide a workaround to fix the offset problem?
I managed to remove the offset by getting the parent box's dimensions. See following example which fixed the above codepen:
var d3 = Plotly.d3;
var gd = document.getElementById('graph');
Plotly.plot('graph', [{
y: [2, 1, 2]
}])
.then(attach);
function attach() {
gd.addEventListener('mousemove', function(evt) {
var bb = evt.target.getBoundingClientRect();
var x = gd._fullLayout.xaxis.p2d(evt.clientX - bb.left);
var y = gd._fullLayout.yaxis.p2d(evt.clientY - bb.top);
Plotly.relayout(gd, 'title', ['x: ' + x, 'y : ' + y].join('<br>'));
});
}
Fixed codepen here: https://codepen.io/flaviofusero/pen/BaZRgzO
Adapted from sleighsoft's implementation here: plotly click events from anywhere on the plot

Center Highcharts tooltip in the middle of donut chart in a responsive way

In Highcharts, I know you can put your tooltip in a fixed position using:
tooltip: {
positioner: function () {
return { x: 50, y: 50 };
},
},
But how would I center it in the same way that margin: 0 auto would center it? I am trying to get the tooltip text to stay in the middle of a donut chart. The solution is probably something obvious but I have yet to figure out what it is. Thanks in advance!
You can make use of chart plotHeight and plotWidth to get access to current chart height and width and adjust the tooltip x and y accordingly as below:
positioner:function(){
return { x: chart.plotWidth/2, y: chart.plotHeight/2 };
}
A working demo here: https://angular-raebwk.stackblitz.io

Highcharts column tooltip - always on top + fit the container

I have a highchart graph with tooltips. This is how I want to render tooltips every time.
When the tootlip doesn't fit the svg container, highcharts swaps the position of tooltip like this.
I know how to fix this but when I do this.
positioner: function(boxWidth, boxHeight, point) {
return {
x: point.plotX,
y: point.plotY - boxHeight
};
},
Tooltip is correctly always on top, but overflows to the right(image_1). I would like to have the tooltip always on top + fit the container from the sides. (image_2)
Is there any easy way to achieve this?
Thanks (http://jsfiddle.net/4xomw3aj/)
Ok I just found out how to 'not swap'. In Tooltip.getPosition()
firstDimension = function (dim, outerSize, innerSize, point) {
ret[dim] = point - distance - innerSize;
},

SAPui5 sap.viz.ui5.StackedColumn custom tooltip on data point

I am trying to implement a custom tooltip in a sap viz stacked column chart. This is the small popup window that appears when the mouse hovers a datapoint. My problem is how to detect the position of the data point so that the tooltip popup points to it. Currently it always points to the graph itself, not the datapoint inside the graph.
Here's what I have:
graph = new sap.viz.ui5.StackedColumn({
width: graphWidth,
height : graphHeight,
//.. more properties here
interaction: new sap.viz.ui5.types.controller.Interaction({
decorations: [{name: "showDetail", fn: showDetailHandler}, {name: "hideDetail", fn:hideDetailHandler}]
}),
and the showDetailHandler is currently like this. It is supposed to display a popup pointing to the data point.
var showDetailHandler = function(oEvent){
var data = oEvent.data;
var offset = '0 0';
var tp3 = new sap.ui.ux3.ToolPopup({
content : [ new sap.ui.commons.Button({
text : "button"
}) ],
});
offset = '0 0';
offset = oEvent.position.x + " " + oEvent.position.y;
tp3.setPosition( sap.ui.core.Popup.Dock.CenterBottom,
sap.ui.core.Popup.Dock.CenterTop,
$(oEvent.container),
offset,
"none");
if (tp3.isOpen()) {
tp3.close();
} else {
tp3.open(sap.ui.core.Popup.Dock.CenterBottom, sap.ui.core.Popup.Dock.CenterTop);
}
};
The docs around this are here:
https://sapui5.hana.ondemand.com/sdk/#docs/api/symbols/sap.ui.core.Popup.html#setPosition
https://sapui5.hana.ondemand.com/sdk/docs/api/symbols/sap.viz.ui5.types.controller.Interaction.html#getDecorations
My understanding is that the offset is an offset to the point calculated by the anchor point. Problem is, offset is completely ignored. Popup always appears at the top of the graph.
However, the normal tooltip appears in the correct place.
Any idea/example?
Thank you in advance.

Finding the Y axis value for a plot line in HIghCharts.js

I am trying to size a background image on a HighCharts line chart dynamically depending on the position of the top plot line. The image I am trying to size is the bell curve in the image below.
I can't set the height of the image as a static value because the size of the screen can change and the top plot line also changes over time.
At the moment I am setting the position of the plot lines with external functions like this:
plotLines: [
value: upperControl3()}, {
color: '#ccc',
zIndex: 3,
width: 1,
label: {
text: '-2s',
x: 520,
y: 3
}
The closest thing to the y value of the top plot line I have been able to find is a dataMax value but this stays the same on every chart load.
I have been trying to overlay and size the image with a function at the end of the chart like this:
function(chart) {
console.log(chart.yAxis[0].plotLinesAndBands[7].axis.plotLinesAndBands[0].axis);
var h = chart.yAxis[0].plotLinesAndBands[7].axis.plotLinesAndBands[0].axis.dataMax;
var y = chart.yAxis[0].axisTitle.y + extra;
// X, Y, Width, Height
chart.renderer.image('images/bell.jpg', 60, y, 200, h).add();
}
Is the any way to find the coordinates of a plot line in highcharts?
You can use plotLinesAndBands object, where plotlines are kept. In the options you have value, whcih can be translated into pixels value by toPixels function.
var $button = $('#button'),
$report = $('#report'),
chart = $('#container').highcharts();
$button.click(function () {
chart.xAxis[0].addPlotLine({
value: 5.5,
color: 'red',
width: 2,
id: 'plot-line-1'
});
var plotline = chart.xAxis[0].plotLinesAndBands[0];
$report.html('Value: ' + plotline.options.value + ' Pixels: ' + chart.xAxis[0].toPixels(plotline.options.value));
});
http://jsfiddle.net/HhP39/1/
If you know which plot line (by index) it is, you can do this:
chart.yAxis[0].plotLinesAndBands[0].options.value
Of course, you need to make sure your data is actually normally distributed, or else that normal curve means nothing :)
And zero-bounded data is not usually normally distributed.

Categories