mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Implemented some more charts.
This commit is contained in:
parent
48624d0a34
commit
f137a08493
@ -101,7 +101,6 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
|||||||
];
|
];
|
||||||
|
|
||||||
$current = clone $start;
|
$current = clone $start;
|
||||||
$today = new Carbon;
|
|
||||||
|
|
||||||
while ($end >= $current) {
|
while ($end >= $current) {
|
||||||
$data['labels'][] = $current->formatLocalized($format);
|
$data['labels'][] = $current->formatLocalized($format);
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
namespace FireflyIII\Generator\Chart\Budget;
|
namespace FireflyIII\Generator\Chart\Budget;
|
||||||
|
|
||||||
|
|
||||||
|
use Config;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Preferences;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ChartJsBudgetChartGenerator
|
* Class ChartJsBudgetChartGenerator
|
||||||
@ -20,6 +22,29 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
|||||||
*/
|
*/
|
||||||
public function budget(Collection $entries)
|
public function budget(Collection $entries)
|
||||||
{
|
{
|
||||||
|
$data = [
|
||||||
|
'count' => 1,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => 'Amount',
|
||||||
|
'data' => [],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.month.' . $language);
|
||||||
|
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||||
|
$data['datasets'][0]['data'][] = $entry[1];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,6 +54,7 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
|||||||
*/
|
*/
|
||||||
public function budgetLimit(Collection $entries)
|
public function budgetLimit(Collection $entries)
|
||||||
{
|
{
|
||||||
|
return $this->budget($entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,14 +81,14 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
|||||||
$spent = [];
|
$spent = [];
|
||||||
$overspent = [];
|
$overspent = [];
|
||||||
$amount = [];
|
$amount = [];
|
||||||
$expenses = [];
|
$expenses = [];
|
||||||
foreach ($entries as $entry) {
|
foreach ($entries as $entry) {
|
||||||
if ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0) {
|
if ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0) {
|
||||||
$left[] = round($entry[1], 2);
|
$left[] = round($entry[1], 2);
|
||||||
$spent[] = round($entry[2], 2);
|
$spent[] = round($entry[2], 2);
|
||||||
$overspent[] = round($entry[3], 2);
|
$overspent[] = round($entry[3], 2);
|
||||||
$amount[] = round($entry[4], 2);
|
$amount[] = round($entry[4], 2);
|
||||||
$expenses[] = round($entry[5], 2);
|
$expenses[] = round($entry[5], 2);
|
||||||
//$data['count']++;
|
//$data['count']++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,5 +113,50 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
|||||||
*/
|
*/
|
||||||
public function year(Collection $budgets, Collection $entries)
|
public function year(Collection $budgets, Collection $entries)
|
||||||
{
|
{
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.month.' . $language);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 0,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($budgets as $budget) {
|
||||||
|
$data['labels'][] = $budget->name;
|
||||||
|
$data['count']++;
|
||||||
|
}
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$array = [
|
||||||
|
'label' => $entry[0]->formatLocalized($format),
|
||||||
|
'data' => [],
|
||||||
|
];
|
||||||
|
array_shift($entry);
|
||||||
|
$array['data'] = $entry;
|
||||||
|
$data['datasets'][] = $array;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
|
||||||
|
|
||||||
|
$chart = new GChart;
|
||||||
|
// add columns:
|
||||||
|
$chart->addColumn(trans('firefly.month'), 'date');
|
||||||
|
foreach ($budgets as $budget) {
|
||||||
|
$chart->addColumn($budget->name, 'number');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
|
||||||
|
$chart->addRowArray($entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
$chart->generate();
|
||||||
|
|
||||||
|
return $chart->getData();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
namespace FireflyIII\Generator\Chart\Category;
|
namespace FireflyIII\Generator\Chart\Category;
|
||||||
|
|
||||||
|
use Config;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Preferences;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,6 +22,27 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
|||||||
*/
|
*/
|
||||||
public function all(Collection $entries)
|
public function all(Collection $entries)
|
||||||
{
|
{
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.month.' . $language);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 1,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => 'Spent',
|
||||||
|
'data' => []
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||||
|
$data['datasets'][0]['data'][] = round($entry[1], 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,7 +65,7 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
|||||||
foreach ($entries as $entry) {
|
foreach ($entries as $entry) {
|
||||||
if ($entry['sum'] != 0) {
|
if ($entry['sum'] != 0) {
|
||||||
$data['labels'][] = $entry['name'];
|
$data['labels'][] = $entry['name'];
|
||||||
$data['datasets'][0]['data'][] = round($entry['sum'],2);
|
$data['datasets'][0]['data'][] = round($entry['sum'], 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +79,8 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
|||||||
*/
|
*/
|
||||||
public function month(Collection $entries)
|
public function month(Collection $entries)
|
||||||
{
|
{
|
||||||
|
return $this->all($entries);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,5 +91,29 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
|||||||
*/
|
*/
|
||||||
public function year(Collection $categories, Collection $entries)
|
public function year(Collection $categories, Collection $entries)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.month.' . $language);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 0,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($categories as $category) {
|
||||||
|
$data['labels'][] = $category->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$date = $entry[0]->formatLocalized($format);
|
||||||
|
array_shift($entry);
|
||||||
|
$data['count']++;
|
||||||
|
$data['datasets'][] = ['label' => $date, 'data' => $entry];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
87
app/Generator/Chart/Report/ChartJsReportChartGenerator.php
Normal file
87
app/Generator/Chart/Report/ChartJsReportChartGenerator.php
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Generator\Chart\Report;
|
||||||
|
|
||||||
|
use Config;
|
||||||
|
use Grumpydictator\Gchart\GChart;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Preferences;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GoogleReportChartGenerator
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Generator\Chart\Report
|
||||||
|
*/
|
||||||
|
class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function yearInOut(Collection $entries)
|
||||||
|
{
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.month.' . $language);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 2,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => trans('firefly.income'),
|
||||||
|
'data' => []
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => trans('firefly.expenses'),
|
||||||
|
'data' => []
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||||
|
$data['datasets'][0]['data'][] = round($entry[1], 2);
|
||||||
|
$data['datasets'][1]['data'][] = round($entry[2], 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $income
|
||||||
|
* @param string $expense
|
||||||
|
* @param int $count
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function yearInOutSummarized($income, $expense, $count)
|
||||||
|
{
|
||||||
|
|
||||||
|
// language:
|
||||||
|
$language = Preferences::get('language', 'en')->data;
|
||||||
|
$format = Config::get('firefly.month.' . $language);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'count' => 2,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => trans('firefly.income'),
|
||||||
|
'data' => []
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => trans('firefly.expenses'),
|
||||||
|
'data' => []
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$data['datasets'][0]['data'][] = round($income, 2);
|
||||||
|
$data['datasets'][1]['data'][] = round($expense, 2);
|
||||||
|
$data['datasets'][0]['data'][] = round(($income / $count), 2);
|
||||||
|
$data['datasets'][1]['data'][] = round(($expense / $count), 2);
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
@ -60,7 +60,7 @@ class BudgetController extends Controller
|
|||||||
$cache->addProperty($last);
|
$cache->addProperty($last);
|
||||||
$cache->addProperty('budget');
|
$cache->addProperty('budget');
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
//return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
$entries = new Collection;
|
$entries = new Collection;
|
||||||
@ -105,7 +105,7 @@ class BudgetController extends Controller
|
|||||||
$cache->addProperty($budget->id);
|
$cache->addProperty($budget->id);
|
||||||
$cache->addProperty($repetition->id);
|
$cache->addProperty($repetition->id);
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
//return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
$entries = new Collection;
|
$entries = new Collection;
|
||||||
@ -215,7 +215,7 @@ class BudgetController extends Controller
|
|||||||
$cache->addProperty('budget');
|
$cache->addProperty('budget');
|
||||||
$cache->addProperty('year');
|
$cache->addProperty('year');
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
//return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
$entries = new Collection;
|
$entries = new Collection;
|
||||||
|
@ -62,7 +62,7 @@ class CategoryController extends Controller
|
|||||||
$cache->addProperty('all');
|
$cache->addProperty('all');
|
||||||
$cache->addProperty('categories');
|
$cache->addProperty('categories');
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
//return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($start <= $end) {
|
while ($start <= $end) {
|
||||||
@ -184,7 +184,7 @@ class CategoryController extends Controller
|
|||||||
$cache->addProperty('category');
|
$cache->addProperty('category');
|
||||||
$cache->addProperty('year');
|
$cache->addProperty('year');
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
//return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
$shared = $shared == 'shared' ? true : false;
|
$shared = $shared == 'shared' ? true : false;
|
||||||
|
@ -55,7 +55,7 @@ class ReportController extends Controller
|
|||||||
$cache->addProperty($year);
|
$cache->addProperty($year);
|
||||||
$cache->addProperty($shared);
|
$cache->addProperty($shared);
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
//return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
$entries = new Collection;
|
$entries = new Collection;
|
||||||
@ -95,7 +95,7 @@ class ReportController extends Controller
|
|||||||
$cache->addProperty($year);
|
$cache->addProperty($year);
|
||||||
$cache->addProperty($shared);
|
$cache->addProperty($shared);
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
//return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
$start = new Carbon($year . '-01-01');
|
$start = new Carbon($year . '-01-01');
|
||||||
|
@ -107,8 +107,8 @@ class FireflyServiceProvider extends ServiceProvider
|
|||||||
$this->app->bind('FireflyIII\Generator\Chart\PiggyBank\PiggyBankChartGenerator', 'FireflyIII\Generator\Chart\PiggyBank\GooglePiggyBankChartGenerator');
|
$this->app->bind('FireflyIII\Generator\Chart\PiggyBank\PiggyBankChartGenerator', 'FireflyIII\Generator\Chart\PiggyBank\GooglePiggyBankChartGenerator');
|
||||||
//$this->app->bind('FireflyIII\Generator\Chart\PiggyBank\PiggyBankChartGenerator', 'FireflyIII\Generator\Chart\PiggyBank\GooglePiggyBankChartGenerator');
|
//$this->app->bind('FireflyIII\Generator\Chart\PiggyBank\PiggyBankChartGenerator', 'FireflyIII\Generator\Chart\PiggyBank\GooglePiggyBankChartGenerator');
|
||||||
|
|
||||||
$this->app->bind('FireflyIII\Generator\Chart\Report\ReportChartGenerator', 'FireflyIII\Generator\Chart\Report\GoogleReportChartGenerator');
|
|
||||||
//$this->app->bind('FireflyIII\Generator\Chart\Report\ReportChartGenerator', 'FireflyIII\Generator\Chart\Report\GoogleReportChartGenerator');
|
//$this->app->bind('FireflyIII\Generator\Chart\Report\ReportChartGenerator', 'FireflyIII\Generator\Chart\Report\GoogleReportChartGenerator');
|
||||||
|
$this->app->bind('FireflyIII\Generator\Chart\Report\ReportChartGenerator', 'FireflyIII\Generator\Chart\Report\ChartJsReportChartGenerator');
|
||||||
|
|
||||||
|
|
||||||
$this->app->bind('FireflyIII\Helpers\Help\HelpInterface', 'FireflyIII\Helpers\Help\Help');
|
$this->app->bind('FireflyIII\Helpers\Help\HelpInterface', 'FireflyIII\Helpers\Help\Help');
|
||||||
|
556
public/js/Chart.StackedBar.js
Normal file
556
public/js/Chart.StackedBar.js
Normal file
@ -0,0 +1,556 @@
|
|||||||
|
(function (factory) {
|
||||||
|
"use strict";
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
// AMD. Register as an anonymous module.
|
||||||
|
define(['chart.js'], factory);
|
||||||
|
} else if (typeof exports === 'object') {
|
||||||
|
// Node/CommonJS
|
||||||
|
module.exports = factory(require('chart.js'));
|
||||||
|
} else {
|
||||||
|
// Global browser
|
||||||
|
factory(Chart);
|
||||||
|
}
|
||||||
|
}(function (Chart) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var helpers = Chart.helpers;
|
||||||
|
|
||||||
|
var defaultConfig = {
|
||||||
|
scaleBeginAtZero : true,
|
||||||
|
|
||||||
|
//Boolean - Whether grid lines are shown across the chart
|
||||||
|
scaleShowGridLines : true,
|
||||||
|
|
||||||
|
//String - Colour of the grid lines
|
||||||
|
scaleGridLineColor : "rgba(0,0,0,.05)",
|
||||||
|
|
||||||
|
//Number - Width of the grid lines
|
||||||
|
scaleGridLineWidth : 1,
|
||||||
|
|
||||||
|
//Boolean - Whether to show horizontal lines (except X axis)
|
||||||
|
scaleShowHorizontalLines: true,
|
||||||
|
|
||||||
|
//Boolean - Whether to show vertical lines (except Y axis)
|
||||||
|
scaleShowVerticalLines: true,
|
||||||
|
|
||||||
|
//Boolean - If there is a stroke on each bar
|
||||||
|
barShowStroke : true,
|
||||||
|
|
||||||
|
//Number - Pixel width of the bar stroke
|
||||||
|
barStrokeWidth : 2,
|
||||||
|
|
||||||
|
//Number - Spacing between each of the X value sets
|
||||||
|
barValueSpacing : 5,
|
||||||
|
|
||||||
|
//Boolean - Whether bars should be rendered on a percentage base
|
||||||
|
relativeBars : false,
|
||||||
|
|
||||||
|
//String - A legend template
|
||||||
|
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>",
|
||||||
|
|
||||||
|
//Boolean - Show total legend
|
||||||
|
showTotal: false,
|
||||||
|
|
||||||
|
//String - Color of total legend
|
||||||
|
totalColor: '#fff',
|
||||||
|
|
||||||
|
//String - Total Label
|
||||||
|
totalLabel: 'Total',
|
||||||
|
|
||||||
|
//Boolean - Hide labels with value set to 0
|
||||||
|
tooltipHideZero: false
|
||||||
|
};
|
||||||
|
|
||||||
|
Chart.Type.extend({
|
||||||
|
name: "StackedBar",
|
||||||
|
defaults : defaultConfig,
|
||||||
|
initialize: function(data){
|
||||||
|
//Expose options as a scope variable here so we can access it in the ScaleClass
|
||||||
|
var options = this.options;
|
||||||
|
|
||||||
|
// Save data as a source for updating of values & methods
|
||||||
|
this.data = data;
|
||||||
|
|
||||||
|
this.ScaleClass = Chart.Scale.extend({
|
||||||
|
offsetGridLines : true,
|
||||||
|
calculateBarX : function(barIndex){
|
||||||
|
return this.calculateX(barIndex);
|
||||||
|
},
|
||||||
|
calculateBarY : function(datasets, dsIndex, barIndex, value){
|
||||||
|
var offset = 0,
|
||||||
|
sum = 0;
|
||||||
|
|
||||||
|
for(var i = 0; i < datasets.length; i++) {
|
||||||
|
sum += datasets[i].bars[barIndex].value;
|
||||||
|
}
|
||||||
|
for(i = dsIndex; i < datasets.length; i++) {
|
||||||
|
if(i === dsIndex && value) {
|
||||||
|
offset += value;
|
||||||
|
} else {
|
||||||
|
offset = +offset + +datasets[i].bars[barIndex].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options.relativeBars) {
|
||||||
|
offset = offset / sum * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.calculateY(offset);
|
||||||
|
},
|
||||||
|
calculateBaseWidth : function(){
|
||||||
|
return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);
|
||||||
|
},
|
||||||
|
calculateBaseHeight : function(){
|
||||||
|
return (this.calculateY(1) - this.calculateY(0));
|
||||||
|
},
|
||||||
|
calculateBarWidth : function(datasetCount){
|
||||||
|
//The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
|
||||||
|
return this.calculateBaseWidth();
|
||||||
|
},
|
||||||
|
calculateBarHeight : function(datasets, dsIndex, barIndex, value) {
|
||||||
|
var sum = 0;
|
||||||
|
|
||||||
|
for(var i = 0; i < datasets.length; i++) {
|
||||||
|
sum += datasets[i].bars[barIndex].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!value) {
|
||||||
|
value = datasets[dsIndex].bars[barIndex].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options.relativeBars) {
|
||||||
|
value = value / sum * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.calculateY(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.datasets = [];
|
||||||
|
|
||||||
|
//Set up tooltip events on the chart
|
||||||
|
if (this.options.showTooltips){
|
||||||
|
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
||||||
|
var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];
|
||||||
|
|
||||||
|
this.eachBars(function(bar){
|
||||||
|
bar.restore(['fillColor', 'strokeColor']);
|
||||||
|
});
|
||||||
|
helpers.each(activeBars, function(activeBar){
|
||||||
|
activeBar.fillColor = activeBar.highlightFill;
|
||||||
|
activeBar.strokeColor = activeBar.highlightStroke;
|
||||||
|
});
|
||||||
|
this.showTooltip(activeBars);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Declare the extension of the default point, to cater for the options passed in to the constructor
|
||||||
|
this.BarClass = Chart.Rectangle.extend({
|
||||||
|
strokeWidth : this.options.barStrokeWidth,
|
||||||
|
showStroke : this.options.barShowStroke,
|
||||||
|
ctx : this.chart.ctx
|
||||||
|
});
|
||||||
|
|
||||||
|
//Iterate through each of the datasets, and build this into a property of the 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);
|
||||||
|
|
||||||
|
helpers.each(dataset.data,function(dataPoint,index){
|
||||||
|
if(!helpers.isNumber(dataPoint)){
|
||||||
|
dataPoint = 0;
|
||||||
|
}
|
||||||
|
//Add a new point for each piece of data, passing any required data to draw.
|
||||||
|
//Add 0 as value if !isNumber (e.g. empty values are useful when 0 values should be hidden in tooltip)
|
||||||
|
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);
|
||||||
|
|
||||||
|
this.eachBars(function(bar, index, datasetIndex){
|
||||||
|
helpers.extend(bar, {
|
||||||
|
base: this.scale.endPoint,
|
||||||
|
height: 0,
|
||||||
|
width : this.scale.calculateBarWidth(this.datasets.length),
|
||||||
|
x: this.scale.calculateBarX(index),
|
||||||
|
y: this.scale.endPoint
|
||||||
|
});
|
||||||
|
bar.save();
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.render();
|
||||||
|
},
|
||||||
|
showTooltip : function(ChartElements, forceRedraw){
|
||||||
|
// Only redraw the chart if we've actually changed what we're hovering on.
|
||||||
|
if (typeof this.activeElements === 'undefined') this.activeElements = [];
|
||||||
|
|
||||||
|
helpers = Chart.helpers;
|
||||||
|
|
||||||
|
var isChanged = (function(Elements){
|
||||||
|
var changed = false;
|
||||||
|
|
||||||
|
if (Elements.length !== this.activeElements.length){
|
||||||
|
changed = true;
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
helpers.each(Elements, function(element, index){
|
||||||
|
if (element !== this.activeElements[index]){
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
return changed;
|
||||||
|
}).call(this, ChartElements);
|
||||||
|
|
||||||
|
if (!isChanged && !forceRedraw){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
this.activeElements = ChartElements;
|
||||||
|
}
|
||||||
|
this.draw();
|
||||||
|
if(this.options.customTooltips){
|
||||||
|
this.options.customTooltips(false);
|
||||||
|
}
|
||||||
|
if (ChartElements.length > 0){
|
||||||
|
// If we have multiple datasets, show a MultiTooltip for all of the data points at that index
|
||||||
|
if (this.datasets && this.datasets.length > 1) {
|
||||||
|
var dataArray,
|
||||||
|
dataIndex;
|
||||||
|
|
||||||
|
for (var i = this.datasets.length - 1; i >= 0; i--) {
|
||||||
|
dataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;
|
||||||
|
dataIndex = helpers.indexOf(dataArray, ChartElements[0]);
|
||||||
|
if (dataIndex !== -1){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var tooltipLabels = [],
|
||||||
|
tooltipColors = [],
|
||||||
|
medianPosition = (function(index) {
|
||||||
|
|
||||||
|
// Get all the points at that particular index
|
||||||
|
var Elements = [],
|
||||||
|
dataCollection,
|
||||||
|
xPositions = [],
|
||||||
|
yPositions = [],
|
||||||
|
xMax,
|
||||||
|
yMax,
|
||||||
|
xMin,
|
||||||
|
yMin;
|
||||||
|
helpers.each(this.datasets, function(dataset){
|
||||||
|
dataCollection = dataset.points || dataset.bars || dataset.segments;
|
||||||
|
if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){
|
||||||
|
Elements.push(dataCollection[dataIndex]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var total = {
|
||||||
|
datasetLabel: this.options.totalLabel,
|
||||||
|
value: 0,
|
||||||
|
fillColor: this.options.totalColor,
|
||||||
|
strokeColor: this.options.totalColor
|
||||||
|
};
|
||||||
|
|
||||||
|
helpers.each(Elements, function(element) {
|
||||||
|
if (this.options.tooltipHideZero && element.value === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xPositions.push(element.x);
|
||||||
|
yPositions.push(element.y);
|
||||||
|
|
||||||
|
total.value += element.value;
|
||||||
|
|
||||||
|
//Include any colour information about the element
|
||||||
|
tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));
|
||||||
|
tooltipColors.push({
|
||||||
|
fill: element._saved.fillColor || element.fillColor,
|
||||||
|
stroke: element._saved.strokeColor || element.strokeColor
|
||||||
|
});
|
||||||
|
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
if (this.options.showTotal) {
|
||||||
|
tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, total));
|
||||||
|
tooltipColors.push({
|
||||||
|
fill: total.fillColor,
|
||||||
|
stroke: total.strokeColor
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
yMin = helpers.min(yPositions);
|
||||||
|
yMax = helpers.max(yPositions);
|
||||||
|
|
||||||
|
xMin = helpers.min(xPositions);
|
||||||
|
xMax = helpers.max(xPositions);
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: (xMin > this.chart.width/2) ? xMin : xMax,
|
||||||
|
y: (yMin + yMax)/2
|
||||||
|
};
|
||||||
|
}).call(this, dataIndex);
|
||||||
|
|
||||||
|
new Chart.MultiTooltip({
|
||||||
|
x: medianPosition.x,
|
||||||
|
y: medianPosition.y,
|
||||||
|
xPadding: this.options.tooltipXPadding,
|
||||||
|
yPadding: this.options.tooltipYPadding,
|
||||||
|
xOffset: this.options.tooltipXOffset,
|
||||||
|
fillColor: this.options.tooltipFillColor,
|
||||||
|
textColor: this.options.tooltipFontColor,
|
||||||
|
fontFamily: this.options.tooltipFontFamily,
|
||||||
|
fontStyle: this.options.tooltipFontStyle,
|
||||||
|
fontSize: this.options.tooltipFontSize,
|
||||||
|
titleTextColor: this.options.tooltipTitleFontColor,
|
||||||
|
titleFontFamily: this.options.tooltipTitleFontFamily,
|
||||||
|
titleFontStyle: this.options.tooltipTitleFontStyle,
|
||||||
|
titleFontSize: this.options.tooltipTitleFontSize,
|
||||||
|
cornerRadius: this.options.tooltipCornerRadius,
|
||||||
|
labels: tooltipLabels,
|
||||||
|
legendColors: tooltipColors,
|
||||||
|
legendColorBackground : this.options.multiTooltipKeyBackground,
|
||||||
|
title: ChartElements[0].label,
|
||||||
|
chart: this.chart,
|
||||||
|
ctx: this.chart.ctx,
|
||||||
|
custom: this.options.customTooltips
|
||||||
|
}).draw();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
helpers.each(ChartElements, function(Element) {
|
||||||
|
var tooltipPosition = Element.tooltipPosition();
|
||||||
|
new Chart.Tooltip({
|
||||||
|
x: Math.round(tooltipPosition.x),
|
||||||
|
y: Math.round(tooltipPosition.y),
|
||||||
|
xPadding: this.options.tooltipXPadding,
|
||||||
|
yPadding: this.options.tooltipYPadding,
|
||||||
|
fillColor: this.options.tooltipFillColor,
|
||||||
|
textColor: this.options.tooltipFontColor,
|
||||||
|
fontFamily: this.options.tooltipFontFamily,
|
||||||
|
fontStyle: this.options.tooltipFontStyle,
|
||||||
|
fontSize: this.options.tooltipFontSize,
|
||||||
|
caretHeight: this.options.tooltipCaretSize,
|
||||||
|
cornerRadius: this.options.tooltipCornerRadius,
|
||||||
|
text: helpers.template(this.options.tooltipTemplate, Element),
|
||||||
|
chart: this.chart,
|
||||||
|
custom: this.options.customTooltips
|
||||||
|
}).draw();
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
update : function(){
|
||||||
|
|
||||||
|
//Iterate through each of the datasets, and build this into a property of the chart
|
||||||
|
helpers.each(this.data.datasets,function(dataset,datasetIndex){
|
||||||
|
|
||||||
|
helpers.extend(this.datasets[datasetIndex], {
|
||||||
|
label : dataset.label || null,
|
||||||
|
fillColor : dataset.fillColor,
|
||||||
|
strokeColor : dataset.strokeColor,
|
||||||
|
});
|
||||||
|
|
||||||
|
helpers.each(dataset.data,function(dataPoint,index){
|
||||||
|
helpers.extend(this.datasets[datasetIndex].bars[index], {
|
||||||
|
value : dataPoint,
|
||||||
|
label : this.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.scale.update();
|
||||||
|
// Reset any highlight colours before updating.
|
||||||
|
helpers.each(this.activeElements, function(activeElement){
|
||||||
|
activeElement.restore(['fillColor', 'strokeColor']);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.eachBars(function(bar){
|
||||||
|
bar.save();
|
||||||
|
});
|
||||||
|
this.render();
|
||||||
|
},
|
||||||
|
eachBars : function(callback){
|
||||||
|
helpers.each(this.datasets,function(dataset, datasetIndex){
|
||||||
|
helpers.each(dataset.bars, callback, this, datasetIndex);
|
||||||
|
},this);
|
||||||
|
},
|
||||||
|
getBarsAtEvent : function(e){
|
||||||
|
var barsArray = [],
|
||||||
|
eventPosition = helpers.getRelativePosition(e),
|
||||||
|
datasetIterator = function(dataset){
|
||||||
|
barsArray.push(dataset.bars[barIndex]);
|
||||||
|
},
|
||||||
|
barIndex;
|
||||||
|
|
||||||
|
for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
|
||||||
|
for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {
|
||||||
|
if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){
|
||||||
|
helpers.each(this.datasets, datasetIterator);
|
||||||
|
return barsArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return barsArray;
|
||||||
|
},
|
||||||
|
buildScale : function(labels){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var dataTotal = function(){
|
||||||
|
var values = [];
|
||||||
|
helpers.each(self.datasets, function(dataset) {
|
||||||
|
helpers.each(dataset.bars, function(bar, barIndex) {
|
||||||
|
if(!values[barIndex]) values[barIndex] = 0;
|
||||||
|
if(self.options.relativeBars) {
|
||||||
|
values[barIndex] = 100;
|
||||||
|
} else {
|
||||||
|
values[barIndex] = +values[barIndex] + +bar.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return values;
|
||||||
|
};
|
||||||
|
|
||||||
|
var scaleOptions = {
|
||||||
|
templateString : this.options.scaleLabel,
|
||||||
|
height : this.chart.height,
|
||||||
|
width : this.chart.width,
|
||||||
|
ctx : this.chart.ctx,
|
||||||
|
textColor : this.options.scaleFontColor,
|
||||||
|
fontSize : this.options.scaleFontSize,
|
||||||
|
fontStyle : this.options.scaleFontStyle,
|
||||||
|
fontFamily : this.options.scaleFontFamily,
|
||||||
|
valuesCount : labels.length,
|
||||||
|
beginAtZero : this.options.scaleBeginAtZero,
|
||||||
|
integersOnly : this.options.scaleIntegersOnly,
|
||||||
|
calculateYRange: function(currentHeight){
|
||||||
|
var updatedRanges = helpers.calculateScaleRange(
|
||||||
|
dataTotal(),
|
||||||
|
currentHeight,
|
||||||
|
this.fontSize,
|
||||||
|
this.beginAtZero,
|
||||||
|
this.integersOnly
|
||||||
|
);
|
||||||
|
helpers.extend(this, updatedRanges);
|
||||||
|
},
|
||||||
|
xLabels : this.options.xLabels || labels,
|
||||||
|
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
|
||||||
|
lineWidth : this.options.scaleLineWidth,
|
||||||
|
lineColor : this.options.scaleLineColor,
|
||||||
|
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
|
||||||
|
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
|
||||||
|
showHorizontalLines : this.options.scaleShowHorizontalLines,
|
||||||
|
showVerticalLines : this.options.scaleShowVerticalLines,
|
||||||
|
padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
|
||||||
|
showLabels : this.options.scaleShowLabels,
|
||||||
|
display : this.options.showScale
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.options.scaleOverride){
|
||||||
|
helpers.extend(scaleOptions, {
|
||||||
|
calculateYRange: helpers.noop,
|
||||||
|
steps: this.options.scaleSteps,
|
||||||
|
stepValue: this.options.scaleStepWidth,
|
||||||
|
min: this.options.scaleStartValue,
|
||||||
|
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.scale = new this.ScaleClass(scaleOptions);
|
||||||
|
},
|
||||||
|
addData : function(valuesArray,label){
|
||||||
|
//Map the values array for each of the datasets
|
||||||
|
helpers.each(valuesArray,function(value,datasetIndex){
|
||||||
|
if (helpers.isNumber(value)){
|
||||||
|
//Add a new point for each piece of data, passing any required data to draw.
|
||||||
|
//Add 0 as value if !isNumber (e.g. empty values are useful when 0 values should be hidden in tooltip)
|
||||||
|
this.datasets[datasetIndex].bars.push(new this.BarClass({
|
||||||
|
value : helpers.isNumber(value)?value:0,
|
||||||
|
label : label,
|
||||||
|
x: this.scale.calculateBarX(this.scale.valuesCount+1),
|
||||||
|
y: this.scale.endPoint,
|
||||||
|
width : this.scale.calculateBarWidth(this.datasets.length),
|
||||||
|
base : this.scale.endPoint,
|
||||||
|
strokeColor : this.datasets[datasetIndex].strokeColor,
|
||||||
|
fillColor : this.datasets[datasetIndex].fillColor
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},this);
|
||||||
|
|
||||||
|
this.scale.addXLabel(label);
|
||||||
|
//Then re-render the chart.
|
||||||
|
this.update();
|
||||||
|
},
|
||||||
|
removeData : function(){
|
||||||
|
this.scale.removeXLabel();
|
||||||
|
//Then re-render the chart.
|
||||||
|
helpers.each(this.datasets,function(dataset){
|
||||||
|
dataset.bars.shift();
|
||||||
|
},this);
|
||||||
|
this.update();
|
||||||
|
},
|
||||||
|
reflow : function(){
|
||||||
|
helpers.extend(this.BarClass.prototype,{
|
||||||
|
y: this.scale.endPoint,
|
||||||
|
base : this.scale.endPoint
|
||||||
|
});
|
||||||
|
var newScaleProps = helpers.extend({
|
||||||
|
height : this.chart.height,
|
||||||
|
width : this.chart.width
|
||||||
|
});
|
||||||
|
this.scale.update(newScaleProps);
|
||||||
|
},
|
||||||
|
draw : function(ease){
|
||||||
|
var easingDecimal = ease || 1;
|
||||||
|
this.clear();
|
||||||
|
|
||||||
|
var ctx = this.chart.ctx;
|
||||||
|
|
||||||
|
this.scale.draw(easingDecimal);
|
||||||
|
|
||||||
|
//Draw all the bars for each dataset
|
||||||
|
helpers.each(this.datasets,function(dataset,datasetIndex){
|
||||||
|
helpers.each(dataset.bars,function(bar,index){
|
||||||
|
var y = this.scale.calculateBarY(this.datasets, datasetIndex, index, bar.value),
|
||||||
|
height = this.scale.calculateBarHeight(this.datasets, datasetIndex, index, bar.value);
|
||||||
|
|
||||||
|
//Transition then draw
|
||||||
|
if(bar.value > 0) {
|
||||||
|
bar.transition({
|
||||||
|
base : this.scale.endPoint - (Math.abs(height) - Math.abs(y)),
|
||||||
|
x : this.scale.calculateBarX(index),
|
||||||
|
y : Math.abs(y),
|
||||||
|
height : Math.abs(height),
|
||||||
|
width : this.scale.calculateBarWidth(this.datasets.length)
|
||||||
|
}, easingDecimal).draw();
|
||||||
|
}
|
||||||
|
},this);
|
||||||
|
},this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}));
|
@ -4,22 +4,36 @@
|
|||||||
Make some colours:
|
Make some colours:
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
#555299
|
#555299
|
||||||
#4285f4
|
#4285f4
|
||||||
#db4437
|
#
|
||||||
#f4b400
|
#
|
||||||
#0f9d58
|
#
|
||||||
#ab47bc
|
#
|
||||||
#00acc1
|
#
|
||||||
#ff7043
|
#
|
||||||
#9e9d24
|
#
|
||||||
#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
#", "#", "#", "#"],
|
||||||
*/
|
*/
|
||||||
var colourSet = [
|
var colourSet = [
|
||||||
[53, 124, 165],
|
[53, 124, 165],
|
||||||
[0, 141, 76],
|
[0, 141, 76],
|
||||||
[219, 139, 11],
|
[219, 139, 11],
|
||||||
[202, 25, 90]
|
[202, 25, 90],
|
||||||
|
[85, 82, 153],
|
||||||
|
[66, 133, 244],
|
||||||
|
[219, 68, 55],
|
||||||
|
[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 = [];
|
var fillColors = [];
|
||||||
@ -153,6 +167,7 @@ function columnChart(URL, container, options) {
|
|||||||
for (var i = 0; i < data.count; i++) {
|
for (var i = 0; i < data.count; i++) {
|
||||||
newData.labels = data.labels;
|
newData.labels = data.labels;
|
||||||
var dataset = data.datasets[i];
|
var dataset = data.datasets[i];
|
||||||
|
console.log('Now at index ' + i + ' (count is ' + fillColors.length + ')');
|
||||||
dataset.fillColor = fillColors[i];
|
dataset.fillColor = fillColors[i];
|
||||||
dataset.strokeColor = strokePointHighColors[i];
|
dataset.strokeColor = strokePointHighColors[i];
|
||||||
dataset.pointColor = strokePointHighColors[i];
|
dataset.pointColor = strokePointHighColors[i];
|
||||||
@ -178,7 +193,36 @@ function columnChart(URL, container, options) {
|
|||||||
*/
|
*/
|
||||||
function stackedColumnChart(URL, container, options) {
|
function stackedColumnChart(URL, container, options) {
|
||||||
"use strict";
|
"use strict";
|
||||||
columnChart(URL, container, options);
|
$.getJSON(URL).success(function (data) {
|
||||||
|
|
||||||
|
var ctx = document.getElementById(container).getContext("2d");
|
||||||
|
var newData = {};
|
||||||
|
newData.datasets = [];
|
||||||
|
console.log('----');
|
||||||
|
console.log('URL: ' + URL);
|
||||||
|
console.log('Total datasets: ' + data.datasets.length);
|
||||||
|
console.log('data.count: ' + data.count);
|
||||||
|
console.log('----');
|
||||||
|
|
||||||
|
for (var i = 0; i < data.count; i++) {
|
||||||
|
newData.labels = data.labels;
|
||||||
|
var dataset = data.datasets[i];
|
||||||
|
console.log('Now at index ' + i + ' (count is ' + fillColors.length + ')');
|
||||||
|
dataset.fillColor = fillColors[i];
|
||||||
|
dataset.strokeColor = strokePointHighColors[i];
|
||||||
|
dataset.pointColor = strokePointHighColors[i];
|
||||||
|
dataset.pointStrokeColor = "#fff";
|
||||||
|
dataset.pointHighlightFill = "#fff";
|
||||||
|
dataset.pointHighlightStroke = strokePointHighColors[i];
|
||||||
|
newData.datasets.push(dataset);
|
||||||
|
}
|
||||||
|
console.log(newData);
|
||||||
|
new Chart(ctx).StackedBar(newData, options);
|
||||||
|
|
||||||
|
}).fail(function () {
|
||||||
|
$('#' + container).addClass('google-chart-error');
|
||||||
|
});
|
||||||
|
console.log('URL for column chart : ' + URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,13 +12,17 @@ $(function () {
|
|||||||
|
|
||||||
function drawChart() {
|
function drawChart() {
|
||||||
"use strict";
|
"use strict";
|
||||||
columnChart('chart/report/in-out/' + year + shared, 'income-expenses-chart');
|
if (typeof columnChart !== undefined) {
|
||||||
columnChart('chart/report/in-out-sum/' + year + shared, 'income-expenses-sum-chart');
|
columnChart('chart/report/in-out/' + year + shared, 'income-expenses-chart');
|
||||||
|
columnChart('chart/report/in-out-sum/' + year + shared, 'income-expenses-sum-chart');
|
||||||
stackedColumnChart('chart/budget/year/' + year + shared, 'budgets');
|
}
|
||||||
stackedColumnChart('chart/category/year/' + year + shared, 'categories');
|
if (typeof stackedColumnChart !== undefined) {
|
||||||
|
stackedColumnChart('chart/budget/year/' + year + shared, 'budgets');
|
||||||
lineChart('/chart/account/month/' + year + '/' + month + shared, 'account-balances-chart');
|
stackedColumnChart('chart/category/year/' + year + shared, 'categories');
|
||||||
|
}
|
||||||
|
if (typeof lineChart !== undefined && typeof month !== 'undefined') {
|
||||||
|
lineChart('/chart/account/month/' + year + '/' + month + shared, 'account-balances-chart');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +27,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div id="budgetOverview"></div>
|
{% if Config.get('firefly.chart') == 'google' %}
|
||||||
|
<div id="budgetOverview"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||||
|
<canvas id="budgetOverview" style="width:100%;height:400px;"></canvas>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -12,7 +12,12 @@
|
|||||||
<h3 class="box-title">{{ 'overview'|_ }} (month)</h3>
|
<h3 class="box-title">{{ 'overview'|_ }} (month)</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div id="month"></div>
|
{% if Config.get('firefly.chart') == 'google' %}
|
||||||
|
<div id="month"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||||
|
<canvas id="month" style="width:100%;height:350px;"></canvas>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -22,7 +27,12 @@
|
|||||||
<h3 class="box-title">{{ 'overview'|_ }} (all)</h3>
|
<h3 class="box-title">{{ 'overview'|_ }} (all)</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div id="all"></div>
|
{% if Config.get('firefly.chart') == 'google' %}
|
||||||
|
<div id="all"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||||
|
<canvas id="all" style="width:100%;height:350px;"></canvas>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,7 +13,12 @@
|
|||||||
<h3 class="box-title">{{ 'incomeVsExpenses'|_ }}</h3>
|
<h3 class="box-title">{{ 'incomeVsExpenses'|_ }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div id="income-expenses-chart"></div>
|
{% if Config.get('firefly.chart') == 'google' %}
|
||||||
|
<div id="income-expenses-chart"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||||
|
<canvas id="income-expenses-chart" style="width:100%;height:400px;"></canvas>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -23,7 +28,12 @@
|
|||||||
<h3 class="box-title">{{ 'incomeVsExpenses'|_ }}</h3>
|
<h3 class="box-title">{{ 'incomeVsExpenses'|_ }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div id="income-expenses-sum-chart"></div>
|
{% if Config.get('firefly.chart') == 'google' %}
|
||||||
|
<div id="income-expenses-sum-chart"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||||
|
<canvas id="income-expenses-sum-chart" style="width:300px;height:400px;"></canvas>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -49,7 +59,12 @@
|
|||||||
<h3 class="box-title">{{ 'categories'|_ }}</h3>
|
<h3 class="box-title">{{ 'categories'|_ }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div id="categories"></div>
|
{% if Config.get('firefly.chart') == 'google' %}
|
||||||
|
<div id="categories"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||||
|
<canvas id="categories" style="width:100%;height:400px;"></canvas>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -61,7 +76,12 @@
|
|||||||
<h3 class="box-title">{{ 'budgets'|_ }}</h3>
|
<h3 class="box-title">{{ 'budgets'|_ }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div id="budgets"></div>
|
{% if Config.get('firefly.chart') == 'google' %}
|
||||||
|
<div id="budgets"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||||
|
<canvas id="budgets" style="width:100%;height:400px;"></canvas>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -76,12 +96,15 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if Config.get('firefly.chart') == 'chartjs' %}
|
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||||
<script type="text/javascript" src="js/Chart.min.js"></script>
|
<script type="text/javascript" src="js/Chart.min.js"></script>
|
||||||
|
<script type="text/javascript" src="js/Chart.StackedBar.js"></script>
|
||||||
<script type="text/javascript" src="js/charts.js"></script>
|
<script type="text/javascript" src="js/charts.js"></script>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var year = '{{start.year}}';
|
var year = '{{start.year}}';
|
||||||
var shared = {% if shared %}'/shared'{% else %}''{% endif %};
|
var shared = {% if shared %}'/shared'
|
||||||
|
{% else %}''{% endif %};
|
||||||
var incomeTopLength = {{ incomeTopLength }};
|
var incomeTopLength = {{ incomeTopLength }};
|
||||||
var expenseTopLength = {{ expenseTopLength }};
|
var expenseTopLength = {{ expenseTopLength }};
|
||||||
var incomeRestShow = false; // starts hidden.
|
var incomeRestShow = false; // starts hidden.
|
||||||
|
Loading…
Reference in New Issue
Block a user