color polyline based geojson property in leaflet - if-statement

I am trying to style (color) my leaflet polyline (geojson object showing a trail) based on some conditions. The condition is the average speed, which is calculated from a timestamp that comes with the geojson. Thanks to this forum, I managed to show the line as expected. But the styling does not work.
The average speed of the example data ist 1.3 km/h, thus the line should be red. But it is blue.
Maybe that is because the polyline is created before the velocitiy was calculated.
But adding that code line later does not work because the calculation of the distance depends on that polyline. Or what ist my mistake?
Any hints how to get that styling right?
Thanks in advance.
Here is a simplified code;
<html>
<head>
<!-- Load leaflet library and use its styling css -->
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"> </script>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script type="text/javascript" src="js/measuredDistance.js"></script>
<link rel="stylesheet" href="style.css" type="text/css" /> //not included
</head>
<body>
<div class="pagewrapper">
<div id="map"></div>
<button onclick="myFunction()">Click me</button>
</div>
<script type="text/javascript">
//add map and set view
var map = L.map('map').setView([48.8,13.03],6);
// add background layer "opentopomap"
var backgroundlayer = L.tileLayer ('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png');
map.addLayer(backgroundlayer);
//get geojson data
var geojsondata = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 1,
"geometry": {
"type": "Point",
"coordinates": [
13.0908549980086,
47.812500986468
]
},
"properties": {
"Source": 2,
"ele": 399.0844,
"time": 1174816297000,
"ObjectId": 2
}
},
{
"type": "Feature",
"id": 2,
"geometry": {
"type": "Point",
"coordinates": [
13.0408219980085,
47.812484986468
]
},
"properties": {
"Source": 2,
"ele": 397.1617,
"time": 1174826310000,
"ObjectId": 2
}
}]};
function myFunction() {
visualizer.sendDataToMap(geojsondata)
};
//---------------------------------------------
//styling function for polyline, depending on velocitiy of track
function restylemap(feature) {
if(velocitiy <= 4) {
return{color: "red"}
}
else if (velocitiy > 4 && velocitiy <= 20) {return
{color:"green"}
}
else {return {color:"grey"}}
};
// function to calculate total time of track
function sum(array) {
return Number(array[array.length - 1] - Number(array[0]));
};
//----------------------------------------------------
var visualizer = {};
visualizer.sendDataToMap = function (jsonData) {{
L.geoJson(jsonData
)};
// read coordinates from geojson object
const latlngs = jsonData.features.map((feature) => [
feature.geometry.coordinates[1],
feature.geometry.coordinates[0]
]);
//access time information from geojson object
const time = jsonData.features.map((feature) => [
feature.properties.time
]);
//create polyline from coordinates and style according to function "restylemap"
var linie = L.polyline(latlngs, {style:restylemap});
//calculate total distance of polyline
var lengthInMeters = linie.measuredDistance();
//remove non numeric chars ("km") from string
var distance = lengthInMeters.replace(/[^\d.-]/g, '');
//calculate time between first and last timestamp
var elapstime = (sum(time) / 1000 / 60 / 60);
//Calculate average speed on track
var velocitiy = distance/elapstime
//add polyline to map
linie.addTo(map);
// center map to polyline
map.fitBounds(linie.getBounds());
//avespeed.toFixed(1)
alert("Velocitiy: "+velocitiy.toFixed(1)+" km/h");
};
</script>
</body>
</html>

Like you said, you add the style to early. Change your code to:
//styling function for polyline, depending on velocitiy of track
function restylemap(velocitiy) { // <-------- NEW
if(velocitiy <= 4) {
return{color: "red"}
}
else if (velocitiy > 4 && velocitiy <= 20) {return
{color:"green"}
}
else {return {color:"grey"}}
};
//create polyline from coordinates and style according to function "restylemap"
var linie = L.polyline(latlngs); // <-------- NEW
//calculate total distance of polyline
var lengthInMeters = linie.measuredDistance();
//remove non numeric chars ("km") from string
var distance = lengthInMeters.replace(/[^\d.-]/g, '');
//calculate time between first and last timestamp
var elapstime = (sum(time) / 1000 / 60 / 60);
//Calculate average speed on track
var velocitiy = distance/elapstime
// Change line color
linie.setStyle(restylemap(velocitiy)); // <-------- NEW
//add polyline to map
linie.addTo(map);

Related

Amcharts 4: On hover bar in ColumnSeries change color

I have a ColumnSeries chart that looks like this:
When I hover a bar I want it to change color to #ffe876.
I have tried to add a hoverState but it doesnt work:
// Create a hover state
var hoverState = valueAxis.columns.template.states.create("hover");
hoverState.properties.fill = am4core.color("#ffe876");
This is my code:
<script>
am4core.ready(function() {
var chart = am4core.create("chartdiv_visits_per_week", am4charts.XYChart);
chart.data = [
{
"x": "31",
"value": 1
},
{
"x": "32",
"value": 2
},
{
"x": "33",
"value": 2
}
];
// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "x";
categoryAxis.renderer.grid.template.disabled = true;
categoryAxis.renderer.labels.template.disabled = true;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.grid.template.disabled = true;
valueAxis.renderer.labels.template.disabled = true;
// Create series
var series1 = chart.series.push(new am4charts.ColumnSeries);
series1.dataFields.valueY = "value";
series1.dataFields.categoryX = "x";
series1.name = "Human unique";
series1.tooltipText = "Human unique week {categoryX}: {valueY}";
series1.fill = am4core.color("#f2a654");
series1.stroke = am4core.color("#f4b570");
series1.strokeWidth = 0;
// Tooltips
chart.cursor = new am4charts.XYCursor();
chart.cursor.snapToSeries = series;
chart.cursor.xAxis = valueAxis;
}); // end am4core.ready()
</script>
<div id="chartdiv_visits_per_week" style="height: 100px;"></div>
What can I do to make the bar change color when I hover it?
You need to add the state to the series, not the axis.
var hoverState = series1.columns.template.states.create("hover");
hoverState.properties.fill = am4core.color("#ffe876");
Demo below:
var chart = am4core.create("chartdiv_visits_per_week", am4charts.XYChart);
chart.data = [
{
"x": "31",
"value": 1
},
{
"x": "32",
"value": 2
},
{
"x": "33",
"value": 2
}
];
// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "x";
categoryAxis.renderer.grid.template.disabled = true;
categoryAxis.renderer.labels.template.disabled = true;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.grid.template.disabled = true;
valueAxis.renderer.labels.template.disabled = true;
// Create series
var series1 = chart.series.push(new am4charts.ColumnSeries);
series1.dataFields.valueY = "value";
series1.dataFields.categoryX = "x";
series1.name = "Human unique";
series1.tooltipText = "Human unique week {categoryX}: {valueY}";
series1.fill = am4core.color("#f2a654");
series1.stroke = am4core.color("#f4b570");
series1.strokeWidth = 0;
// Create a hover state
var hoverState = series1.columns.template.states.create("hover");
hoverState.properties.fill = am4core.color("#ffe876");
// Tooltips
chart.cursor = new am4charts.XYCursor();
chart.cursor.snapToSeries = series1;
chart.cursor.xAxis = valueAxis;
<script src="//cdn.amcharts.com/lib/4/core.js"></script>
<script src="//cdn.amcharts.com/lib/4/charts.js"></script>
<script src="//cdn.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv_visits_per_week" style="height: 100px;"></div>

Am charts 4 LineSeries legend colors doesn't match graph colors

I have created a series chart using AmCharts version 4.
I have a red line that represents created cases and green line that represent closed cases. However my legend is blue for both lines. How can I get the legend color to fit the graph color?
I added color in the data section.
My code is here:
<script>
am4core.ready(function() {
var chart = am4core.create("chartdiv_cases_created_per_day", am4charts.XYChart);
chart.data = [
{
"x": "Mon 1",
"created_value": 1,
"created_color": am4core.color("red"),
"closed_value": 2,
"closed_color": am4core.color("green")
},
{
"x": "Tue 2",
"created_value": 4,
"created_color": am4core.color("red"),
"closed_value": 2,
"closed_color": am4core.color("green")
},
{
"x": "Wed 3",
"created_value": 3,
"created_color": am4core.color("red"),
"closed_value": 1,
"closed_color": am4core.color("green")
}
];
// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "x";
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
// Create series
var series1 = chart.series.push(new am4charts.LineSeries());
series1.dataFields.valueY = "created_value";
series1.dataFields.categoryX = "x";
series1.name = "Opprettet";
series1.propertyFields.stroke = "created_color";
series1.propertyFields.fill = "created_color";
series1.strokeWidth = 1;
series1.tooltipText = "Opprettet: {valueY}";
// Create series 2
var series2 = chart.series.push(new am4charts.LineSeries());
series2.dataFields.valueY = "closed_value";
series2.dataFields.categoryX = "x";
series2.name = "Lukket";
series2.propertyFields.stroke = "closed_color";
series2.propertyFields.fill = "closed_color";
series2.tooltipText = "Lukket: {valueY}";
// Legend
chart.legend = new am4charts.Legend();
chart.legend.labels.template.text = "[bold {color}]{name}[/]";
// Tooltips
chart.cursor = new am4charts.XYCursor();
chart.cursor.snapToSeries = series;
chart.cursor.xAxis = valueAxis;
}); // end am4core.ready()
</script>
<div id="chartdiv_cases_created_per_day" style="height: 300px;"></div>
Seems like you're combining data and js-objects. That might be what you want but I would perhaps suggest that you separate them, as it would make it easier that day you need to add data from server.
There is no need to include the color for each point. Most likely you want the same color for all the points in the same series.
That you can achieve like this:
series.stroke = am4core.color(color);
series.fill = am4core.color(color);
You have already named the series in the data as created_value and closed_value so we can easily make a function that adds the data, names the series' and colorize them :)
In which turn you just call
createSeries("created_value", "Created", "red");
createSeries("closed_value", "Closed", "green");
Full code (I'm sure there's more refactoring you could do):
am4core.useTheme(am4themes_animated); // Not needed, but looks cool ;)
// Create chart instance
var chart = am4core.create("chartdiv_cases_created_per_day", am4charts.XYChart);
// Add data
chart.data = [{
"date": new Date(2018, 0, 1),
"created_value": 362,
"closed_value": 699
}, {
"date": new Date(2018, 0, 2),
"created_value": 269,
"closed_value": 450
}, {
"date": new Date(2018, 0, 3),
"created_value": 700,
"closed_value": 358
}, {
"date": new Date(2018, 0, 4),
"created_value": 490,
"closed_value": 367
}, {
"date": new Date(2018, 0, 5),
"created_value": 500,
"closed_value": 485
}, {
"date": new Date(2018, 0, 6),
"created_value": 550,
"closed_value": 354
}, {
"date": new Date(2018, 0, 7),
"created_value": 420,
"closed_value": 350,
}];
// Create axes
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.grid.template.location = 0;
dateAxis.renderer.minGridDistance = 30;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
// Create series
function createSeries(field, name, color) {
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.valueY = field;
series.dataFields.dateX = "date";
series.name = name;
series.tooltipText = "{dateX}: [b]{valueY}[/]";
series.strokeWidth = 2;
series.stroke = am4core.color(color);
series.fill = am4core.color(color);
// Set up tooltip
series.adapter.add("tooltipText", function(ev) {
var text = "[bold]{dateX}[/]\n"
chart.series.each(function(item) {
text += "[" + item.stroke.hex + "]●[/] " + item.name + ": {" + item.dataFields.valueY + "}\n";
});
return text;
});
series.tooltip.getFillFromObject = false;
series.tooltip.background.fill = am4core.color("#fff");
series.tooltip.label.fill = am4core.color("#00");
var bullet = series.bullets.push(new am4charts.CircleBullet());
bullet.circle.stroke = am4core.color("#fff");
bullet.circle.strokeWidth = 2;
return series;
}
createSeries("created_value", "Åpnet", "red");
createSeries("closed_value", "Lukket", "green");
chart.legend = new am4charts.Legend();
chart.cursor = new am4charts.XYCursor();
chart.cursor.maxTooltipDistance = 0;
<script src="//www.amcharts.com/lib/4/core.js"></script>
<script src="//www.amcharts.com/lib/4/charts.js"></script>
<script src="//www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv_cases_created_per_day"></div>

why does my chart.js barograph order by whole numbers and then floats?

Trying to use Chart.js to plot a bar chart.
When I feed it the data below, it will display all the whole numbers first, and then the decimals. I tried converting the keys to floats as you can see, however, i'm still getting the same thing.
Does anyone have any ideas why the plot shows whole numbers first?
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.bundle.js"></script>
<!-- <script src="app.js"></script> -->
</head>
<body>
<h1>
Snapshot Chart
</h1>
<div class="chart" height="400" width="400">
<canvas id="myChart" width="400" height="400"></canvas>
<script>
var snapshot = {
5590.0: 28.89890034,
5590.22: 28.84890034,
5590.92: 24.14890034,
5591.5: 24.12890034,
5592.38: 24.11230034,
5594.13: 24.09590034,
5595.0: 23.99590034,
5595.1: 23.98586534,
5595.14: 23.88586534,
5595.16: 18.58586534,
5595.52: 17.45586534,
5595.53: 17.43946534,
5596.62: 16.33946534,
5598.98: 16.32286534,
5598.99: 16.27015,
5599.66: 16.25355,
5599.76: 11.45355,
5599.78: 11.43715,
5600.0: 11.33715,
5600.52: 11.32715,
5601.06: 11.31715,
5601.7: 11.30055,
5603.41: 11.28415,
5604.18: 11.26775,
5604.19: 6.64775,
5604.26: 5.60775,
5604.27: 5.59115,
5605.61: 4.55115,
5606.95: 4.53455,
5606.96: 4.51795,
5607.47: 3.91795,
5608.14: 3.90155,
5608.18: 3.55855,
5608.29: 2.31158,
5608.3: 2.25158,
5611.0: 2.15158,
5613.94: 2.14046,
5613.95: 0.358,
5616.64: 0.06,
5616.79: 0.01,
5616.8: 0.06122924,
5616.82: 0.11689229,
5616.84: 0.16749515,
5616.85: 0.21349783,
5617.2: 0.25531852,
5617.21: 0.2933374,
5617.5: 0.6153374,
5617.86: 0.64990008,
5617.88: 0.68132075,
5617.89: 0.70988505,
5617.9: 0.73585264,
5617.91: 0.75945958,
5617.92: 0.78092048,
5618.2: 0.8004182,
5619.31: 2.5834882,
5619.39: 3.1865882,
5620.0: 3.1965882,
5620.84: 3.21431504,
5620.87: 3.23043038,
5620.89: 3.24508079,
5620.92: 3.25839944,
5620.93: 3.27050732,
5620.94: 3.28151466,
5620.97: 3.29152636,
5623.44: 20.06906733,
5623.46: 24.54906733,
5626.85: 25.79761733,
5627.0: 25.80790432,
5628.13: 30.79790432,
5631.01: 30.81790432,
5631.19: 31.67990432,
5631.59: 32.39463287,
5632.38: 32.50142845,
5632.78: 32.57805041,
5632.81: 36.27805041,
5633.18: 36.32805041,
5636.37: 40.44805041,
5636.48: 40.46805041,
5637.0: 40.47805041,
5639.27: 40.48805041,
5639.8: 55.75838641,
5639.82: 59.55838641,
5640.0: 59.56838641,
5640.66: 59.57838641,
5640.69: 59.58838641,
5640.84: 59.61058741,
5640.85: 59.62058741,
5641.01: 59.64058741,
5641.55: 59.65058741,
5641.62: 59.66058741,
5643.01: 59.72548741,
5643.28: 63.46548741,
5645.0: 63.96528741,
5646.15: 65.77811741,
}
var keyArray = Object.keys(snapshot)
for (var i = 0; i < keyArray.length; i++) {
keyArray[i] = parseFloat(keyArray[i])
}
var valueArray = Object.values(snapshot)
for (var i = 0; i < valueArray.length; i++) {
valueArray[i] = parseFloat(valueArray[i])
}
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: keyArray,
datasets: [{
label: 'Volume',
data: valueArray,
backgroundColor: CanvasGradient,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true,
}
}]
}
}
});
</script>
</div>
</body>
</html>
Changing the data format slightly seems to solve the problem. If you add single quotes around the x-axis values then it should display in the correct order.
So the snapshot variable would become:
var snapshot = {
'5590.0': 28.89890034,
'5590.22': 28.84890034,
'5590.92': 24.14890034,
'5591.5': 24.12890034,
'5592.38': 24.11230034,
'5594.13': 24.09590034,
'5595.0': 23.99590034,
'5595.1': 23.98586534,
'5595.14': 23.88586534,
'5595.16': 18.58586534,
'5595.52': 17.45586534,
'5595.53': 17.43946534,
'5596.62': 16.33946534,
'5598.98': 16.32286534,
'5598.99': 16.27015,
'5599.66': 16.25355,
'5599.76': 11.45355,
'5599.78': 11.43715,
'5600.0': 11.33715,
'5600.52': 11.32715,
'5601.06': 11.31715,
'5601.7': 11.30055,
'5603.41': 11.28415,
'5604.18': 11.26775,
'5604.19': 6.64775,
'5604.26': 5.60775,
'5604.27': 5.59115,
'5605.61': 4.55115,
'5606.95': 4.53455,
'5606.96': 4.51795,
'5607.47': 3.91795,
'5608.14': 3.90155,
'5608.18': 3.55855,
'5608.29': 2.31158,
'5608.3': 2.25158,
'5611.0': 2.15158,
'5613.94': 2.14046,
'5613.95': 0.358,
'5616.64': 0.06,
'5616.79': 0.01,
'5616.8': 0.06122924,
'5616.82': 0.11689229,
'5616.84': 0.16749515,
'5616.85': 0.21349783,
'5617.2': 0.25531852,
'5617.21': 0.2933374,
'5617.5': 0.6153374,
'5617.86': 0.64990008,
'5617.88': 0.68132075,
'5617.89': 0.70988505,
'5617.9': 0.73585264,
'5617.91': 0.75945958,
'5617.92': 0.78092048,
'5618.2': 0.8004182,
'5619.31': 2.5834882,
'5619.39': 3.1865882,
'5620.0': 3.1965882,
'5620.84': 3.21431504,
'5620.87': 3.23043038,
'5620.89': 3.24508079,
'5620.92': 3.25839944,
'5620.93': 3.27050732,
'5620.94': 3.28151466,
'5620.97': 3.29152636,
'5623.44': 20.06906733,
'5623.46': 24.54906733,
'5626.85': 25.79761733,
'5627.0': 25.80790432,
'5628.13': 30.79790432,
'5631.01': 30.81790432,
'5631.19': 31.67990432,
'5631.59': 32.39463287,
'5632.38': 32.50142845,
'5632.78': 32.57805041,
'5632.81': 36.27805041,
'5633.18': 36.32805041,
'5636.37': 40.44805041,
'5636.48': 40.46805041,
'5637.0': 40.47805041,
'5639.27': 40.48805041,
'5639.8': 55.75838641,
'5639.82': 59.55838641,
'5640.0': 59.56838641,
'5640.66': 59.57838641,
'5640.69': 59.58838641,
'5640.84': 59.61058741,
'5640.85': 59.62058741,
'5641.01': 59.64058741,
'5641.55': 59.65058741,
'5641.62': 59.66058741,
'5643.01': 59.72548741,
'5643.28': 63.46548741,
'5645.0': 63.96528741,
'5646.15': 65.77811741,
}
Hope this helps.

How do I hide values past the x-axis in chartjs 2.0?

How do I hide values past the x-axis in chartjs 2.0? You will notice the chart juts past the -60 mark. The x-axis uses a time scale and I have the max and min values set.
Here's my chart configuration:
{
"type":"line",
"data":{
"datasets":[
{
"label":"Scatter Dataset",
"data":[
{
"x":"2016-09-16T16:36:53Z",
"y":88.46153846153845
},
...
{
"x":"2016-09-16T16:37:54Z",
"y":88.3076923076923
}
],
"pointRadius":0,
"backgroundColor":"rgba(0,0,255,0.5)",
"borderColor":"rgba(0,0,255,0.7)"
}
]
},
"options":{
"title":{
"display":true,
"text":"Water Level Over Last 60 Seconds"
},
"animation":false,
"scales":{
"xAxes":[
{
"type":"time",
"position":"bottom",
"display":true,
"time":{
"max":"2016-09-16T16:37:54Z",
"min":"2016-09-16T16:36:54.000Z",
"unit":"second",
"unitStepSize":5
},
"ticks":{
callback: function(value, index, values) {
return "-" + (60 - 5 * index);
}
}
}
],
"yAxes":[
{
"display":true,
"ticks":{
}
}
]
},
"legend":{
"display":false
}
}
}
You can achieve this using Chart.js plugins. They let you handle events occuring while creating, updating or drawing the chart.
Here, you'll need to affect before the chart is initialised :
// We first create the plugin
var cleanOutPlugin = {
// We affect the `beforeInit` event
beforeInit: function(chart) {
// Replace `ticks.min` by `time.min` if it is a time-type chart
var min = chart.config.options.scales.xAxes[0].ticks.min;
// Same here with `ticks.max`
var max = chart.config.options.scales.xAxes[0].ticks.max;
var ticks = chart.config.data.labels;
var idxMin = ticks.indexOf(min);
var idxMax = ticks.indexOf(max);
// If one of the indexes doesn't exist, it is going to bug
// So we better stop the program until it goes further
if (idxMin == -1 || idxMax == -1)
return;
var data = chart.config.data.datasets[0].data;
// We remove the data and the labels that shouldn't be on the graph
data.splice(idxMax + 1, ticks.length - idxMax);
data.splice(0, idxMin);
ticks.splice(idxMax + 1, ticks.length - idxMax);
ticks.splice(0, idxMin);
}
};
// We now register the plugin to the chart's plugin service to activate it
Chart.pluginService.register(cleanOutPlugin);
The plugin is basically a loop through the data to remove the values that shouldn't be displayed.
You can see this plugin working in a live example on jsFiddle.
For instance, the following chat with a min set to 2 and a max to 6 ...
... would give the following result :

Chart.js bar color based on labels values

The code I need is here:
chart.js bar chart color change based on value
Dola changes the color of the bars based on the values of the datasets using myObjBar.datasets[0].bars
I want to do the same thing but with the labels values (good, average, bad) e.g.
var barChartData = {
labels: ["good", "average", "bad"],
datasets: [
{
data: [1, 3, 10]
}
]
};
var ctx = document.getElementById("mycanvas").getContext("2d");
window.myObjBar = new Chart(ctx).Bar(barChartData, {
responsive : true
});
var bars = myObjBar.labels[0]; //I need this line
for(i=0;i<bars.length;i++){
var color="green";
if(bars[i].value=="bad"){
color="red";
}
else if(bars[i].value=="average"){
color="orange"
}
else{
color="green"
}
bars[i].fillColor = color;
}
myObjBar.update();
Instead of using bars[i].value property, you can use bars[i].label which gives you the label of the xAxe.
So in your loop, change to this :
for(i=0;i<bars.length;i++){
var color="green";
if(bars[i].label == "bad"){
color="red";
}
else if(bars[i].label == "average"){
color="orange"
}
else{
color="green"
}
bars[i].fillColor = color;
}
You can find the full code in this jsFiddle and here is its result :