I want some customization in the Gantt chart as follows:
display some text/html on the top left section (interaction of x and y-axis)
show x Axis (header) with black color in the background and some other customization in styles but got nothing in documentation.
Please refer attached image.
https://i.stack.imgur.com/Ir1gN.png
You can render text via SVG renderer, set position from the plot area. What interaction section do you mean, could you show screenshot?
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer
Gantt chart is draw by line, and draw automatically, you can't find background options for axis in our documentation.
Possibility to make this is draw rectangle by SVG renderer and set them under draw line.
chart: {
events: {
render: function() {
var chart = this,
series = chart.series,
plotLeft = chart.plotLeft,
plotTop = chart.plotTop,
plotWidth = chart.plotWidth;
if (chart.myBackground) {
chart.myBackground.destroy();
}
chart.myBackground = chart.renderer.rect(plotLeft, plotTop, plotWidth, 50, 0)
.attr({
'stroke-width': 2,
stroke: 'red',
fill: 'yellow',
opacity: 0.5,
zIndex: -1
})
.add();
}
}
},
Live demo:
https://jsfiddle.net/BlackLabel/xmg31aez/
Related
I want to align Highcharts PlotLine Label with the line (not top or bottom). Is it possible?
Thank!
I think that the easiest way to achieve it is by rendering the plotLine and adding the custom label on it to cover part of the line.
Demo: https://jsfiddle.net/BlackLabel/b50k6hov/
Code:
chart: {
events: {
render() {
let chart = this,
plotLineCor = chart.yAxis[0].plotLinesAndBands[0].svgElem.d.split(' '),
x = plotLineCor[1],
y = plotLineCor[2];
if (!chart.label) {
// render label in init position
chart.label = chart.renderer.label('TEXT', 0, 0)
.css({
color: 'red'
})
.attr({
fill: 'white',
padding: 12,
zIndex: 6
})
.add();
}
// translate label after reach resize
chart.label.translate(x, y - chart.label.getBBox().height / 2)
}
}
},
API: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#label
API: https://api.highcharts.com/highcharts/chart.events.render
I change the color and radius of my spline's marker as soon as it crosses a certain value by using point.update however now I am aggregating the data using dataGrouping and I have lost that ability. How can I color the aggregated data point?
Currently it is not possible to update grouped points. Please check a thread in this github isssue: https://github.com/highcharts/highcharts/issues/5147
However, you can use attr method directly on SVG point elements:
chart: {
events: {
load: function() {
var points = this.series[0].groupedData;
points.forEach(function(point) {
if (point.y > 30) {
point.graphic.attr({
width: 8,
height: 8,
fill: 'red',
translateX: -2
});
}
});
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/58afeL47/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
In Highcharts, there is a possibility to shift the y-Axis labels into the plot-area with
yAxis: {
labels: {
align: 'left',
x: 0,
y: -2
}
}
With this setting, the labels are covered by the lines, data-labels and so on.
Is it possible to draw the horizontal grid lines across the yAxis-Label-Area without making the xAxis and the series start there. The wished behavior is indicated with the black lines in the image below.
The simplest solution is to adjust the xAxis, for example:
xAxis: {
min: -0.5
}
Live demo: http://jsfiddle.net/BlackLabel/qnayxb04/
API: https://api.highcharts.com/highcharts/xAxis.min
If you want to have more control over the lines, you can use setAttribute to edit the path element:
chart: {
events: {
load: function() {
var gridLines = this.yAxis[0].gridGroup.element.children,
i,
path;
for (i = 0; i < gridLines.length; i++) {
path = gridLines[i].attributes.d.nodeValue;
path = 'M 40' + path.substr(4);
gridLines[i].setAttribute('d', path)
}
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/61h5qtn9/1/
The default behavior of the x-axis title alignment is within the bounds of the x-axis. However, the legend alignment is within the bounds of the entire chart. Thus, if you align both center, they have a slight offset. How can I get the legend to base its position off of the x-axis bounds instead? My graph options are dynamic, so I would need to do it dynamically.
Sample JS Fiddle
$('#container').highcharts({
legend: { margin:5, padding:0 },
xAxis:{
title:{
text:'THIS IS MY X-AXIS TITLE',
align:'middle',
},
categories:["A","B","C","D","E","F"]
}
});
Thanks in advance!
Example for you: http://jsfiddle.net/xqag5e72/2/
In short, you can change translation for legend to be similar to xAxis' title:
function moveLegend(e) {
var legend = this.legend,
x = this.plotLeft + (this.xAxis[0].width / 2) - legend.group.getBBox().width / 2,
y = legend.group.translateY;
legend.group.attr({
transform: 'translate(' + x + ',' + y +')'
});
}
Note: I'm using load and redraw events, to translate legend after first initialization and later to make this legend responsive.
I want to draw a background behind a plotLine label in a highstock chart.
Using an example from the Highstock API, I came up with this code (crt is the chart object):
var textbox = crt.yAxis[ 0 ].plotLinesAndBands[ 0 ].label;
var box = textbox.getBBox();
crt.renderer.rect(box.x - 3, box.y + 1, box.width + 6, box.height, 3).attr({
fill: '#0c0',
id: 'labelBack',
opacity: .7,
'stroke-width': 0,
zIndex: 4
}).add();
This draws a semi-transparent box behind the label as intended (the label has zIndex 5). However when the chart is resized, the box maintains the same position relative to the top-left of the chart, causing misalignment with the label text (the position of the label changes because of the chart resizing).
I tried using the chart redraw event for this, but even though I can see that the event is fired, and the function is executed again, no other boxes are drawn (I was trying to get more boxes to appear on each redraw, planning to solve removing obsolete boxes in the next iteration).
How can I solve this?
It feels more like a hack than a genuine solution, but I have come up with a workaround that solves my issue for now, I have the function below:
var labelBackground = null;
function labelDrawBack(crt) {
if ( isIntraDay ) {
var textbox = crt.yAxis[ 0 ].plotLinesAndBands[ 0 ].label;
if ( !!labelBackground ) {
labelBackground.attr({ y: textbox.y - 10 });
} else {
var box = textbox.getBBox();
labelBackground = crt.renderer.rect( box.x - 3, box.y + 1, box.width + 6, box.height, 3 ).attr( {
fill: '#fff',
id: 'labelBack',
opacity: .65,
'stroke-width': 0,
zIndex: 4
}).add();
}
}
}
I make sure this function is executed immediately after the chart is initialized and additionally I attach the function to the chart object that is returned from the StockChart call:
var chartObj = new Highcharts.StockChart( chartConfig, function ( crt ) {
labelDrawBack( crt );
} );
chartObj.labelDraw = labelDrawBack;
And in the chart options I have added this to the chart.redraw event:
events: {
redraw: function() {
this.labelDraw(this);
}
}
This works as intended, moving the transparent background with the label (which is moved vertically when the chart is resized).
The reason I have redirected the call in the chart redraw event is that the labelDrawBack function is defined in another function than the one where my chart options are defined, thus the labelDrawBack function is out of scope there.