do not show 0 value on google line chart - angularjs

var data = google.visualization.arrayToDataTable([
['Year', 'Massachusetts', 'National'],
['2010', 88, 76],
['2011', 0, 82],
['2012', 96, 86],
['2013', 100, 91],
['2014', 0, 94],
['2015', -1, 98],
['2016', 100, 99],
['2017', 124, 100],
['2018', 125, 102]
]);
This is the data I am using to create a line chart, I do not want to show 0's and negative values on the chart. I just want to skip these values.
my current chart looks like this
Expected chart is like this

we can use a data view with calculated columns,
to replace values less than or equal to zero with null
var view = new google.visualization.DataView(data);
var viewColumns = [0];
for (var i = 1; i < data.getNumberOfColumns(); i++) {
addViewColumn(i);
}
view.setColumns(viewColumns);
function addViewColumn(columnIndex) {
viewColumns.push({
calc: function (dt, row) {
var valNew = null;
var valOrig = dt.getValue(row, columnIndex);
if (valOrig > 0) {
valNew = valOrig;
}
return valNew;
},
label: data.getColumnLabel(columnIndex),
type: data.getColumnType(columnIndex)
});
}
then use the following configuration option, which skips null values
interpolateNulls: true
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Year', 'Massachusetts', 'National'],
['2010', 88, 76],
['2011', 0, 82],
['2012', 96, 86],
['2013', 100, 91],
['2014', 0, 94],
['2015', -1, 98],
['2016', 100, 99],
['2017', 124, 100],
['2018', 125, 102]
]);
var view = new google.visualization.DataView(data);
var viewColumns = [0];
for (var i = 1; i < data.getNumberOfColumns(); i++) {
addViewColumn(i);
}
view.setColumns(viewColumns);
function addViewColumn(columnIndex) {
viewColumns.push({
calc: function (dt, row) {
var valNew = null;
var valOrig = dt.getValue(row, columnIndex);
if (valOrig > 0) {
valNew = valOrig;
}
return valNew;
},
label: data.getColumnLabel(columnIndex),
type: data.getColumnType(columnIndex)
});
}
var options = {
title: 'Average Home Insurance Premium',
interpolateNulls: true
};
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(view, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>

Related

How we can merge json object together

i have my first function:
$scope.loadDataFromToMonth= function (from,to,year) {
// $scope.loadDataFromToMonthArrivee(from,to,2016);
var url = servername+'admin/dashboard/getIncidentDepartByMonthFromTo/'+from+'/'+to+'/'+year;
// alert(url);
function onSuccess(response) {
console.log("+++++getIncidentDepartByMonthFromTo SUCCESS++++++");
if (response.data.success != false) {
$scope.payloadgetIncidentDepartByMonthFromTo = response.data.data;
var getIncidentDepartByMonthFromTo= $scope.payloadgetIncidentDepartByMonthFromTo;
console.log(JSON.stringify(getIncidentDepartByMonthFromTo));
$scope.data = {}; // new object
$scope.data.datasets = []; // new array in data object ..
$scope.data.labels =[];
var theWholeOb={};
var dataSetObj = {}; //temp object to push into dataset array..
var dataSetObjtwo = {};
/////////////anomalies depart
dataSetObj.data = [];
dataSetObj.label= 'My First dataset';
dataSetObj.fillColor='rgba(220,220,220,0.2)';
dataSetObj.strokeColor= 'rgba(220,220,220,1)';
dataSetObj.pointColor= 'rgba(220,220,220,1)';
dataSetObj.pointStrokeColor= '#fff';
dataSetObj.pointHighlightFill= '#fff';
dataSetObj.pointHighlightStroke='rgba(220,220,220,1)';
getIncidentDepartByMonthFromTo.forEach(function(data) {
var monthNumber = $filter('date')(data.la_date, "MM");
var mun = data.number;
$scope.data.labels.push(monthNumber);
dataSetObj.data.push(mun);
});
$scope.data.datasets.push(dataSetObj);
}
else {
alert("failure");
}
};
function onError(response) {
console.log("-------getIncidentDepartByMonthFromTo FAILED-------");
//$scope.stopSpin('spinner-0');
console.log(response.data);
console.log("Inside getIncidentDepartByMonthFromTo error condition...");
};
//----MAKE AJAX REQUEST CALL to GET DATA----
ajaxServicess.getData(url,username,password, 'GET', '').then(onSuccess,onError);
};
this function return this result:
$scope.data = {
labels: ['Jan', 'Feb' 'Jul'],
datasets: [
{
label: 'My First dataset',
fillColor: 'rgba(220,220,220,0.2)',
strokeColor: 'rgba(220,220,220,1)',
pointColor: 'rgba(220,220,220,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(220,220,220,1)',
data: [75, 59, 80, 81, 56, 55]
}
]
};
it works good.
and i have the second function its return the same result but with different data of cours:
$scope.loadDataFromToMonthArrivee= function (from,to,year) {
var url =servername+'admin/dashboard/getIncidentArriveeByMonthFromTo/'+from+'/'+to+'/'+year;
//alert(url);
function onSuccess(response) {
console.log("+++++getIncidentArriveeByDate SUCCESS++++++");
if (response.data.success != false) {
$scope.payloadDayMonthYearData = response.data.data;
var loadedDataByDayMonthYear= $scope.payloadDayMonthYearData;
alert('xxx'+JSON.stringify(loadedDataByDayMonthYear));
$scope.data = {}; // new object
$scope.data.datasets = []; // new array in data object ..
$scope.data.labels =[];
var theWholeOb={};
var dataSetObj = {}; //temp object to push into dataset array..
var dataSetObjtwo = {};
/////////////anomalies arrivee
dataSetObjtwo.data = [];
$scope.date=[];
dataSetObjtwo.label='My Second dataset';
dataSetObjtwo.fillColor= 'rgba(151,187,205,0.2)';
dataSetObjtwo.strokeColor= 'rgba(151,187,205,1)';
dataSetObjtwo.pointColor= 'rgba(151,187,205,1)';
dataSetObjtwo.pointStrokeColor= '#fff';
dataSetObjtwo.pointHighlightFill='#fff';
dataSetObjtwo.pointHighlightStroke= 'rgba(151,187,205,1)';
loadedDataByDayMonthYear.forEach(function(data) {
var monthNumber = $filter('date')(data.la_date, "MM");
$scope.date.push(monthNumber);
var mun = data.number;
$scope.data.labels.push($scope.monthNumber);
dataSetObjtwo.data.push(mun);
});
$scope.data.datasets.push(dataSetObjtwo);
} else {
alert("failure");
}
// $scope.stopSpin('spinner-0');
};
function onError(response) {
console.log("-------getIncidentArriveeByDate FAILED-------");
//$scope.stopSpin('spinner-0');
console.log(response.data);
console.log("Inside getIncidentArriveeByDate error condition...");
};
//----MAKE AJAX REQUEST CALL to GET DATA----
ajaxServicess.getData(url,username,password, 'GET', '').then(onSuccess, onError);
};
this function return this result:
$scope.data = {
labels: [ 'Jan', 'Feb' 'Jul','Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [
{
label: 'My Second dataset',
fillColor: 'rgba(151,187,205,0.2)',
strokeColor: 'rgba(151,187,205,1)',
pointColor: 'rgba(151,187,205,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(151,187,205,1)',
data: [ 102, 123, 145, 60, 161]
}
]
};
it works good also, but my question is : how i can declare the second function inside the first function and combine the data returned and get the final result like this:
$scope.data = {
labels: [ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [
{
label: 'My Second dataset',
fillColor: 'rgba(151,187,205,0.2)',
strokeColor: 'rgba(151,187,205,1)',
pointColor: 'rgba(151,187,205,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(151,187,205,1)',
data: [ 102, 123, 145, 60, 161]
},{
label: 'My First dataset',
fillColor: 'rgba(220,220,220,0.2)',
strokeColor: 'rgba(220,220,220,1)',
pointColor: 'rgba(220,220,220,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(220,220,220,1)',
data: [75, 59, 80, 81, 56, 55]
}
]
};
As long as your objects do only contain arrays you might solve this as follows:
$scope.combineParts = function(part1, part2) {
var merged = angular.copy( part1 );
for ( key in part1 )
{
if ( part2.hasOwnProperty(key) )
merged[key].push.apply(merged[key], part2[key])
}
return merged;
}
Demo in this fiddle: https://jsfiddle.net/gat4co9x/
Hope this helps. ;)
EDIT: To integrate just call the second function in onSuccess of the first, and the combineParts in the onSuccess of the second.
Thisis a bit of easier change for you,first call the $scope.loadDataFromToMonth(params); function and inside that function on success call second function $scope.loadDataFromToMonthArrivee(params); after you prepare $scope.data.
Now don't initialise $scope.data again in $scope.loadDataFromToMonthArrivee(params); and just do this $scope.data.datasets.push(dataSetObjtwo);
I have below provided the similar code so just try using same don't get confused and try anything new but stick to it and after this works you can work on separating labels list from the both objects.
$scope.loadDataFromToMonth= function (from,to,year) {
// $scope.loadDataFromToMonthArrivee(from,to,2016);
var url = servername+'admin/dashboard/getIncidentDepartByMonthFromTo/'+from+'/'+to+'/'+year;
// alert(url);
function onSuccess(response) {
console.log("+++++getIncidentDepartByMonthFromTo SUCCESS++++++");
if (response.data.success != false) {
$scope.payloadgetIncidentDepartByMonthFromTo = response.data.data;
var getIncidentDepartByMonthFromTo= $scope.payloadgetIncidentDepartByMonthFromTo;
console.log(JSON.stringify(getIncidentDepartByMonthFromTo));
$scope.data = {}; // new object
$scope.data.datasets = []; // new array in data object ..
$scope.data.labels =[];
var theWholeOb={};
var dataSetObj = {}; //temp object to push into dataset array..
var dataSetObjtwo = {};
/////////////anomalies depart
dataSetObj.data = [];
dataSetObj.label= 'My First dataset';
dataSetObj.fillColor='rgba(220,220,220,0.2)';
dataSetObj.strokeColor= 'rgba(220,220,220,1)';
dataSetObj.pointColor= 'rgba(220,220,220,1)';
dataSetObj.pointStrokeColor= '#fff';
dataSetObj.pointHighlightFill= '#fff';
dataSetObj.pointHighlightStroke='rgba(220,220,220,1)';
getIncidentDepartByMonthFromTo.forEach(function(data) {
var monthNumber = $filter('date')(data.la_date, "MM");
var mun = data.number;
$scope.data.labels.push(monthNumber);
dataSetObj.data.push(mun);
});
$scope.data.datasets.push(dataSetObj);
$scope.loadDataFromToMonthArrivee(params);//call the second list http call after you prepare first object ...
}
else {
alert("failure");
}
};
function onError(response) {
console.log("-------getIncidentDepartByMonthFromTo FAILED-------");
//$scope.stopSpin('spinner-0');
console.log(response.data);
console.log("Inside getIncidentDepartByMonthFromTo error condition...");
};
$scope.loadDataFromToMonthArrivee= function (from,to,year) {
var url =servername+'admin/dashboard/getIncidentArriveeByMonthFromTo/'+from+'/'+to+'/'+year;
//alert(url);
function onSuccess(response) {
console.log("+++++getIncidentArriveeByDate SUCCESS++++++");
if (response.data.success != false) {
$scope.payloadDayMonthYearData = response.data.data;
var loadedDataByDayMonthYear= $scope.payloadDayMonthYearData;
alert('xxx'+JSON.stringify(loadedDataByDayMonthYear));
var theWholeOb={};
var dataSetObj = {}; //temp object to push into dataset array..
var dataSetObjtwo = {};
/////////////anomalies arrivee
dataSetObjtwo.data = [];
$scope.date=[];
dataSetObjtwo.label='My Second dataset';
dataSetObjtwo.fillColor= 'rgba(151,187,205,0.2)';
dataSetObjtwo.strokeColor= 'rgba(151,187,205,1)';
dataSetObjtwo.pointColor= 'rgba(151,187,205,1)';
dataSetObjtwo.pointStrokeColor= '#fff';
dataSetObjtwo.pointHighlightFill='#fff';
dataSetObjtwo.pointHighlightStroke= 'rgba(151,187,205,1)';
loadedDataByDayMonthYear.forEach(function(data) {
var monthNumber = $filter('date')(data.la_date, "MM");
$scope.date.push(monthNumber);
var mun = data.number;
$scope.data.labels.push($scope.monthNumber);
dataSetObjtwo.data.push(mun);
});
$scope.data.datasets.push(dataSetObjtwo);
} else {
alert("failure");
}
// $scope.stopSpin('spinner-0');
};
function onError(response) {
console.log("-------getIncidentArriveeByDate FAILED-------");
//$scope.stopSpin('spinner-0');
console.log(response.data);
console.log("Inside getIncidentArriveeByDate error condition...");
};

Dynamically change zoom

I need to change zoom of Google Maps. Code:
function _initMap(vm) {
vm.windowOptions = {
show: false
};
var latSum = 0;
var longSum = 0;
for (var i = 0, length = vm.markers.length; i < length; i++) {
//calculate center of map (1st part)
latSum += vm.markers[i].coords.latitude;
longSum += vm.markers[i].coords.longitude;
//assign an icon
vm.markers[i].iconUrl = getIconUrl(vm.markers[i].deviceType);
}
var centeredLatitude = latSum / vm.markers.length;
var centeredLongitude = longSum / vm.markers.length;
vm.control = {};
vm.map = {
center: setCenterMap(),
options: getMapOptions(),
zoom: setMapZoom(),
events: {
click: function (mapModel, eventName, originalEventArgs) {
var e = originalEventArgs[0];
$log.log('gz', e.latLng.lat() + ' ' + e.latLng.lng());
console.log('xxx', mapModel);
}
},
show: true,
refresh: function (a, b, c, d) {
vm.map.control.refresh();
}
};
vm.clusterOptions = {
minimumClusterSize: 2,
zoomOnClick: true,
styles: [{
url: 'assets/images/markers/m1.png',
width: 53,
height: 53,
textColor: 'white',
textSize: 17,
fontFamily: 'Open Sans'
}],
averageCenter: true,
clusterClass: 'cluster-icon'
};
vm.window = {
location: undefined,
templateUrl: 'app/components/maps/maps.info.template.html',
show: false,
options: getMapWindowOptions()
};
vm.clickMarker = function (marker, event, object) {
vm.window.show = false;
vm.window.details = object.details;
vm.window.location = object.coords;
vm.window.show = true;
vm.sendChoosenDeviceToController(object);
angular.element('#right-menu').focus();
};
vm.closeClick = function () {
vm.window.show = false;
}
}
but the code:
center: setCenterMap()
zoom: setMapZoom()
when I call the methods center and zoom does not change center and zoom. How to update center and zoom dynamically ? The methods are properly exectued during initiation of map but after initialization does not want to change.
The solution was just simply:
scope.map.center = {
'latitude': scope.markers[i].coords.latitude,
'longitude': scope.markers[i].coords.longitude
};
GoogleMaps knows about that change and works nice.

N3 Pie Chart changing color form controller when value changes

In a site a show a n3 pie chart.
Therefore i have defined the options and data in the controller like this:
$scope.gdata = [{ label: "Performance", value: 0, color: "green", complementBrightness: 0, colorComplement: "black", suffix: "%" }];
$scope.options = { thickness: 8, mode: "gauge", total: 100 };
The data is set dynamically like this:
self.load = function() {
$http.get('/api/data')
.then(function(response) {
$scope.data = response.data;
var value = response.data.ApiApdex * 100;
var color = "";
if (value >= 90) {
color = "green";
}
if (value < 75) {
color = "red";
}
else {
color = "#FFA873";
}
var object = [{ label: "Performance", value: value, color: color, complementBrightness: 0, colorComplement: "black", suffix: "%" }];
$scope.gdata = object;
}
}
All Values are aplied, but not the color. it always shows the color it had assigned in the begining .
I Also tried to update only the value and leave one instance of the data object alive.
Same problem. the value applies but not the color
what am i doing wrong?

Cannot read property 'length' of undefined

I have a problem with my angular JS function
when I first call this function, everything is good. But my next attempts cause an error and stops it from working.
My js code:
$scope.updateUptimeCalendar = function() {
$scope.loadHeatMap();
$scope.getMonthHeatMap(new Date().getFullYear(), new Date().getMonth());
};
$scope.loadHeatMapData = function (date) {
var time = date.getTime();
var isMonthLoaded = false;
var eps = 1000 * 60 * 60 * 6; // epsilont +-6 hours
angular.forEach($scope.heatMatData, function (record) {
if (!isMonthLoaded) {
if (Math.abs(record.date - time) < eps) {
isMonthLoaded = true;
}
}
});
if (!isMonthLoaded) {
$scope.getMonthHeatMap(date.getFullYear(), date.getMonth());
};
};
$scope.getMonthHeatMap = function(fullYear, month) {
$scope.setLoadingState(true);
var monthStart = new Date(Date.UTC(fullYear, month, 1));
var monthEnd;
if (month == 12) {
monthEnd = new Date(Date.UTC(fullYear + 1, 1, 1));
} else {
monthEnd = new Date(Date.UTC(fullYear, month + 1, 1));
};
monthStart = monthStart.getTime();
monthEnd = monthEnd.getTime();
var turnOnDuration;
$http.post('Statistic/GetClientStateStatisticByDays', {
clientId: $scope.$parent.clientForStatistic.ClientId,
stateId: 1,
beginPeriod: monthStart,
endPeriod: monthEnd
}).success(function(data) {
$scope.$parent.processResponse(data);
angular.forEach(data, function(record) {
turnOnDuration = record.Duration / (1000 * 60 * 60);
$scope.heatMatData.push({
date: record.AvarageTime,
value: Number((turnOnDuration).toFixed(0)),
});
});
$scope.heatMatData.sort(function(a, b) {
return a.date - b.date;
});
//todo: fixed this when try to get null data values DK
$scope.setLoadingState(false);
$scope.cal.update($scope.heatMatData);
});
};
$scope.heatMapDateParser = function (data) {
var stats = {};
for (var d in data) {
stats[data[d].date / 1000] = data[d].value;
}
return stats;
};
$scope.loadHeatMap = function () {
$('#statistic-modal-chart-container').empty();
$('#statistic-modal-chart-container-calendar').empty();
$scope.cal = new CalHeatMap();
$scope.cal.init({
data: $scope.heatMatData,
afterLoadData: $scope.heatMapDateParser,
considerMissingDataAsZero: true,
//todo: use to set visible dates interval. MR
//minDate: new Date(2014, 9),
//maxDate: new Date(),
itemSelector: "#statistic-modal-chart-container-calendar",
domain: "month",
domainLabelFormat: "%b %Y",
subDomain: "x_day",
subDomainTextFormat: "%d",
itemName: "Hour",
cellSize: 35,
range: 1,
displayLegend: true,
legend: [0, 4, 8, 12, 16, 20, 25],
legendColors: {
base: '#ededed',
empty: '#ededed',
min: '#FFFFFF',
max: '#3366FF'
},
legendHorizontalPosition: "center",
previousSelector: "#uptime-calendar-prev",
nextSelector: "#uptime-calendar-next",
afterLoadNextDomain: function (date) {
$scope.loadHeatMapData(date);
},
afterLoadPreviousDomain: function (date) {
$scope.loadHeatMapData(date);
},
itemNamespace: "animationDuration-a",
tooltip: true
});
};
If I use debug, the error occurs in this row $scope.cal.update($scope.heatMatData);
I get this error
my error:
TypeError: Cannot read property 'length' of undefined
at e (http:/Scripts/d3.min.js:3:10447)
at Array.pa.data (http://Scripts/d3.min.js:3:11196)
at Object.CalHeatMap.fill (http://Scripts/cal-heatmap.min.js:8:20667)
at http://Scripts/cal-heatmap.min.js:9:4615
at h (http:/Scripts/cal-heatmap.min.js:9:1605)
at Object.CalHeatMap.getDatas (http:/Scripts/cal-heatmap.min.js:9:1940)
at Object.CalHeatMap.update (http://Scripts/cal-heatmap.min.js:9:4537)
at http://Scripts/Controllers/statistic-ctrl.js:355:24
at http://Scripts/angular.min.js:72:45
at L (http:/Scripts/angular.min.js:99:469) angular.min.js:92
(anonymous function) angular.min.js:92
(anonymous function) angular.min.js:68
L angular.min.js:99
L angular.min.js:99
(anonymous function) angular.min.js:101
k.$eval angular.min.js:111
k.$digest angular.min.js:108
k.$apply angular.min.js:112
h angular.min.js:72
w angular.min.js:77
A.onreadystatechange
please anybody help me!
Put
$scope.heatMatData = [];
as first instruction

Raphael JS paper.set and multiple access

I try to create a set of Raphael objects, and animate them when window (for example) is clicked.
So this works: http://jsfiddle.net/6YdrG/2/
$(function() {
(function () {
var R = Raphael($('#svg')[0]);
var i, circles = circlenumber = R.set();
var v = [{offset: 0, circleVal: '+ 29 %'}, {offset: 120, circleVal: '+ 90 %'}, {offset: 240, circleVal: '+ 107 %'}, {offset: 360, circleVal: '+ 20 %'}];
for (i = 0; i <= 3; i++) {
circles[i] = R.circle(29+v[i].offset, 29, 10).attr({fill: '#000', stroke: 'none'});
//circlenumber[i] = R.text(29+v[i].offset, 29, v[i].circleVal).attr({font: '12px JauresSemibold, serif', fill: '#fff'});
};
$(window).click(function() {
console.log('click');
for (i = 0; i <= 3; i++) {
circles[i].animate(Raphael.animation({r: 28}, 800, 'easeInOut').delay(100*(i)));
};
});
})();
});
But if you remove "//" to add the circlenumber[i] elements, it doesn't works anymore…
Ideas? Thanks!
I think your problem is the way you define i
Check this http://jsfiddle.net/6YdrG/5/
You had i initialised as R.Set().

Resources