blob: df04217d5e17816d33a9c7487ab8c16fd607c679 [file] [log] [blame]
AppServices.Services.factory('charts', function () {
var lineChart,
areaChart,
paretoChart,
pieChart,
pieCompare,
xaxis,
seriesIndex;
return {
convertLineChart: function (chartData, chartTemplate, dataDescription, settings, currentCompare) {
lineChart = chartTemplate;
// console.log('chartData',chartData[0])
if (typeof chartData[0] === 'undefined') {
chartData[0] = {};
chartData[0].datapoints = []
}
var dataPoints = chartData[0].datapoints,
dPLength = dataPoints.length,
label;
if(currentCompare === 'YESTERDAY'){
// lineChart = chartTemplate;
seriesIndex = dataDescription.dataAttr.length;
label = 'Yesterday ';
}
else if(currentCompare === 'LAST_WEEK'){
// lineChart = chartTemplate;
seriesIndex = dataDescription.dataAttr.length;
label = 'Last Week ';
}else{
lineChart = chartTemplate;
seriesIndex = 0;
lineChart.series = [];
label = '';
}
xaxis = lineChart.xAxis[0];
xaxis.categories = [];
//the next 2 setting options are provided in the timeFormat dropdown, so we must inspect them here
if (settings.xaxisformat) {
xaxis.labels.formatter = new Function(settings.xaxisformat);
}
if (settings.step) {
xaxis.labels.step = settings.step;
}
//end check
for (var i = 0; i < dPLength; i++) {
var dp = dataPoints[i];
xaxis.categories.push(dp.timestamp);
}
//check to see if there are multiple "chartGroupNames" in the object, otherwise "NA" will go to the else
if(chartData.length > 1){
for (var l = 0; l < chartData.length; l++){
if(chartData[l].chartGroupName){
dataPoints = chartData[l].datapoints;
// dPLength = dataPoints.length;
lineChart.series[l] = {};
lineChart.series[l].data = [];
lineChart.series[l].name = chartData[l].chartGroupName;
lineChart.series[l].yAxis = 0;
lineChart.series[l].type = 'line';
lineChart.series[l].color = dataDescription.colors[i];
lineChart.series[l].dashStyle = 'solid';
lineChart.series[l].yAxis.title.text = dataDescription.yAxisLabels;
plotData(l,dPLength,dataPoints,dataDescription.detailDataAttr,true)
}
}
}else{
var steadyCounter = 0;
//loop over incoming data members for axis setup... create empty arrays and settings ahead of time
//the seriesIndex is for the upcoming compare options - if compare is clicked... if it isn't just use 0 :/
for (var i = seriesIndex;i < (dataDescription.dataAttr.length + (seriesIndex > 0 ? seriesIndex : 0)); i++) {
var yAxisIndex = dataDescription.multiAxis ? steadyCounter : 0;
lineChart.series[i] = {};
lineChart.series[i].data = [];
lineChart.series[i].name = label + dataDescription.labels[steadyCounter];
lineChart.series[i].yAxis = yAxisIndex;
lineChart.series[i].type = 'line';
lineChart.series[i].color = dataDescription.colors[i];
lineChart.series[i].dashStyle = 'solid';
lineChart.yAxis[yAxisIndex].title.text = dataDescription.yAxisLabels[(dataDescription.yAxisLabels > 1 ? steadyCounter : 0)];
steadyCounter++;
}
plotData(seriesIndex,dPLength,dataPoints,dataDescription.dataAttr,false)
}
function plotData(counter,dPLength,dataPoints,dataAttrs,detailedView){
//massage the data... happy ending
for (var i = 0; i < dPLength; i++) {
var dp = dataPoints[i];
var localCounter = counter;
//loop over incoming data members
for (var j = 0; j < dataAttrs.length; j++) {
if(typeof dp === 'undefined'){
lineChart.series[localCounter].data.push([i, 0]);
}else{
lineChart.series[localCounter].data.push([i, dp[dataAttrs[j]]]);
}
if(!detailedView){
localCounter++;
}
}
}
}
return lineChart;
},
convertAreaChart: function (chartData, chartTemplate, dataDescription, settings, currentCompare) {
areaChart = angular.copy(areaChart);
// console.log('chartData',chartData[0])
if (typeof chartData[0] === 'undefined') {
chartData[0] = {};
chartData[0].datapoints = []
}
var dataPoints = chartData[0].datapoints,
dPLength = dataPoints.length,
label;
if(currentCompare === 'YESTERDAY'){
// areaChart = chartTemplate;
seriesIndex = dataDescription.dataAttr.length;
label = 'Yesterday ';
}
else if(currentCompare === 'LAST_WEEK'){
// areaChart = chartTemplate;
seriesIndex = dataDescription.dataAttr.length;
label = 'Last Week ';
}else{
areaChart = chartTemplate;
seriesIndex = 0;
areaChart.series = [];
label = '';
}
xaxis = areaChart.xAxis[0];
xaxis.categories = [];
//the next 2 setting options are provided in the timeFormat dropdown, so we must inspect them here
if (settings.xaxisformat) {
xaxis.labels.formatter = new Function(settings.xaxisformat);
}
if (settings.step) {
xaxis.labels.step = settings.step;
}
//end check
for (var i = 0; i < dPLength; i++) {
var dp = dataPoints[i];
xaxis.categories.push(dp.timestamp);
}
//check to see if there are multiple "chartGroupNames" in the object, otherwise "NA" will go to the else
if(chartData.length > 1){
for (var l = 0; l < chartData.length; l++){
if(chartData[l].chartGroupName){
dataPoints = chartData[l].datapoints;
// dPLength = dataPoints.length;
areaChart.series[l] = {};
areaChart.series[l].data = [];
areaChart.series[l].fillColor = dataDescription.areaColors[l];
areaChart.series[l].name = chartData[l].chartGroupName;
areaChart.series[l].yAxis = 0;
areaChart.series[l].type = 'area';
areaChart.series[l].pointInterval = 1;
areaChart.series[l].color = dataDescription.colors[l];
areaChart.series[l].dashStyle = 'solid';
areaChart.series[l].yAxis.title.text = dataDescription.yAxisLabels;
plotData(l,dPLength,dataPoints,dataDescription.detailDataAttr,true)
}
}
}else{
var steadyCounter = 0;
//loop over incoming data members for axis setup... create empty arrays and settings ahead of time
//the seriesIndex is for the upcoming compare options - if compare is clicked... if it isn't just use 0 :/
for (var i = seriesIndex;i < (dataDescription.dataAttr.length + (seriesIndex > 0 ? seriesIndex : 0)); i++) {
var yAxisIndex = dataDescription.multiAxis ? steadyCounter : 0;
areaChart.series[i] = {};
areaChart.series[i].data = [];
areaChart.series[i].fillColor = dataDescription.areaColors[i];
areaChart.series[i].name = label + dataDescription.labels[steadyCounter];
areaChart.series[i].yAxis = yAxisIndex;
areaChart.series[i].type = 'area';
areaChart.series[i].pointInterval = 1;
areaChart.series[i].color = dataDescription.colors[i];
areaChart.series[i].dashStyle = 'solid';
areaChart.yAxis[yAxisIndex].title.text = dataDescription.yAxisLabels[(dataDescription.yAxisLabels > 1 ? steadyCounter : 0)];
steadyCounter++;
}
plotData(seriesIndex,dPLength,dataPoints,dataDescription.dataAttr,false)
}
function plotData(counter,dPLength,dataPoints,dataAttrs,detailedView){
//massage the data... happy ending
for (var i = 0; i < dPLength; i++) {
var dp = dataPoints[i];
var localCounter = counter;
//loop over incoming data members
for (var j = 0; j < dataAttrs.length; j++) {
if(typeof dp === 'undefined'){
areaChart.series[localCounter].data.push(0);
}else{
areaChart.series[localCounter].data.push(dp[dataAttrs[j]]);
}
if(!detailedView){
localCounter++;
}
}
}
}
return areaChart;
},
convertParetoChart: function (chartData, chartTemplate, dataDescription, settings, currentCompare) {
paretoChart = chartTemplate;
if (typeof chartData === 'undefined') {
chartData = [];
}
var label,
cdLength = chartData.length,
compare = false,
allParetoOptions = [],
stackedBar = false;
seriesIndex = 0;
function getPreviousData(){
for(var i = 0;i < chartTemplate.series[0].data.length;i++){
//pulling the "now" values for comparison later, assuming they will be in the 0 index :)
allParetoOptions.push(chartTemplate.xAxis.categories[i])
}
}
if(typeof dataDescription.dataAttr[1] === 'object'){
stackedBar = true;
}
if(currentCompare === 'YESTERDAY'){
label = 'Yesterday ';
compare = true;
if(stackedBar){
seriesIndex = dataDescription.dataAttr[1].length;
}
getPreviousData()
}
else if(currentCompare === 'LAST_WEEK'){
label = 'Last Week ';
compare = true;
if(stackedBar){
seriesIndex = dataDescription.dataAttr[1].length;
}
seriesIndex =
getPreviousData()
}else{
compare = false;
label = '';
paretoChart.xAxis.categories = [];
paretoChart.series = [];
paretoChart.series[0] = {};
paretoChart.series[0].data = [];
paretoChart.legend.enabled = false;
}
paretoChart.plotOptions.series.borderColor = dataDescription.borderColor;
//create a basic compare series (more advanced needed for stacked bar)
if(compare && !stackedBar){
paretoChart.series[1] = {};
paretoChart.series[1].data = [];
//repopulate array with 0 values based on length of NOW data
for(var i = 0; i < allParetoOptions.length; i++) {
paretoChart.series[1].data.push(0);
}
paretoChart.legend.enabled = true;
// paretoChart.series[1].name = label;
// paretoChart.series[0].name = "Now";
}
for (var i = 0; i < cdLength; i++) {
var bar = chartData[i];
if(!compare){
paretoChart.xAxis.categories.push(bar[dataDescription.dataAttr[0]]);
//if we send multiple attributes to be plotted, assume it's a stacked bar for now
if(typeof dataDescription.dataAttr[1] === 'object'){
createStackedBar(dataDescription,paretoChart,paretoChart.series.length);
}else{
paretoChart.series[0].data.push(bar[dataDescription.dataAttr[1]]);
paretoChart.series[0].name = dataDescription.labels[0];
paretoChart.series[0].color = dataDescription.colors[0];
}
}else{
//check if this is a stacked bar
var newLabel = bar[dataDescription.dataAttr[0]],
newValue = bar[dataDescription.dataAttr[1]],
previousIndex = allParetoOptions.indexOf(newLabel);
//make sure this label existed in the NOW data
if(previousIndex > -1){
if(typeof dataDescription.dataAttr[1] === 'object'){
createStackedBar(dataDescription,paretoChart,paretoChart.series.length);
}else{
paretoChart.series[1].data[previousIndex] = newValue;
paretoChart.series[1].name = (label !== '' ? label + ' ' + dataDescription.labels[0] : dataDescription.labels[0]);
paretoChart.series[1].color = dataDescription.colors[1];
}
}else{
//not found for comparison
}
}
}
function createStackedBar(dataDescription,paretoChart,startingPoint){
paretoChart.plotOptions = {
series: {
shadow: false,
borderColor: dataDescription.borderColor,
borderWidth: 1
},
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
};
var start = dataDescription.dataAttr[1].length,
steadyCounter = 0,
stackName = label;
if(compare){
paretoChart.legend.enabled = true;
}
for (var f = seriesIndex; f < (start + seriesIndex); f++) {
if(!paretoChart.series[f]){
paretoChart.series[f] = {'data':[]}
}
paretoChart.series[f].data.push(bar[dataDescription.dataAttr[1][steadyCounter]]);
paretoChart.series[f].name = (label !== '' ? label + ' ' + dataDescription.labels[steadyCounter] : dataDescription.labels[steadyCounter]);
paretoChart.series[f].color = dataDescription.colors[f];
paretoChart.series[f].stack = label;
steadyCounter++
}
}
return paretoChart;
},
convertPieChart: function (chartData, chartTemplate, dataDescription, settings, currentCompare) {
var label,
cdLength = chartData.length,
compare = false;
pieChart = chartTemplate;
if(currentCompare === 'YESTERDAY'){
label = 'Yesterday ';
compare = false; //override for now to false
}
else if(currentCompare === 'LAST_WEEK'){
label = 'Last Week ';
compare = false; //override for now to false
}else{
compare = false;
pieChart.series[0].data = [];
if (pieChart.series[0].dataLabels) {
if(typeof pieChart.series[0].dataLabels.formatter === 'string'){
pieChart.series[0].dataLabels.formatter = new Function(pieChart.series[0].dataLabels.formatter);
}
}
}
pieChart.plotOptions.pie.borderColor = dataDescription.borderColor;
if(compare){
pieChart.series[1].data = [];
if (pieChart.series[1].dataLabels) {
if(typeof pieChart.series[1].dataLabels.formatter === 'string'){
pieChart.series[1].dataLabels.formatter = new Function(pieChart.series[1].dataLabels.formatter);
}
}
}
var tempArray = [];
for (var i = 0; i < cdLength; i++) {
var pie = chartData[i];
tempArray.push({
name:pie[dataDescription.dataAttr[0]],
y:pie[dataDescription.dataAttr[1]],
color:''
});
}
//sort by name prop so we can have a good looking comparison donut
sortJsonArrayByProperty(tempArray,'name');
//add colors so they match up
for (var i = 0; i < tempArray.length; i++) {
tempArray[i].color = dataDescription.colors[i];
}
if(!compare){
pieChart.series[0].data = tempArray;
}else{
pieChart.series[1].data = tempArray;
}
return pieChart;
}
}
function sortJsonArrayByProperty(objArray, prop, direction){
if (arguments.length<2) throw new Error("sortJsonArrayByProp requires 2 arguments");
var direct = arguments.length>2 ? arguments[2] : 1; //Default to ascending
if (objArray && objArray.constructor===Array){
var propPath = (prop.constructor===Array) ? prop : prop.split(".");
objArray.sort(function(a,b){
for (var p in propPath){
if (a[propPath[p]] && b[propPath[p]]){
a = a[propPath[p]];
b = b[propPath[p]];
}
}
// convert numeric strings to integers
a = a.match(/^\d+$/) ? +a : a;
b = b.match(/^\d+$/) ? +b : b;
return ( (a < b) ? -1*direct : ((a > b) ? 1*direct : 0) );
});
}
}
});