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
Related
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
Need to add separate tooltip for point marker.
I am using crosshair for displaying tooltip in Highcharts. Also, for some of the series data points I am adding a marker(in yellow circle). I want to know if it is possible to have a custom tooltip on hovering specifically on the marker point, but I would also like to retain the normal crosshair tooltip behavior on the same point (i.e. while hovering outside the yellow marker area for the same data point, tooltip should respect the tooltip formatter and on hovering exactly on the marker tooltip should show a different text related to the marker). Is it possible to achieve?
[My intention is to create a hoverable annotation marker, but at the same time retain the default tooltip behavior for the same point]
Please see the images below to get an idea about the expected behavior. Please ignore the series data, since they are generated dynamically, and is different on every page refresh. What I want to achieve is to have a crosshair tooltip for the '05-Jan-2019' data point, and also show a different looking or custom tooltip when user hovers specifically on the 'yellow' marker for the same data point.
Any suggestions related to alternative ways to achieve this are also welcome.
Here is how I am adding the marker in my series data :
function formatSeriesData(allSeries, annotations, categories) {
for (let i = 0; i <= allSeries.length; i++) {
let serie = allSeries[i];
if (serie && !serie['color']) {
serie = {
...serie,
color: defaultColors[i]
}
allSeries[i] = serie;
}
//add annotations - if present
if (serie && annotations && annotations.length) {
const applicableAnnotations = _.filter(annotations, {
name: serie.name
});
const annotationDates = _.map(applicableAnnotations, 'date'); //get all annotation dates
let modifiedDataArray = [];
let dataArray = serie.data; //get all series data
for (let j = 0; j < dataArray.length; j++) {
let dateForValue = categories[j]; //get the date corresponding to the value
let annotation = _.find(applicableAnnotations, {
date: dateForValue
});; //pick the annotation object
let ptObj = {
dimension: "",
y: dataArray[j]
};
if (annotation && annotation.annotation) {
ptObj["marker"] = {
enabled: true,
radius: 6,
fillColor: '#FDBE2C',
symbol: 'circle'
};
}
modifiedDataArray.push(ptObj);
}
serie = {
...serie,
data: modifiedDataArray
}
allSeries[i] = serie;
}
}
console.log("allSeries ", allSeries);
return allSeries;
}
To achieve the wanted result you can create a chart with two series - line with disabled enableMouseTracking and scatter with default tooltip and mouse events to control the display of crosshair:
Highcharts.chart('container', {
series: [{
data: [1, 2, 3, 4],
enableMouseTracking: false
}, {
color: 'yellow',
events: {
mouseOver: function() {
this.xAxis.update({
crosshair: {
width: 0,
label: {
enabled: false
}
}
});
},
mouseOut: function() {
this.xAxis.update({
crosshair: {
width: 1,
label: {
enabled: true
}
}
});
}
},
marker: {
radius: 8,
symbol: 'circle'
},
stickyTracking: false,
data: [{
x: 2,
y: 3
}]
}],
xAxis: {
crosshair: {
label: {
enabled: true
},
snap: false
}
}
});
Live demo: http://jsfiddle.net/BlackLabel/k83u0spd/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.Axis#update
https://api.highcharts.com/highcharts/series.line.enableMouseTracking
https://api.highcharts.com/highcharts/series.line.stickyTracking
I am using Highcharts it is working fine but i want to change in pie slice when i click on single pie slice then that slice overlap two slice(right or left slice).
Below is the image attached tha i have done in pie chart.
Below is the image attached of the expexted pie chart result
You can add your own method, which will resize shape on click, for example: http://jsfiddle.net/BlackLabel/8vd6cod1/
function resizeSlice(point, change) {
// Original shape params are stored in shapeArgs:
var shape = point.shapeArgs;
if (point.graphic) {
point.graphic.attr({
// "r" is outer radius:
r: shape.r + change,
// "innerR" is inner radius:
innerR: shape.innerR - change
});
}
}
// Build the chart
Highcharts.chart('container', {
chart: {
type: 'pie',
events: {
// On window resize, apply change:
redraw: function() {
Highcharts.each(this.series[0].points, function(point) {
resizeSlice(point, point.customResized ? 5 : 0)
});
}
}
},
plotOptions: {
pie: {
innerSize: '90%',
cursor: 'pointer',
dataLabels: {
enabled: false
},
point: {
events: {
click: function() {
var change = 0;
// Custom param, can be called whatever we want:
this.customResized = !this.customResized;
if (this.customResized) {
// Let's resize!
change = 5;
}
resizeSlice(this, change);
}
}
}
}
},
series: [{
data: [3, 4, 5, 6]
}]
});
I have make some change to this code for re size all other pie.
: http://jsfiddle.net/8vd6cod1/2/
function resizeSlice(point, change) {
// Original shape params are stored in shapeArgs:
var shape = point.shapeArgs;
if (point.graphic) {
point.graphic.attr({
// "r" is outer radius:
r: shape.r + change,
// "innerR" is inner radius:
innerR: shape.innerR - change
});
}
}
// Build the chart
Highcharts.chart('container', {
chart: {
type: 'pie',
events: {
// On window resize, apply change:
redraw: function() {
Highcharts.each(this.series[0].points, function(point) {
resizeSlice(point, point.customResized ? 5 : 0)
});
}
}
},
plotOptions: {
pie: {
innerSize: '90%',
cursor: 'pointer',
dataLabels: {
enabled: false
},
point: {
events: {
click: function() {
Highcharts.each(this.series.points, function(point) {
resizeSlice(point, 0)
});
var change = 0;
// Custom param, can be called whatever we want:
this.customResized = !this.customResized;
if (this.customResized) {
// Let's resize!
change = 5;
}
resizeSlice(this, change);
}
}
}
}
},
series: [{
data: [3, 4, 5, 6]
}]
});
I have a pie chart here. On click event it drills down and on mouseover it does the slice animation. The slice animation is copied from an answer here from Pawel Fus
The events I have on pie chart point are as below,
mouseOut: function () {
setTranslation(this, false);
},
mouseOver: function() {
setTranslation(this, true);
},
click: function() {
var drilldown = this.drilldown;
if (drilldown) { // drill down
setChart(drilldown.name, drilldown.categories, drilldown.data, drilldown.color);
} else { // restore
setChart(name, categories, data);
}
}
and the functions used in them are
function setChart(name, categories, data, color) {
chart.xAxis[0].setCategories(categories);
chart.series[0].remove();
chart.addSeries({
name: name,
data: data,
pointPadding: -0.3,
borderWidth: 0,
pointWidth: 15,
shadow: false,
color: color || 'white'
});
}
function setTranslation(p, slice){
p.sliced = slice;
if(p.sliced){
p.graphic.animate(p.slicedTranslation);
} else {
p.graphic.animate({
translateX: 0,
translateY: 0
});
}
}
The problem I have is it throws following exception:
Uncaught TypeError: Property 'select' of object #<Object> is not a function highcharts.src.js:12364
It breaks the chart when clicking on it for drilldown.
I am not sure what I am doing wrong but I guess the mouseover event is getting messed up on drilldown.
It would be great if I can get both these features working together.
The problem is with actual running animation. I advice to not use setting translation to a pie chart until all animations for a slice are don, see: http://jsfiddle.net/5H675/5/
function setTranslation(p, slice) {
p.sliced = slice;
if (!$(p.graphic).is(':animated')) {
if (p.sliced) {
p.graphic.animate(p.slicedTranslation);
} else {
p.graphic.animate({
translateX: 0,
translateY: 0
});
}
}
}