Related
We are having some issues when working with highcharts in React. When I change to full screen mode using the menu button I am not able to see the option "Exit from full screen". Instead, the option stills "View in full screen".... However, if I click this option it actually exit full screen mode. I want to be able to see the text "exit full screen". I think the problem is in the event declared on the last lines of this code (exporting.chartOptions.chart).
useEffect(() => {
const chart = chartRef?.current?.chart;
if (!chart?.renderer) return;
setChartOptions(({ chart, credits, legend, xAxis, yAxis, plotOptions, ...currentOptions }) => ({
...currentOptions,
chart: {
...chart,
...chartExtraOptions.current?.chart,
},
credits: {
...credits,
position: {
...credits?.position,
...chartExtraOptions.current?.credits.position,
},
},
legend: {
...legend,
...chartExtraOptions.current?.legend,
},
xAxis: {
...xAxis,
...chartData?.xAxis,
title: { text: undefined },
plotLines: [
{
value: ((chartData?.xAxis?.max ?? 0) + (chartData?.xAxis?.min ?? 0)) / 2,
color: "#84acbc",
},
],
},
yAxis: {
...yAxis,
...chartData?.yAxis,
title: { text: undefined },
plotLines: [
{
value: ((chartData?.yAxis?.max ?? 0) + (chartData?.yAxis?.min ?? 0)) / 2,
color: "#84acbc",
},
],
},
series: chartData?.series,
exporting: {
chartOptions: {
chart: {
events: {
load: function (this) {
chartAxesTitles.current.forEach((element) => {
const { args, attr, css } = element.svg.userOptions;
// Use updated x and y positions
const newArgs = [args[0], element.svg.x, element.svg.y];
createLabel(this.renderer, { args: newArgs, attr, css });
renderWatermarkLabels(this, true);
});
// console.log(this);
},
},
},
},
},
but i have no idea why!!! Any ideas? Thanks!
I add the config for the charts in case it helps:
import { WATERMARK } from "constants/chartCommons";
export const OPTIONS: Highcharts.Options = {
chart: {
className: "IndividualPositioningChart",
type: "scatter",
spacing: [0, 0, 0, 0],
},
credits: {
text: WATERMARK,
href: "#",
position: {
align: "left",
},
style: {
fontSize: "8px",
},
},
title: {
text: undefined,
},
xAxis: {
startOnTick: false,
lineWidth: 0,
tickColor: "transparent",
gridLineColor: "transparent",
labels: {
enabled: false,
},
},
yAxis: {
gridLineColor: "transparent",
labels: {
enabled: false,
},
},
legend: {
verticalAlign: "bottom",
itemWidth: 150,
margin: 20,
},
tooltip: {
snap: 1,
enabled: true,
backgroundColor: "black",
borderWidth: 0,
borderRadius: 2,
padding: 4,
shadow: false,
useHTML: true,
style: {
color: "white",
fontSize: "11px",
},
headerFormat: undefined,
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
y: 13,
x: 8,
align: "left",
useHTML: true,
padding: 5,
style: {
fontWeight: "normal",
fontSize: "14px",
color: "#515151",
width: 250,
},
},
stickyTracking: false,
},
},
series: [],
};
Finnaly, I solved my problem removing the load event from the useEffect hook. The load event is declared now in the chart config file and passed as a parameter to the getOption function.
It looks like this:
export const getOption = (load: Highcharts.ChartLoadCallbackFunction): Highcharts.Options => {
return {
chart: {
className: "TeamCompetitiveChart",
spacing: [0, 0, 0, 0],
type: "scatter",
},
credits: {
text: WATERMARK,
href: "#",
position: {
align: "left",
},
style: {
fontSize: "8px",
},
},
title: {
text: undefined,
},
xAxis: {
title: undefined,
startOnTick: false,
lineWidth: 0,
tickColor: "transparent",
gridLineColor: "transparent",
labels: {
enabled: false,
},
},
yAxis: {
title: undefined,
gridLineColor: "transparent",
labels: {
enabled: false,
},
},
legend: {
verticalAlign: "bottom",
itemWidth: 150,
margin: 20,
},
tooltip: {
enabled: false,
},
plotOptions: {
series: {
marker: {
radius: 8,
},
dataLabels: {
enabled: true,
y: 13,
x: 8,
align: "left",
useHTML: true,
padding: 5,
style: {
fontWeight: "normal",
fontSize: "14px",
color: "#515151",
width: 250,
},
},
stickyTracking: false,
point: {
events: {
click: undefined,
},
},
},
},
series: [],
exporting: {
chartOptions: {
chart: {
events: {
load,
},
},
},
},
};
};
...and this in the hook:
const chartAxesTitles = useRef<IChartAxisTitle[]>([]);
const chartRef = useRef<IRefObjectForHighchartsReact>(null);
const load: Highcharts.ChartLoadCallbackFunction = function (this: Highcharts.Chart) {
chartAxesTitles.current.forEach((element: IChartAxisTitle) => {
const { args, attr, css } = element.svg.userOptions;
// Use updated x and y positions
const newArgs = [args[0], element.svg.x, element.svg.y];
createLabel(this.renderer, { args: newArgs, attr, css });
renderWatermarkLabels(this, true);
});
};
const [chartOptions, setChartOptions] = useState<Highcharts.Options>(getOption(load));
const { renderWatermarkLabels } = useRenderWatermarkLabels(chartData);
I want to show my categories on the top of each bar chart. like the image.
for this i set bar-chart option as below without any xAxis categories label.
options: {
title: null,
chart: {
type: 'bar'
},
colors: ['#9696b2', '#ff058d'],
xAxis: {
categories: ['Tokyo', 'Fukuoka', 'Hiroshima', 'Osaka', 'Nagoya'],
visible: false,
},
yAxis: {
visible: false,
},
tooltip: {
valueSuffix: ' '
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
}
},
legend: {
enabled: false
},
credits: {
enabled: false
},
series: [{
name: 'Compliant',
data: [1300, 1121, 1700, 1121, 700]
}, {
name: 'Non-Compliant',
data: [60, 30, 50, 20, 0]
}]
}
how can i make this one with stacked horizontal bars?
You can align labels to left and position them by x and y properties:
xAxis: {
...,
lineWidth: 0,
labels: {
align: 'left',
x: 0,
y: -24
}
}
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/4767/
API Reference: https://api.highcharts.com/gantt/xAxis.labels
is there any way to set specific size of PolarLine Chart (not the ChartArea, the chart)
In the image it can be seen the "space reserver to I don't know what"
So there is two options, determine the size of Chart, or equalize the size of chart to the ChartArea.
$("#chart2").kendoChart({
chartArea: {
background:"",
border: {
width: 2,
color: "green"
}
},
legend:{
visible: false
},
seriesDefaults: {
type: "polarLine",
style: "smooth"
},
series: [{
data: [
[0,75.07200602],[10,81.64361286],
[20,91.39178047],[30,98.75515111],
[40,99.92040115],[50,92.10607453],
[60,74.91674346],[70,50.02020242],
[80,11.87856731],[90,0.998505703]
]
}],
xAxis:
{
startAngle: 90,
majorUnit: 10,
reverse :true,
majorGridLines: {
max: 360,
min: 0,
visible: true
},
labels:
{
visible: false,
margin:3,
template:"#: value # º"
}
},
yAxis:
{
max: 100,
min :0,
majorUnit: 10,
labels:
{
visible: false
}
},
tooltip: {
visible: true,
format: "{0}",
template: "#: value #"
},
transitions:false
});
White space problem
The solution was creating a function that rezise chart once is calculated depending the cointainer size, in my case was:
function reziseChart(ParentDiv)
{
var clientHeight = document.getElementById(ParentDiv).clientHeight;
var c = $("#chart2").data("kendoChart");
c.options.chartArea.margin = - clientHeight * 0.425;
c.refresh();
}
Referring to the question i want to move my y-axis scrollbar with mouse wheel
Is there any way to do it ?
yAxis:
{
scrollbar: {
enabled: true,
showFull: false
},
}
Updated Code
Bellow is my updated code
var chart1 = new Highcharts.Chart({
chart: {
renderTo: 'container1',
type: 'column',
zoomType: 'xy',
panning: true,
panKey: 'shift',
//type: 'column',
//zoomType: 'xy',
//panning: true,
//pankey: 'shift',
resetZoomButton: {
position: {
//align: 'right', // by default
//verticalAlign: 'top', // by default
x: -10,
y: 350,
//height: 25
},
relativeTo: 'chart'
}
},
scrollbar:{
enabled: true
},
navigator: {
//xAxis: {
// tickWidth: 0,
// lineWidth: 0,
// gridLineWidth: 1,
// tickPixelInterval: 200,
// labels: {
// align: 'left',
// style: {
// color: '#888'
// },
// x: 3,
// y: -4
// }
//},
//yAxis: {
// gridLineWidth: 0,
// startOnTick: false,
// endOnTick: false,
// minPadding: 0.1,
// maxPadding: 0.1,
// labels: {
// enabled: false
// },
// title: {
// text: null
// },
// tickWidth: 0
//},
//series: {
// //data: arry_kwh_2,
// type: 'column',
// color: '#4572A7',
// fillOpacity: 0.05,
// dataGrouping: {
// smoothed: true
// },
// lineWidth: 1,
// marker: {
// enabled: true
// }
//},
enabled: true,
height: 30,
},
rangeSelector: {
buttonTheme: { // styles for the buttons
fill: 'none',
stroke: 'none',
'stroke-width': 0,
r: 8,
style: {
color: '#039',
fontWeight: 'bold'
},
states: {
hover: {
},
select: {
fill: '#039',
style: {
color: 'white'
}
}
}
},
enabled: true,
inputBoxWidth: 160,
inputStyle: {
color: '#039',
fontWeight: 'bold'
},
labelStyle: {
color: 'black',
fontWeight: 'bold'
},
buttons: [{
type: 'minute',
count: 60 * 6,
text: '6h'
}, {
type: 'day',
count: 1,
text: '1d'
}, {
type: 'day',
count: 7,
text: '7d'
},
{
type: 'day',
count: 14,
text: '2w'
},
{
type: 'day',
count: 21,
text: '3w'
},
{
type: 'month',
count: 1,
text: '1m'
},
{
type: 'all',
text: 'All'
}]
},
plotOptions: {
column: {
turboThreshold: 50000
}
},
title: {
text: 'Energy vs Date & Time',
style: {
fontWeight: 'bold',
}
},
xAxis: {
type: 'datetime',
//min: 0,
//max: 100000
},
yAxis:
{
scrollbar: {
enabled: true,
showFull: false
},
alternateGridColor: '#FDFFD5',
title: {
text: 'Energy (kWh)',
style: {
//color: '#FF00FF',
fontSize: '12px',
//sfont: 'bold 200px Verdana, sans-serif',
}
}
},
series:
[
{
name: 'Energy kWh',
color: 'green',
data: arry_kwh,
}
],
});
The data in the series is in array format
Any help would be highly appreciated
There is no such feature in Highcharts nor in Highstock. You could add a mouse wheel event and bind it with a setExtremes function for yAxis.
http://jsfiddle.net/3q79ey8h/1/
(function(H) {
//internal functions
function stopEvent(e) {
if (e) {
if (e.preventDefault) {
e.preventDefault();
}
if (e.stopPropagation) {
e.stopPropagation();
}
e.cancelBubble = true;
}
}
//the wrap
H.wrap(H.Chart.prototype, 'render', function(proceed) {
var chart = this,
mapNavigation = chart.options.mapNavigation;
proceed.call(chart);
// Add the mousewheel event
H.addEvent(chart.container, document.onmousewheel === undefined ? 'DOMMouseScroll' : 'mousewheel', function(event) {
var delta, extr, step, newMin, newMax, axis = chart.yAxis[0];
e = chart.pointer.normalize(event);
// Firefox uses e.detail, WebKit and IE uses wheelDelta
delta = e.detail || -(e.wheelDelta / 120);
delta = delta < 0 ? 1 : -1;
if (chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {
extr = axis.getExtremes();
step = (extr.max - extr.min) / 5 * delta;
axis.setExtremes(extr.min + step, extr.max + step, true, false);
}
stopEvent(event); // Issue #5011, returning false from non-jQuery event does not prevent default
return false;
});
});
}(Highcharts));
Below is a bar graph where the green bars never go over 100 and the red bars never go below -100.
However in the graph's yAxis you can see -150%.
I found this fix here, however it did not work. yAxis: {min: 0, max: 100}
Is there another way to accomplish this?
Here is the area where I add those bar graphs
function addSentimentSeries(name, data) {
var index = findTheIndex(name);
var color = name === 'Positive sentiment' ? '#009900' : '#FF0000';
if (index) {
chart.series[index].update({
showInLegend: false,
yAxis: 2,
type: 'column',
name: name,
color: color,
data: data,
dataGrouping: { enabled: false }
}, true);
} else {
chart.addSeries({
showInLegend: false,
yAxis: 2,
type: 'column',
name: name,
color: color,
data: data,
dataGrouping: { enabled: false }
}, true);
}
chart.hideLoading();
chart.redraw();
}
This is the 'fix' I implemented from the answer I found above, it did not do anything, my bar graphs still display -150%
vm.config.yAxis.push({
height: '30%',
top: '70%',
gridLineWidth: 0,
title: {
text: 'Sentiment',
style: { color: '#BFBFBF' }
},
yAxis: { min: 0, max: 100 },
offset: 0,
labels: {
formatter: function() {
return this.value + '%';
},
style: { color: '#BFBFBF' }
},
opposite: false
});
You should set the minPadding and maxPadding parameters as 0, then you reduce the spacing on a axis.
yAxis: {
minPadding: 0,
maxPadding: 0
}