Files
firefly-iii/public/v1/js/ff/charts.js

437 lines
11 KiB
JavaScript
Raw Normal View History

2016-04-10 10:05:50 +02:00
/*
* charts.js
2020-02-16 13:59:41 +01:00
* Copyright (c) 2019 james@firefly-iii.org
2016-04-10 10:05:50 +02:00
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
2017-10-21 08:40:00 +02:00
*
* This program is distributed in the hope that it will be useful,
2017-10-21 08:40:00 +02:00
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
2017-10-21 08:40:00 +02:00
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
2016-04-10 10:05:50 +02:00
*/
2017-11-25 08:54:52 +01:00
/** global: Chart, defaultChartOptions, accounting, defaultPieOptions, noDataForChart, todayText */
var allCharts = {};
2017-11-17 19:31:48 +01:00
/*
Make some colours:
*/
var colourSet = [
[53, 124, 165],
2018-07-01 09:43:44 +02:00
[0, 141, 76], // green
[219, 139, 11],
2018-07-01 09:43:44 +02:00
[202, 25, 90], // paars rood-ish #CA195A
2015-06-27 20:39:50 +02:00
[85, 82, 153],
[66, 133, 244],
2018-07-01 09:43:44 +02:00
[219, 68, 55], // red #DB4437
2015-06-27 20:39:50 +02:00
[244, 180, 0],
[15, 157, 88],
[171, 71, 188],
[0, 172, 193],
[255, 112, 67],
[158, 157, 36],
[92, 107, 192],
[240, 98, 146],
[0, 121, 107],
2016-04-10 10:05:50 +02:00
[194, 24, 91]
];
var fillColors = [];
for (var i = 0; i < colourSet.length; i++) {
fillColors.push("rgba(" + colourSet[i][0] + ", " + colourSet[i][1] + ", " + colourSet[i][2] + ", 0.5)");
}
2016-04-10 10:05:50 +02:00
Chart.defaults.global.legend.display = false;
Chart.defaults.global.animation.duration = 0;
2016-04-10 10:20:15 +02:00
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;
/**
2016-11-16 20:35:25 +01:00
*
* @param data
* @returns {{}}
*/
2016-11-16 20:35:25 +01:00
function colorizeData(data) {
var newData = {};
newData.datasets = [];
2020-10-24 17:27:36 +02:00
for (var loop = 0; loop < data.count; loop++) {
2016-11-16 20:35:25 +01:00
newData.labels = data.labels;
2020-10-24 17:27:36 +02:00
var dataset = data.datasets[loop];
dataset.fill = false;
2020-10-24 17:27:36 +02:00
dataset.backgroundColor = dataset.borderColor = fillColors[loop];
2016-11-16 20:35:25 +01:00
newData.datasets.push(dataset);
}
return newData;
}
/**
2016-11-16 20:35:25 +01:00
* Function to draw a line chart:
2022-04-12 18:19:30 +02:00
* @param URL
* @param container
*/
2022-04-12 18:19:30 +02:00
function lineChart(URL, container) {
"use strict";
2015-06-27 22:11:03 +02:00
2016-11-16 20:35:25 +01:00
var colorData = true;
2017-06-02 13:00:43 +02:00
var options = $.extend(true, {}, defaultChartOptions);
2016-11-16 20:35:25 +01:00
var chartType = 'line';
2015-06-27 17:05:39 +02:00
2022-04-12 18:19:30 +02:00
drawAChart(URL, container, chartType, options, colorData);
}
2019-12-20 17:28:49 +01:00
/**
* Function to draw a line chart that doesn't start at ZERO.
2022-04-12 18:19:30 +02:00
* @param URL
2019-12-20 17:28:49 +01:00
* @param container
*/
2022-04-12 18:19:30 +02:00
function lineNoStartZeroChart(URL, container) {
2019-12-20 17:28:49 +01:00
"use strict";
var colorData = true;
var options = $.extend(true, {}, defaultChartOptions);
var chartType = 'line';
options.scales.yAxes[0].ticks.beginAtZero = false;
2022-04-12 18:19:30 +02:00
drawAChart(URL, container, chartType, options, colorData);
2019-12-20 17:28:49 +01:00
}
2019-09-15 06:56:20 +02:00
/**
* Overrules the currency the line chart is drawn in.
*
2022-04-12 18:19:30 +02:00
* @param URL
2019-09-15 06:56:20 +02:00
* @param container
*/
2022-04-12 18:19:30 +02:00
function otherCurrencyLineChart(URL, container, currencySymbol) {
2019-09-15 06:56:20 +02:00
"use strict";
var colorData = true;
var newOpts = {
scales: {
xAxes: [
{
gridLines: {
display: false
},
ticks: {
// break ticks when too long.
callback: function (value, index, values) {
return formatLabel(value, 20);
}
}
}
],
yAxes: [{
display: true,
//hello: 'fresh',
ticks: {
callback: function (tickValue) {
"use strict";
// use first symbol or null:
return accounting.formatMoney(tickValue);
},
beginAtZero: true
}
}]
},
};
//var options = $.extend(true, newOpts, defaultChartOptions);
var options = $.extend(true, defaultChartOptions, newOpts);
console.log(options);
var chartType = 'line';
2022-04-12 18:19:30 +02:00
drawAChart(URL, container, chartType, options, colorData);
2019-09-15 06:56:20 +02:00
}
/**
* Function to draw a chart with double Y Axes and stacked columns.
*
2022-04-12 18:19:30 +02:00
* @param URL
* @param container
*/
2022-04-12 18:19:30 +02:00
function doubleYChart(URL, container) {
"use strict";
var colorData = true;
var options = $.extend(true, {}, defaultChartOptions);
options.scales.yAxes = [
// y axis 0:
{
display: true,
ticks: {
callback: function (tickValue) {
"use strict";
return accounting.formatMoney(tickValue);
},
beginAtZero: true
},
position: "left",
"id": "y-axis-0"
},
// and y axis 1:
{
display: true,
ticks: {
callback: function (tickValue) {
"use strict";
return accounting.formatMoney(tickValue);
},
beginAtZero: true
},
position: "right",
"id": "y-axis-1"
}
];
options.stacked = true;
options.scales.xAxes[0].stacked = true;
2016-12-23 07:20:47 +01:00
var chartType = 'bar';
2022-04-12 18:19:30 +02:00
drawAChart(URL, container, chartType, options, colorData);
}
2016-12-23 18:34:58 +01:00
/**
* Function to draw a chart with double Y Axes and non stacked columns.
*
2022-04-12 18:19:30 +02:00
* @param URL
2016-12-23 18:34:58 +01:00
* @param container
*/
2022-04-12 18:19:30 +02:00
function doubleYNonStackedChart(URL, container) {
2016-12-23 18:34:58 +01:00
"use strict";
var colorData = true;
var options = $.extend(true, {}, defaultChartOptions);
2016-12-23 18:34:58 +01:00
options.scales.yAxes = [
// y axis 0:
{
display: true,
ticks: {
2017-01-02 12:09:46 +01:00
callback: function (tickValue) {
2016-12-23 18:34:58 +01:00
"use strict";
return accounting.formatMoney(tickValue);
},
beginAtZero: true
},
position: "left",
"id": "y-axis-0"
},
// and y axis 1:
{
display: true,
ticks: {
2017-01-02 12:09:46 +01:00
callback: function (tickValue) {
2016-12-23 18:34:58 +01:00
"use strict";
return accounting.formatMoney(tickValue);
},
beginAtZero: true
},
position: "right",
"id": "y-axis-1"
}
];
var chartType = 'bar';
2022-04-12 18:19:30 +02:00
drawAChart(URL, container, chartType, options, colorData);
2016-12-23 18:34:58 +01:00
}
/**
*
2022-04-12 18:19:30 +02:00
* @param URL
* @param container
*/
2022-04-12 18:19:30 +02:00
function columnChart(URL, container) {
"use strict";
2016-11-16 20:35:25 +01:00
var colorData = true;
2017-06-02 13:00:43 +02:00
var options = $.extend(true, {}, defaultChartOptions);
2016-11-16 20:35:25 +01:00
var chartType = 'bar';
2015-06-27 20:39:50 +02:00
2022-04-12 18:19:30 +02:00
drawAChart(URL, container, chartType, options, colorData);
}
2018-07-01 09:43:44 +02:00
/**
*
2022-04-12 18:19:30 +02:00
* @param URL
2018-07-01 09:43:44 +02:00
* @param container
*/
2022-04-12 18:19:30 +02:00
function columnChartCustomColours(URL, container) {
2018-07-01 09:43:44 +02:00
"use strict";
var colorData = false;
var options = $.extend(true, {}, defaultChartOptions);
var chartType = 'bar';
2022-04-12 18:19:30 +02:00
drawAChart(URL, container, chartType, options, colorData);
2018-07-01 09:43:44 +02:00
}
/**
*
2022-04-12 18:19:30 +02:00
* @param URL
* @param container
*/
2022-04-12 18:19:30 +02:00
function stackedColumnChart(URL, container) {
"use strict";
2015-06-27 17:32:52 +02:00
2016-11-16 20:35:25 +01:00
var colorData = true;
2017-02-23 17:47:36 +01:00
var options = $.extend(true, {}, defaultChartOptions);
2016-11-16 20:35:25 +01:00
options.stacked = true;
options.scales.xAxes[0].stacked = true;
2017-02-23 17:43:29 +01:00
options.scales.yAxes[0].stacked = true;
2016-11-16 20:35:25 +01:00
var chartType = 'bar';
2022-04-12 18:19:30 +02:00
drawAChart(URL, container, chartType, options, colorData);
2016-11-16 20:35:25 +01:00
}
2015-06-27 17:32:52 +02:00
2016-11-16 20:35:25 +01:00
/**
*
2022-04-12 18:19:30 +02:00
* @param URL
2016-11-16 20:35:25 +01:00
* @param container
*/
2022-04-12 18:19:30 +02:00
function pieChart(URL, container) {
2016-11-16 20:35:25 +01:00
"use strict";
2015-06-27 17:32:52 +02:00
2016-11-16 20:35:25 +01:00
var colorData = false;
2017-06-02 13:00:43 +02:00
var options = $.extend(true, {}, defaultPieOptions);
2016-11-16 20:35:25 +01:00
var chartType = 'pie';
2015-06-27 17:32:52 +02:00
2022-04-12 18:19:30 +02:00
drawAChart(URL, container, chartType, options, colorData);
}
2018-08-28 05:21:23 +02:00
/**
*
2022-04-12 18:19:30 +02:00
* @param URL
2018-08-28 05:21:23 +02:00
* @param container
*/
2022-04-12 18:19:30 +02:00
function multiCurrencyPieChart(URL, container) {
2018-08-28 05:21:23 +02:00
"use strict";
var colorData = false;
var options = $.extend(true, {}, pieOptionsWithCurrency);
var chartType = 'pie';
2022-04-12 18:19:30 +02:00
drawAChart(URL, container, chartType, options, colorData);
2018-08-28 05:21:23 +02:00
}
2016-11-17 20:02:55 +01:00
/**
2022-04-12 18:19:30 +02:00
* @param URL
2016-11-17 20:02:55 +01:00
* @param container
* @param chartType
* @param options
* @param colorData
2017-11-17 19:31:48 +01:00
* @param today
2016-11-17 20:02:55 +01:00
*/
2022-04-12 18:19:30 +02:00
function drawAChart(URL, container, chartType, options, colorData) {
2017-07-23 08:16:11 +02:00
var containerObj = $('#' + container);
if (containerObj.length === 0) {
2016-11-17 20:02:55 +01:00
return;
}
2022-04-12 18:19:30 +02:00
$.getJSON(URL).done(function (data) {
2017-07-23 08:16:11 +02:00
containerObj.removeClass('general-chart-error');
2020-02-23 13:15:48 +01:00
// if result is empty array, or the labels array is empty, show error.
2022-04-12 18:19:30 +02:00
// console.log(URL);
2020-02-23 14:01:08 +01:00
// console.log(data.length);
// console.log(typeof data.labels);
// console.log(data.labels.length);
2020-02-23 13:15:48 +01:00
if (
// is undefined
typeof data === 'undefined' ||
// is empty
0 === data.length ||
// isn't empty but contains no labels
2020-02-23 14:01:08 +01:00
(typeof data === 'object' && typeof data.labels === 'object' && 0 === data.labels.length)
2020-02-23 13:15:48 +01:00
) {
2016-11-17 20:02:55 +01:00
// remove the chart container + parent
var holder = $('#' + container).parent().parent();
if (holder.hasClass('box') || holder.hasClass('box-body')) {
2016-11-25 16:54:13 +01:00
// find box-body:
var boxBody;
if (!holder.hasClass('box-body')) {
boxBody = holder.find('.box-body');
} else {
boxBody = holder;
}
2016-11-25 16:54:13 +01:00
boxBody.empty().append($('<p>').append($('<em>').text(noDataForChart)));
2016-11-17 20:02:55 +01:00
}
return;
}
if (colorData) {
data = colorizeData(data);
}
if (allCharts.hasOwnProperty(container)) {
allCharts[container].data.datasets = data.datasets;
allCharts[container].data.labels = data.labels;
allCharts[container].update();
} else {
// new chart!
var ctx = document.getElementById(container).getContext("2d");
2017-11-17 19:31:48 +01:00
var chartOpts = {
2016-11-17 20:02:55 +01:00
type: chartType,
data: data,
2017-11-17 19:31:48 +01:00
options: options,
2018-03-11 13:22:34 +01:00
lineAtIndex: [],
annotation: {},
2017-11-17 19:31:48 +01:00
};
2018-03-11 18:40:08 +01:00
if (typeof drawVerticalLine !== 'undefined') {
if (drawVerticalLine !== '') {
// draw line using annotation plugin.
chartOpts.options.annotation = {
annotations: [{
type: 'line',
id: 'a-line-1',
mode: 'vertical',
scaleID: 'x-axis-0',
value: drawVerticalLine,
borderColor: 'red',
borderWidth: 1,
label: {
backgroundColor: 'rgba(0,0,0,0)',
fontFamily: "sans-serif",
fontSize: 12,
fontColor: "#333",
position: "right",
xAdjust: -20,
yAdjust: -125,
enabled: true,
content: todayText
}
}]
};
}
2017-11-17 19:31:48 +01:00
}
allCharts[container] = new Chart(ctx, chartOpts);
2016-11-17 20:02:55 +01:00
}
}).fail(function () {
$('#' + container).addClass('general-chart-error');
});
}