I am using Angular and Higcharts to visualize some data. I have gotten many of the other Highchart components working, now I want to use the gauges. I went to the Highcharts website and used the example at their demo section. Unfortunately this is not working.
For some reason the gauge is blank but the other parts of my component shows up. Example below:
My code looks like this:
TS file
import { Component, OnInit } from '#angular/core';
import * as Highcharts from 'highcharts';
#Component({
selector: 'app-speedo',
templateUrl: './speedo.component.html',
styleUrls: ['./speedo.component.scss']
})
export class SpeedoComponent implements OnInit {
chartOptions: any;
Highcharts: typeof Highcharts = Highcharts;
chartRef: Highcharts.Chart;
updateFromInput = false;
constructor() { }
ngOnInit(): void {
this.myChart();
}
chartCallback: Highcharts.ChartCallbackFunction = (chart) => {
this.chartRef = chart;
};
myChart(){
this.chartOptions = {
chart: {
type: 'solidgauge'
},
title: null,
pane: {
center: ['50%', '85%'],
size: '140%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor:
Highcharts.defaultOptions.legend.backgroundColor || '#EEE',
innerRadius: '60%',
outerRadius: '100%',
shape: 'arc'
}
},
exporting: {
enabled: false
},
tooltip: {
enabled: false
},
// the value axis
yAxis: {
stops: [
[0.1, '#55BF3B'], // green
[0.5, '#DDDF0D'], // yellow
[0.9, '#DF5353'] // red
],
lineWidth: 0,
tickWidth: 0,
minorTickInterval: null,
tickAmount: 2,
title: {
y: -70
},
labels: {
y: 16
}
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 5,
borderWidth: 0,
useHTML: true
}
}
}
}
setTimeout(() => {
window.dispatchEvent(
new Event('resize')
);
}, 300);
}
}
HTML file
<p>speedo works!</p>
<highcharts-chart
[Highcharts]="Highcharts"
[options]="chartOptions"
style="width: 100%; height: 400px; display: block;"
[(update)]="updateFromInput"
[callbackFunction]="chartCallback">
</highcharts-chart>
Does anyone know what is wrong with this code. How can I fix it so that the gauge actually shows up?
If anyone can recommend any other package I can use to show real time data on a gauge I would appreciate it. This package should be easy to use, or at least have more resources than Highcharts where one can find tutorials an so on.
Thanks in advance!
There are a few glitches:
The highcharts-more module is missing. Import it at the begging
import HC_more from "highcharts/highcharts-more";
HC_more(Highcharts);
Your demo was not working simply because there was nothing to show.
All you have to do to fix this is to set the data in the series object.
Remember to always add the series type for each series.
series: [
{
type: "gauge",
data: [80]
}
]
Also, I highly recommend Highhcarts official documentation where you might find more examples and descriptions.
API:
https://api.highcharts.com/highcharts/series.gauge
https://github.com/highcharts/highcharts-angular
Demo:
https://stackblitz.com/edit/highcharts-angular-gauge
Related
Hello I have the following design That I have to implement. I am using apexcharts as a chart library in my application .
I could not find any gauge/indicator related information of apexchart while googling and now
quite not sure weather it is possible to implement the chart as required design.
2 important elements on my design
custom indicator
rounded edges of the arc
Do you have any idea that could help me here ?
Thank You.
var options = {
series: [44, 55, 41, 17, 15],
chart: {
type: "donut"
},
plotOptions: {
pie: {
startAngle: -90,
endAngle: 90,
offsetY: 10
}
},
grid: {
padding: {
bottom: -80
}
},
responsive: [
{
breakpoint: 480,
options: {
chart: {
width: 200
},
legend: {
position: "bottom"
}
}
}
]
};
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
<div id="chart"></div>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
there is one in Echarts i use it before
https://echarts.apache.org/examples/en/editor.html?c=gauge-progress
I am using HighCharts for the first time and it's proving to be difficult to find sources to help me with this problem.
I am trying to display multiple charts with different numbers of series. Rather than set up multiple options templates I want to use just one and use a function to customize the options object each time. Here I've provided mock data for what one of the charts will look like as received from the API. In the application I plan on feeding it from HTML.
I keep running into various problems due to my lack of understanding of HighCharts, right now I am just going around in circles fixing one problem only for a past problem to pop-up again I was hoping someone can point me in the right direction.
This is my Class:
export class CompletenessTabComponent implements OnInit, AfterViewInit {
#ViewChild('chartTarget') chartTarget: ElementRef;
chart: Highcharts.ChartObject;
dataObj = {"id":0,
"tableName":"d1 vs d2",
"data":{"d1Count":[50,45,55,60,70],
"d2Count":[40,32,55,58,33],
"Errors":[2,3,4,1,0]},
"dates":[20180927,20180928,20181001,20181002,20181003]
};
constructor() { }
setHighChartOptions(data, seriesNames, chartTitle ): any {
count = 1;
highChartOptions.title.text = chartTitle;
highChartOptions.xAxis.data = data.dates;
this.chart.series[0].setData(this.dataObj.data[0]);
Object.keys(data.data).forEach((key) =>
this.chart.addSeries({
name: seriesNames[count],
data: data.data[key],
type: 'line'
}) count ++
);
return highChartOptions;
}
getHighChartOptions(){
return highChartOptions;
}
ngOnInit() {
this.chart = chart(this.chartTarget.nativeElement, this.setHighChartOptions(this.dataObj, ['d1', 'd2', 'error'], this.dataObj.tableName));
Object.keys(this.dataObj.data).forEach(key =>
console.log(key, this.dataObj.data[key]))
}
ngAfterViewInit() {
}
}
const highChartOptions = {
colors:
['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'],
credits: {
enabled: false
},
chart: {
backgroundColor: null,
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
itemStyle: {
fontSize: '10px',
fontWeight: 'normal'
}
},
tooltip: {
valuePrefix: '$'
},
title: {
text: ''
},
xAxis: {
type: 'date',
data: [],
title: 'date'
},
yAxis: {
title: {
align: 'middle',
rotation: 0,
text: ''
}
},
plotOptions: {
series: {
marker: {
enabled: false
},
shadow: false
}
},
series: [{
type: 'line',
name: '',
data: [null]
}]
};
A few errors I keep receiving are:
in setHighChartOptions() : Cannot read property 'series' of undefined (at, this.chart.series[0]), & cannot read 'keys' of undefined (at the start of the ForEach loop).
I believe the big issue is the chart object is undefined which doesn't make sense since I've instantiated it at the top of the class and then onInit I set the chart options.
I hope you will be able spot my errors and assist me. Thank You.
Most probably, it's because you're trying to refer to series which is not already defined. Actually, if you calling the setHighchartsOptions for a first time, your chart is not defined yet.
In order to make it works, please try to init the chart first (even could be the empty chart, without any data), and then call another methods on Chart object, like addSeries. Something like that, but i didn't saw whole your app, so it's hard to write completely adjusted solution.
ngOnInit() {
this.chart = chart(this.chartTarget.nativeElement, {});
this.chart.update(this.setHighChartOptions(this.dataObj, ['d1', 'd2', 'error'], this.dataObj.tableName))
Object.keys(this.dataObj.data).forEach(key =>
console.log(key, this.dataObj.data[key]))
}
First of all, you must be careful to use import correctly all js package in your Angular project:
import { chart } from 'highcharts';
import * as Highcharts from 'highcharts';
Also, you must check does your package installed correctly with "npm"?
After all, As my point of view, this example can help you to better understand how to use "highcharts" package in your project, other configs depend on the version of "highcharts" you are using it.
import { Component, ElementRef, ViewChild } from '#angular/core';
import { chart } from 'highcharts';
import * as Highcharts from 'highcharts';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Highcharts Sample';
#ViewChild('chartTarget') chartTarget: ElementRef;
chart: Highcharts.ChartObject;
ngAfterViewInit() {
const options: Highcharts.Options = {
chart: {
type: 'bar'
},
title: {
text: 'Sample Title'
},
xAxis: {
categories: ['Top Test', 'Test 2', 'Test3']
},
yAxis: {
title: {
text: 'Fox Rex'
}
},
series: [{
name: 'Tomi',
data: [1, 0, 4]
}, {
name: 'Alex',
data: [5, 7, 3]
}]
};
this.chart = chart(this.chartTarget.nativeElement, options);
}
addSeries(){
this.chart.addSeries({
name:'Test',
data:[2,3,7]
})
}
}
And HTML template of sample:
<div #chartTarget>
chart target sample
</div>
Also, you must serve data to highcharts as the format is standard for that, check JSON sample data format in examples in highcharts website.
I have issue with react-chartjs-2 and chartjs-plugin-streaming, my goal was to create a live graph with stream, but it ends up in error and I don't quite know why. Anyhow, my imports are like this:
import { Chart, Bubble } from 'react-chartjs-2';
import ChartStream from 'chartjs-plugin-streaming';
Then right below that is this part:
Chart.pluginService.register(ChartStream);
and then theres's this part in component render
<Bubble
data={{
labels: ['demo'],
datasets: [{
backgroundColor: 'rgba(75,192,192,1)',
data: []
}]
}}
options={{
plugins: {
streaming: {
onRefresh: function(chart) {
chart.data.datasets[0].data.push({
x: Date.now(),
y: Math.random() * 100,
r: 5
});
},
delay: 500,
refresh: 1000,
frameRate: 30,
duration: 3600000 // 3600000 = 1hour
}
},
scales: {
xAxes: [{
type: 'realtime',
id: 'x-axis-0'
}]
}
}}
/>
first error that happens right on navigation is this:
Uncaught TypeError: Cannot set property 'options' of undefined
at core.controller.js:51
at Array.forEach ()
at n (core.controller.js:50)
at e.update (core.controller.js:340)
at e.construct (core.controller.js:121)
at new e (core.js:7)
at t.renderChart (index.js:228)
at t.componentDidMount (index.js:53)
at e.notifyAll (CallbackQueue.js:76)
at r.close (ReactReconcileTransaction.js:80)
because in core.controller.js of chartjs is this part:
function updateConfig(chart) {
var newOptions = chart.options;
// Update Scale(s) with options
if (newOptions.scale) {
chart.scale.options = newOptions.scale;
} else if (newOptions.scales) {
newOptions.scales.xAxes.concat(newOptions.scales.yAxes).forEach(function(scaleOptions) {
chart.scales[scaleOptions.id].options = scaleOptions;
});
}
// Tooltip
chart.tooltip._options = newOptions.tooltips;
}
the part that fails is this:
chart.scales[scaleOptions.id].options = scaleOptions;
and it's caused by these options I set before, upon debugging there is no x-axis-0 in chart.scales, only y-axis-0
scales: {
xAxes: [{
type: 'realtime',
id: 'x-axis-0'
}]
}
Anyone know how to work around this issue?
The problem seems that when a chart instance is constructed, the 'realtime' scale is not registered yet, and chart.scales['x-axis-0'] is left undefined. Please make sure the chartjs-plugin-streaming is imported before a chart is constructed.
By the way, you don't need to register the plugin object to the pluginService explicitly. It is done with import 'chartjs-plugin-streaming'. Try this working sample:
import React from 'react';
import ReactDOM from 'react-dom';
import { Bubble } from 'react-chartjs-2';
import 'chartjs-plugin-streaming';
ReactDOM.render(
<Bubble
data={{
datasets: [{
label: 'demo',
backgroundColor: 'rgba(75,192,192,1)',
data: []
}]
}}
options={{
plugins: {
streaming: {
onRefresh: function(chart) {
chart.data.datasets[0].data.push({
x: Date.now(),
y: Math.random() * 100,
r: 5
});
},
delay: 500,
refresh: 1000,
frameRate: 30,
duration: 3600000 // 3600000 = 1hour
}
},
scales: {
xAxes: [{
type: 'realtime'
}]
}
}}
/>
, document.getElementById('root'));
I have a component where I have to show high maps. No errors but the maps is always empty
My chart options object :
let chartData = [{ code3: "ABW", z: 105 }, { code3: "AFG", z: 35530 }];
this.chartConfigObject = new MapChart(<any>{
chart: {
borderWidth: 1,
map: 'custom/world'
},
title: {
text: 'World population 2013 by country'
},
subtitle: {
text: 'Demo of Highcharts map with bubbles'
},
legend: {
enabled: false
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
series: [{
name: 'Countries',
color: '#E0E0E0',
enableMouseTracking: false
}, {
type: 'mapbubble',
name: 'Population 2016',
joinBy: ['iso-a3', 'code3'],
data: chartData,
map: mapData,
minSize: 4,
maxSize: '12%',
tooltip: {
pointFormat: '{point.properties.hc-a2}: {point.z} thousands'
}
}]
});
When I console the created MapChart object i am getting the series as null always.
What am i missing and why the maps series is always null?
I am using angular-highcharts component as explained here :
https://github.com/cebor/angular-highcharts
reproduced in stackblitz: https://stackblitz.com/edit/angular-highcharts-stock-nbvnuw?file=app%2Fapp.module.ts
You are not providing the map data to your chart , so it doesn't know which map to show. Try showing the map data like mapData: Highcharts.maps['custom/world'] under Series.
If you cannot access the maps in your Highcharts reference , try importing all the maps (JS files) from the HighMaps library into your project and reference them in your typescript component file like this:
const Highcharts = {maps: {}};
require('../../../assets/maps')(Highcharts); //your custom project path
and use mapData: Highcharts['maps']['custom/world'] or whatever is the map you wanted to use like 'countries/us/us-all'
Below is working map code using angular-highcharts to plot the map and points on it:
getMap(data) {
return new MapChart({
chart: {
events: {
load: function (point) {
//do something here on page load
}
},
spacingBottom: 20
backgroundColor: '#FFF',
style: {fontFamily: 'inherit'}
},
title: {
text: ''
},
mapNavigation: {
enabled: true
},
tooltip: {
headerFormat: '',
formatter: function () {
var toolTipTxt = '<b>' + this.point.options.name + '</b>';
return toolTipTxt;
}
},
plotOptions: {
series: {
color: '#00A778',
marker: {
radius: 6,
symbol: 'circle',
lineColor: '#00A778',
lineWidth: 1,
states: {
select: {
fillColor: '#00A778',
lineWidth: 1,
lineColor: '#00A778'
}
}
},
point: {
events: {
click: function () {
this.select(null, true);
}
}
}
}
},
series: [
{
//mapData: Highcharts['maps']['custom/world']
mapData: Highcharts.maps['custom/world'],
name: 'Basemap',
borderColor: '#A0A0A0',
nullColor: 'rgba(200, 200, 200, 0.3)',
showInLegend: false,
data: []
},
{
// Specify points using lat/lon
type: 'mappoint',
name: 'MySites',
data: data
}
]
});
}
Also you need proj4js library to plot points on the map, in case if that's your requirement as well.
Hope this helps !
Might, it can be useful.
Here is the solution for angular-highcharts:
1) Download the map from collection:
https://code.highcharts.com/mapdata/
2) Create a variable that equals to the content of this file and export it:
instead of
Highcharts.maps["custom/world"] = { ... content of the file ... }
use
const worldMap = { ... content of the file ... }
export default worldMap;
2) Import this map to your component (for world-map.ts):
import worldMap from './world-map';
3) use
chart: {
...
map: worldMap,
...
},
And, of course, don't forget to add a couple of lines to your module:
import { ChartModule, HIGHCHARTS_MODULES } from 'angular-highcharts';
import * as highmaps from 'highcharts/modules/map.src';
#NgModule({
...
providers: [
{ provide: HIGHCHARTS_MODULES, useFactory: () => [highmaps] }
],
...
})
About modules: https://www.npmjs.com/package/angular-highcharts#highmaps
Here is the working example:
https://stackblitz.com/edit/angular-highcharts-stock-byjo6a
Solution was found here:
https://forum.highcharts.com/highmaps-usage-f14/highmaps-bubble-chart-is-empty-t40432/
Updated & Resolved, see below.
I have been working on this for several days, searching and reading many tutorials and I am still stuck. Ultimately I am working on a page that will contain multiple solid gauge charts with data supplied by JSON from an SQLITE3 database. The database is updated every minute and I would like to have the chart data update dynamically, not by refreshing the browser page.
For the purpose of my learning, I have reduced this down to one chart.
All current and future data will be arranged as such:
PHP
[{"name":"s1_id","data":[684172]},
{"name":"s1_time","data":[1483097398000]},
{"name":"s1_probe_id","data":["28-0000071cba01"]},
{"name":"s1_temp_c","data":[22.125]},
{"name":"s1_temp_f","data":[71.825]},
{"name":"s2_id","data":[684171]},
{"name":"s2_time","data":[1483097397000]},
{"name":"s2_probe_id","data":["28-0000071d7153"]},
{"name":"s2_temp_c","data":[22.062]},
{"name":"s2_temp_f","data":[71.7116]}]
This is the current layout of my java:
JS
$(function() {
var options = {
chart: {
type: 'solidgauge'
},
title: null,
pane: {
center: ['50%', '90%'],
size: '140%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || '#EEE',
innerRadius: '60%',
outerRadius: '100%',
shape: 'arc'
}
},
tooltip: {
enabled: false
},
// the value axis
yAxis: {
stops: [
[0.10, '#2b908f'],//Blue
[0.35, '#55BF3B'],//Green
[0.65, '#DDDF0D'],//Yellow
[0.90, '#DF5353']//Red
],
lineWidth: 0,
minorTickInterval: null,
tickPixelInterval: 1000,
tickWidth: 0,
title: {
y: -70
},
labels: {
y: 16
},
min: 0,
max: 1000000,
title: {
text: 'Degree C'
}
},
plotOptions: {
solidgauge: {
dataLabels: {
y: -10,
borderWidth: 0,
useHTML: true
}
}
},
series: []
};
var gauge1;
$.getJSON('sgt3.php', function(json){
options.chart.renderTo = 'chart1';
options.series.push(json[0]);
gauge1 = new Highcharts.Chart(options);
});
});
I was using information from this post but it leaves off the dynamic update aspect. As I mentioned before, I will have more charts rendering to div ids, all coming from the one JSON array, which is why I have referenced the following link:
Multiple dynamic Highcharts on one page with json
If anyone has an idea how to dynamically update this please let me know. I have tried several setInterval methods but all they seem to do is redraw the chart but no data is updated.
Update:
I spent a while doing some more iterations and resolved before coming back here. I changed each gauge to have their own function such as:
$('#gauge0').highcharts(Highcharts.merge(options, {
yAxis: {
min: 15,
max: 30,
tickPositions: [15, 20, 25, 30],
title: {
text: 'Table'
}
},
credits: {
enabled: false
},
series: [{
data: [30],
dataLabels: {
y: 20,
format: '<div style="text-align:center"><span style="font-size:48px;color:' +
((Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black') + '">{y:.3f}</span><br/>' +
'<span style="font-size:12px;color:silver">Degree C</span></div>'
},
tooltip: {
valueSuffix: 'Tooltip 1'
}
}]
}));
Then got the setInterval to work by assigning to each gauge respectively. I have added a lot more info than just the two I referenced but each var and setData can be added respectively.
// Bring life to the dials
setInterval(function() {
$.ajax({
url: 'data_temps.php',
success: function(json) {
var chart0 = $('#gauge0').highcharts();
var chart1 = $('#gauge1').highcharts();
// add the point
chart0.series[0].setData(json[3]['data'],true);
chart1.series[0].setData(json[8]['data'],true);
},
cache: false
})
}, 1000)
Hopefully this can help someone in the future. This may not be the most efficient way but its working great right now. Thanks again everyone for your suggestions.
You may try something like this:
change:
var gauge1;
$.getJSON('sgt3.php', function(json){
options.chart.renderTo = 'chart1';
options.series.push(json[0]);
gauge1 = new Highcharts.Chart(options);
});
to:
options.chart.renderTo = 'chart1';
var gauge1 = new Highcharts.Chart(options);
$.getJSON('sgt3.php', function(json){
gauge1.series[0].points.length = 0;
gauge1.series[0].points.push(json[0]);
});
That is, updating the existing series on a chart instead of re-creating it.
As I've mentioned in the comment before, highcharts provide an example of dynamically updated gauge:
http://jsfiddle.net/gh/get/jquery/3.1.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/gauge-solid/