dataLabels position issue for area chart (Highcharts) - graph

Area chart with Highcharts
I Created area chart jsfiddle.click on the above link to find out my code for your reference.
How to display the values like an uploaded image.

This can be done by using the load event like this:
chart: {
type: 'area',
inverted: false,
events: {
load: function() {
let pointLabelPositions = []
let labelSeries = this.series[0]
let otherSeries = this.series[1]
for (var i = 0; i < labelSeries.data.length; i++) {
pointLabelPositions.push({
dataLabels: {
y: (otherSeries.data[i].plotY - labelSeries.data[i].plotY) / 2
}
})
}
labelSeries.update({
data: pointLabelPositions
})
}
}
},
$(function() {
$('#container').highcharts({
chart: {
type: 'area',
inverted: false,
events: {
load: function() {
let pointLabelPositions = []
let labelSeries = this.series[0]
let otherSeries = this.series[1]
for (var i = 0; i < labelSeries.data.length; i++) {
pointLabelPositions.push({
dataLabels: {
y: (otherSeries.data[i].plotY - labelSeries.data[i].plotY) / 2
}
})
}
labelSeries.update({
data: pointLabelPositions
})
}
}
},
title: {
text: 'Average fruit consumption during one week'
},
tooltip: {
enabled: false
},
subtitle: {
style: {
position: 'absolute',
right: '0px',
bottom: '40px'
}
},
legend: {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: -150,
y: 100,
floating: true,
borderWidth: 1,
backgroundColor: '#FFFFFF'
},
xAxis: {
categories: [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec'
]
},
yAxis: {
title: {
text: 'Number of units'
},
labels: {
formatter: function() {
return this.value;
}
},
min: 0
},
plotOptions: {
area: {
fillColor: {
pattern: {
path: {
d: 'M 0 0 L 10 10 M 9 -1 L 11 1 M -1 9 L 1 11',
strokeWidth: 0.8
},
width: 0.5,
height: 2,
opacity: 0.9,
}
}
}
},
series: [{
name: 'John',
data: [10.2, 11, 10.9, 10.1, 10, 10.3, 10.2, 11.1, 11, 10.5, 10.6, 10.9],
dataLabels: {
enabled: true,
formatter: function() {
var secondY = this.series.chart.series[1].yData[this.point.x],
firstY = this.y;
return firstY - secondY;
}
},
color: '#FFERE',
fillColor: {
pattern: {
color: '#77d4a1'
}
}
}, {
name: 'Jane',
data: [2.1, 2.2, 2, 2, 2.3, 2.4, 2.1, 2.3, 2.1, 2.4, 3.5, 3],
color: '#FFERE',
fillColor: {
pattern: {
color: 'hsl(0, 0%, 98%)'
}
}
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/pattern-fill.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
Working fiddle example: http://jsfiddle.net/7gvuA/22/

Related

Chart.js: grid lines only on dataset points

I created a simple chart:
const myChart = new Chart(document.getElementById('myChartChart').getContext('2d');, {
type: 'scatter',
data: {
datasets: [{
label: 'Dataset',
data: [{
x: -40,
y: 34,
}, {
x: -10,
y: 45,
}, {
x: 140,
y: 45,
}],
fill: true,
stepped: true,
}]
},
options: {
responsive: true,
scales: {
x: {
suggestedMin: -50,
suggestedMax: 150,
ticks: {
callback: function(value, index, values) {
return value + ' °C';
}
},
},
y: {
suggestedMin: 32,
suggestedMax: 46,
ticks: {
callback: function(value, index, values) {
return value + ' bar';
}
},
}
},
plugins: {
legend: {
display: false
}
}
}
});
Fiddle: https://jsfiddle.net/o6b97xL2
But I don't like to have static periodical grid lines and labels but only on my three data points.
With callbacks I only get the defined steps from the grid. How can I achieve something like this:
Image Link (You need at least 10 reputation to post images)
You can define afterBuildTicks callbacks on both axes. In there, you replace the axis ticks with your own ticks extracted from your data.
Please take a look at your amended code and see how it works.
const data = [
{ x: -40, y: 34 },
{ x: -10, y: 45 },
{ x: 140, y: 45 }
];
myChart = new Chart('myChartChart', {
type: 'scatter',
data: {
datasets: [{
label: 'Dataset',
data: data,
fill: true,
stepped: true,
}]
},
options: {
responsive: true,
scales: {
x: {
suggestedMin: -50,
suggestedMax: 150,
afterBuildTicks: axis => axis.ticks = data.map(v => ({ value: v.x })),
ticks: {
callback: v => v + ' °C'
}
},
y: {
suggestedMin: 32,
suggestedMax: 46,
afterBuildTicks: axis => axis.ticks = data.map(v => ({ value: v.y })),
ticks: {
callback: v => v + ' bar'
}
}
},
plugins: {
legend: {
display: false
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.2/chart.min.js"></script>
<canvas id="myChartChart"></canvas>

Stock chart timeline buttons and date field left align with chart

I need guide make my chart as shown in the attached screenshot.
I have been using HighCharts for this purpose, but couldn't find appropriate options or configurations to do so. Following is the screen shot of my required design:
I am also attaching the fiddle link to my current implementation that I used to achieve these design requirements.
My Fiddle
HTML:
<script src="https://code.jquery.com/jquery-3.1.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>
JavaScript:
Highcharts.stockChart('container', {
chart: {
spacingLeft: 200,
},
navigator: {
enabled: false
},
scrollbar: {
enabled: false
},
title : {
text : 'Activity'
},
rangeSelector: {
allButtonsEnabled: true,
buttons: [{
type: 'month',
count: 3,
text: 'Daily',
dataGrouping: {
forced: true,
units: [['day', [1]]]
}
}, {
type: 'year',
count: 1,
text: 'Weekly',
dataGrouping: {
forced: true,
units: [['week', [1]]]
}
}, {
type: 'all',
text: 'Monthly',
dataGrouping: {
forced: true,
units: [['month', [1]]]
}
}],
buttonTheme: {
width: 60
},
selected: 2
},
legend: {
enable: true,
align: 'left',
verticalAlign: 'top',
layout: 'vertical',
x: 0,
y: 100
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
month: '%e. %b',
year: '%b'
}
},
series: [{
name: 'Label 1',
color: "#00aade",
data: [[1501545600000, 5], [1504224000000,4], [1506816000000, 6],[1509494400000,5]]
},
{
name: 'Label 2',
color: "#8cc63e",
data: [[1501545600000, 1], [1504224000000,0], [1506816000000, 2],[1509494400000,0]]
}]
});
Kindly if some one can guide me in doing proper configurations or styling to achieve this.
Thanks.
This is the closest I could get
http://jsfiddle.net/0yax1bav/5/
Add spacing on the left:
chart: {
spacingLeft: 300,
},
Move legend to the left:
legend: {
enabled: true,
align: 'left',
verticalAlign: 'top',
layout: 'vertical',
x: -250,
y: 150
},
Move title to the left:
title : {
align: 'left',
x: -280,
text : 'Activity',
floating: true
},
Move range to the left:
rangeSelector: {
floating: true,
x: 0,
verticalAlign: 'middle',
buttonPosition: {
align: 'left',
y: 20,
x: -140
},
inputPosition: {
align: 'left',
y: 15,
x: -280
},
...
Disable exporting buttons:
exporting:{
buttons:{
contextButton: {
enabled: false
}
}
}
Highcharts.stockChart('container', {
chart: {
spacingLeft: 300,
},
legend: {
enabled: true,
align: 'left',
verticalAlign: 'top',
layout: 'vertical',
x: -250,
y: 150
},
navigator: {
enabled: false
},
scrollbar: {
enabled: false
},
exporting:{
buttons:{
contextButton: {
enabled: false
}
}
},
title : {
align: 'left',
x: -280,
text : 'Activity',
floating: true
},
rangeSelector: {
floating: true,
x: 0,
verticalAlign: 'middle',
buttonPosition: {
align: 'left',
y: 20,
x: -140
},
inputPosition: {
align: 'left',
y: 15,
x: -280
},
allButtonsEnabled: true,
buttons: [{
type: 'month',
count: 3,
text: 'Daily',
dataGrouping: {
forced: true,
units: [['day', [1]]]
}
}, {
type: 'year',
count: 1,
text: 'Weekly',
dataGrouping: {
forced: true,
units: [['week', [1]]]
}
}, {
type: 'all',
text: 'Monthly',
dataGrouping: {
forced: true,
units: [['month', [1]]]
}
}],
buttonTheme: {
width: 60
},
selected: 2
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
month: '%e. %b',
year: '%b'
}
},
series: [{
name: 'Label 1',
color: "#00aade",
data: [[1501545600000, 5], [1504224000000,4], [1506816000000, 6],[1509494400000,5]]
},
{
name: 'Label 2',
color: "#8cc63e",
data: [[1501545600000, 1], [1504224000000,0], [1506816000000, 2],[1509494400000,0]]
}]
});
I was able to get this far. Highcharts x,y coordinates are a bit challenging to use, but you needed to do a bit more styling on buttonPosition,inputPosition, and Title (see screenshot) to move them to the right side:
HTML:
<script src="https://code.jquery.com/jquery-3.1.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>
JavaScript:
Highcharts.stockChart('container', {
chart: {
marginLeft: 300,
},
navigator: {
enabled: false
},
scrollbar: {
enabled: false
},
title : {
text : 'Activity',
x: -280
},
rangeSelector: {
x: 0,
verticalAlign: 'middle',
buttonPosition: {
align: 'left',
y: 20,
x: -140
},
inputPosition: {
align: 'left',
y: 15,
x: -280
},
allButtonsEnabled: true,
buttons: [{
type: 'month',
count: 3,
text: 'Daily',
dataGrouping: {
forced: true,
units: [['day', [1]]]
}
}, {
type: 'year',
count: 1,
text: 'Weekly',
dataGrouping: {
forced: true,
units: [['week', [1]]]
}
}, {
type: 'all',
text: 'Monthly',
dataGrouping: {
forced: true,
units: [['month', [1]]]
}
}],
buttonTheme: {
width: 60
},
selected: 2
},
legend: {
width: 100,
align: 'left',
x: 0, // = marginLeft - default spacingLeft
y: -100,
itemWidth: 100,
borderWidth: 1
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
month: '%e. %b',
year: '%b'
}
},
series: [{
name: 'Label 1',
color: "#00aade",
data: [[1501545600000, 5], [1504224000000,4], [1506816000000, 6],[1509494400000,5]]
},
{
name: 'Label 2',
color: "#8cc63e",
data: [[1501545600000, 1], [1504224000000,0], [1506816000000, 2],[1509494400000,0]]
}]
});
The legend doesn't appear to be rendering - check to make sure that your data is in the proper format and also try playing around with x and y.

How to show multi data Labels on group column highcharts

I have the data that I want to display on column like this:
I tried this code but it isn't working. How can I do this?
HTML:
<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>
Javascript:
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Column chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'right',
x: -70,
verticalAlign: 'top',
y: 20,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
formatter: function() {
var allSeries = this.series.chart.series;
var totalAmount = 0;
for(var s in allSeries) { totalAmount += allSeries[s].points[this.point.x].Amount; }
return '<b>'+ this.x +'</b><br/>'+
this.series.name +': '+ this.y + ' (<b>$ ' + this.point.Amount +') <br/>'+
'Total: '+ this.point.stackTotal + ' (<b>$ ' + totalAmount +')';
}
},
plotOptions: {
column: {
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black, 0 0 3px black'
},
formatter: function() {
return this.point.Amount + '%'
},
}
}
},
series: [{
name: 'John',
data: [{y: 5, Amount: 100}, {y: 3, Amount: 60}, {y: 4, Amount: 80}]
}, {
name: 'Joe',
data: [{y: 3, Amount: 60}, {y: 4, Amount: 80}, {y: 4, Amount: 80}]
}]
});
});
Check out this Fiddle
dataLabels: {
enabled: true,
useHTML: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black, 0 0 3px black'
},
formatter: function() {
var pointHeight = this.point.shapeArgs.height + 20;
return '<div class="datalabel" style="position: relative; top: 0px">' + this.point.Amount + '%' + '</div><div class="datalabelInside" style="text-shadow:none;color:#000;position: absolute; top:' + pointHeight / 2 + 'px">' + this.y + '</div>';
}
}

How to achieve this graph with highcharts

How could I achieve the chart below as accurate as possible?
I'm trying to achieve the chart in the picture below with highcharts, the problem I have is that I can't achieve the gradients and the purple cut-line
this is what I have donde so far : jsFiddle
$(function () {
$('#container').highcharts({
chart: {
type: 'areaspline'
},
options: {
title: {
text: "Historical report"
},
heigth: 200
},
legend: {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: 150,
y: 100,
floating: true,
borderWidth: 1,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
},
xAxis: {
categories: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
plotBands: [
{
from: 4.5,
to: 6.5,
color: 'rgba(68, 170, 213, .2)'
}
]
},
yAxis: {
title: {
text: 'Fruit units'
}
},
tooltip: {
shared: true,
valueSuffix: ' units'
},
credits: {
enabled: false
},
plotOptions: {
areaspline: {
fillOpacity: 0.5
}
},
series: [
{
name: 'John',
data: [3, 9, null, 5, 4, 10, 12],
lineColor: "#5A66AF"
}, {
name: 'Jane',
data: [1, 10, null, 3, 3, 5, 4],
lineColor: '#47a06b'
}, {
name: 'Roberto',
data: [10, 15, null, 15, 9, 9, 4],
lineColor: '#2ba9db'
}
]
});
});
The line is achieved by the DashStyle property:
http://api.highcharts.com/highcharts#plotOptions.line.dashStyle
The gradient fill is a matter of defining the gradient stops in the fillColor property:
http://api.highcharts.com/highcharts#plotOptions.area.fillColor
http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-software/highcharts.com/tree/master/samples/highcharts/plotoptions/area-fillcolor-gradient/
(though, FWIW, that extreme white end to the gradient is reeeeally distracting...)

highcharts solid gauge: bigger tick marks

I am making a solid gauge with highcharts. I am trying to make the ticks long enough to span both data series. The goal is for a white line to cut through the colored bands at 10, 6, 2.9, and 0%. Notice how at 2.9%, the tick doesn't go all the way through (even though the length is set to 100).
I have tried yAxis.tickLength to make the ticks longer, to no avail. I also tried yAxis.tickPosition: 'inside'. That doesn't solve it either. Here is my JSFiddle.
http://jsfiddle.net/ncernek/wy6bo63p/2/
Thank you for your help.
If you add dummy second pane and yAxis, then ticks will be both inside and outside - because in fact there will be 2 ticks looking like one.
Example: http://jsfiddle.net/Lcz6juea/
And if I get wrong index of ticks (over series) then you could use this code without zIndex set for axes: http://jsfiddle.net/Lcz6juea/1/
$(function() {
// Uncomment to style it like Apple Watch
/*
if (!Highcharts.theme) {
Highcharts.setOptions({
chart: {
backgroundColor: 'black'
},
colors: ['#F62366', '#9DFF02', '#0CCDD6'],
title: {
style: {
color: 'silver'
}
},
tooltip: {
style: {
color: 'silver'
}
}
});
}
// */
Highcharts.setOptions({
chart: {
backgroundColor: 'white'
},
colors: ['#FE670A', '#0277a0', 'white']
});
Highcharts.chart('container', {
chart: {
type: 'solidgauge',
marginTop: 50
},
title: {
text: 'Discepant Reads',
style: {
fontSize: '24px'
}
},
tooltip: {
borderWidth: 0,
backgroundColor: 'none',
shadow: false,
style: {
fontSize: '16px'
},
pointFormat: '{series.name}<br><span style="font-size:2em; color: {point.color}; font-weight: bold; text-align: center">{point.y}%</span>',
positioner: function(labelWidth, labelHeight) {
return {
x: 200 - labelWidth / 2,
y: 180
};
}
},
pane: [{
startAngle: -140,
endAngle: 140,
background: [{ // Track for Move
outerRadius: '112%',
innerRadius: '88%',
backgroundColor: Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0.3).get(),
borderWidth: 0,
shape: 'arc'
}, { // Track for Exercise
outerRadius: '87%',
innerRadius: '63%',
backgroundColor: Highcharts.Color(Highcharts.getOptions().colors[1]).setOpacity(0.3).get(),
borderWidth: 0,
shape: 'arc'
}, { // Track for Stand
outerRadius: '62%',
innerRadius: '38%',
backgroundColor: Highcharts.Color(Highcharts.getOptions().colors[2]).setOpacity(0.3).get(),
borderWidth: 0,
shape: 'arc'
}]
}, {
startAngle: -140,
endAngle: 140,
size: '95%',
background: []
}],
yAxis: [{
reversed: true,
min: 0,
max: 10,
lineWidth: 0,
tickLength: 100,
tickWidth: 4,
tickColor: 'white',
tickPosition: 'outside',
minorTickLength: 0,
tickPositions: [0, 2.9, 6, 10],
zIndex: 4,
labels: {
distance: 30,
enabled: true,
x: 0,
y: 0,
format: '{value} %',
style: {
fontSize: 16
}
}
}, {
pane: 1,
linkedTo: 0,
reversed: true,
min: 0,
max: 10,
lineWidth: 0,
tickLength: 100,
tickWidth: 4,
tickColor: 'white',
tickPosition: 'inside',
minorTickLength: 0,
tickPositions: [0, 2.9, 6, 10],
zIndex: 4,
labels: {
enabled: false
}
}],
plotOptions: {
solidgauge: {
borderWidth: '34px',
dataLabels: {
enabled: false
},
linecap: 'round',
stickyTracking: false
}
},
series: [{
name: 'Your Score',
borderColor: Highcharts.getOptions().colors[0],
data: [{
color: Highcharts.getOptions().colors[0],
radius: '100%',
innerRadius: '100%',
y: 4
}],
dataLabels: {
borderRadius: 0,
backgroundColor: "#fff",
borderWidth: 0,
borderColor: "#FFF",
style: {
fontSize: "50px"
},
color: "grey",
crop: true,
formatter: function() {
var s;
s = '<span style="font-size: 50px;">' + this.point.y + '</span>';
return s;
},
y: -30,
zIndex: 90
}
}, {
name: 'Department Average',
borderColor: Highcharts.getOptions().colors[1],
data: [{
color: Highcharts.getOptions().colors[1],
radius: '75%',
innerRadius: '75%',
y: 6
}]
}, {
name: '',
borderColor: Highcharts.getOptions().colors[2],
data: [{
color: Highcharts.getOptions().colors[2],
radius: '50%',
innerRadius: '50%',
y: 50
}]
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/solid-gauge.js"></script>
<div id="container" style="width: 400px; height: 400px; margin: 0 auto">
</div>
Using JavaScript
Highcharts.wrap(Highcharts.Tick.prototype, 'getMarkPath', function (prev, x, y, tickLength, tickWidth, horiz, renderer) {
return renderer.rect(x, y, 2, 80, 0)
.attr({
'stroke-width': 2,
stroke: 'white',
zIndex: 4,
style: 'transform: rotateZ(45deg) translateY(-290px)'
}).add();
});
You'd have to figure out a way to override each tick, but it's doable.
--
Using CSS
The (almost) pure CSS way is to target the exact SVG path and apply a transform to it. By no means is this way ideal, but it does provide a way to get the job done.
.highcharts-axis path:nth-child(2) {
transform: scale3d(1.6, 1, 1) rotateY(-59.7deg) translate(0, 25px);
stroke-width: 2;
}
.highcharts-axis path:nth-child(3) {
transform: scale3d(3.9, 1, 1) rotateY(-70deg) translate(0, 56px);
stroke-width: 2;
}
You would also have to adjust the zIndex attribute of the yAxis so that the redrawn ticks are on top of the other paths:
yAxis: {
...
zIndex: 4
}

Resources