<!DOCTYPE html>
<html>
<head>
<title>CHARTIST Demo project</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/chartist/0.11.0/chartist.min.css" />
<link rel="stylesheet" href="style.css">
</head>
<body>
<div ng-controller="chartistController as chartist" class="chart-container">
<chartist class="ct-chart" chartist-data="chartist.barData" chartist-chart-options="chartist.barOptions" chartist-chart-type="Bar"></chartist>
<chartist class="ct-chart" chartist-data="chartist.lineData" chartist-chart-options="chartist.lineOptions" chartist-chart-type="Line"></chartist>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartist/0.11.0/chartist.min.js"></script>
<script src="angular-chartist.js"></script>
<script src="chartist-plugin-legend.js"></script>
<script src="chartist-plugin-targetline.js"></script>
<script src="script.js"></script>
</body>
</html>
.chart-container {
position: relative;
}
$ct-series-colors: ( #FA8203, #42D0EC) !default;
.chart-container > chartist {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 300px;
}
.ct-series-a .ct-line {
stroke: #FA8203;
}
.ct-series-a .ct-point {
fill:none;
stroke-width: 12px;
stroke: #FA8203;
}
.ct-series-a .ct-grid {
stroke: #FA8203;
}
.ct-target-line {
stroke: #424949;
stroke-width: 1px;
stroke-dasharray: 0px;
shape-rendering: crispEdges;
}
.ct-series-a .ct-bar {
stroke-width: 40;
stroke: #54B286;
}
.ct-series-a .ct-bar[ct|meta="positiveSeries"] {
stroke: #54B286;
stroke-width: 40;
}
.ct-series-a .ct-bar[ct|meta="negativeSeries"] {
stroke: #F15A73;
stroke-width: 40;
}
.ct-legend {
position: relative;
z-index: 10;
list-style: none;
top:400;
li {
position: relative;
padding-left: 10px;
margin-bottom: 3px;
background-color: transparent;
}
li:before {
width: 2px;
height: 12px;
position: absolute;
left: 0;
content: '';
border: 3px solid transparent;
border-radius: 2px;
}
li.inactive:before {
background: transparent;
}
&.ct-legend-inside {
position: absolute;
top: 0;
right: 0;
}
@for $i from 0 to length($ct-series-colors) {
.ct-series-#{$i}:before {
background-color: nth($ct-series-colors, $i + 1);
border-color: nth($ct-series-colors, $i + 1);
}
}
}
angular.module('app', [
'angular-chartist'
]);
var appController = function() {
this.barOptions = {
title: {
text: "Sample"
},
axisY: {
high: 3000,
low: -500,
showGrid: false
},
axisX: {
showGrid: false
},
plugins: [
Chartist.plugins.legend({
legendNames: ['Kumul.Ertrag', 'Ertrag'],
position: 'top'
}),
Chartist.plugins.ctTargetLine({
value: 424.5
})
]
};
this.lineOptions = {
title: {
text: "Sample"
},
axisY: {
high: 3000,
low: -500,
showGrid: false,
showLabel: false
},
axisX: {
showGrid: true,
showLabel: false
},
chartPadding: {
left: 40
},
showPoint: true,
lineSmooth: false,
plugins: [
Chartist.plugins.legend({
legendNames: ['Kumul.Ertrag', 'Ertrag'],
position: 'top'
})
]
};
/*this.events = {
draw: function(data) {
if (data.type === 'bar') {
data.element.attr({
style: 'stroke-width: 40'
});
}
}
};*/
var barSeries = [];
var barSeriesData = [524.5, -171.1, 827.2, 285.8, 917.4, 302.1, 680.8, 220.9, -270.6, 430.0, -235.8, 19.0];
angular.forEach(barSeriesData, function(val, key) {
if (val < 0) {
barSeries.push({
meta: "negativeSeries",
value: val
});
} else {
barSeries.push({
meta: "positiveSeries",
value: val
});
}
});
this.barData = {
title: {
text: "Sample"
},
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
series: [barSeries]
};
this.lineData = {
title: {
text: "Sample"
},
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
series: [
[344.5, 273.1, 560, 885.8, 1877.4, 2004.1, 2483.8, 2604.8, 2433.2, 2764.4, 2529, 2538]
]
}
}
angular.module('app').controller('chartistController', appController);
angular.bootstrap(document, ['app']);
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('angular'), require('chartist')) :
typeof define === 'function' && define.amd ? define(['angular', 'chartist'], factory) :
(global['angular-chartist'] = factory(global.angular,global.Chartist));
}(this, (function (angular,Chartist) { 'use strict';
angular = angular && 'default' in angular ? angular['default'] : angular;
Chartist = Chartist && 'default' in Chartist ? Chartist['default'] : Chartist;
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var angularChartistModule = angular.module('angular-chartist', []);
var AngularChartistCtrl = function () {
AngularChartistCtrl.$inject = ["$scope", "$element"];
function AngularChartistCtrl($scope, $element) {
'ngInject';
var _this = this;
classCallCheck(this, AngularChartistCtrl);
this.data = $scope.data;
this.chartType = $scope.chartType;
this.events = $scope.events() || {};
this.options = $scope.chartOptions() || null;
this.responsiveOptions = $scope.responsiveOptions() || null;
this.element = $element[0];
this.renderChart();
$scope.$watch(function () {
return {
data: $scope.data,
chartType: $scope.chartType,
chartOptions: $scope.chartOptions() || null,
responsiveOptions: $scope.responsiveOptions() || null,
events: $scope.events() || {}
};
}, this.update.bind(this), true);
$scope.$on('$destroy', function () {
if (_this.chart) {
_this.chart.detach();
}
});
}
createClass(AngularChartistCtrl, [{
key: 'bindEvents',
value: function bindEvents() {
var _this2 = this;
Object.keys(this.events).forEach(function (eventName) {
_this2.chart.on(eventName, _this2.events[eventName]);
});
}
}, {
key: 'unbindEvents',
value: function unbindEvents(events) {
var _this3 = this;
Object.keys(events).forEach(function (eventName) {
_this3.chart.off(eventName, events[eventName]);
});
}
}, {
key: 'renderChart',
value: function renderChart() {
// ensure that the chart does not get created without data
if (this.data) {
this.chart = Chartist[this.chartType](this.element, this.data, this.options, this.responsiveOptions);
this.bindEvents();
return this.chart;
}
}
}, {
key: 'update',
value: function update(newConfig, oldConfig) {
// Update controller with new configuration
this.chartType = newConfig.chartType;
this.data = newConfig.data;
this.options = newConfig.chartOptions;
this.responsiveOptions = newConfig.responsiveOptions;
this.events = newConfig.events;
// If chart type changed we need to recreate whole chart, otherwise we can update
if (!this.chart || newConfig.chartType !== oldConfig.chartType) {
this.renderChart();
} else {
if (!angular.equals(newConfig.events, oldConfig.events)) {
this.unbindEvents(oldConfig.events);
this.bindEvents();
}
this.chart.update(this.data, this.options);
}
}
}]);
return AngularChartistCtrl;
}();
angularChartistModule.controller('AngularChartistCtrl', AngularChartistCtrl).directive('chartist', function () {
'ngInject';
return {
restrict: 'EA',
scope: {
// mandatory
data: '=chartistData',
chartType: '@chartistChartType',
// optional
events: '&chartistEvents',
chartOptions: '&chartistChartOptions',
responsiveOptions: '&chartistResponsiveOptions'
},
controller: 'AngularChartistCtrl'
};
});
var angularChartist = angularChartistModule.name;
return angularChartist;
})));
angular.module('app').service(html2pdfService);
var html2pdfService = function() {
this.html
}
angular.module('app').service(chart2imgService);
var chart2imgService = function() {
}
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['chartist'], function (chartist) {
return (root.returnExportsGlobal = factory(chartist));
});
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like enviroments that support module.exports,
// like Node.
module.exports = factory(require('chartist'));
} else {
root['Chartist.plugins.legend'] = factory(root.Chartist);
}
}(this, function (Chartist) {
/**
* This Chartist plugin creates a legend to show next to the chart.
*
*/
'use strict';
var defaultOptions = {
className: '',
classNames: false,
removeAll: false,
legendNames: false,
clickable: true,
onClick: null,
position: 'top'
};
Chartist.plugins = Chartist.plugins || {};
Chartist.plugins.legend = function (options) {
function compareNumbers(a, b) {
return a - b;
}
// Catch invalid options
if (options && options.position) {
if (!(options.position === 'top' || options.position === 'bottom' || options.position instanceof HTMLElement)) {
throw Error('The position you entered is not a valid position');
}
if(options.position instanceof HTMLElement){
// Detatch DOM element from options object, because Chartist.extend currently chokes on circular references present in HTMLElements
var cachedDOMPosition = options.position;
delete options.position;
}
}
options = Chartist.extend({}, defaultOptions, options);
if(cachedDOMPosition){
// Reattatch the DOM Element position if it was removed before
options.position = cachedDOMPosition
}
return function legend(chart) {
var existingLegendElement = chart.container.querySelector('.ct-legend');
if (existingLegendElement) {
// Clear legend if already existing.
existingLegendElement.parentNode.removeChild(existingLegendElement);
}
// Set a unique className for each series so that when a series is removed,
// the other series still have the same color.
if (options.clickable) {
var newSeries = chart.data.series.map(function (series, seriesIndex) {
if (typeof series !== 'object') {
series = {
value: series
};
}
series.className = series.className || chart.options.classNames.series + '-' + Chartist.alphaNumerate(seriesIndex);
return series;
});
chart.data.series = newSeries;
}
var legendElement = document.createElement('ul'),
isPieChart = chart instanceof Chartist.Pie;
legendElement.className = 'ct-legend';
if (chart instanceof Chartist.Pie) {
legendElement.classList.add('ct-legend-inside');
}
if (typeof options.className === 'string' && options.className.length > 0) {
legendElement.classList.add(options.className);
}
if (chart.options.width) {
legendElement.style.cssText = 'width: ' + chart.options.width + 'px;margin: 0 auto;';
}
var removedSeries = [],
originalSeries = chart.data.series.slice(0);
// Get the right array to use for generating the legend.
var legendNames = chart.data.series,
useLabels = isPieChart && chart.data.labels && chart.data.labels.length;
if (useLabels) {
var originalLabels = chart.data.labels.slice(0);
legendNames = chart.data.labels;
}
legendNames = options.legendNames || legendNames;
// Check if given class names are viable to append to legends
var classNamesViable = (Array.isArray(options.classNames) && (options.classNames.length === legendNames.length));
// Loop through all legends to set each name in a list item.
legendNames.forEach(function (legend, i) {
var li = document.createElement('li');
li.className = 'ct-series-' + i;
// Append specific class to a legend element, if viable classes are given
if (classNamesViable) {
li.className += ' ' + options.classNames[i];
}
li.setAttribute('data-legend', i);
li.textContent = legend.name || legend;
legendElement.appendChild(li);
});
chart.on('created', function (data) {
// Append the legend element to the DOM
if(!(options.position instanceof HTMLElement))
{
switch (options.position) {
case 'top':
chart.container.insertBefore(legendElement, chart.container.childNodes[0]);
break;
case 'bottom':
chart.container.insertBefore(legendElement, null);
break;
}
}
else {
// Appends the legend element as the last child of a given HTMLElement
options.position.insertBefore(legendElement, null);
}
});
if (options.clickable) {
legendElement.addEventListener('click', function (e) {
var li = e.target;
if (li.parentNode !== legendElement || !li.hasAttribute('data-legend'))
return;
e.preventDefault();
var seriesIndex = parseInt(li.getAttribute('data-legend')),
removedSeriesIndex = removedSeries.indexOf(seriesIndex);
if (removedSeriesIndex > -1) {
// Add to series again.
removedSeries.splice(removedSeriesIndex, 1);
li.classList.remove('inactive');
} else {
if (!options.removeAll) {
// Remove from series, only if a minimum of one series is still visible.
if ( chart.data.series.length > 1) {
removedSeries.push(seriesIndex);
li.classList.add('inactive');
}
// Set all series as active.
else {
removedSeries = [];
var seriesItems = Array.prototype.slice.call(legendElement.childNodes);
seriesItems.forEach(function (item) {
item.classList.remove('inactive');
});
}
}
else {
// Remove series unaffected if it is the last or not
removedSeries.push(seriesIndex);
li.classList.add('inactive');
}
}
// Reset the series to original and remove each series that
// is still removed again, to remain index order.
var seriesCopy = originalSeries.slice(0);
if (useLabels) {
var labelsCopy = originalLabels.slice(0);
}
// Reverse sort the removedSeries to prevent removing the wrong index.
removedSeries.sort(compareNumbers).reverse();
removedSeries.forEach(function (series) {
seriesCopy.splice(series, 1);
if (useLabels) {
labelsCopy.splice(series, 1);
}
});
if (options.onClick) {
options.onClick(chart, e);
}
chart.data.series = seriesCopy;
if (useLabels) {
chart.data.labels = labelsCopy;
}
chart.update();
});
}
};
};
return Chartist.plugins.legend;
}));
/**
* Chartist.js plugin to display a target line on a chart.
* With code from @gionkunz in https://github.com/gionkunz/chartist-js/issues/235
* and @OscarGodson in https://github.com/gionkunz/chartist-js/issues/491.
* Based on https://github.com/gionkunz/chartist-plugin-pointlabels
*/
/* global Chartist */
(function(window, document, Chartist) {
'use strict';
var defaultOptions = {
class: 'ct-target-line',
value: null
};
Chartist.plugins = Chartist.plugins || {};
Chartist.plugins.ctTargetLine = function(options) {
options = Chartist.extend({}, defaultOptions, options);
return function ctTargetLine(chart) {
function projectY(chartRect, bounds, value) {
return chartRect.y1 - (chartRect.height() / bounds.max * value)
}
chart.on('created', function (context) {
var targetLineY = projectY(context.chartRect, context.bounds, options.value);
context.svg.elem('line', {
x1: context.chartRect.x1,
x2: context.chartRect.x2,
y1: targetLineY,
y2: targetLineY
}, options.class);
});
};
};
}(window, document, Chartist));