Related
I'm using angular6 and the office highcharts angular wrapper (https://github.com/highcharts/highcharts-angular) in version 2.4.0.
Everything is working good except the labels that can be placed manually on the chart.
I just don't manage to get them refreshed.
I have a graph that can be filtered through the back-end. When I get the new generated data I update the data in my chartOptions which are used in the html as [options]="chartOptions" for the angular component.
The chartOptions are instanciated from my default class like this: this.chartOptions = new GraphConfigSeqAtteptedVsAchived().chartOptions;
The Class looks like this:
`import * as Highcharts from 'highcharts';
export class GraphConfigSeqAtteptedVsAchived{
public chartOptions: any;
constructor(){
this.chartOptions = {
chart: {
height: 600,
width: 620,
events:{load: function(){
this.myTooltip = new Highcharts.Tooltip(this, this.options.tooltip);
}
},
backgroundColor: 'transparent',
},
credits: {
text: 'charname',
href: ''
},
labels: {
},
exporting:{
chartOptions:{
title: {
text:'not set',
style:{
color: '#000000'
},
margin: 0
}
}
},
tooltip: {
enabled: false
},
xAxis: {
min: -10,
max: 0,
width: 535,
title: {
text: 'Rainfall (mm)',
style: {
fontWeight: "bold",
color: '#000000'
}
},
reversed: true,
tickInterval: 1
},
yAxis: {
min: -10,
max: 0,
title: {
text: 'Rainfall (mm)',
style: {
fontWeight: "bold",
color: '#000000'
}
},
reversed: true,
tickInterval: 1
},
title: {
text: ' as',
margin: 0,
style:{
color: 'transparent'
}
},
legend: {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: 100,
y: 90,
floating: true,
backgroundColor: '#FFFFFF',
borderWidth: 1,
navigation: {
enabled: false
}
},
plotOptions: {
scatter: {
stickyTracking: false,
allowPointSelect: true,
marker: {
radius: 3,
states: {
hover: {
enabled: true,
lineColor: 'rgb(100,100,100)'
}
}
},
tooltip: {
headerFormat: '<b>{series.name}</b><br>',
pointFormat: '',
hideDelay: 500
},
symbol: "circle",
events: {
mouseOut: function() {
this.chart.myTooltip.hide();
this.chart.myTooltip.options.enabled = false;
},
mouseOver: function() {
if(this.halo) {
this.halo.attr({
'class': 'highcharts-tracker'
}).toFront();
}
},
click: function(event) {
this.chart.myTooltip.options.enabled = true;
this.chart.myTooltip.refresh(event.point, event);
}
}
},
line:{
events: {
legendItemClick: function () {
return false;
}
}
},
series:{
allowPointSelect: true
}
},
series: [{
type: 'line',
data: [[30, 30], [-30, -30]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 1
}
},
showInLegend: false,
color: "rgba(0, 0, 0, 0.6)",
enableMouseTracking: false
},{
type: 'line',
data: [[30, 29.5], [-29.5, -30]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(125, 162, 159, 0.35)",
enableMouseTracking: false
},{
type: 'line',
data: [[29.5, 30], [-30, -29.5]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(125, 162, 159, 0.35)",
enableMouseTracking: false
},{
type: 'line',
data: [[29, 30], [-30, -29]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(197, 144, 161, 0.35)",
enableMouseTracking: false
},{
type: 'line',
data: [[30, 29], [-29, -30]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(197, 144, 161, 0.35)",
enableMouseTracking: false
}]
}
}
}`
The generated data is in the typescript dynamically added and all of that works just fine. Everything is refreshed after I set the updateFlag for [(update)]="updateGraph". The axis titles are also fine.
The only thing that's not refreshed for me are the labels i dynamically added to the chart like this:
let labelTotalNumberOfEyes = {
html : this.translate.instant('GRAPHS.TOTAL_NUMBER_OF_EYES') + ': ' + (scatterSeries.data.length + scatterSeriesRetreatment.data.length),
style : {
left : '330px',
top : '368px',
fontSize : '14px',
backgroundColor: '#FFFFFF',
borderWidth: 1,
}
}
this.chartOptions.labels.items.push(labelTotalNumberOfEyes);
Does someone have any idea what I'm might doing wrong? I don't see any further option than just setting this update flag and it works fine for everything but the labels.
Please let me know if you're missing any information.
Thanks in advance.
This issue is actually a Highcharts bug. I've reported it here: https://github.com/highcharts/highcharts/issues/10429.
As a workaround, you can use Highcharts.SVGRenderer to add a custom label and store reference to it in your component. Next, when updating, call attr() method on the label (Highcharts.SVGElement) and set new options. Check demo and code posted below.
Add a label on chart callback:
constructor() {
const self = this;
this.chartCallback = chart => {
self.chart = chart;
self.label = chart.renderer
.text("test", 100, 100)
.css({
fill: "#555",
fontSize: 16
})
.add()
.toFront();
};
}
call attr() on the label while updating:
update_chart() {
const self = this,
chart = this.chart;
chart.showLoading();
setTimeout(() => {
chart.hideLoading();
self.chartOptions.series = [
{
data: [10, 25, 15],
name: "updatedSerieName"
}
];
self.chartOptions.yAxis.title.text = "updatedData";
self.label
.attr({
text: "test1",
x: 150,
y: 120
})
.css({
fill: "red",
fontSize: 20
});
self.updateFromInput = true;
}, 2000);
}
Demo:
https://codesandbox.io/s/8zo0yvqqwj
API reference:
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#text
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
I would like to develop a Spider Web Radar which looks similar to the graph shown in image below using highcharts. can you please tell me wether this could be achieved using High charts. please check the below code and image attached
This is my approach Fiddle.
Highcharts.chart('container', {
chart: {
polar: true,
type: 'area',
},
legend: {
enabled: false
},
title: {
text: 'Budget vs spending',
x: -90
},
pane: {
size: '90%'
},
xAxis: {
categories: ['Bonds', 'Future', 'Past', 'Value', 'Health', 'Divedend'],
tickmarkPlacement: 'on',
lineWidth: 0
},
yAxis: {
gridLineInterpolation: 'polygon',
lineWidth: 0,
min: 0,
labels:
{
enabled: false
}
},
tooltip: {
shared: true,
pointFormat: '<span style="color:{series.color}">{series.name}: <b>${point.y:,.0f}</b><br/>'
},
series: [{
color: {
linearGradient: {
x1: 0,
y1: 0,
x2: 1,
y2: 0
},
stops: [
[0, '#50e3c2'],
[1, '#50e3c2']
]
},
marker: {
enabled: false,
states: {
hover: {
radius: 8,
symbol: 'square',
}
}
},
name: 'Allocated Budget',
data: [80, 70, 60, 70, 70, 60],
pointPlacement: 'on',
shadow: {
color: '#000000',
width: 7,
opacity: 0.08,
offsetY: 3,
offsetX: 0
},
}]
});
I'm using High charts gauge-solid. So I need to create below like chart.
Can you tell me how to give different data sets for this chart (each and every color has its own data)?
What I need is this:
This is what I have tried: jsfiddle
$(function () {
$('#gauge').highcharts({
chart: {
type: 'solidgauge',
backgroundColor: 'transparent'
},
title: null,
pane: {
center: ['50%', '70%'],
size: '130%',
startAngle: -120,
endAngle: 120,
background: {
backgroundColor: '#fff',
innerRadius: '75%',
outerRadius: '100%',
shape: 'arc',
borderColor: 'transparent'
}
},
tooltip: {
enabled: false
},
// the value axis
yAxis: {
min: 0,
max: 100,
stops: [
[0.1, '#e74c3c'], // red
[0.5, '#f1c40f'], // yellow
[0.9, '#2ecc71'] // green
],
minorTickInterval: null,
tickPixelInterval: 400,
tickWidth: 0,
gridLineWidth: 0,
gridLineColor: 'transparent',
labels: {
enabled: false
},
title: {
enabled: false
}
},
credits: {
enabled: false
},
plotOptions: {
solidgauge: {
innerRadius: '75%',
dataLabels: {
y: -45,
borderWidth: 0,
useHTML: true
}
}
},
series: [{
data: [83],
dataLabels: {
format: '<p style="text-align:center;">{y}%</p>'
}
}]
});
});
data array can contain more than one value for a series:
series: [{
data: [80, 150, 200]
}]
Live demo: http://jsfiddle.net/kkulig/tou6wwxj/
If you want every dial to move only within its own range then you can simply make sure that a proper value is assigned to a point while initializing or updating it.
I am completely new to Highcharts and need to design a horizontal bar chart that looks exactly like the image below.
I've tried fiddling around and managed to display the 4 and 2 inside the bars. However, I'm unable to display the text 'Completed' above the first bar and the text 'To Action' below the second bar. I also want to eliminate the gap between the bars. Below is my code so far.
var chart = new Highcharts.Chart({
chart: {
renderTo:'container',
//marginLeft:120,
type:'bar'
},
legend: { enabled: false},
colors:['#173c64'],
xAxis: {
categories: ['4','2'],
labels: {
align:'left',
x:5,
style: {
fontSize: '4em',
color:'#fff'
}
},
lineWidth: 0,
gridLineWidth: 0,
lineColor: 'transparent',
minorTickLength: 0,
tickLength: 0,
title: {
enabled: false
}
},
yAxis: {
lineWidth: 0,
gridLineWidth: 0,
lineColor: 'transparent',
labels: {
enabled: false
},
minorTickLength: 0,
tickLength: 0,
title: {
enabled: false
}
},
title: {
margin:0,
useHTML: true,
text: "This Month",
style: {"color": "#333333", "fontSize": "1.5rem","fontWeight": "bold"}
},
series:[{
data:[{y: 20, color:'#0091dc'},{y: 17, color:'#173c64'}]
}]
});
Added the subtitle for Completed and added custom label to footer for To Action and for removing space between bars added plotOptions with
groupPadding: 0,pointPadding: 0, in chart
This is near to your requirements. Hope this helps
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
//marginLeft:120,
type: 'bar',
events: {
load: function() {
var label = this.renderer.label("To Action")
.css({
width: '100px',
fontSize: '1.5rem'
})
.add();
label.align(Highcharts.extend(label.getBBox(), {
align: 'left',
x: 0, // offset
verticalAlign: 'bottom',
y: -30 // offset
}), null, 'spacingBox');
}
},
marginBottom: 120
},
legend: {
enabled: false
},
colors: ['#173c64'],
xAxis: {
categories: ['4', '2'],
labels: {
align: 'left',
x: 5,
style: {
fontSize: '4em',
color: '#fff'
}
},
lineWidth: 0,
gridLineWidth: 0,
lineColor: 'transparent',
minorTickLength: 0,
tickLength: 0,
title: {
enabled: false
}
},
yAxis: {
lineWidth: 0,
gridLineWidth: 0,
lineColor: 'transparent',
labels: {
enabled: false
},
minorTickLength: 0,
tickLength: 0,
title: {
enabled: false
}
},
plotOptions: {
bar: {
stacking: "normal",
groupPadding: 0, //add here
pointPadding: 0, //add here
}
},
title: {
margin: 0,
useHTML: true,
text: "This Month",
style: {
"color": "#333333",
"fontSize": "1.5rem",
"fontWeight": "bold"
}
},
subtitle: {
align: 'left',
y: 40, //offset
useHTML: true,
text: 'Completed',
style: {
"color": "#333333",
"fontSize": "1.5rem"
}
},
series: [{
data: [{
y: 20,
color: '#0091dc'
}, {
y: 17,
color: '#173c64'
}]
}]
})
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
I am trying to add padding in between my chart and plot area, as you can see in the screenshot below, the markers are overflowing across the borders of the plot area.
Is there a way for me to add padding to the bottom of the plot area, or a way to move up the chart series slightly so that it doesn't overflow?
Here is a fiddle: http://jsfiddle.net/H3Asy/5/
Here is the JS code:
$('#container').highcharts({
chart: {
type: 'areaspline',
marginLeft: 25,
plotBorderWidth: 2,
plotBackgroundColor: {
linearGradient: [0, 0, 0, 178],
stops: [
[0.5, 'rgb(255, 255, 255)'],
[1, 'rgb(221, 221, 221)']
]
},
events: {
load: function(){
this.plotBackground.attr({ rx: 15, ry: 15 });
this.plotBorder.attr({ rx: 15, ry: 15 });
}
}
},
legend: {
enabled: false
},
credits: {
enabled: false
},
exporting: {
enabled: false
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
categories: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22],
lineWidth: 0,
minorGridLineWidth: 0,
lineColor: 'transparent',
minorTickLength: 0,
tickLength: 0,
labels: {
rotation: -90,
align: 'right',
style: {
fontSize: '12px',
fontWeight: 'bold',
fontFamily: 'Sterling, sans-serif',
color: '#999'
},
x: 5,
y: 28
}
},
yAxis: {
title: {
text: ''
},
labels: {
formatter: function() {
if(this.isFirst) {
return this.value;
}
return bytesToSize(this.value, 0, true);
},
style: {
fontSize: '12px',
fontWeight: 'bold',
fontFamily: 'Sterling, sans-serif',
color: '#999'
},
align: 'center',
x: -16,
y: 12
},
gridLineColor: 'transparent'
},
tooltip: {
shared: true,
formatter: function() {
var tooltip = $('<div>');
var total = 0;
$.each(this.points, function(i, point){
total += this.y;
tooltip.append($('<div style="color: ' + point.series.area.fill + ';">').html(point.series.name + ': ' + bytesToSize(this.y,2)));
if(!(i % 2)){
tooltip.append('<br />');
}
});
tooltip.prepend($('<div style="color: #999;">').html('Total: ' + bytesToSize(total,2) + '<br />'));
return tooltip.get(0).outerHTML;
}
},
plotOptions: {
areaspline: {
lineWidth: 1.3,
marker: {
states: {
hover: {
radius: 5
}
}
},
states: {
hover: {
lineWidth: 1.3
}
}
}
},
series: [{
name: 'Download',
fillColor: 'rgba(0, 140, 194, 0.3)',
lineColor: '#008cc2',
data: [0,4815834355,23055591595,0,0,15404821463,0,20217522975,5521887522,0,0,1371666239,2134496,0,2948406184,12384283037,8231543133,9268703354,11368292543,1747717890,4540649201,4705338812]
}, {
name: 'Upload',
fillColor: 'rgba(117, 0, 198, 0.4)',
lineColor: '#7500c6',
marker: {
enabled: false,
states: {
hover: {
enabled: false
}
}
},
data: [0,201112067,1160271286,0,0,748962337,0,2289905587,211355292,0,0,64669389,559747,0,368939264,954704437,385646325,453112460,251406236,131414580,312915384,153890742]
}]
});
There is no perfect solution for that, but only two workarounds:
set min and startOnTick for xAxis, demo: http://jsfiddle.net/H3Asy/6/
yAxis: {
min: -1024 * 1024 * 1024,
startOnTick: false,
}
set threshold for series and startOnTick for xAxis, demo: http://jsfiddle.net/H3Asy/7/
yAxis: {
startOnTick: false
},
plotOptions: {
areaspline: {
threshold: -1
}
}