Can we shoe the text inside the Highchart timeline bar?
for reference please look years into the attached snap.[timeline_spac][1]
[1]: https://i.stack.imgur.com/n1yvQ.jpg
You can use the SVGRenderer tool to render those labels.
Demo: https://jsfiddle.net/BlackLabel/d60o35sL/
events: {
render() {
const chart = this;
chart.series[0].points.forEach(point => {
const x = point.plotX;
const y = point.plotY + chart.plotTop + point.graphic.height / 3;
if (point.customLabel) {
point.customLabel.destroy()
}
point.customLabel = chart.renderer
.text(
'test',
x,
y
)
.css({
color: 'white',
})
.add();
point.customLabel.toFront()
})
}
}
},
API: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#text
API: https://api.highcharts.com/highcharts/chart.events.render
Related
I have an x-range chart, and I need to add custom components (SVG icons) at the start of each data point ("x" prop value). Something like this (red circles are where custom components should be):
My idea is to place a custom component with position absolute, but I can't figure out how to transform timestamp values of the X axis to pixels. Or maybe there is a better solution?
Codesandbox demo
There are multiple ways to achieve what you want:
A. You can get a chart reference and use Axis.toPixels method to calculate the required coordinates:
export default function Chart() {
const chartComponentRef = useRef(null);
const [x1, setX1] = useState(0);
useEffect(() => {
if (chartComponentRef) {
const chart = chartComponentRef.current.chart;
const xAxis = chart?.xAxis[0];
const x1 = xAxis?.toPixels(Date.UTC(2022, 7, 10));
setX1(x1);
}
}, [chartComponentRef]);
return (
<div style={{ position: "relative" }}>
<HighchartsReact
ref={chartComponentRef}
highcharts={Highcharts}
options={staticOptions}
/>
<div style={{ position: "absolute", bottom: 70, left: x1 }}>ICON</div>
</div>
);
}
Live demo: https://codesandbox.io/s/highcharts-react-custom-componentt-ysjfh8?file=/src/Chart.js
API Reference: https://api.highcharts.com/class-reference/Highcharts.Axis#toPixels
B. You can also get coordinates from a point:
useEffect(() => {
if (chartComponentRef) {
const chart = chartComponentRef.current.chart;
const point = chart.series[0].points[2];
setX1(chart.plotLeft + point.plotX);
}
}, [chartComponentRef]);
Live demo: https://codesandbox.io/s/highcharts-react-custom-componentt-f7nveg?file=/src/Chart.js
C. Use Highcharts API to render and update the custom icons:
const staticOptions = {
chart: {
type: "xrange",
height: 200,
events: {
render: function () {
const chart = this;
const r = 10;
const distance = 25;
chart.series[0].points.forEach((point, index) => {
if (!point.customIcon) {
point.customIcon = chart.renderer
.circle()
.attr({
fill: "transparent",
stroke: "red",
"stroke-width": 2
})
.add();
}
point.customIcon.attr({
x: point.plotX + chart.plotLeft + r,
y:
point.plotY +
chart.plotTop +
(index % 2 ? distance : -distance),
r
});
});
}
}
},
...
};
Live demo: https://codesandbox.io/s/highcharts-react-custom-componentt-f-87eof0?file=/src/Chart.js
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#circle
I want to highlight the selected Y-axis label in Gantt charts. Also is there any way through which we can give some background color to the y-axis title?
yAxis: {
className: "highcharts-color-0",
uniqueNames: true,
title: {
text: "Data"
},
labels: {
events: {
click: function () {
alert("hellowww");
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(10, plotTop, 500, 30, 1)
.attr({
"stroke-width": 2,
stroke: "red",
fill: "yellow",
opacity: 0.5,
zIndex: -1
})
.add();
}
}
}
}
enter image description here
link to code pen https://codepen.io/mehrotrarohit07/pen/PoKxvQp?editors=1010
Try to use this approach:
yAxis: {
labels: {
events: {
click: function() {
const chart = this.chart;
const axis = this.axis;
const labelPos = this.pos;
const tick = axis.ticks[labelPos]
const x = chart.marginRight;
const width = tick.slotWidth;
const height = axis.height / (axis.tickPositions.length);
const y = axis.top + labelPos * height;
chart.renderer
.rect(x, y, tick.slotWidth, height)
.attr({
fill: 'yellow',
zIndex: 0
})
.add();
}
}
}
},
I hope that everything is clear from the code - in case of any doubts feel free to ask.
Demo: https://jsfiddle.net/BlackLabel/qyj327Lx/
API: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#rect
Good day!
How do I add a button to link it to a graph?
I mean, when I add a button. When I stretch the graph, the button remains at its same coordinates when it should have moved as well.
I add it like this:
chart.renderer.button('Reset', 500, 200, function() {
console.log(chart);
}, null, null, null).attr({
zIndex: 4
}).add();
Below is a guideline of how to creates responsive buttons using the render feature.
Demo: https://jsfiddle.net/BlackLabel/tj50heo1/
chart: {
events: {
render() {
let chart = this,
x = chart.plotWidth / 2 + chart.plotLeft,
y = chart.plotHeight;
if (chart.customBtn) {
chart.customBtn.destroy();
}
chart.customBtn = chart.renderer.button('Reset', x, y, function() {}, null, null, null).attr({
zIndex: 4,
}).add();
//center button after render with width value
chart.customBtn.translate(chart.customBtn.x - chart.customBtn.width /2, chart.customBtn.y)
}
}
},
API: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#button
API: https://api.highcharts.com/highcharts/chart.events.render
I have an indicator which is a function of x, y.
How can i draw this indicator on top of chart?
Lets say here https://jsfiddle.net/yv3pehj8/
plotOptions: {
series: {
point: {
events: {
mouseOver: function () {
var chart = this.series.chart;
if (!chart.lbl) {
chart.lbl = chart.renderer.label('')
.attr({
padding: 10,
r: 10,
fill: Highcharts.getOptions().colors[1]
})
.css({
color: '#FFFFFF'
})
.add();
}
chart.lbl
.show()
.attr({
text: 'x: ' + this.x + ', y: ' + this.y
});
}
}
}
Instead of printing x,y value on the corner, I wanted to draw a line at an angle of 45 degrees to the hover point ranging from [x-10, x+10]. How could I do it in the most performant way?
TIA
EDIT
Many thanks for the solution. To make it a bit more complicated. i want to reach the following effect as seen in this image []
i want to draw the blue/red curves as you see in the image on mouse hover.. Would you happen to have a solution for this #ppotaczek??
Instead of rendering the label, you can render a path:
plotOptions: {
series: {
point: {
events: {
mouseOver: function() {
var chart = this.series.chart,
path = [
'M',
chart.plotLeft + this.plotX - 10,
chart.plotTop + this.plotY - 10,
'L',
chart.plotLeft + this.plotX + 10,
chart.plotTop + this.plotY + 10
];
if (!chart.lbl) {
chart.lbl = chart.renderer.path(path)
.attr({
'stroke-width': 2,
stroke: 'red'
})
.add();
}
chart.lbl
.show()
.attr({
d: path
});
}
}
},
...
}
}
Live demo: https://jsfiddle.net/BlackLabel/zo46fuxb/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#path
I try to create a pie chart with the halo effect. This works on hover but not on select. Is this possible?
Because we want to keep our selected item visible without slicing it out... So we want to show our selected slice with the halo effect but can't find if this is possible
Highcharts doesn't provide such a functionality out of the box. However, you can achieve it by adding your custom code in point click event callback. There you can render a halo effect using Highcharts renderer.path() method. Check the demo and code posted below and do not hesitate to ask me any question if something is unclear for you.
Code:
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie',
events: {
load: function() {
var chart = this;
chart.customHalo = {
graphic: null,
index: null
}
}
}
}
...
series: [{
...
point: {
events: {
click: function() {
var point = this,
chart = point.series.chart,
shapeArgs = point.shapeArgs,
size = 10,
opacity = 0.5,
path = chart.renderer
.symbols
.arc(
shapeArgs.x + chart.plotLeft,
shapeArgs.y + chart.plotTop,
shapeArgs.r + size,
shapeArgs.r + size, {
innerR: shapeArgs.r - 1,
start: shapeArgs.start,
end: shapeArgs.end
}
),
drawNewGraphic = false,
arc;
drawNewGraphic = (chart.customHalo.index !== point.index) ? true : false;
if (!drawNewGraphic && chart.customHalo.graphic) {
chart.customHalo.graphic.destroy();
chart.customHalo.index = null;
chart.customHalo.graphic = null;
} else if (chart.customHalo.graphic) {
chart.customHalo.graphic.destroy();
}
if (drawNewGraphic) {
arc = chart.renderer
.path(path)
.attr({
fill: point.color,
opacity: opacity
}).add();
chart.customHalo = {
index: point.index,
graphic: arc
}
chart.customHalo.index = point.index;
}
}
}
},
...
}]
Demo:
https://jsfiddle.net/BlackLabel/59hyq14v/
API reference:
https://api.highcharts.com/highcharts/chart.events.load
https://api.highcharts.com/highcharts/series.pie.point.events.click