I'm trying to change the size of two yAxis for a Stockchart when a legend is clicked. I've tried this but neither of them work:
plotOptions: {
series: {
events: {
legendItemClick: function(event) {
// does not change the height on the y axis
chart.yAxis[0].height = 5;
chart.redraw();
// changes the size but throws:
// Uncaught TypeError: Cannot read property 'options' of undefined
var chartOptions = chart.options;
chartOptions.yAxis[0].height = 5;
chart = new Highcharts.Chart(chartOptions);
}
},
}
},
Fiddle here
You can use axis.update() like in the example:
$('#up').click(function(){
chart.yAxis[0].update({
height:100
});
});
http://jsfiddle.net/EhRA8/
Related
I use highchart (spider)
I want to give different color for each grid line of y axis.
Is there any elegant way to do that (I mean - without jQuery and complex css selectors)
Please see attached picture.
You can wrap renderGridLine method from the Tick prototype:
(function(H) {
var colors = ['#0050d1', '#de0735', '#00e031', '#ffb300', '#c800ff'],
i = 0;
H.wrap(H.Tick.prototype, 'renderGridLine', function(proceed) {
if (!this.axis.isXAxis) {
this.axis.options.gridLineColor = colors[i];
if (this.isLast) {
i = 0;
} else {
i++;
}
}
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
});
}(Highcharts));
Live demo: https://jsfiddle.net/BlackLabel/45fh27tc/
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts
Or set the color afrer chart initialization in a load event:
var colors = ['#0050d1', '#de0735', '#00e031', '#ffb300', '#c800ff'];
Highcharts.chart('container', {
chart: {
...
events: {
load: function() {
var yAxis = this.yAxis[0];
yAxis.tickPositions.forEach(function(tPos, i) {
yAxis.ticks[tPos].gridLine.attr({
stroke: colors[i]
});
});
}
}
},
...
});
Live demo: https://jsfiddle.net/BlackLabel/xbLtur48/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
https://api.highcharts.com/highcharts/chart.events.load
I have developed one webpage to show multiple charts. It is based on drop down menu selection. For example, if I select line then Line chart should appear in the container, if I select dual axis chart, it should appear in the same container. But while creating synchronized chart. I am facing one problem. It seems that the charts are being created, but they are not getting appended to container. Please help me out.
My code is as follows:
SynchronizedChart.js:
/**
* Synchronize zooming through the setExtremes event handler.
*/
function syncExtremes(e) {
var thisChart = this.chart;
if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
Highcharts.each(Highcharts.charts, function (chart) {
if (chart !== thisChart) {
if (chart.xAxis[0].setExtremes) { // It is null while updating
chart.xAxis[0].setExtremes(e.min, e.max, undefined, false, { trigger: 'syncExtremes' });
}
}
});
}
}
function drawSyncChart(Takennumber) {
/**
* In order to synchronize tooltips and crosshairs, override the
* built-in events with handlers defined on the parent element.
*/
/*$('#displayPanel').bind('mousemove touchmove touchstart', function (e) {
var chart,
point,
i,
event;
for (i = 0; i < Highcharts.charts.length; i = i + 1) {
chart = Highcharts.charts[i];
event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
point.highlight(e);
}
}
});*/
/**
* Override the reset function, we don't need to hide the tooltips and crosshairs.
*/
Highcharts.Pointer.prototype.reset = function () {
return undefined;
};
/**
* Highlight a point by showing tooltip, setting hover state and draw crosshair
*/
Highcharts.Point.prototype.highlight = function (event) {
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
var output = { "xData": [], "datasets": [] };
//**********************************************
// DATA MANIPULATION AS PER HIGHCHART CONVENTION
//**********************************************
//console.log(JSON.stringify(output));
$.each(output.datasets, function (i, dataset) {
// Add X values
dataset.data = Highcharts.map(dataset.data, function (val, j) {
return [output.xData[j], val];
});
$('<div class="tmp">')
.appendTo('#displayPanel')
.highcharts({
chart: {
marginLeft: 40, // Keep all charts left aligned
spacingTop: 20,
spacingBottom: 20
},
title: {
text: dataset.name,
align: 'left',
margin: 0,
x: 30
},
credits: {
enabled: false
},
legend: {
enabled: false
},
xAxis: {
type: 'datetime',
labels: {
formatter: function () {
return Highcharts.dateFormat('%a %d %b %H:%M:%S', this.value);
}
},
crosshair: true,
},
series: [{
data: dataset.data,
name: dataset.name,
type: dataset.type,
color: Highcharts.getOptions().colors[i],
}]
});
// Append the chart
//div.appendTo("#displayPanel");
});
I am loading JS in following order:
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="../highcharts/highcharts.js"></script>
<script src="../highcharts/modules/exporting.js"></script>
<script src="../highcharts/themes/dark-unica.js"></script>
<script src="../PageJS/Admin/SynchronizedChart.js"></script>
And I am getting the error as follows:
SynchronizedChart.js:94 Uncaught TypeError: $(...).appendTo(...).highcharts is not a function
at Object.<anonymous> (SynchronizedChart.js:94)
at Function.each (datatables.min.js:14)
at drawSyncChart (SynchronizedChart.js:81)
at drawColumnChart (Chart.js:9)
at HTMLSelectElement.<anonymous> (ChemicalAnalysisChart.js:45)
at HTMLSelectElement.dispatch (datatables.min.js:16)
at HTMLSelectElement.r.handle (datatables.min.js:16)
(anonymous) # SynchronizedChart.js:94
each # datatables.min.js:14
drawSyncChart # SynchronizedChart.js:81
drawColumnChart # Chart.js:9
(anonymous) # ChemicalAnalysisChart.js:45
dispatch # datatables.min.js:16
r.handle # datatables.min.js:16
I solved the problem by separating creation of HighCharts and appending to the existing container. Please refer below code for reference:
$('<div id="chart' + i + '" class="col-md-20">').appendTo('#displayPanel');
var chart = new Highcharts.Chart({....... });
Also cleared the container before appending the Charts.
$(".highcharts-container").remove();
How can I hide a stackLabel (a label above the column) in highCharts when the text in the label is bigger than the column (As you can see in the image below).
I want to show empty string when my data exceeds the column width.
This is part of the code which is responsible for showing the data:
yAxis: {
stackLabels: {
style: {
color: 'black'
},
enabled: true
formatter: function () {
return this.total + " mm ";
}
}
}
Create a function which loop through the stack labels and compare their width with the point's width - according to the comparison hide or show the label.
Function can look like this:
function hideLabel() {
const axis = this.yAxis[0];
const stacks = axis.stacks.column;
const pointWidth = this.series[0].points[0].shapeArgs.width;
Object.keys(stacks).forEach(key => {
const label = stacks[key].label;
label.attr({
visibility: label.getBBox().width > pointWidth ? 'hidden' : 'visible'
});
})
}
Set this function on load and redraw events:
chart: {
type: 'column',
events: {
load: hideLabel,
redraw: hideLabel
}
},
example: http://jsfiddle.net/nq5ke47z/
In highcharts initialization I've set array of only one color. I would like to change this with another array on charts's hover event. In other words chart is default monochromatic and after hover it becomes colorful.
config = {
colors: ["#C0C0C0"]
};
chart = $('#chart').highcharts(config).highcharts()
$('#chart').hover(function(){
chart.options.colors = ["#E84C3D", "#C1392B", '#D25400', "#E67F22", "#F39C11"]
}, function(){
chart.options.colors = ["#C0C0C0"]
});
Unfortunately it doesn't work. How should I do it?
You can set the plotOptions events:
plotOptions: {
column:{colorByPoint:true},
series: {
animation:false,
events: {
mouseOver: function(e) {
//console.log( chart.options);
var options = chart.options;
if(options.colors[0]!='#E84C3D')
{
options.colors=['#E84C3D','#C1392B','#D25400','#E67F22','#F39C11'];
chart = new Highcharts.Chart(options);
}
},
mouseOut: function(e) {
var options = chart.options;
if(options.colors[0]!='#C0C0C0')
{
options.colors=['#C0C0C0'];
chart = new Highcharts.Chart(options);
}
}
}
}
}
demo http://jsfiddle.net/eNMvw/134/
Instad of creating chart multiple time, better is using series.update() and apply colors per bars.
I want to change the zoom-type from "x" to "xy" without creating new instance,
I want do do it like update() method they have..
located in myChart.options.chart.zoomType
You can do something like this:
var chart1 = new Highcharts.StockChart({
chart: {
zoomType: 'xy', //requried!
...
}
...
});
function SwitchToZoomX() {
chart1.pointer.zoomX = true;
chart1.pointer.zoomY = false;
chart1.pointer.zoomHor = true;
chart1.pointer.zoomVert = false;
}
function SwitchToZoomY() {
chart1.pointer.zoomY = true;
chart1.pointer.zoomX = false;
chart1.pointer.zoomVert = true;
chart1.pointer.zoomHor = false;
}
With Highcharts v5 you can now do this:
chart1.update({chart: {zoomType: "y"}})
The update function dynamically updates the chartoptions to imperitively change zoomType post render.
First Prepare a string for the chart to display
Clone Series To Redraw as highcharts set it null after draw.
var seriesClone=[{
name: 'USD to EUR',
data: [1,2,3,4,4,5,6,7,7,8,8,8,9,10,14]
}]
Series Options To SET
var chartOptions={
chart: {
renderTo:'container',
zoomType: 'xy'
},
rangeSelector: {
selected: 1
},
series: [{
name: 'USD to EUR',
data: [1,2,3,4,4,5,6,7,7,8,8,8,9,10,14]
}]
}
var chart = new Highcharts.StockChart(chartOptions);
And When you want to change the value of ZoomType redeclare the chart like this
chartOptions.chart.zoomType='y';
chartOptions.series=seriesClone;
myChart=new Highcharts.StockChart(chartOptions);
Working example JSFIDDLE