Change Chart.js Stacked Bar Chart bar color based on status - bar-chart

I have Chart.js stacked bar chart where I am displaying the number of applications received for the past 6 months, say Jan to June. Now I am stuck with this: I have to color the bars based on the status as well, so one bar can have multiple colors. How can I do this?
Current code:
$.ajax({
url: "../Overiew/GetCandidate",
data: '',
type: "GET",
dataType: "json",
success: function (data) {
console.log(data);
var date = [];
for (var i in data) {
date.push(data[i].can_main_created_month
}
console.log(date);
var count = [];
for (var i = 0; i < date.length; i++) {
if (count[date[i]]) {
count[date[i]]++;
} else {
count[date[i]] = 1;
}
}
count = Object.keys(count).map(v => count[v]);
console.log(count);
var status = [];
for (var i in data) {
status.push(data[i].can_main_status);
}
console.log(status);
var inprocess = status[0]; //Blue Color
var hired = status[1]; //Green Color
var rejected = status[0]; //Red Color
var data = {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [{
label: "Number of Records",
fillColor: "rgba(151,187,205,0.5)",
strokeColor: "rgba(151,187,205,0.8)",
highlightFill: "rgba(151,187,205,0.75)",
highlightStroke: "rgba(151,187,205,1)",
data: [count[1], count[2], 0, 0, count[0], 0]
}]
};
var ctx = $('#barChart').get(0).getContext("2d");
var barchart = new Chart(ctx).Bar(data);
}
}
});
Current Stacked Bar Chart:

Related

Is it possible that we can add dynamic borders to X axis labels and sub labels in chart.js?

I need to create dynamic borders to labels and sub labels of chart.js graph. Is there any way of achieving this scenario?.
Below is the output I am expecting.
Labels and sub labels are having borders
Has anyone been able to achieve this with the library?
Thanks in advance.
I have tried this code but unable to get borders to labels.
var data = [{"omlPartgroupid":"191 ","xmonth":"10","xyear":"2015","QTY":"52"},{"omlPartgroupid":"191 ","xmonth":"11","xyear":"2015","QTY":"145"},{"omlPartgroupid":"191 ","xmonth":"12","xyear":"2015","QTY":"122"},{"omlPartgroupid":"191 ","xmonth":"1","xyear":"2016","QTY":"348"},{"omlPartgroupid":"191 ","xmonth":"2","xyear":"2016","QTY":"460"},{"omlPartgroupid":"191 ","xmonth":"3","xyear":"2016","QTY":"187"},{"omlPartgroupid":"191 ","xmonth":"4","xyear":"2016","QTY":"109"},{"omlPartgroupid":"191 ","xmonth":"5","xyear":"2016","QTY":"234"},{"omlPartgroupid":"191 ","xmonth":"6","xyear":"2016","QTY":"166"},{"omlPartgroupid":"191 ","xmonth":"7","xyear":"2016","QTY":"186"},{"omlPartgroupid":"191 ","xmonth":"8","xyear":"2016","QTY":"250"},{"omlPartgroupid":"191 ","xmonth":"9","xyear":"2016","QTY":"1077"},{"omlPartgroupid":"191 ","xmonth":"10","xyear":"2016","QTY":"594"},{"omlPartgroupid":"193 ","xmonth":"10","xyear":"2015","QTY":"39"},{"omlPartgroupid":"193 ","xmonth":"11","xyear":"2015","QTY":"183"},{"omlPartgroupid":"193 ","xmonth":"12","xyear":"2015","QTY":"136"},{"omlPartgroupid":"193 ","xmonth":"1","xyear":"2016","QTY":"212"},{"omlPartgroupid":"193 ","xmonth":"2","xyear":"2016","QTY":"460"},{"omlPartgroupid":"193 ","xmonth":"3","xyear":"2016","QTY":"176"},{"omlPartgroupid":"193 ","xmonth":"4","xyear":"2016","QTY":"187"},{"omlPartgroupid":"193 ","xmonth":"5","xyear":"2016","QTY":"174"},{"omlPartgroupid":"193 ","xmonth":"6","xyear":"2016","QTY":"151"},{"omlPartgroupid":"193 ","xmonth":"7","xyear":"2016","QTY":"164"},{"omlPartgroupid":"193 ","xmonth":"8","xyear":"2016","QTY":"237"},{"omlPartgroupid":"193 ","xmonth":"9","xyear":"2016","QTY":"798"},{"omlPartgroupid":"193 ","xmonth":"10","xyear":"2016","QTY":"662"},{"omlPartgroupid":"195 ","xmonth":"10","xyear":"2015","QTY":"9"},{"omlPartgroupid":"195 ","xmonth":"11","xyear":"2015","QTY":"38"},{"omlPartgroupid":"195 ","xmonth":"12","xyear":"2015","QTY":"35"},{"omlPartgroupid":"195 ","xmonth":"1","xyear":"2016","QTY":"68"},{"omlPartgroupid":"195 ","xmonth":"2","xyear":"2016","QTY":"161"},{"omlPartgroupid":"195 ","xmonth":"3","xyear":"2016","QTY":"73"},{"omlPartgroupid":"195 ","xmonth":"4","xyear":"2016","QTY":"69"},{"omlPartgroupid":"195 ","xmonth":"5","xyear":"2016","QTY":"56"},{"omlPartgroupid":"195 ","xmonth":"6","xyear":"2016","QTY":"55"},{"omlPartgroupid":"195 ","xmonth":"7","xyear":"2016","QTY":"50"},{"omlPartgroupid":"195 ","xmonth":"8","xyear":"2016","QTY":"114"},{"omlPartgroupid":"195 ","xmonth":"9","xyear":"2016","QTY":"1046"},{"omlPartgroupid":"195 ","xmonth":"10","xyear":"2016","QTY":"883"},{"omlPartgroupid":"197 ","xmonth":"10","xyear":"2015","QTY":"34"},{"omlPartgroupid":"197 ","xmonth":"11","xyear":"2015","QTY":"76"},{"omlPartgroupid":"197 ","xmonth":"12","xyear":"2015","QTY":"114"},{"omlPartgroupid":"197 ","xmonth":"1","xyear":"2016","QTY":"173"},{"omlPartgroupid":"197 ","xmonth":"2","xyear":"2016","QTY":"327"},{"omlPartgroupid":"197 ","xmonth":"3","xyear":"2016","QTY":"134"},{"omlPartgroupid":"197 ","xmonth":"4","xyear":"2016","QTY":"125"},{"omlPartgroupid":"197 ","xmonth":"5","xyear":"2016","QTY":"200"},{"omlPartgroupid":"197 ","xmonth":"6","xyear":"2016","QTY":"104"},{"omlPartgroupid":"197 ","xmonth":"7","xyear":"2016","QTY":"99"},{"omlPartgroupid":"197 ","xmonth":"8","xyear":"2016","QTY":"191"},{"omlPartgroupid":"197 ","xmonth":"9","xyear":"2016","QTY":"845"},{"omlPartgroupid":"197 ","xmonth":"10","xyear":"2016","QTY":"578"},{"omlPartgroupid":"199 ","xmonth":"10","xyear":"2015","QTY":"35"},{"omlPartgroupid":"199 ","xmonth":"11","xyear":"2015","QTY":"75"},{"omlPartgroupid":"199 ","xmonth":"12","xyear":"2015","QTY":"76"},{"omlPartgroupid":"199 ","xmonth":"1","xyear":"2016","QTY":"105"},{"omlPartgroupid":"199 ","xmonth":"2","xyear":"2016","QTY":"229"},{"omlPartgroupid":"199 ","xmonth":"3","xyear":"2016","QTY":"147"},{"omlPartgroupid":"199 ","xmonth":"4","xyear":"2016","QTY":"73"},{"omlPartgroupid":"199 ","xmonth":"5","xyear":"2016","QTY":"50"},{"omlPartgroupid":"199 ","xmonth":"6","xyear":"2016","QTY":"58"},{"omlPartgroupid":"199 ","xmonth":"7","xyear":"2016","QTY":"103"},{"omlPartgroupid":"199 ","xmonth":"8","xyear":"2016","QTY":"4230"},{"omlPartgroupid":"199 ","xmonth":"9","xyear":"2016","QTY":"2570"},{"omlPartgroupid":"199 ","xmonth":"10","xyear":"2016","QTY":"730"}];
var omlPartgroupid =[];
var xyear =[];
var xmonth =[];
var QTY=[];
var labelData = [];
for(var i in data){
omlPartgroupid.push("PartGroup"+ data[i].omlPartgroupid);
xyear.push(data[i].xyear);
xmonth.push(data[i].xmonth);
QTY.push(data[i].QTY);
labelData.push(data[i].xmonth + "|" + data[i].xyear + "|" + data[i].omlPartgroupid);
}
var chartdata ={
labels:labelData,
datasets :[
{
backgroundColor: 'rgba(200,200,200,0.75)',
borderColor: 'rgba(200,200,200,0.75)',
hoverBackground: 'rgba(200,200,200,1)',
hoverBorderColor: 'rgba(200,200,200,1)',
xAxisID:'time',
data:QTY
}
]
};
var ctx=$("#mycanvas");
var barGraph =new Chart(ctx,{
type: 'bar',
data: chartdata,
options: {
scales: {
xAxes:[ {
id: 'time',
type: 'category',
ticks: {
callback: function(label) {
var labelArray = label.split("|");
return labelArray[0] + "/" + labelArray[1];
}
}
},
{
id: 'partGroup',
type: 'category',
gridLines: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
ticks: {
display:true,
callback: function(label) {
var labelArray = label.split("|");
return labelArray[0] === "10" && labelArray[1] == "2015" ? labelArray[2] : "";
}
}
}
]
}
}
});
<canvas id="mycanvas">

Razor chart.js labels/data not in sync

I have a Razor application that generates three columns of data to use in a chart graph. The page and javascript to do that looks like this:
<div><canvas id="myChart"></canvas></div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
var Maanden = [];
var Totalen = [];
#foreach (var m in Model.Grafieks)
{
#:Maanden.push("#m.maand" + "-" + "#m.jaar");
#:Totalen.push(#m.Total);
}
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: Maanden,
datasets: [
{ label: 'Facturen €',
data: Totalen,
backgroundColor: 'rgb(255, 255, 132)',
borderColor: 'rgb(255, 99, 132)',
borderWidth: 1,
}
]
},
});
</script>
Problem is that the labels are displayed OK but the data is off. Every second column is empty and its data pushed to the next column:
Chrome says:
Is there something wrong pushing the data into the arrays?
I had to convert the comma in decimal Totalen to a period!
#foreach (var m in Model.Grafieks)
{
#:Maanden.push("#m.maand" + "-" + "#m.jaar");
<text>bedrag = parsePotentiallyGroupedFloat("#m.Total");</text>
#:Totalen.push(bedrag);
}
function parsePotentiallyGroupedFloat(stringValue) {
stringValue = stringValue.trim();
var result = stringValue.replace(/[^0-9]/g, '');
if (/[,\.]\d{2}$/.test(stringValue)) {
result = result.replace(/(\d{2})$/, '.$1');
}
return parseFloat(result);
}
The function "parsePotentiallyGroupedFloat" is from here: Convert String with Dot or Comma as decimal separator to number in JavaScript

KendoGrid refresh

I'm using KendoGrid to display some data fetched from my service.
The user selects some parameters (company and date) and cliks on a load button.
The user selects a month on a datePicker and the server will return data from that date plus 11 months.
I only display the grid after the user click on the load button.
Load function:
function loadGrid(e) {
var companyIds = [1, 3, 7]; // user select it
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var rowHeaders = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"];
var _dataSource = function () {
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: URL,
dataType: "json",
data: {
companyIds: companyIds,
date: kendo.toString(picker.value(), "yyyy-MM-dd") // user select it
}
}
},
schema: {
data: function (data) {
// function to handle data returned from server
var dataArray = [];
var index = 0;
for (var key in data[0]) {
if (Object.prototype.hasOwnProperty.call(data[0], key)) {
var property = key;
if (property == "date") {
continue;
}
key = {};
key["X"] = rowHeaders[index];
index++;
for (var i = 0; i < data.length; i++) {
var date = data[i].date;
var dateSplit = date.split("-");
var year = dateSplit[0];
var month = months[dateSplit[1] - 1];
var header = month + "_" + year;
key[header] = data[i][property];
}
dataArray.push(key);
}
}
return dataArray;
}
}
});
return dataSource;
};
$("#grid").kendoGrid({
scrollable: false,
editable: false,
dataSource: _dataSource()
});
}
When I click on the load button for the first time, the datasource is loaded and the grid is displayed correctly.
But, for instance, if I change the date on the datePicker and click on the load button again, the datasource is loaded with the correct data (new records for other months), but the grid is not refreshed.
If the first time I select the month Jan/2015, it loads and displays from Jan/2015 until Dec/2015, which is correct.
But if than I select the month Feb/2015, the datasource loads from Feb/2015 until Jan/2016 (correct), but the grid display the columns from Jan/2015 until Dec/2015, which is wrong. In this case, the column Jan/2015 is shown empty and the column Jan/2016 is not displayed.
Can someone point me to the right direction?
Thanks!
You should use a function for your dataSource -> transport -> read -> data:
data: function() {
return {
companyIds: companyIds,
date: kendo.toString(picker.value(), "yyyy-MM-dd") // user select it
};
}
UPDATE:
Here is how I would do it:
function loadGrid(e) {
$("#grid").data("kendoGrid").dataSource.fetch();
}
function getData() {
var companyIds = ...
var picker = ...
return {
companyIds: companyIds,
date: kendo.toString(picker.value(), "yyyy-MM-dd") // user select it
};
}
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: URL,
dataType: "json",
data: getData
}
},
schema: {
data: function (data) {
// function to handle data returned from server
var dataArray = [];
var index = 0;
for (var key in data[0]) {
if (Object.prototype.hasOwnProperty.call(data[0], key)) {
var property = key;
if (property == "date") {
continue;
}
key = {};
key["X"] = rowHeaders[index];
index++;
for (var i = 0; i < data.length; i++) {
var date = data[i].date;
var dateSplit = date.split("-");
var year = dateSplit[0];
var month = months[dateSplit[1] - 1];
var header = month + "_" + year;
key[header] = data[i][property];
}
dataArray.push(key);
}
}
return dataArray;
}
}
});
$("#grid").kendoGrid({
scrollable: false,
editable: false,
dataSource: dataSource
});
I ended up destroying and recreating the grid when the user clicks on load button.
$("#loadButton").kendoButton({
click: loadGrid
});
var loaded = false;
function loadGrid(e) {
if (value) {
if (loaded) {
var grid = $("#grid").data("kendoGrid");
grid.wrapper.empty();
grid.destroy();
}
$("#grid").kendoGrid({
scrollable: false,
editable: false,
autoBind: false,
dataSource: _dataSource()
});
$("#grid").data("kendoGrid").dataSource.read();
loaded = true;
} else {
e.preventDefault();
alert("aaaa");
}
}

HighCharts : Xaxis lables misplaced

I want to label xaxis with values from JSON data that is happening but it is printing it at wrong place as shown in screenshot :
Here only seven values are present its labeled in that manner but actual data is plotted by leaving a gap of one. For example at 11th there is value and then again at 13t so total seven values but taking 14 places and label properly taking there first seven places how to match labels and bar graph
Following is my code snippet :
var obj = data[$("#host").val()].stats_vol.result.sectoutput;
var my_data_list = [];
var my_data_list1 = [];
var my_data_list2 = [];
var volumes = [];
for(var key in obj) {
var avg_latency = parseInt(obj[key].avg_latency);
var read_latency = parseInt(obj[key].read_latency);
var write_latency = parseInt(obj[key].write_latency);
console.log(key);
volumes.push(key);
my_data_list.push('Average Latency', parseInt(avg_latency));
my_data_list1.push('Read Latency', parseInt(read_latency));
my_data_list2.push('Write Latency', parseInt(write_latency));
}
$('#graphcontainer3').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Volume Level Latency'
},
yAxis: {
tickInterval: 100,
title: {
text: 'Latency(ms)'
}
},
xAxis: {
categories: volumes,
},
tooltip: {
headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
'<td style="padding:0"><b>{point.y:.1f} ms</b></td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 2
}
},
series: [{
name: 'Average latency',
data: my_data_list,
}, {
name: 'Read Latency',
data: my_data_list1,
}, {
name: 'Write Latency ',
data: my_data_list2,
}]
});
Can anyone help me in this code to make this work fine???
I rectified the problem by myself :) It just I was giving labels two times
var obj = data[$("#host").val()].stats_vol.result.sectoutput;
var my_data_list3 = [];
var my_data_list1 = [];
var my_data_list2 = [];
var volumes = [];
for(var key in obj) {
var avg_latency = parseInt(obj[key].avg_latency);
var read_latency = parseInt(obj[key].read_latency);
var write_latency = parseInt(obj[key].write_latency);
console.log(avg_latency);
volumes.push(key);
my_data_list3.push(parseInt(avg_latency)); //here no need to give label again as it is done my volume(key)
my_data_list1.push( parseInt(read_latency));
my_data_list2.push(parseInt(write_latency));
}
This is what I was expecting as output .Hope it might be helpful for someone else hence answered.

Chart.js dynamic bar width

I have a requirement to render a set of time series data of contiguous blocks.
I need to describe a series of bars which could span many hours, or just minutes, with their own Y value.
I'm not sure if ChartJS is what I should be using for this, but I have looked at extending the Bar type, but it seems very hard coded for each bar to be the same width. The Scale Class internally is used for labels, chart width etc, not just the bars themselves.
I am trying to achieve something like this that works in Excel: http://peltiertech.com/variable-width-column-charts/
Has anyone else had to come up with something similar?
I found I needed to do this and the answer by #potatopeelings was great, but out of date for version 2 of Chartjs. I did something similar by creating my own controller/chart type via extending bar:
//controller.barw.js
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.barw = {
hover: {
mode: 'label'
},
scales: {
xAxes: [{
type: 'category',
// Specific to Bar Controller
categoryPercentage: 0.8,
barPercentage: 0.9,
// grid line settings
gridLines: {
offsetGridLines: true
}
}],
yAxes: [{
type: 'linear'
}]
}
};
Chart.controllers.barw = Chart.controllers.bar.extend({
/**
* #private
*/
getRuler: function() {
var me = this;
var scale = me.getIndexScale();
var options = scale.options;
var stackCount = me.getStackCount();
var fullSize = scale.isHorizontal()? scale.width : scale.height;
var tickSize = fullSize / scale.ticks.length;
var categorySize = tickSize * options.categoryPercentage;
var fullBarSize = categorySize / stackCount;
var barSize = fullBarSize * options.barPercentage;
barSize = Math.min(
helpers.getValueOrDefault(options.barThickness, barSize),
helpers.getValueOrDefault(options.maxBarThickness, Infinity));
return {
fullSize: fullSize,
stackCount: stackCount,
tickSize: tickSize,
categorySize: categorySize,
categorySpacing: tickSize - categorySize,
fullBarSize: fullBarSize,
barSize: barSize,
barSpacing: fullBarSize - barSize,
scale: scale
};
},
/**
* #private
*/
calculateBarIndexPixels: function(datasetIndex, index, ruler) {
var me = this;
var scale = ruler.scale;
var options = scale.options;
var isCombo = me.chart.isCombo;
var stackIndex = me.getStackIndex(datasetIndex);
var base = scale.getPixelForValue(null, index, datasetIndex, isCombo);
var size = ruler.barSize;
var dataset = me.chart.data.datasets[datasetIndex];
if(dataset.weights) {
var total = dataset.weights.reduce((m, x) => m + x, 0);
var perc = dataset.weights[index] / total;
var offset = 0;
for(var i = 0; i < index; i++) {
offset += dataset.weights[i] / total;
}
var pixelOffset = Math.round(ruler.fullSize * offset);
var base = scale.isHorizontal() ? scale.left : scale.top;
base += pixelOffset;
size = Math.round(ruler.fullSize * perc);
size -= ruler.categorySpacing;
size -= ruler.barSpacing;
}
base -= isCombo? ruler.tickSize / 2 : 0;
base += ruler.fullBarSize * stackIndex;
base += ruler.categorySpacing / 2;
base += ruler.barSpacing / 2;
return {
size: size,
base: base,
head: base + size,
center: base + size / 2
};
},
});
};
Then you need to add it to your chartjs instance like this:
import Chart from 'chart.js'
import barw from 'controller.barw'
barw(Chart); //add plugin to chartjs
and finally, similar to the other answer, the weights of the bar widths need to be added to the data set:
var data = {
labels: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.7)",
highlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 30, 56, 65, 40],
weights: [1, 0.9, 1, 2, 1, 4, 0.3]
},
]
};
This will hopefully get someone onto the right track. What I have certainly isn't perfect, but if you make sure you have the right number of weight to data points, you should be right.
Best of luck.
This is based on the #Shane's code, I just posted to help, since is a common question.
calculateBarIndexPixels: function (datasetIndex, index, ruler) {
const options = ruler.scale.options;
const range = options.barThickness === 'flex' ? computeFlexCategoryTraits(index, ruler, options) : computeFitCategoryTraits(index, ruler, options);
const barSize = range.chunk;
const stackIndex = this.getStackIndex(datasetIndex, this.getMeta().stack);
let center = range.start + range.chunk * stackIndex + range.chunk / 2;
let size = range.chunk * range.ratio;
let start = range.start;
const dataset = this.chart.data.datasets[datasetIndex];
if (dataset.weights) {
//the max weight should be one
size = barSize * dataset.weights[index];
const meta = this.chart.controller.getDatasetMeta(0);
const lastModel = index > 0 ? meta.data[index - 1]._model : null;
//last column takes the full bar
if (lastModel) {
//start could be last center plus half of last column width
start = lastModel.x + lastModel.width / 2;
}
center = start + size * stackIndex + size / 2;
}
return {
size: size,
base: center - size / 2,
head: center + size / 2,
center: center
};
}
For Chart.js you can create a new extension based on the bar class to do this. It's a bit involved though - however most of it is a copy paste of the bar type library code
Chart.types.Bar.extend({
name: "BarAlt",
// all blocks that don't have a comment are a direct copy paste of the Chart.js library code
initialize: function (data) {
// the sum of all widths
var widthSum = data.datasets[0].data2.reduce(function (a, b) { return a + b }, 0);
// cumulative sum of all preceding widths
var cumulativeSum = [ 0 ];
data.datasets[0].data2.forEach(function (e, i, arr) {
cumulativeSum.push(cumulativeSum[i] + e);
})
var options = this.options;
// completely rewrite this class to calculate the x position and bar width's based on data2
this.ScaleClass = Chart.Scale.extend({
offsetGridLines: true,
calculateBarX: function (barIndex) {
var xSpan = this.width - this.xScalePaddingLeft;
var x = this.xScalePaddingLeft + (cumulativeSum[barIndex] / widthSum * xSpan) - this.calculateBarWidth(barIndex) / 2;
return x + this.calculateBarWidth(barIndex);
},
calculateBarWidth: function (index) {
var xSpan = this.width - this.xScalePaddingLeft;
return (xSpan * data.datasets[0].data2[index] / widthSum);
}
});
this.datasets = [];
if (this.options.showTooltips) {
Chart.helpers.bindEvents(this, this.options.tooltipEvents, function (evt) {
var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];
this.eachBars(function (bar) {
bar.restore(['fillColor', 'strokeColor']);
});
Chart.helpers.each(activeBars, function (activeBar) {
activeBar.fillColor = activeBar.highlightFill;
activeBar.strokeColor = activeBar.highlightStroke;
});
this.showTooltip(activeBars);
});
}
this.BarClass = Chart.Rectangle.extend({
strokeWidth: this.options.barStrokeWidth,
showStroke: this.options.barShowStroke,
ctx: this.chart.ctx
});
Chart.helpers.each(data.datasets, function (dataset, datasetIndex) {
var datasetObject = {
label: dataset.label || null,
fillColor: dataset.fillColor,
strokeColor: dataset.strokeColor,
bars: []
};
this.datasets.push(datasetObject);
Chart.helpers.each(dataset.data, function (dataPoint, index) {
datasetObject.bars.push(new this.BarClass({
value: dataPoint,
label: data.labels[index],
datasetLabel: dataset.label,
strokeColor: dataset.strokeColor,
fillColor: dataset.fillColor,
highlightFill: dataset.highlightFill || dataset.fillColor,
highlightStroke: dataset.highlightStroke || dataset.strokeColor
}));
}, this);
}, this);
this.buildScale(data.labels);
// remove the labels - they won't be positioned correctly anyway
this.scale.xLabels.forEach(function (e, i, arr) {
arr[i] = '';
})
this.BarClass.prototype.base = this.scale.endPoint;
this.eachBars(function (bar, index, datasetIndex) {
// change the way the x and width functions are called
Chart.helpers.extend(bar, {
width: this.scale.calculateBarWidth(index),
x: this.scale.calculateBarX(index),
y: this.scale.endPoint
});
bar.save();
}, this);
this.render();
},
draw: function (ease) {
var easingDecimal = ease || 1;
this.clear();
var ctx = this.chart.ctx;
this.scale.draw(1);
Chart.helpers.each(this.datasets, function (dataset, datasetIndex) {
Chart.helpers.each(dataset.bars, function (bar, index) {
if (bar.hasValue()) {
bar.base = this.scale.endPoint;
// change the way the x and width functions are called
bar.transition({
x: this.scale.calculateBarX(index),
y: this.scale.calculateY(bar.value),
width: this.scale.calculateBarWidth(index)
}, easingDecimal).draw();
}
}, this);
}, this);
}
});
You pass in the widths like below
var data = {
labels: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.7)",
highlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 30, 56, 65, 40],
data2: [10, 20, 30, 20, 10, 40, 10]
},
]
};
and you call it like so
var ctx = document.getElementById('canvas').getContext('2d');
var myLineChart = new Chart(ctx).BarAlt(data);
Fiddle - http://jsfiddle.net/moye0cp4/