I successfully created a charts with two y axis using Highcharts JS Library.
However you can see the y-Axis is stacked (Fahrenheit and temperature), is it possible to merge it to one ?
Here is my code.
<script type="text/javascript">
$(function () {
$('#container').highcharts({
chart: {
type: 'line'
},
time: {
timezone: 'Australia/Brisbane'
},
title: {
text: 'Temperature Graph'
},
xAxis: {
type: 'datetime',
categories: <?php echo json_encode($tgl, JSON_NUMERIC_CHECK); ?>,
title: {
text: 'Dates'
},
},
yAxis: [{
title: {
text: 'temperature'
}
}, {
title: {
text: 'Fahrenheit'
}
}],
series: [{
name: 'Celcius',
data: <?php echo json_encode($suhu, JSON_NUMERIC_CHECK);?>
}, {
name: 'Fahrenheit',
data: <?php echo json_encode($lembap, JSON_NUMERIC_CHECK); ?>,
yAxis: 1
}]
});
});
</script>
You can render this chart with only one yAxis and use the labels.formatter callback to format the displaying labels and show also the Fahrenheit values.
Demo: https://jsfiddle.net/BlackLabel/L8e9g1n3/
labels: {
formatter() {
let fahrenheitValue = 1.8 * this.value + 32;
return this.value + " / " + fahrenheitValue
}
}
API: https://api.highcharts.com/highcharts/yAxis.labels.formatter
If you need you can customize the tooltip in the same way by using the tooltip.formatter.
API: https://api.highcharts.com/highcharts/tooltip.formatter
Related
I have a highchart/highstock where I get my data from a php file. My problem is that If I'm using multiple series the RangeSelector Buttons do not work (In the example the 1h buttno (1 hour) should work. Example: https://jsfiddle.net/mymarcelsql/8xL34qyk/15/
That's my File:
<?php
require("php/00connection.php");
$sql = $conn->query("SELECT read_tickets, write_tickets, epoch_time FROM tickets_available ORDER BY epoch_time;")->fetchAll();
foreach ($sql as $row) {
$read_tickets[] = $row['read_tickets'];
$write_tickets[] = $row['write_tickets'];
}
?>
<script type="text/javascript">
$(document).ready(function() {
var categoriesDate = [ <?php foreach ($sql as $row) { ?>
'<?php $date = $row['epoch_time'] / 1000; echo (date('Y-m-d H:i', $date)) ?>',
<?php } ?>
];
var seriesReadTickets = [ <?php echo join($read_tickets, ',') ?> ];
var seriesWriteTickets = [ <?php echo join($write_tickets, ',') ?> ];
var options ={
chart: {
renderTo: 'tickets',
type: 'line',
zoomType: 'x',
setSize: 400
},
title: {
text: "Memory"
},
xAxis: {
categories: categoriesDate,
title: {
text: "Datetime"
},
type:'datetime',
labels: {
format: '{value:%Y-%m-%d %H:%M}',
}
},
yAxis: {
title: {
text: 'Available Tickets'
}
},
rangeSelector: {
enabled: true,
inputEnabled: false,
buttonPosition: {
align: 'right'
},
labelStyle: {
display: 'none'
},
buttons: [
{
type: 'hour',
count: 1,
text: '1h'
},
{
type: 'day',
count: 1,
text: '1d'
},
{
type: 'month',
count: 1,
text: '1m'
},
{
type: 'month',
count: 6,
text: '6m'
},
{
type: 'year',
count: 1,
text: '1y'
},
{
type: 'all',
text: 'All'
}
]
},
tooltip: {
//crosshairs: true,
shared: true,
valueSuffix: '',
xDateFormat: '%Y-%m-%d %H:%M'
},
series: [{
name: 'Read Tickets',
data: seriesReadTickets
}, {
name: 'Write Tickets',
data: seriesWriteTickets
}]
};
var chart = new Highcharts.Chart(options);
});
</script>
But If I use a single series the buttons are working correctly.
Thanks for your help!
Using xAxis.categories automatically sets a type of the axis to category and the range selector feature works only with the datetime axis type.
You need to convert your data to [x, y] format and use the datetime axis type.
API Reference: https://api.highcharts.com/highcharts/series.line.data
I have very simple data that has come from my MSSQL Server to a JSON_Encode.
Here is my PHP Code (located in myPHPFile.php):
<?php
$serverName = "MyServer";
$connectionInfo = array( "Database"=>"MyDatabase", "UID"=>"MyUID", "PWD"=>"MyPWD");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
$tsql = "SELECT * FROM [MyDatabase].[dbo].[MyView] ORDER BY Year";
$stmt = sqlsrv_query( $conn, $tsql);
$rows = array();
while($r = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$res[] = $r;
}
print json_encode($res, JSON_NUMERIC_CHECK);
sqlsrv_free_stmt( $stmt);
sqlsrv_close( $conn);
?>
That gives me the following print:
[{"Year":2016,"Number":41},{"Year":2017,"Number":512},{"Year":2018,"Number":1895},{"Year":2019,"Number":3132}]
Great. There's the data.
I've tried every tutorial, every highcharts forum post, and every stackoverflow question to get this simple data from my php file in JSON format, into a Highcharts Chart. Perhaps I am missing something obvious.
So let's look at my HTML file:
In the head:
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script type="text/javascript">
$(function () {
var chart;
$(document).ready(function() {
$.getJSON("myPHPFile.php", function(json) {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
},
xAxis: {
title: { text: 'Year'}
},
yAxis: {
title: {
text: 'Number'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
series: json
});
});
});
});
</script>
And then obviously my div
<div id="container"></div>
What am I missing? The HTML window is just blank. No chart rendered.
The Highchart examples show another example to setup the chart. The following format can be used:
$(document).ready(function() {
$.getJSON("myPHPFile.php", function(json) {
var series = json.map(function(record){
return [record.Year, record.Number];
})
Highcharts.chart('container', {
chart: {
renderTo: 'container',
type: 'line',
},
xAxis: {
title: {
text: 'Year'
}
},
yAxis: {
title: {
text: 'Number'
},
},
series: [{
data: series
}],
});
});
});
Checkout the live demo below:
const data = [{
"Year": 2016,
"Number": 41
}, {
"Year": 2017,
"Number": 512
}, {
"Year": 2018,
"Number": 1895
}, {
"Year": 2019,
"Number": 3132
}];
const series = data.map(record => [record.Year, record.Number])
Highcharts.chart('container', {
chart: {
renderTo: 'container',
type: 'line',
},
xAxis: {
title: {
text: 'Year'
}
},
yAxis: {
title: {
text: 'Number'
},
},
series: [{
data: series
}],
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/series-label.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container"></div>
I have been trying to customize an excellent jsfiddle that I was fortunate enough to be directed to in an earlier question here: Switching between many Highcharts using buttons or link text
I am very new to javascript programming (and highcharts also) and I am having some difficulties in retrieving my own data from a database. Currently I have set up my charts like the following:
$('chart1').ready(function() {
var options = {
chart: {
renderTo: 'chart1',
type: 'column',
marginTop: 40,
marginBottom: 75
},
legend: {
enabled: false
},
title: {
text: 'Revenues',
x: 25 //center
},
xAxis: {
title: {
text: ''
},
categories: []
},
yAxis: {
showInLegend: false,
tickAmount: 11,
endOnTick: false,
startOnTick: true,
labels: {
formatter: function () {
return Highcharts.numberFormat(this.value, 0, '.', ',');
}
},
title: {
text: '<?php echo $unitCurr; ?>'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
this.x +': '+ Highcharts.numberFormat(this.y, 0,'.',',');
}
},
series: []
}
var tableName = '<?php echo $tableName; ?>'
$.getJSON("../../companies/charts/data.php", {id: escape(tableName)}, function(json) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
chart = new Highcharts.Chart(options);
});
});
At the bottom you will notice that I am using JSON to retrieve information from my database and everything works just fine. In my earlier question I was asking about how to switch charts using buttons instead and was directed to the following jsfiddle: http://jsfiddle.net/jlbriggs/7ntyzo6u/
This example consists of 3 charts but I have just been trying to manipulate the first chart in order to find out if I could make my own data display instead of the random data that is being generated:
var chart,
chartOptions = {},
chartData = {};
chartData.chart1 = randomData(25);
chartData.chart2 = randomData(10, true);
chartData.chart3 = randomData(65, true, 300);
chartOptions.chart1 = {
chart: {
type: 'column'
},
title: {
text: 'Chart 1 Title'
},
yAxis: {
title: {
text: 'Chart 1<br/>Y Axis'
}
},
series: [{
name: 'Chart 1 Series',
data: chartData.chart1
}]
};
But no matter how much I tried, I just can't seem to change the "data: chartData.chart1" in such a way that it retrieve the arrays I get from my $.getJSON function. Can any of you help me explain why, for instance, the below code doesn't work?. Here I try to exchange the ChartData.chart1 array for my database data. I'm not experienced enough to tell whether its the whole random number generation part of the code that prevents it from working or if it's my understanding thats severely lacking. (I have made sure that the data from data.php is indeed available, since I can display it in a normal array when I try).
var chart,
chartOptions = {},
chartData = {};
chartData.chart2 = randomData(10, true);
chartData.chart3 = randomData(65, true, 300);
$.getJSON("../../companies/charts/data.php", {id: escape(tableName)}, function(json) {
chartData.chart1 = json[6]['data'];
});
chartOptions.chart1 = {
chart: {
type: 'column'
},
title: {
text: 'Chart 1 Title'
},
yAxis: {
title: {
text: 'Chart 1<br/>Y Axis'
}
},
series: [{
name: 'Chart 1 Series',
data: chartData.chart1
}]
};
Any assistance you can provide will be greatly appreciated!
You're actually very close to something that will work. Your problem is related to the timing of async calls relative to inline code, and also the way assignments work in javascript.
As a quick example, here's some code:
x = {foo:5};
y = x.foo;
x.foo = 9;
At the end of this, x.foo is 9, but y is still 5.
Your line of code
chartData.chart1 = json[6]['data'];
doesn't execute until after the call to the server completes; it's contained within a call back function. However, this section of code
chartOptions.chart1 = {
chart: {
type: 'column'
},
title: {
text: 'Chart 1 Title'
},
yAxis: {
title: {
text: 'Chart 1<br/>Y Axis'
}
},
series: [{
name: 'Chart 1 Series',
data: chartData.chart1
}]
};
executes immediately. See the problem? You've cooked the current value of chartData.chart into chartOptions.chart1 BEFORE the server call has completed. That's why you're not seeing your data.
Instead, try something like this:
chartOptions.chart1 = {
chart: {
type: 'column'
},
title: {
text: 'Chart 1 Title'
},
yAxis: {
title: {
text: 'Chart 1<br/>Y Axis'
}
},
series: [{
name: 'Chart 1 Series',
data: []
}]
};
$.getJSON("../../companies/charts/data.php", {id: escape(tableName)}, function(json) {
chartOptions.chart1.series[0].data = json[6]['data'];
});
Now when your data comes back, you're putting it into the object that is actually being used to render the chart (once you click on the right button). Keep in mind that it's going to be empty until the server call completes.
I have been using highchart for graphical display of my records. HighChart works fine with my php variable with comma separated values in it. However, I couldn't get this done using javascript variable with comma separated values. Please help me with this. Your help is much appreciated. Thanks. My codes are shown below.
Javascript
<script type="text/javascript">
var res = [];
var data_graph = [];
function show_graphics(){
$.post("<?php echo base_url(); ?>main_controller/show_monthly_analytics_ajax", '', function(data){
if( data.notify == "Success" ){
Object.keys(data.upload_data).forEach(function(key) {
res.push(data.upload_data[key]);
});
data_graph = res.join(",");
console.log(data_graph );
} else{
console.log(data.notify);
}
},'json');
$('#container').highcharts({
chart: {
type: 'column',
margin: 75,
options3d: {
enabled: true,
alpha: 10,
beta: 25,
depth: 70
}
},
title: {
text: '3D chart with null values'
},
subtitle: {
text: 'Notice the difference between a 0 value and a null point'
},
plotOptions: {
column: {
depth: 25
}
},
xAxis: {
categories: Highcharts.getOptions().lang.shortMonths
},
yAxis: {
title: {
text: null
}
},
series: [{
name: 'Sales',
data: [data_graph]
}]
});
}
</script>
When I look at the console, the values being showed of the variable array data_graph seems right but the chart never showed a graph. What is the problem with this?
Modification
<script type="text/javascript">
var res = [];
function show_graphics(){
$.post("<?php echo base_url(); ?>main_controller/show_monthly_analytics_ajax", '', function(data){
if( data.notify == "Success" ){
Object.keys(data.upload_data).forEach(function(key) {
res.push(data.upload_data[key]);
});
//aa = res.join(",");
console.log(res);
} else{
console.log(data.notify);
}
},'json');
$('#container').highcharts({
chart: {
type: 'column',
margin: 75,
options3d: {
enabled: true,
alpha: 10,
beta: 25,
depth: 70
}
},
title: {
text: '3D chart with null values'
},
subtitle: {
text: 'Notice the difference between a 0 value and a null point'
},
plotOptions: {
column: {
depth: 25
}
},
xAxis: {
categories: Highcharts.getOptions().lang.shortMonths
},
yAxis: {
title: {
text: null
}
},
series: [{
name: 'Sales',
data: [res]
}]
});
}
</script>
Response
The data part/section for series property should be an array of numbers.
According to your explanation, your implementation is as if you would have the following:
series: [{
name: 'Sales',
data: ['1, 2, 1, 0'] // this is an array with one string element, which is wrong
}]
But, it should be:
series: [{
name: 'Sales',
data: [1, 2, 1, 0]
}]
See JSfiddle demo here
EDIT
Besides the change that I suggested above, consider that the $.post call is an async execution. Then, you should only draw the chart when data is 'ready' by moving $('#container').highcharts(...) block inside the success callback as follows:
if( data.notify == "Success" ){
Object.keys(data.upload_data).forEach(function(key) {
res.push(data.upload_data[key]);
});
$('#container').highcharts({
...
...
series: [{
name: 'Sales',
data: res
}]
});
} else {
console.log(data.notify);
}
$(function () {
$('#containerGraph').highcharts({
chart: {
type: 'column'
},
title: {
text: ''
},
subtitle: {
text: ''
},
exporting: { enabled: false },
credits: { enabled: false },
xAxis: {
type: 'category',
title: {
text: 'Date'
},
labels: {
rotation: -45,
style: {
fontSize: '10px',
fontFamily: 'Verdana, sans-serif'
}
}
},
plotOptions: {
column: {
colorByPoint: true
}
},
yAxis: {
min: 0,
title: {
text: 'Time (minutes)'
}
},
legend: {
enabled: false
},
tooltip: {
//pointFormat: '<b>{point.y:.1f} minutes</b>{point.x:}'
formatter: function() {
return '<b>'+ this.y +'</b>'+
'minutes<br>'+ this.point.z + 'hi' ;
},
//shared: true
},
series: [{
name: 'Time',
data: [
['<?php print $buildDate[0]?>', <?php print $lastFifteenDurationArray[0]?>, <?php echo $svnHistory[0]?>],
['<?php print $buildDate[1]?>', <?php print $lastFifteenDurationArray[1]?>, <?php print $svnHistory[1]?>],
['<?php print $buildDate[2]?>', <?php print $lastFifteenDurationArray[2]?>, <?php print $svnHistory[2]?>],
['<?php print $buildDate[3]?>', <?php print $lastFifteenDurationArray[3]?>, <?php print $svnHistory[3]?>],
['<?php print $buildDate[4]?>', <?php print $lastFifteenDurationArray[4]?>, <?php print $svnHistory[4]?>],
['<?php print $buildDate[5]?>', <?php print $lastFifteenDurationArray[5]?>, <?php print $svnHistory[5]?>]
],
lang: {noData: "No Data Available"},
dataLabels: {
enabled: false
}
}]
});
});
The value of z-axiz in the tooltip shows Undefined in the chart.
I also tried this.point.config[2], but that doesn't work either.
When I debugged the code, the z-value in the data field is correctly resolved.
Is it because I have to specify type of data or something?
Can someone tell me what I am doing wrong?
In case you wan't a third dimension you'll need to define it like this: data = [{y: yValue, z: zValue, additional: additionalVal}], like this you can access this.point.z (and this.point.additional). Anyway, it seems that using the series X values as x-axis category label does not work while working with an array of objects. In order to make it run, do it like this:
xAxis: {
type: 'category',
categories: ['09-01-2015','09-01-2015'], /* your old x-data */
title: {
text: 'Date'
}
},
series: [{
name: 'Time',
/* data is now an array of objects */
data: [
{y:25, z:492076},
{y:26, z:496222}
],
}
updated Fiddle is here