Flot Charts: bar + line, different colours and custom data parameters - javascript

The goal
What i need is one Flot chart that contains different coloured bars, with different coloured lines over the top.
Many questions answer how to achieve different coloured bars.
And many pages answer how to add bars AND lines.
But i want to combine these two solutions.
An added bonus would be to be able to add custom parameters to each bar / line (see the "testId" example below) - however this is not necessarily required, as a workaround I could create an object on page load that references each bar's position (e.g. the "ticks" array).
My current workaround
I can already achieve this using multiple data sets as seen in this jFiddle, which i have constructed based off this answer's jFiddle, however this requires multiple different data sets per colour variant of each bar / line like so:
var dataBarsRed = {
data: [
[0, 1],
[2, 1.9],
],
color: 'red'
};
var dataBarsOrange = {
data: [
[1, 2],
[3, 3.9],
],
color: 'orange'
};
var dataBarsGreen = {
data: [
[4, 4],
[5, 4.5]
],
color: 'green'
};
var dataLineRed = {
data: [
[0, 2, 2],
[1, 2, 2],
[2, 2, 2],
[3, 2, 2],
[4, 2, 2],
[5, 2, 2],
],
label: '60% efficiency',
color: 'red',
bars: {
barWidth: 1
}
};
var dataLineOrange = {
data: [
[0, 4, 4],
[1, 4, 4],
[2, 4, 4],
[3, 4, 4],
[4, 4, 4],
[5, 4, 4],
],
label: '85% efficency',
color: 'orange',
bars: {
barWidth: 1
}
};
And add them like so:
$.plot("#placeholder", [dataBarsRed, dataBarsOrange, dataBarsGreen, dataLineRed, dataLineOrange],...
From what i can tell, there is no way to add any custom data parameters to this data structure, in which each item has it's own set of custom variables (e.g. object id's to link to the back-end, like "testId" - see "The Rationale").
The rationale
Is there a way to achieve what i need using the same structure for the bar data as the first link:
var data = [
{ data: [[0,1]], color: "red", testId: 30 },
{ data: [[1,2]], color: "yellow", testId: 31 },
{ data: [[2,3]], color: "green", testId: 32 }
];
The reason i'd like to do it this way is that it would be much simpler to build the Flot Data Object on the Java side (return it as JSON from ajax) but also it has the added benefit of adding your own parameters to each bar / line (e.g. "testId" shown above. The id's themselves would be utilised to retrieve more data via ajax on click or hover of the bar.
For Example:
$(container).bind('plothover', function(event, position, item){
console.log(item.series.testId)
});
Final thoughts
I feel like i'm going round in circles with this. I love the Flot charts plugin and it's flexibility, but there are numerous ways to implement the same visual outcome.
Thanks.
- Steve.

The Solution
See this jFiddle for the complete code.
After considering what Raidri is saying regarding it's simplicity, I've taken another stab at it and I've gotten something working as i need it to, with a bit more consistency. I feel a bit silly for not seeing this before (perhaps i did and a syntax error caused me to move on). Anyway, if anyone is interested here's the code:
NOTE: This does feel like a bodge or a hack - i'm not sure if this kind of data structure was ever intended, but it gets the job done for my purposes.
var data = [
{ data: [[0,1]], color: "red", testId: 30, isBar: true },
{ data: [[1,2]], color: "orange", testId: 31, isBar: true },
{ data: [[2,1.9]], color: "red", testId: 32, isBar: true },
{ data: [[3,3.9]], color: "orange", testId: 33, isBar: true },
{ data: [[4,4]], color: "green", testId: 34, isBar: true },
{ data: [[5,4.5]], color: "green", testId: 35, isBar: true },
{ data: [[0, 4, 4],[0.5, 4, 4],[1, 4, 4],[1.5, 4, 4],[2, 4, 4],[2.5, 4, 4],[3, 4, 4],[3.5, 4, 4],[4, 4, 4],[4.5, 4, 4],[5, 4, 4]], shadowSize: 0, color: 'orange', isLine: true, label: '85% efficiency' },
{ data: [[0, 2, 2],[0.5, 2, 2],[1, 2, 2],[1.5, 2, 2],[2, 2, 2],[2.5, 2, 2],[3, 2, 2],[3.5, 2, 2],[4, 2, 2],[4.5, 2, 2],[5, 2, 2]], shadowSize: 0, color: 'red', isLine: true, label: '60% efficiency' },
{ data: [[0, -1, -1]], shadowSize: 0, color: 'green', label: '100% efficiency', isLine: true }
];
var plot = $.plot("#placeholder", data, {
bars: {
show: true,
align: 'center',
barWidth: 0.5
},
lines: {
show: true,
lineWidth: 0.1,
fill: false
},
grid: {
hoverable: true,
autoHighlight: true
},
xaxis: {
ticks: [[0,'Steve'],[1,'Bob'],[2,'Chris'],[3,'Joe'],[4,'Dave'], [5, 'Jon']]
},
yaxis: {
min: 0,
max: 5
},
legend:{
container: '#legend'
}
});
There are some slight nuances, such as the number of line points (data elements per line) need to take into account the bar width. E.g. if my bar width was 1 i'd only need 5 elements, but since i have a width of 0.5 i need 10 line elements per data array (to fill in the gaps). Also, "shadowSize: 0" is required or you'd get a grey shadow in the middle of the line.
I've also added "isBar" and "isLine" to each element so my hover event can distinguish between them so it does not update the info box when the line is hovered. This is because the way I've done this is a bit of a "hack" in the sense that the line is not one line, but a line per column. Without this further distinction of type, hovering over the line would display the bar's name depending on your mouse's x-position.
I've also had to add a "fake" green line for the legend - position 0, referencing start and end positions that are outside the axis range (-1, in this example, 6 would also work). I realise i can probably create a custom legend...but it was simpler to just let flot deal with it itself.

You can simply combine your five data objects into one array of objects und you can also add your own properties to these objects, like this:
var data = [ {
data: [
[0, 1],
[2, 1.9],
],
color: 'red',
testId: 31
}, {
data: [
[1, 2],
[3, 3.9],
],
color: 'orange',
testId: 32
}, {
//...
}];
And using your own properties for example in the hover-event is as simple as
$('#details').html("<span class='detail'>...(testId = " + item.series.testId + ")</span>");
See the updated fiddle for the full example.
PS: For the lines in your chart, maybe markings are a better fit (see the documentation and this fiddle, where one of the lines is replaced by a marking).

Related

Pie of a Pie chart in HighCharts

I have a question regarding to Highcharts option for plotting a "pie-of-a-pie" chart. I need to show something similar to the one: https://www.amcharts.com/demos/pie-of-a-pie/?theme=material Can i do the same thing in Highcharts? If yes please do help.
If not possible in High Charts, can you please help in amcharts only?
Yes, you can achieve that result in Highcharts. You can use two pie series and update one of them in series.point.events.click funtion. For example:
series: [{
data: [{
y: 1,
details: [1, 3, 2]
}, {
y: 2,
details: [4, 31, 2]
}, {
y: 3,
details: [14, 3, 2]
}],
point: {
events: {
click: function() {
var series = this.series.chart.series;
series[1].setData(this.details.slice());
}
}
},
center: [200, 100],
size: 200
}, {
size: 100,
center: [500, 100],
data: []
}]
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/4996/
API Reference:
https://api.highcharts.com/highcharts/series.pie.size
https://api.highcharts.com/highcharts/series.pie.center
https://api.highcharts.com/highcharts/series.pie.point.events.click
https://api.highcharts.com/class-reference/Highcharts.Series#setData

How to remove the inside-border from doughnut chart? Chart.js

I want to remove the marked white line, is there any option to do that? If not, how can one achieve this without painting over canvas?
You can set borderWidth property to 0.
options: {
elements: {
arc: {
borderWidth: 0
}
}
}
jsfiddle
Update
If you just want to remove only one border then you can do this using following code
datasets: [{
data: [1, 2, 3, 4],
backgroundColor: ["#BDC3C7","#9B59B6","#E74C3C","#26B99A"],
borderWidth: [0, 1, 1, 0]
}]
jsfiddle

How to create highlight area under curve in high chart?

I create a high chart using angular 4 and I want to highlight a particular portion of Highchart.
Ex Image :https://www.screencast.com/t/MHxo59j2dM
As per above image if data point value goes below to some limit (like 0) then highlight with "Red" color and if it goes below 8 then highlight with Yellow
I'm not sure whether its possible with Highchart or not but if someone had created this kind of features then please let me know.
Highchart provides Area Chart option - https://www.highcharts.com/demo/area-negative but my chart is normal and I don't want to highlight all series point.
There's no such functionality in Highcharts, but you can mimic it by using polygon series and plot lines:
var chart = Highcharts.chart('container', {
plotOptions: {
polygon: {
showInLegend: false
}
},
yAxis: {
tickInterval: 1,
plotLines: [{
value: 4,
color: 'orange',
width: 2
}, {
value: 3,
color: 'red',
width: 2
}]
},
series: [{
data: [6, 4, 3, 1, 2, 3, 4, 7]
}, {
type: 'polygon',
data: [[1,4], [2, 4], [2,3]],
color: 'orange'
}, {
type: 'polygon',
data: [[5,4], [6, 4], [5,3]],
color: 'orange'
}, {
type: 'polygon',
data: [[2,3], [5, 3], [4,2], [3,1], [2,3]],
color: 'red'
}]
});
Live working example: http://jsfiddle.net/kkulig/fbomb7cf/
It will require some programming to make the process of creating these areas automatic (in my fiddle everything is hard-coded).
To achieve similar styling you can try patter fill Highcharts plugin: https://www.highcharts.com/blog/extension/pattern-fill/
API references:
http://api.highcharts.com/highcharts/series.polygon
http://api.highcharts.com/highcharts/yAxis.plotLines

How to build Scada Alerts using HighCharts

Hey I need to convert zamel code to JavaScript Code. One of the controllers of zamel, allows monitoring of Scada alerts. I have the following controller:
The way this controller works:
we have 20 alerts on board, each alert has 3 states:
Ok State - color with green.
Alert state - color with yellow.
Danger state - color with red.
I need to build a controller using Highcharts API, The controller need to deal with real time data(update on live). The controller need to be responsive and collapsible.
Can I achieve this goals using HighCharts API , If so how.
I would be glad for any initial help in build this controller.
I think that in your case the best idea will be to use simple heatmap chart. It will give you a possibility of changing the data, resizing the chart, using tooltip etc.
Here you can find code that may help you:
$('#container').highcharts({
chart: {
type: 'heatmap',
marginTop: 40,
marginBottom: 80,
},
xAxis: {
visible: false
},
yAxis: {
visible: false
},
title: {
text: 'Example'
},
colorAxis: {
stops: [
[0, 'green'],
[0.5, 'green'],
[0.49, 'yellow'],
[0.9, 'yellow'],
[0.9, 'red']
],
min: 0,
max: 1
},
legend: {
enabled: false
},
series: [{
borderWidth: 10,
borderColor: 'white',
keys: ['x', 'y', 'value', 'name'],
data: [
[0, 0, 1, 'name1'],
[0, 1, 0, 'name2'],
[0, 2, 0.5, 'name3'],
[0, 3, 0.5, 'name4'],
[0, 4, 0, 'name5'],
[1, 0, 1, 'name6'],
[1, 1, 0, 'name7'],
[1, 2, 1, 'name8'],
[1, 3, 0, 'name9'],
[1, 4, 0, 'name10']
],
dataLabels: {
enabled: true,
color: '#000000',
formatter: function() {
return (this.key)
}
}
}]
});
I have used 3 values: 0 for 'ok', 0.5 for 'alert' and 1 for 'danger'.
Here you can see an example how it can work: http://jsfiddle.net/d7zt64v4/1/

Can we draw a Line Chart with both solid and dotted line in it?

In real time analytics, you might want to state explicitly, that the present day has not been over yet and the data for the day is incomplete.
So, you might want to draw the line that joins the last and the penultimate point with a dotted stroke.
This is how Mixpanel does it.
Can this be done using the Chart JS v2 pre-alpha?
Yes, but you have to work around a couple of glitches
Warning: Sub-optimal example to work around glitches
var lineChartData = {
labels: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
datasets: [{
label: "My First dataset",
data: [1, 8, 3, 4, 2, 3, 4],
borderColor: '#66f',
borderDash: [20, 30]
},{
label: "My First dataset",
data: [1, 8, 3, 4, 2, , ],
borderColor: '#66f',
}]
};
var ctx = document.getElementById("chart").getContext("2d");
var myChart = new Chart(ctx, {
type: "line",
data: lineChartData,
options: {
elements: {
line: {
fill: false
}
}
}
});
Notice that the first dataset doesn't have the values set to blank and that 2nd dataset has one extra value than required - these effectively work around a couple of glitches (including https://github.com/nnnick/Chart.js/issues/1284)
Fiddle - https://jsfiddle.net/uwb8357r/

Categories