Hello Charts.js Team,
I noticed that the colors for my charts are not working as intended in Safari.
Here is a screenshot of the issue:
How can I fix this issue?
Here is my Charts.js code:
function drawWIPChart() {
var URL = window.location.href;
var dates = [];
var clientCosts = [];
var num_Approveds = [];
var num_NewEstimates = [];
var num_ApprovedCreateJobs = [];
var num_AwaitingBillings = [];
var num_CostSubmitteds = [];
if (URL.indexOf("london") !== -1) {
$.ajax({
url: '../financial-reports/wip-data-london.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
clientCosts.push(item.clientCostsTotal);
num_Approveds.push(item.num_Approved);
num_ApprovedCreateJobs.push(item.num_ApprovedCreateJob);
num_AwaitingBillings.push(item.num_AwaitingBilling);
num_CostSubmitteds.push(item.num_CostSubmitted);
myChart.update();
});
});
}
if (URL.indexOf("nw") !== -1) {
$.ajax({
url: '../financial-reports/wip-data-nw.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
clientCosts.push(item.clientCostsTotal);
num_Approveds.push(item.num_Approved);
num_ApprovedCreateJobs.push(item.num_ApprovedCreateJob);
num_AwaitingBillings.push(item.num_AwaitingBilling);
num_CostSubmitteds.push(item.num_CostSubmitted);
myChart.update();
});
});
}
if (URL.indexOf("loupe") !== -1) {
$.ajax({
url: '../financial-reports/wip-data-loupe.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
clientCosts.push(item.clientCostsTotal);
num_Approveds.push(item.num_Approved);
num_ApprovedCreateJobs.push(item.num_ApprovedCreateJob);
num_AwaitingBillings.push(item.num_AwaitingBilling);
num_CostSubmitteds.push(item.num_CostSubmitted);
myChart.update();
});
});
}
if (URL.indexOf("new-york") !== -1) {
$.ajax({
url: '../financial-reports/wip-data-new-york.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
clientCosts.push(item.clientCostsTotal);
num_Approveds.push(item.num_Approved);
num_ApprovedCreateJobs.push(item.num_ApprovedCreateJob);
num_AwaitingBillings.push(item.num_AwaitingBilling);
num_CostSubmitteds.push(item.num_CostSubmitted);
myChart.update();
});
});
}
if (URL.indexOf("content") !== -1) {
$.ajax({
url: '../financial-reports/wip-data-content.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
clientCosts.push(item.clientCostsTotal);
num_Approveds.push(item.num_Approved);
num_ApprovedCreateJobs.push(item.num_ApprovedCreateJob);
num_AwaitingBillings.push(item.num_AwaitingBilling);
num_CostSubmitteds.push(item.num_CostSubmitted);
myChart.update();
});
});
}
if (URL.indexOf("berlin") !== -1) {
$.ajax({
url: '../financial-reports/wip-data-berlin.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
clientCosts.push(item.clientCostsTotal);
num_Approveds.push(item.num_Approved);
num_ApprovedCreateJobs.push(item.num_ApprovedCreateJob);
num_AwaitingBillings.push(item.num_AwaitingBilling);
num_CostSubmitteds.push(item.num_CostSubmitted);
myChart.update();
});
});
}
if (URL.indexOf("abu-dhabi") !== -1) {
$.ajax({
url: '../financial-reports/wip-data-abu-dhabi.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
clientCosts.push(item.clientCostsTotal);
num_Approveds.push(item.num_Approved);
num_ApprovedCreateJobs.push(item.num_ApprovedCreateJob);
num_AwaitingBillings.push(item.num_AwaitingBilling);
num_CostSubmitteds.push(item.num_CostSubmitted);
myChart.update();
});
});
} else {
$.ajax({
url: '../financial-reports/wip-data.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
clientCosts.push(item.clientCostsTotal);
num_Approveds.push(item.num_Approved);
num_ApprovedCreateJobs.push(item.num_ApprovedCreateJob);
num_AwaitingBillings.push(item.num_AwaitingBilling);
num_CostSubmitteds.push(item.num_CostSubmitted);
myChart.update();
});
});
}
var chartData = {
labels: dates,
datasets: [{
type: 'line',
data: clientCosts,
label: "WIP Total",
backgroundColor: 'rgba(71, 86, 119, 0.2)',
borderColor: 'rgba(71, 86, 119, .8)'
}, {
backgroundColor: 'rgba(97, 188, 109, 0.2)',
borderColor: 'rgba(97, 188, 109, .8)',
label: 'Status = Approved',
yAxisID: '2ndAxis',
type: 'bar',
data: num_Approveds
}, {
backgroundColor: 'rgba(84, 172, 210, 0.2)',
borderColor: 'rgba(84, 172, 210, .8)',
label: 'Status = Approved Create Jobs',
yAxisID: '2ndAxis',
type: 'bar',
data: num_ApprovedCreateJobs
}, {
label: 'Status = Awaiting Billing',
backgroundColor: 'rgba(247, 218, 100, 0.2)',
borderColor: 'rgba(247, 218, 100, .8)',
yAxisID: '2ndAxis',
type: 'bar',
data: num_AwaitingBillings
}, {
label: 'Status = Cost Submitted',
backgroundColor: 'rgba(250, 160, 38, 0.2)',
borderColor: 'rgba(250, 160, 38, .8)',
yAxisID: '2ndAxis',
type: 'bar',
data: num_CostSubmitteds
}]
};
// Get the context of the canvas element we want to select
var ctx = document.getElementById("wipChart").getContext("2d");
// Instantiate a new chart
var myChart = new Chart(ctx, {
responsive: true,
type: 'bar',
data: chartData,
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
},
stacked: true
}, {
type: 'linear',
id: '2ndAxis',
stacked: true,
ticks: {
beginAtZero: true
}
}],
xAxes: [{
stacked: true
}]
}
}
});
}
drawWIPChart();
function drawBudgetsChart() {
var dates = [];
var invoices = [];
var budgets = [];
var URL = window.location.href;
if (URL.indexOf("london") !== -1) {
$.ajax({
url: '../financial-reports/budget-vs-billing-data-london.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
invoices.push(item.invoice);
budgets.push(item.budget);
myBudgetsChart.update();
});
});
}
if (URL.indexOf("nw") !== -1) {
$.ajax({
url: '../financial-reports/budget-vs-billing-data-nw.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
invoices.push(item.invoice);
budgets.push(item.budget);
myBudgetsChart.update();
});
});
}
if (URL.indexOf("loupe") !== -1) {
$.ajax({
url: '../financial-reports/budget-vs-billing-data-loupe.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
invoices.push(item.invoice);
budgets.push(item.budget);
myBudgetsChart.update();
});
});
}
if (URL.indexOf("new-york") !== -1) {
$.ajax({
url: '../financial-reports/budget-vs-billing-data-new-york.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
invoices.push(item.invoice);
budgets.push(item.budget);
myBudgetsChart.update();
});
});
}
if (URL.indexOf("content") !== -1) {
$.ajax({
url: '../financial-reports/budget-vs-billing-data-content.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
invoices.push(item.invoice);
budgets.push(item.budget);
myBudgetsChart.update();
});
});
}
if (URL.indexOf("berlin") !== -1) {
$.ajax({
url: '../financial-reports/budget-vs-billing-data-berlin.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
invoices.push(item.invoice);
budgets.push(item.budget);
myBudgetsChart.update();
});
});
}
if (URL.indexOf("abu-dhabi") !== -1) {
$.ajax({
url: '../financial-reports/budget-vs-billing-data-abu-dhabi.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
invoices.push(item.invoice);
budgets.push(item.budget);
myBudgetsChart.update();
});
});
} else {
$.ajax({
url: '../financial-reports/budget-vs-billing-data.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
invoices.push(item.invoice);
budgets.push(item.budget);
myBudgetsChart.update();
});
});
}
console.log(dates, invoices, budgets);
var budgetsChartData = {
labels: dates,
datasets: [{
backgroundColor: ['rgba(65, 168, 95, 0.2)'],
borderColor: ['rgba(65, 168, 95, .8)'],
label: "Invoice Amount",
data: invoices
}, {
backgroundColor: ['rgba(41, 105, 176, 0.2)'],
borderColor: ['rgba(41, 105, 176, 0.8)'],
label: "Budget Amount",
data: budgets
}]
};
// Get the context of the canvas element we want to select
var ctx = document.getElementById("budgetChart").getContext("2d");
// Instantiate a new chart
var myBudgetsChart = new Chart(ctx, {
responsive: true,
type: 'line',
data: budgetsChartData,
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
}
drawBudgetsChart();
function drawExpensesChart() {
var dates = [];
var expenses = [];
var outworks = [];
var expensesOutworks = [];
var budgetedOutworks = [];
var URL = window.location.href;
if (URL.indexOf("london") !== -1) {
$.ajax({
url: '../financial-reports/outwork-vs-expenses-data-london.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
expenses.push(item.expense);
outworks.push(item.outwork);
expensesOutworks.push(item.expensesOutwork);
budgetedOutworks.push(item.budgetedOutwork);
myExpensesChart.update();
});
});
}
if (URL.indexOf("nw") !== -1) {
$.ajax({
url: '../financial-reports/outwork-vs-expenses-data-nw.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
expenses.push(item.expense);
outworks.push(item.outwork);
expensesOutworks.push(item.expensesOutwork);
budgetedOutworks.push(item.budgetedOutwork);
myExpensesChart.update();
});
});
}
if (URL.indexOf("loupe") !== -1) {
$.ajax({
url: '../financial-reports/outwork-vs-expenses-data-loupe.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
expenses.push(item.expense);
outworks.push(item.outwork);
expensesOutworks.push(item.expensesOutwork);
budgetedOutworks.push(item.budgetedOutwork);
myExpensesChart.update();
});
});
}
if (URL.indexOf("new-york") !== -1) {
$.ajax({
url: '../financial-reports/outwork-vs-expenses-data-new-york.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
expenses.push(item.expense);
outworks.push(item.outwork);
expensesOutworks.push(item.expensesOutwork);
budgetedOutworks.push(item.budgetedOutwork);
myExpensesChart.update();
});
});
}
if (URL.indexOf("content") !== -1) {
$.ajax({
url: '../financial-reports/outwork-vs-expenses-data-content.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
expenses.push(item.expense);
outworks.push(item.outwork);
expensesOutworks.push(item.expensesOutwork);
budgetedOutworks.push(item.budgetedOutwork);
myExpensesChart.update();
});
});
}
if (URL.indexOf("berlin") !== -1) {
$.ajax({
url: '../financial-reports/outwork-vs-expenses-data-berlin.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
expenses.push(item.expense);
outworks.push(item.outwork);
expensesOutworks.push(item.expensesOutwork);
budgetedOutworks.push(item.budgetedOutwork);
myExpensesChart.update();
});
});
}
if (URL.indexOf("abu-dhabi") !== -1) {
$.ajax({
url: '../financial-reports/outwork-vs-expenses-data-abu-dhabi.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
expenses.push(item.expense);
outworks.push(item.outwork);
expensesOutworks.push(item.expensesOutwork);
budgetedOutworks.push(item.budgetedOutwork);
myExpensesChart.update();
});
});
} else {
$.ajax({
url: '../financial-reports/outwork-vs-expenses-data.php',
dataType: 'json'
}).done(function(data) {
data.forEach(function(item) {
dates.push(item.date);
expenses.push(item.expense);
outworks.push(item.outwork);
expensesOutworks.push(item.expensesOutwork);
budgetedOutworks.push(item.budgetedOutwork);
myExpensesChart.update();
});
});
}
console.log(dates, expenses, outworks, expensesOutworks, budgetedOutworks);
var expensesChartData = {
labels: dates,
datasets: [{
label: "Expenses",
backgroundColor: ['rgba(209, 72, 64, 0.2)'],
borderColor: ['rgba(209, 72, 64, 0.8)'],
data: expenses
}, {
label: "Outwork",
backgroundColor: ['rgba(43, 130, 201, 0.2)'],
borderColor: ['rgba(43, 130, 201, 0.8)'],
data: outworks
}, {
label: "Budgeted Outwork",
backgroundColor: ['rgba(0, 168, 133, 0.2)'],
borderColor: ['rgba(0, 168, 133, 0.8)'],
data: budgetedOutworks
}, {
label: "Total Expenses + Outwork",
backgroundColor: ['rgba(146, 101, 184, 0.2)'],
borderColor: ['rgba(146, 101, 184, 0.8)'],
data: expensesOutworks
}]
};
// Get the context of the canvas element we want to select
var ctx = document.getElementById("expensesChart").getContext("2d");
// Instantiate a new chart
var myExpensesChart = new Chart(ctx, {
responsive: true,
type: 'line',
data: expensesChartData,
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
}
drawExpensesChart();
The charts are displaying properly in Chrome, here is what they are supposed to look like:
I am 99% sure that this is problem
datasets: [{
backgroundColor: ['rgba(65, 168, 95, 0.2)'],
borderColor: ['rgba(65, 168, 95, .8)'],
label: "Invoice Amount",
data: invoices
}, {
backgroundColor: ['rgba(41, 105, 176, 0.2)'],
borderColor: ['rgba(41, 105, 176, 0.8)'],
label: "Budget Amount",
data: budgets
}]
the colors should be strings rather than arrays of strings. In Chrome, this happens to work because of how chrome treats arrays. I believe the behaviour is undefined in the ecmascript spec.
datasets: [{
backgroundColor: 'rgba(65, 168, 95, 0.2)',
borderColor: 'rgba(65, 168, 95, .8)',
label: "Invoice Amount",
data: invoices
}, {
backgroundColor: 'rgba(41, 105, 176, 0.2)',
borderColor: 'rgba(41, 105, 176, 0.8)',
label: "Budget Amount",
data: budgets
}]
That fixed it. Thank you!
I also would like to confirm that your solution fixed the problem!
@etimberg Thanks!
Most helpful comment
I am 99% sure that this is problem
the colors should be strings rather than arrays of strings. In Chrome, this happens to work because of how chrome treats arrays. I believe the behaviour is undefined in the ecmascript spec.