mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 10:47:00 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			437 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			437 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
			Vendored
		
	
	
	
| /*
 | |
|  * charts.js
 | |
|  * Copyright (c) 2019 james@firefly-iii.org
 | |
|  *
 | |
|  * 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.
 | |
|  *
 | |
|  * This program is distributed in the hope that it will be useful,
 | |
|  * 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.
 | |
|  *
 | |
|  * 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/>.
 | |
|  */
 | |
| /** global: Chart, defaultChartOptions, accounting, defaultPieOptions, noDataForChart, todayText */
 | |
| var allCharts = {};
 | |
| 
 | |
| 
 | |
| /*
 | |
|  Make some colours:
 | |
|  */
 | |
| var colourSet = [
 | |
|     [53, 124, 165],
 | |
|     [0, 141, 76], // green
 | |
|     [219, 139, 11],
 | |
|     [202, 25, 90], // paars rood-ish #CA195A
 | |
|     [85, 82, 153],
 | |
|     [66, 133, 244],
 | |
|     [219, 68, 55], // red #DB4437
 | |
|     [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],
 | |
|     [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)");
 | |
| }
 | |
| 
 | |
| Chart.defaults.global.legend.display = false;
 | |
| Chart.defaults.global.animation.duration = 0;
 | |
| Chart.defaults.global.responsive = true;
 | |
| Chart.defaults.global.maintainAspectRatio = false;
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  * @param data
 | |
|  * @returns {{}}
 | |
|  */
 | |
| function colorizeData(data) {
 | |
|     var newData = {};
 | |
|     newData.datasets = [];
 | |
| 
 | |
|     for (var loop = 0; loop < data.count; loop++) {
 | |
|         newData.labels = data.labels;
 | |
|         var dataset = data.datasets[loop];
 | |
|         dataset.fill = false;
 | |
|         dataset.backgroundColor = dataset.borderColor = fillColors[loop];
 | |
|         newData.datasets.push(dataset);
 | |
|     }
 | |
|     return newData;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Function to draw a line chart:
 | |
|  * @param URL
 | |
|  * @param container
 | |
|  */
 | |
| function lineChart(URL, container) {
 | |
|     "use strict";
 | |
| 
 | |
|     var colorData = true;
 | |
|     var options = $.extend(true, {}, defaultChartOptions);
 | |
|     var chartType = 'line';
 | |
| 
 | |
|     drawAChart(URL, container, chartType, options, colorData);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Function to draw a line chart that doesn't start at ZERO.
 | |
|  * @param URL
 | |
|  * @param container
 | |
|  */
 | |
| function lineNoStartZeroChart(URL, container) {
 | |
|     "use strict";
 | |
| 
 | |
|     var colorData = true;
 | |
|     var options = $.extend(true, {}, defaultChartOptions);
 | |
|     var chartType = 'line';
 | |
|     options.scales.yAxes[0].ticks.beginAtZero = false;
 | |
| 
 | |
|     drawAChart(URL, container, chartType, options, colorData);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Overrules the currency the line chart is drawn in.
 | |
|  *
 | |
|  * @param URL
 | |
|  * @param container
 | |
|  */
 | |
| function otherCurrencyLineChart(URL, container, currencySymbol) {
 | |
|     "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';
 | |
| 
 | |
|     drawAChart(URL, container, chartType, options, colorData);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Function to draw a chart with double Y Axes and stacked columns.
 | |
|  *
 | |
|  * @param URL
 | |
|  * @param container
 | |
|  */
 | |
| 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;
 | |
| 
 | |
|     var chartType = 'bar';
 | |
| 
 | |
|     drawAChart(URL, container, chartType, options, colorData);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Function to draw a chart with double Y Axes and non stacked columns.
 | |
|  *
 | |
|  * @param URL
 | |
|  * @param container
 | |
|  */
 | |
| function doubleYNonStackedChart(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"
 | |
|         }
 | |
| 
 | |
|     ];
 | |
|     var chartType = 'bar';
 | |
| 
 | |
|     drawAChart(URL, container, chartType, options, colorData);
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  * @param URL
 | |
|  * @param container
 | |
|  */
 | |
| function columnChart(URL, container) {
 | |
|     "use strict";
 | |
|     var colorData = true;
 | |
|     var options = $.extend(true, {}, defaultChartOptions);
 | |
|     var chartType = 'bar';
 | |
| 
 | |
|     drawAChart(URL, container, chartType, options, colorData);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  * @param URL
 | |
|  * @param container
 | |
|  */
 | |
| function columnChartCustomColours(URL, container) {
 | |
|     "use strict";
 | |
|     var colorData = false;
 | |
|     var options = $.extend(true, {}, defaultChartOptions);
 | |
|     var chartType = 'bar';
 | |
| 
 | |
|     drawAChart(URL, container, chartType, options, colorData);
 | |
| 
 | |
| }
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  * @param URL
 | |
|  * @param container
 | |
|  */
 | |
| function stackedColumnChart(URL, container) {
 | |
|     "use strict";
 | |
| 
 | |
|     var colorData = true;
 | |
|     var options = $.extend(true, {}, defaultChartOptions);
 | |
| 
 | |
|     options.stacked = true;
 | |
|     options.scales.xAxes[0].stacked = true;
 | |
|     options.scales.yAxes[0].stacked = true;
 | |
| 
 | |
|     var chartType = 'bar';
 | |
| 
 | |
|     drawAChart(URL, container, chartType, options, colorData);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  * @param URL
 | |
|  * @param container
 | |
|  */
 | |
| function pieChart(URL, container) {
 | |
|     "use strict";
 | |
| 
 | |
|     var colorData = false;
 | |
|     var options = $.extend(true, {}, defaultPieOptions);
 | |
|     var chartType = 'pie';
 | |
| 
 | |
|     drawAChart(URL, container, chartType, options, colorData);
 | |
| 
 | |
| }
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  * @param URL
 | |
|  * @param container
 | |
|  */
 | |
| function multiCurrencyPieChart(URL, container) {
 | |
|     "use strict";
 | |
| 
 | |
|     var colorData = false;
 | |
|     var options = $.extend(true, {}, pieOptionsWithCurrency);
 | |
|     var chartType = 'pie';
 | |
| 
 | |
|     drawAChart(URL, container, chartType, options, colorData);
 | |
| 
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @param URL
 | |
|  * @param container
 | |
|  * @param chartType
 | |
|  * @param options
 | |
|  * @param colorData
 | |
|  * @param today
 | |
|  */
 | |
| function drawAChart(URL, container, chartType, options, colorData) {
 | |
|     var containerObj = $('#' + container);
 | |
|     if (containerObj.length === 0) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     $.getJSON(URL).done(function (data) {
 | |
|         containerObj.removeClass('general-chart-error');
 | |
| 
 | |
|         // if result is empty array, or the labels array is empty, show error.
 | |
|         // console.log(URL);
 | |
|         // console.log(data.length);
 | |
|         // console.log(typeof data.labels);
 | |
|         // console.log(data.labels.length);
 | |
|         if (
 | |
|             // is undefined
 | |
|             typeof data === 'undefined' ||
 | |
|             // is empty
 | |
|             0 === data.length ||
 | |
|             // isn't empty but contains no labels
 | |
|             (typeof data === 'object' && typeof data.labels === 'object' && 0 === data.labels.length)
 | |
|         ) {
 | |
|             // remove the chart container + parent
 | |
|             var holder = $('#' + container).parent().parent();
 | |
|             if (holder.hasClass('box') || holder.hasClass('box-body')) {
 | |
|                 // find box-body:
 | |
|                 var boxBody;
 | |
|                 if (!holder.hasClass('box-body')) {
 | |
|                     boxBody = holder.find('.box-body');
 | |
|                 } else {
 | |
|                     boxBody = holder;
 | |
|                 }
 | |
|                 boxBody.empty().append($('<p>').append($('<em>').text(noDataForChart)));
 | |
|             }
 | |
|             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");
 | |
|             var chartOpts = {
 | |
|                 type: chartType,
 | |
|                 data: data,
 | |
|                 options: options,
 | |
|                 lineAtIndex: [],
 | |
|                 annotation: {},
 | |
|             };
 | |
|             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
 | |
|                             }
 | |
|                         }]
 | |
|                     };
 | |
|                 }
 | |
|             }
 | |
|             allCharts[container] = new Chart(ctx, chartOpts);
 | |
|         }
 | |
| 
 | |
|     }).fail(function () {
 | |
|         $('#' + container).addClass('general-chart-error');
 | |
|     });
 | |
| }
 |