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
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 am trying to find a way to control width of the x-axis labels container in bar charts in styled mode. I want to have preset values and depending on the preset have labels to take 20, 30, 40, 50% of the graphic. Is there a property for that?
Thank you!
If you want to set labels' width depending on their length and relative to chart width, you can use chart.event.render to achieve that. It will allow you to find the number of characters and set dynamically the percentage width.
var allowChartUpdate = true;
Highcharts.chart('container', {
chart: {
type: 'bar',
styledMode: true,
events: {
render: function() {
if (allowChartUpdate) {
this.xAxis[0].categories.forEach(category => {
if (category.length > 10) {
var dynamicMargin = this.chartWidth * 50 / 100;
allowChartUpdate = false;
this.update({
chart: {
marginLeft: dynamicMargin
}
}, true, true, false);
allowChartUpdate = true;
}
})
}
}
}
},
...
Demo:
https://jsfiddle.net/BlackLabel/59xjq4du/
API Reference:
https://api.highcharts.com/highcharts/chart.events.render
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
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
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