I'm trying to plot column and the line chart in one combined chart. I have to read values from a table and pass it to the series. I have read them into an array and passing it to the data attribute(arrays val3 and val4) but it is not working. When I generate an array with data not from the table(array val2 and first_array_work), it works.
Following is the JSFiddle https://jsfiddle.net/AnilKumarVallur/13x2uj7a/1/ and also the complete code is attached here.
`<html>
<head>
<title>Highcharts Tutorial</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
</head>
<body>
<div id="container" style="width: 550px; height: 400px; margin: 0 auto"></div>
<script language="JavaScript">
$(document).ready(function() {
var cat_array = [];
var first_array_work = [49.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4];
var val2 = [];
for(var i=0;i<5;i++){
val2[i] = 10*i;
}
var first_array = [];
var header_cat = 1;
$("#datatable tr").eq(0).find('td').each(function(){
if(header_cat){
header_cat = 0;
}
else{
cat_array.push($(this).text());
}
})
var header_first = 1;
var i=0;
var val3 = [];
$("#datatable tr").eq(1).find('td').each(function(){
if(header_first){
header_first = 0;
}
else{
//first_array.push($(this).text());
val3[i] = ($(this).text());
//alert(val3[i]);
i++;
}
})
var cat = cat_array;
var val4 = [];
for(var m=0;m<val3.length;m++){
val4[m] = val3[m];
}
var chart = {
zoomType: 'xy'
};
var subtitle = {
text: 'Source: WorldClimate.com'
};
var title = {
text: 'Average Monthly Temperature and Rainfall in Tokyo'
};
var xAxis = {
categories: cat,
crosshair: true
};
var yAxis= [{ // Primary yAxis
labels: {
format: '{value}\xB0C',
style: {
color: Highcharts.getOptions().colors[1]
}
},
title: {
text: 'Temperature',
style: {
color: Highcharts.getOptions().colors[1]
}
}
}, { // Secondary yAxis
title: {
text: 'Rainfall',
style: {
color: Highcharts.getOptions().colors[0]
}
},
labels: {
format: '{value} mm',
style: {
color: Highcharts.getOptions().colors[0]
}
},
opposite: true
}];
var tooltip = {
shared: true
};
var legend = {
layout: 'vertical',
align: 'left',
x: 120,
verticalAlign: 'top',
y: 100,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
};
var series= [{
name: 'Rainfall',
type: 'column',
yAxis: 1,
data: val2,
tooltip: {
valueSuffix: ' mm'
}
}, {
name: 'Temperature',
type: 'spline',
data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6],
tooltip: {
valueSuffix: '\xB0C'
}
}
];
var json = {};
json.chart = chart;
json.title = title;
json.subtitle = subtitle;
json.xAxis = xAxis;
json.yAxis = yAxis;
json.tooltip = tooltip;
json.legend = legend;
json.series = series;
$('#container').highcharts(json);
});
</script>
<table id='datatable'>
<tr><td>Amb Temp</td><td>-40</td><td>-30</td><td>-20</td><td>-10</td><td>0</td><td>10</td><td>-40</td><td>-30</td><td>-20</td><td>-10</td><td>0</td><td>10</td></tr>
<tr><td>Active</td><td>10.0</td><td>20</td><td>10</td><td>20</td><td>10</td><td>20</td><td>10</td></tr>
<tr><td>Sleep</td><td>20</td><td>30</td><td>10</td><td>20</td><td>10</td><td>20</td><td>10</td><td>20</td><td>10</td><td>20</td><td>10</td><td>20</td></tr>
</table>
</body>
</html>`
As far as I can see, the exact problem is in data type. Highcharts library is waiting for an array of floats as an input data, and you're trying to give it an array of strings. I've edited your code a little bit: https://jsfiddle.net/13x2uj7a/2/. Here I've just used parseFloat inside of this block:
$("#datatable tr").eq(1).find('td').each(function(){
if(header_first){
header_first = 0;
}
else{
//first_array.push($(this).text());
val3[i] = parseFloat($(this).text());
//alert(val3[i]);
i++;
}
})
and could get some data from table on the graph.
Related
I'm working with Highchart. I've got a multiple series graph in which several series can be associated to the same y-axis. The association is based on the measurement unit, which is also the y-axis id. Series are added dynamically.
Each y-axis has setExtremes() different than null and for this reason I have encountered one problems that it seems I can't resolve.
When hiding a series. I want the associative y-axis to be visible until all the series associated to that specific axis are hidden also. At the moment I was able just to hide the y-axis once one of the series is set to series.hide()
The used code is presented below. And can be accessed in jsfiddle through this like: http://jsfiddle.net/39xBU/134/ .
$(function () {
//creates chart options
var options = {
chart: {
renderTo: 'container',
zoomType: 'xy'
},
title: {
text: 'Axis manipulation'
},
xAxis: [{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
}],
yAxis: [{ // Primary yAxis
id:'°C',
labels: {
formatter: function() {
return this.value +'°C';
},
style: {
color: '#89A54E'
}
},
title:{
text:''
},
opposite: true,
showEmpty: false
}, { // Secondary yAxis
id:'mm',
gridLineWidth: 0,
labels: {
formatter: function() {
return this.value +' mm';
},
style: {
color: '#4572A7'
}
},
title:{
text:''
},
showEmpty: false
}],
tooltip: {
formatter: function() {
var unit = {
'Rainfall': 'mm',
'Temperature': '°C',
'Sea-Level Pressure': 'mb'
}[this.series.name];
return ''+
this.x +': '+ this.y +' '+ unit;
}
},
legend: {
layout: 'vertical',
align: 'left',
x: 120,
verticalAlign: 'top',
y: 80,
floating: true,
backgroundColor: '#FFFFFF'
},
series: []
};
// Adds series to the chart. i do this because in the real application I add data dinamically
options.series.push({
name: 'Rainfall',
color: '#4572A7',
type: 'spline',
yAxis: getAssociativeYAxisIndex('mm', options.yAxis),
data: [149.9, 171.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 195.6, 154.4]
});
options.series.push({
name: 'Sea-Level Pressure',
type: 'spline',
color: '#4572A7',
yAxis: getAssociativeYAxisIndex('mm', options.yAxis),
data: [116, 116, 115.9, 115.5, 112.3, 109.5, 109.6, 110.2, 113.1, 116.9, 118.2, 116.7],
marker: {
enabled: false
},
dashStyle: 'shortdot'
});
options.series.push({
name: 'Temperature',
color: '#89A54E',
type: 'column', // date is not shown only if it is 'spline'
yAxis:getAssociativeYAxisIndex('°C', options.yAxis),
data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
});
var chart = new Highcharts.Chart(options);
//after rendering I set axis limits, based on their measurement unit.
var yAxis1 = chart.get('mm');
yAxis1.setExtremes(0, 200);
var yAxis2 = chart.get('°C');
yAxis2.setExtremes(0, 40);
// hide Rainfall button
$("#b1").click(function(){
chart.series[0].hide()
chart.yAxis[1].update({
labels: {
enabled: false
},
title: {
text: null
}
});
});
// hide sealevel button
$("#b").click(function(){
chart.series[1].hide()
chart.yAxis[1].update({
labels: {
enabled: false
},
title: {
text: null
}
});
});
// delete rainfall button
$("#b2").click(function(){
chart.series[0].remove();
chart.yAxis[1].setExtremes(null, null);
});
// delete sea-level button
$("#b3").click(function(){
chart.series[1].remove();
chart.yAxis[1].setExtremes(null, null);
});
//get's series associatie axis
function getAssociativeYAxisIndex(seriesMeasureUnit, yAxis) {
var axisIndex = -1;
$.each(yAxis, function (index, axes) {
if (seriesMeasureUnit == axes.id) {
axisIndex = index;
return false;
}
});
return axisIndex;
};
});
Any suggestions to this matter would be very useful.
You can simply check if all of series are hidden, this way: http://jsfiddle.net/39xBU/135/
And code:
new function to make it easy to read:
function hideShowAxis(series) {
var axis = series.yAxis,
show = false;
$.each(axis.series, function (i, e) {
if (e.visible) {
show = true;
}
});
axis.update({
labels: {
enabled: show
}
});
}
and execute:
// hide Rainfall button
$("#b1").click(function () {
chart.series[0].hide()
hideShowAxis(chart.series[0]);
});
// hide sealevel button
$("#b").click(function () {
chart.series[1].hide()
hideShowAxis(chart.series[1]);
});
I saw a similar question here.
In reply its written that we can have background color by making a rectangle.
My question is how I can get x and Y position of all the ticks on axis. I will need it because I want background color only on alternate dates.
Thanks
Here's a quick example that shades between the 2nd and 4th ticks:
var tickStart = 1;
var tickEnd = 3;
$(function () {
var rect = null;
function drawRect(chart){
if (rect){
rect.element.remove();
}
var xAxis = chart.xAxis[0];
var pixStart = xAxis.toPixels (xAxis.tickPositions[tickStart], false);
var pixEnd = xAxis.toPixels (xAxis.tickPositions[tickEnd], false);
rect = chart.renderer.rect(pixStart, chart.chartHeight - xAxis.bottom, pixEnd - pixStart , 25, 00)
.attr({
'stroke-width': 0,
stroke: '#888888',
fill: '#888888',
zIndex: 3
})
.add();
}
$('#container').highcharts({
chart: {
events: {
load: function() {
drawRect(this);
},
redraw: function(){
drawRect(this);
}
}
},
xAxis: {
},
series: [{
animation: false,
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
});
Fiddle here.
Did you try to use labels.formatter with background and useHTML flag? Something like this: http://jsfiddle.net/AeV7h/
xAxis: {
categories: ['Foo', 'Bar', 'Foobar'],
labels: {
useHTML: true,
formatter: function() {
return '<span class="hc-label">' + this.value + '</span>';
}
}
},
And CSS:
.hc-label {
background-color: red;
padding: 0px 5px;
color: yellow;
}
Currently I have script just like that.
Here categories1 array having numbering (1,2,...) and data1 array contains values for x axis(3,8,2,1) and data2 array contains values for showing in tooltip.
I want to show categories1 array in x-axis and tooltip showing data2 array in tooltip.
$(function () {
var jsonData = JSON.parse('[{"category":"Abc","value":3},{"category":"abc1","value":8},{"category":"abc2","value":2},{"category":"abc3","value":1}]');
var categories1 = [];
for (var i = 1; i <= jsonData.length; i++) {
categories1.push(i.toString());
}
var data1 = [];
var data2 = [];
for (var i = 0; i < jsonData.length; i++) {
data1.push(jsonData[i].value);
data2.push(jsonData[i].category);
}
colorArray = ['#4a4a4a']
Highcharts.setOptions({
colors: colorArray
});
$('#containerBrandChart').highcharts({
chart: {
type: 'column'
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
categories: categories1,
labels: {
rotation: 30,
align: 'top'
},
},
yAxis: {
min: 0,
title: {
text: ''
}
},
tooltip: {
headerFormat: '<span style="font-size:10px">{point.key}</span>: <b>{point.y}</b>',
pointFormat: '',
footerFormat: '',
borderWidth: '0',
borderRadius: '8px',
backgroundColor: '#000000',
shared: true,
useHTML: true,
style: {
height: 'auto',
opacity: '.8',
filter: 'alpha(opacity = 80)',
padding: '10px',
fontFamily: '"tele-grotesk",Arial,Helvetica,sans-serif',
fontWeight: 'bold',
color: '#ffffff',
fontSize: '1.125em'
}
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
},
series: {
states: {
hover: {
enabled: false
}
},
point: {
events: {
mouseOver: function (event) {
this.options.oldColor = this.color;
this.graphic.attr("fill", "#e20074");
var point = this;
//alert(this.x+1)
var t = this.x + 1;
$("#Brand" + t).css("background-color", "#e20074")
$("#Brand" + t).css("color", "white")
},
mouseOut: function (event) {
this.graphic.attr("fill", "#4a4a4a");
this.graphic.attr("fill", this.options.oldColor);
var t = this.x + 1;
$("#Brand" + t).css("background-color", "white")
$("#Brand" + t).css("color", "#666666")
}
}
},
}
},
credits: {
enabled: false
},
legend: {
enabled: false
},
series: [{
name: '',
data: data1
}]
});
});
I want to show numbering in x-axis and tooltip shows based on according category.
You can use tooltip formatter ans customise contnet of tooltip.
http://api.highcharts.com/highcharts#tooltip.formatter
I am trying to generate multi axes graph uding highchart as below.
But its not working, array generation and all are quite fine.
If i hardcode totalNoOfLabels and totalLabelsSize then its working. Please suggest:
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
$(function () {
var result=[{"date":"2013-05-01","propertiesList": {"labelsCount":"14","totalSize":"62.62"}},{"date":"2013-05-04","propertiesList":{"labelsCount":"4","totalSize":"22.43"}},{"date":"2013-05-03","propertiesList":{"labelsCount":"7","totalSize":"34.09"}},{"date":"2013-05-02","propertiesList":{"labelsCount":"13","totalSize":"67.51"}},{"date":"2013-05-05","propertiesList":{"labelsCount":"3","totalSize":"11.65"}}];
var totalNoOfLabels=[];
var totalLabelsSize=[];
var dates=[];
dailyStatList = JSON.stringify(result);
var statsObj = $.parseJSON(dailyStatList);
$.each(statsObj, function() {
dates.push(this.date);
totalNoOfLabels.push(this.propertiesList.labelsCount);
totalLabelsSize.push(this.propertiesList.totalSize);
});
$('#container').highcharts({
chart: {
zoomType: 'xy'
},
title: {
text: 'Info'
},
xAxis: [{
categories: dates
}],
yAxis: [{ // Primary yAxis
labels: {
style: {
color: '#89A54E'
}
},
title: {
text: 'No of labels',
style: {
color: '#89A54E'
}
}
}, { // Secondary yAxis
title: {
text: 'Size ',
style: {
color: '#4572A7'
}
},
labels: {
style: {
color: '#4572A7'
}
},
opposite: true
}],
tooltip: {
shared: true
},
legend: {
layout: 'vertical',
align: 'left',
x: 120,
verticalAlign: 'top',
y: 100,
floating: true,
backgroundColor: '#FFFFFF'
},
series: [{
name: 'Labels',
color: '#4572A7',
type: 'column',
yAxis: 1,
data: totalNoOfLabels
}, {
name: 'Size',
color: '#89A54E',
type: 'spline',
data: totalLabelsSize
}]
});
});
labelsCount and totalSize should be numbers, not strings. Parse that values, or put in JSON as numbers and will work properly.
I've got a simple chart showing candlesticks with volume columns underneath: http://jsfiddle.net/T83Xy/
Basically, I want to use black and red for the columns depending on whether it closes higher than the open or not. I've seen some samples by pushing Y: data, color: '#000000' as the parameter. The problem is I'm pushing a date and a volume number. I attempted to push X: date, Y: data, color: '#000000' but it's throwing errors and not giving me the expected result.
At first, you need to set series.turboThreshold to 0 if you have a big amount of points. This will disable the input data format check.
Then, to apply column colors depending on candles, I suggest you this piece of code:
Highcharts.seriesTypes.column.prototype.pointAttribs = (function(func) {
return function(point, state) {
var attribs = func.apply(this, arguments);
var candleSeries = this.chart.series[0]; // Probably you'll need to change the index
var candlePoint = candleSeries.points.filter(function(p) { return p.index == point.index; })[0];
var color = (candlePoint.open < candlePoint.close) ? '#FF0000' : '#000000'; // Replace with your colors
attribs.fill = state == 'hover' ? Highcharts.Color(color).brighten(0.3).get() : color;
return attribs;
};
}(Highcharts.seriesTypes.column.prototype.pointAttribs));
Be careful as this code will affect ALL of your charts that currently on page. But you can easily add some conditions to run this only on specific chart. Here is a default Highstock demo with the code above.
This worked perfectly for me:
$(function () {
jQuery.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json&callback=?', function (data) {
// split the data set into ohlc and volume
var volumeColor = '';
var ohlc = [],
volume = [],
dataLength = data.length,
// set the allowed units for data grouping
groupingUnits = [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]],
i = 0;
for (i; i < dataLength; i += 1) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
if (i==0) {
volumeColor = '#CCCCCC';
} else {
if (data[i][1] >= data[i-1][1]) {
volumeColor = '#006633';
} else {
volumeColor = '#CC0033';
}
}
volume.push({
x: data[i][0], // the date
y: data[i][5],
color: volumeColor
});
}
// create the chart
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 1
},
title: {
text: 'AAPL Historical'
},
yAxis: [{
labels: {
align: 'right',
x: -3
},
title: {
text: 'OHLC'
},
height: '60%',
lineWidth: 2
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: 'Volume'
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
turboThreshold: Number.MAX_VALUE,
dataGrouping: {
enabled: false,
units: groupingUnits
}
}]
});
});
});
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<div id="container" style="height:400px;min-width:310px"></div>
The current (HighCharts 7+) solution for this, which doesn't require overriding any methods, is to simply set the color attribute for the volume point according to the comparison between the current candlestick point's open and its close: green if <, red if >, and yellow if equal.
Here is a minimal example.
// Return a color matching the candle by comparing the open (1) and close (4)
function volumeBarColor(point) {
if (point[1] < point[4])
return 'green';
if (point[1] > point[4])
return 'red';
return 'yellow';
}
Highcharts.getJSON('https://www.highcharts.com/samples/data/aapl-ohlcv.json', data => {
// Split the data set into ohlc and volume
const ohlc = [],
volume = [];
for (let i = 0; i < data.length; i += 1) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4], // close
]);
volume.push({
x: data[i][0], // the date
y: data[i][5], // the volume
color: volumeBarColor(data[i]),
});
}
// Create the chart
Highcharts.stockChart('container', {
title: {
text: 'AAPL Historical'
},
yAxis: [{
labels: {
align: 'right',
x: -3
},
height: '60%',
}, {
labels: {
align: 'right',
x: -3
},
top: '65%',
height: '35%',
offset: 0,
}],
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
}]
});
});
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/data.js"></script>
<div id="container"></div>