Flot line chart issue - javascript

I need to create a line chart like in the image:
What I have achieved till now is
var line_opt = {
series: {
lines: { show: true },
points: { show: true }
},
grid: {
hoverable: true,
clickable: true
},
yaxis: {
min: 0,
max: 6,
autoscaleMargin: .5,
labelWidth: -15,
tickLength: 0,
tickFormatter: function suffixFormatter(val, axis) {
return (val.toFixed(0));
}
},
xaxis: {
tickSize: 1
}
};
var lineData = [
[1, 5], [2, 4], [3, 4], [4, 4], [5, 3], [6, 4], [7, 4], [8, 3], [9, 4], [10, 3],
[11, 3], [12, 4], [13, 4], [14, 3], [15, 3], [16, 3], [17, 3], [18, 3], [19, 4], [20, 3],
[21, 3], [22, 3], [23, 3], [24, 2], [25, 2], [26, 3], [27, 2], [28, 2], [29, 2]
];
Is there any way that the X axis lines start from the bottom of the chart and end where the point is (like in the first image) and also hide the x axis labels without the lines?

This can be achieved with different options (removing the gridlines) and using markings to fake the gridline only up to the chart:
Code (see this fiddle for the working demo):
var line_opt = {
series: {
lines: {
show: true
},
points: {
show: false
}
},
grid: {
backgroundColor: { colors: ["#fff", "#ddd"] },
hoverable: true,
clickable: true,
borderWidth: 0,
markings: []
},
yaxis: {
min: 0,
max: 6,
autoscaleMargin: .5,
//labelWidth: -15,
tickLength: 0,
tickFormatter: function suffixFormatter(val, axis) {
return (val.toFixed(0));
}
},
xaxis: {
ticks: false,
autoscaleMargin: .01,
tickSize: 1,
tickLength: 0 // only needed if ticks is not false
}
};
var lineData = [ ... ];
for (var i=0; i < lineData.length; i++){
line_opt.grid.markings.push({
xaxis: { from: lineData[i][0], to: lineData[i][0] },
yaxis: { from: 0, to: lineData[i][1] },
lineWidth: 1,
color: "#aaaaaa"
});
}

Reading the API documentation, it should be possible.
For the lines ending where the point is, use the grid options, the aboveData:
grid: {
show: boolean
aboveData: boolean
color: color
backgroundColor: color/gradient or null
labelMargin: number
axisMargin: number
markings: array of markings or (fn: axes -> array of markings)
borderWidth: number
borderColor: color or null
minBorderMargin: number or null
clickable: boolean
hoverable: boolean
autoHighlight: boolean
mouseActiveRadius: number
}
You shouldn't need an xaxis for anything at that point, you can just hide it:
xaxis, yaxis: {
show: null or true/false

Related

Highcharts Stacked column Chart in grouped format

I need to design the same below image chart example in Highchart.js which is built in excel. Can anyone please help me to develop this in highcharts.js only like the below image?
Image Preview
I already have implemented it in a similar way. But I need this in a different group of colors and combinations in the same chart. -
`https://jsfiddle.net/shwetapandey/rwmxoka5`
I suggest to add new series, with different xAxis, series.columnrange.xAxis. To styling you have options to adjust like xAxis.left and xAxis.top.
chart: {
type: 'columnrange',
},
xAxis: [{
width: '33%',
offset: 0,
}, {
left: '50%',
width: '33%',
offset: 0,
}],
plotOptions: {
xAxis: {
labels: {
enabled: true
}
},
columnrange: {
grouping: false,
dataLabels: {
enabled: true,
}
}
},
series: [{
name: 'Joe',
color: '#E5DDE3',
data: [
[-5, 5],
[-10, 10],
[-13, 13],
[-16, 16],
[-19, 19]
]
},
{
name: 'Jane',
color: '#BEA9BA',
data: [
[-3.5, 3.5],
[-6, 6],
[-7, 7],
[-9, 9],
[-12, 12]
]
},
{
color: '#A5879E',
name: 'John',
data: [
[-1.5, 1.5],
[-2, 2],
[-3, 3],
[-4, 4],
[-5, 5]
]
},
{
name: 'Joe1',
color: '#FFA500',
xAxis: 1,
data: [
[-5, 5],
[-10, 10],
[-13, 13],
[-16, 16],
[-19, 19]
].reverse()
},
{
name: 'Jane1',
color: '#FFA500',
xAxis: 1,
data: [
[-3.5, 3.5],
[-6, 6],
[-7, 7],
[-9, 9],
[-12, 12]
]
},
{
color: '#FFA500',
name: 'John1',
xAxis: 1,
data: [
[-1.5, 1.5],
[-2, 2],
[-3, 3],
[-4, 4],
[-5, 5]
]
}
]
Demo: https://jsfiddle.net/BlackLabel/cpjgvds9/
To control each series you need to write a custom legend control, for this you can use legend.labelFormatter, that give you callback function to format each of the series' labels.
EDIT ------
To control many group series I used callback function events.legendItemClick builded in series events. They give way to manage series at legend in that case I compare name of series and index of items to hide and show group of series with custom legend.
events: {
legendItemClick: function() {
let name = this.name.substring(this.name.length - 1, this.name.length);
let _i = this._i;
this.chart.series.forEach(function(p, i) {
console.log('p: ', p, 'i: ', i);
if (name === p.name.substring(p.name.length - 1, p.name.length) && _i !== p._i) {
(!p.visible) ? p.show(): p.hide()
}
})
}
}
Demo: https://jsfiddle.net/BlackLabel/v0kt5b14

Is it possible to load Highcharts options from a file?

In a project, I want to work with Highcharts, but instead of putting the options code directly on to the website I rather would like to see it in an extra file, e.g. charts.js. Is it possible?
What I have done so far:
I created the general chart and it works. I tried to put the options code as shown on Highcharts in a file called charts.js and include it into the header. But it doesn't work, shows an error #13.
The code I used was
function getPointCategoryName(point, dimension) {
var series = point.series,
isY = dimension === 'y',
axis = series[isY ? 'yAxis' : 'xAxis'];
return axis.categories[point[isY ? 'y' : 'x']];
}
Highcharts.chart('container', {
chart: {
type: 'heatmap',
marginTop: 40,
marginBottom: 80,
plotBorderWidth: 1
},
title: {
text: 'Sales per employee per weekday'
},
xAxis: {
categories: ['Alexander', 'Marie', 'Maximilian', 'Sophia', 'Lukas', 'Maria', 'Leon', 'Anna', 'Tim', 'Laura']
},
yAxis: {
categories: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
title: null,
reversed: true
},
accessibility: {
point: {
descriptionFormatter: function (point) {
var ix = point.index + 1,
xName = getPointCategoryName(point, 'x'),
yName = getPointCategoryName(point, 'y'),
val = point.value;
return ix + '. ' + xName + ' sales ' + yName + ', ' + val + '.';
}
}
},
colorAxis: {
min: 0,
minColor: '#FFFFFF',
maxColor: Highcharts.getOptions().colors[0]
},
legend: {
align: 'right',
layout: 'vertical',
margin: 0,
verticalAlign: 'top',
y: 25,
symbolHeight: 280
},
tooltip: {
formatter: function () {
return '<b>' + getPointCategoryName(this.point, 'x') + '</b> sold <br><b>' +
this.point.value + '</b> items on <br><b>' + getPointCategoryName(this.point, 'y') + '</b>';
}
},
series: [{
name: 'Sales per employee',
borderWidth: 1,
data: [[0, 0, 10], [0, 1, 19], [0, 2, 8], [0, 3, 24], [0, 4, 67], [1, 0, 92], [1, 1, 58], [1, 2, 78], [1, 3, 117], [1, 4, 48], [2, 0, 35], [2, 1, 15], [2, 2, 123], [2, 3, 64], [2, 4, 52], [3, 0, 72], [3, 1, 132], [3, 2, 114], [3, 3, 19], [3, 4, 16], [4, 0, 38], [4, 1, 5], [4, 2, 8], [4, 3, 117], [4, 4, 115], [5, 0, 88], [5, 1, 32], [5, 2, 12], [5, 3, 6], [5, 4, 120], [6, 0, 13], [6, 1, 44], [6, 2, 88], [6, 3, 98], [6, 4, 96], [7, 0, 31], [7, 1, 1], [7, 2, 82], [7, 3, 32], [7, 4, 30], [8, 0, 85], [8, 1, 97], [8, 2, 123], [8, 3, 64], [8, 4, 84], [9, 0, 47], [9, 1, 114], [9, 2, 31], [9, 3, 48], [9, 4, 91]],
dataLabels: {
enabled: true,
color: '#000000'
}
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
yAxis: {
labels: {
formatter: function () {
return this.value.charAt(0);
}
}
}
}
}]
}
});
Is there a way to put the code into a fail and let it work as it would if code, CDN and Co. are on one page? Or is there anything I do wrong?
Highcharts error #13 means that Highcharts is unable to find the HTML element to render the chart in. From your description it looks like your script is fired before DOM is fully loaded. As a solution put all your code from chart.js file into DOMContentLoaded event callback function:
window.addEventListener('DOMContentLoaded', (event) => {
// chart.js
});
Or just put your script before the closing </body>:
<html>
....
<body>
....
<script type="text/javascript" src="chart.js"></script>
</body>
</html>

Can't change xaxis in highcharts

I wan't to create a heatmap for different days and months, but i run into a problem that xAxis doesn't change when i add aditional element in array it can have only 10 elements but i need 12.
The same problem with yAxis that is only 5 elements, but i need to add 7 in total.
After adding another element to X or Y axis - nothing happening.
JSFiddle included - https://jsfiddle.net/nw6ux40e/
JS below.
var series = point.series,
isY = dimension === 'y',
axis = series[isY ? 'yAxis' : 'xAxis'];
return axis.categories[point[isY ? 'y' : 'x']];
}
Highcharts.chart('container', {
chart: {
type: 'heatmap',
marginTop: 40,
marginBottom: 80,
plotBorderWidth: 1
},
title: {
text: 'Sales per employee per weekday'
},
xAxis: {
categories: ['Alexander', 'Marie', 'Maximilian', 'Sophia', 'Lukas', 'Maria', 'Leon', 'Anna', 'Tim', 'Laura', 'Michi']
},
yAxis: {
categories: ['One', 'Two', 'Three', 'Four', 'Five', 'Six'],
title: null,
reversed: true
},
accessibility: {
point: {
descriptionFormatter: function (point) {
var ix = point.index + 1,
xName = getPointCategoryName(point, 'x'),
yName = getPointCategoryName(point, 'y'),
val = point.value;
return ix + '. ' + xName + ' sales ' + yName + ', ' + val + '.';
}
}
},
colorAxis: {
min: 0,
minColor: '#FFFFFF',
maxColor: Highcharts.getOptions().colors[0]
},
legend: {
align: 'right',
layout: 'vertical',
margin: 0,
verticalAlign: 'top',
y: 25,
symbolHeight: 280
},
tooltip: {
formatter: function () {
return '<b>' + getPointCategoryName(this.point, 'x') + '</b> sold <br><b>' +
this.point.value + '</b> items on <br><b>' + getPointCategoryName(this.point, 'y') + '</b>';
}
},
series: [{
name: 'Sales per employee',
borderWidth: 1,
data: [[0, 0, 10], [0, 1, 19], [0, 2, 8], [0, 3, 24], [0, 4, 67], [1, 0, 92], [1, 1, 58], [1, 2, 78], [1, 3, 117], [1, 4, 48], [2, 0, 35], [2, 1, 15], [2, 2, 123], [2, 3, 64], [2, 4, 52], [3, 0, 72], [3, 1, 132], [3, 2, 114], [3, 3, 19], [3, 4, 16], [4, 0, 38], [4, 1, 5], [4, 2, 8], [4, 3, 117], [4, 4, 115], [5, 0, 88], [5, 1, 32], [5, 2, 12], [5, 3, 6], [5, 4, 120], [6, 0, 13], [6, 1, 44], [6, 2, 88], [6, 3, 98], [6, 4, 96], [7, 0, 31], [7, 1, 1], [7, 2, 82], [7, 3, 32], [7, 4, 30], [8, 0, 85], [8, 1, 97], [8, 2, 123], [8, 3, 64], [8, 4, 84], [9, 0, 47], [9, 1, 114], [9, 2, 31], [9, 3, 48], [9, 4, 91]],
dataLabels: {
enabled: true,
color: '#000000'
}
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
yAxis: {
labels: {
formatter: function () {
return this.value.charAt(0);
}
}
}
}
}]
}
}); ```
If you want to use categories you will need to add the new values to the category array.
Next, you will need to add wanted points. Notice that array looks like this: [x, y, value], so if you want to increase the yAxis labels you will need to add an additional point for each category.
Demo: https://jsfiddle.net/BlackLabel/8pts76bn/
Data example:
[0, 0, 10],
[0, 1, 19],
[0, 2, 8],
[0, 3, 24],
[0, 4, 67],
[0, 5, 67],
API: https://api.highcharts.com/highcharts/series.heatmap.data

How to insert values in bars (flotcharts)

I have some problems to show some values in bars. I want a chart like this: Example. I don't know what I'm missing in here.
$('#myModalChart').on('shown.bs.modal', function (e) {
var data = [{
label: "Foo",
data: [
[2],
[3, 9, 12],
[6, 0, 3],
[9, 11, 12],
[12, 0, 1],
[15, 0, 2],
[18],
[3, 12, 12],
[9, 12, 12]
]
},
{
label: "Bar",
data: [
[2],
[3, 0, 5],
[6, 3, 7],
[9, 4, 11],
[12, 1, 3],
[15, 2, 5],
[18]
]
},
{
label: "Tree",
data: [
[2],
[3, 5, 9],
[6, 7, 15],
[9, 0, 4],
[12, 3, 13],
[15, 5, 17],
[15, 17, 17],
[12, 13, 13],
[6, 15, 15],
[18]
]
},];
var options = {
series: {
bars: {
show: true,
barWidth: 1
}
},
xaxis: {
align: "center",
ticks: [
[3.5, 'text1'],
[6.5, 'text2'],
[9.5, 'text3'],
[12.5, 'text4'],
[15.5, 'text5']
]
}
};
var plot = $.plot("#chart2", data, options)
});
I want a chart like this, with labels in it. And I wish have in all of them.
What I'm missing?
You have to create and place the data value labels yourself. How to do this can be seen in this answer.
I created a fiddle adjusting it to your code. Only the first data series (foo) has labels for now. you will have to adjust the position. The relevant code:
$.each(plot.getData()[0].data, function (i, el) {
if (el.length > 1) {
var o = plot.pointOffset({
x: el[0],
y: el[1]
});
$('<div class="data-point-label">' + el[1] + '</div>').css({
position: 'absolute',
left: o.left + 4,
top: o.top,
'text-align': 'center',
display: 'none'
}).appendTo(plot.getPlaceholder()).fadeIn('slow');
}
});
But you may also have to cleanup your data. You have multiple data points with the same x values (which means bars behind / in front of each other which leads to some being invisible). Take a look at the side-by-side and stack plugins on the flot plugin page.

Line chart not drawn to scale

Is there any way that this chart is not drawn to scale?
http://forum.highcharts.com/resources/image/4227
I need every point occupies a separate row and evenly.
That is, in this graph, it should appear one line for each of the first 2 points of each series and the vertical distance between each should be the same as the distance between the lines below.
The series are dynamically loaded and the number of points each serie is variable.
http://jsfiddle.net/fpanci/yL6mw/
$(function () {
$(document).ready(function() {
$("#container").highcharts({
chart: {
inverted: true,
spacingLeft: 0,
spacingRight: 0
},
title: {
text: ' ',
x: -20 //center
},
xAxis: {
minorGridLineColor: '#000000',
minorGridLineWidth: 1,
minorTickLength: 0,
minorTickInterval: 1,
tickInterval: 1,
labels: { enabled: true },
maxPadding: 0.05,
min: 0
},
yAxis: {
title: { text: ' ' },
plotLines: [{
value: 0,
width: 1,
color: '#C0C0C0'
}],
labels: { enabled: true },
minorGridLineWidth: 1,
minorTickLength: 0,
minorTickInterval: 20,
tickInterval: 20,
min: 0,
max: 100
},
exporting: { enabled: false },
tooltip: { enabled: false },
legend: { enabled: false },
series: [{
color: '#0000FF',
connectNulls: true,
data: [[0.2, 24.25], [0.5, 30.61], [1, 43.61], [2, 34.51], [3, 32.39], [4, 36.47], [5, 36.4], [6, null], [7, 24.68], [8, 37.79]]
},{
color: '#980000',
dashStyle: 'shortdot',
connectNulls: true,
data: [[0.2, 38], [0.5, 52], [1, 50], [2, null], [3, 32], [4, null], [5, 34], [6, null], [7, 25], [8, null]]
},{
color: '#38761D',
dashStyle: 'ShortDashDotDot',
connectNulls: true,
data: [[0.2, 20], [0.5, 27], [1, 35], [2, null], [3, 29], [4, null], [5, 30], [6, null], [7, 22], [8, null]]
}]
});
});
});
Thanks!
The data is plotting exactly where you've told it to.
Your first 2 x values in each data set are 0.2 and 0.5 - so that is where the points are plotted.
If you don't want them plotted that way, just remove the x values from the data, and they will plot in sequence.
Example:
http://jsfiddle.net/jlbriggs/yL6mw/1/
If you want to have the 0.2 and 0.5 as axis labels, but want them evenly spaced still, you'll need to use categories for your x axis.
Example:
http://jsfiddle.net/jlbriggs/yL6mw/2/

Categories