How to achieve grouping of stacked bars in angular charts? - angularjs

This is what I want to achieve:
I have tried it in plunkr, but unable to come up with the correct structure of data.
I have seen that it's possible in chart.js.
'use strict';
var app = angular.module('examples', ['chart.js', 'ui.bootstrap']);
app.controller('StackedBarCtrl', ['$scope', function ($scope) {
$scope.labels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
$scope.type = 'StackedBar';
$scope.series = ['2015', '2016'];
$scope.options = {
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
};
$scope.$on('chart-create', function(event, instance){
// used to obtain chart instance
$scope.chart = instance.chart;
});
$scope.onclick = function(elements,e)
{
// helper function that translates an event to a position in canvas coordinates
var pos = Chart.helpers.getRelativePosition(e, $scope.chart);
// inRange is the function on the chart element that is used for hit testing
var intersect = elements.find(function(element) {
return element.inRange(pos.x, pos.y);
});
if(intersect){
alert('You clicked ' + $scope.labels[intersect._index] + ' ' + $scope.series[intersect._datasetIndex]);
}
}
$scope.data = [
[65, 59, 90, 81, 56, 55, 40],
[28, 48, 40, 19, 96, 27, 100]
];
}]);

Related

How to fix labels clashing problem in RGraph pie chart?

I'm creating RGraph pie chart in which labels are clashing. Though I am using labels.sticks property to fix this issue but it has no effect on the output.
Here's my code to draw pie chart:
<script type="text/javascript">
$(document).ready(function(){
// Some data that is to be shown on the pie chart. It should be an array of numbers.
var data = [6.3, 2.1, 1.1, 3.2, 7.4, 10.5, 5.3, 27.4, 1.1, 4.2];
var labels = ['Data Loggers 6', 'Data Translation 2', 'Energy Loggers 1', 'Hobo 3', 'iButton 7', 'ICP 10', 'MCC 5', 'Monnit 26', 'Orchestrator 1', 'Sensors 4'];
for(var i = 0; i < data.length; i++)
{
labels[i] = labels[i] + ', ' + data[i] + '%';
}
var colors_arr = new Array('#00FFFF', '#7FFFD4', '#FFE4C4', '#0000FF', '#8A2BE2', '#A52A2A', '#7FFF00', '#FF7F50', '#B8860B', '#A9A9A9', '#8B008B', '#FF1493', '#228B22', '#DAA520', '#20B2AA', '#87CEFA', '#6B8E23', '#FF0000', '#FFFF00', '#F5DEB3');
var colors = new Array();
for(var i = 0; i < data.length; i++)
{
colors[i] = colors_arr[i];
}
// Create the Pie chart
var pie = new RGraph.Pie({
id: 'report_prospects_qty_products_canvas' ,
data: data,
options: {
labels: {
self: labels,
sticks: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
},
tooltips: {
self: labels,
//event: 'onmousemove',
},
shadow: false,
strokestyle: 'transparent',
title: {
self: 'Products',
bold: false,
y: 10
},
radius: 70,
colors: colors,
text: {
size: 8,
color: "red",
angle: 45
},
},
}).roundRobin();
$('#report_prospects_qty_products_wrapper').mouseout(function(){
// Hide the tooltip
RGraph.hideTooltip();
// Redraw the canvas so that any highlighting is gone
RGraph.redraw();
});
});
</script>
HTML
<!-- Put this where you want the chart to show up: -->
<div id="cvs_wrapper">
<!-- An example of using CSS to resize the canvas tag. -->
<canvas id="report_prospects_qty_products_canvas" width="600" height="250" style="width:100%;">[No canvas support]</canvas>
</div>
Output:
To fix labels clashing issue, I am using following option:
options: {
labels: {
self: labels,
sticks: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
},
According to RGraph docs:
labels.sticks Stipulates that sticks for the labels are shown. This
can also be an array of stick lengths - which may be useful if you're
experiencing the labels clashing. Default: false
FYI, I am using // version: 2015-05-24
Judging by the configuration snippet that you posted then I'm guessing that you might be using an older version. The current version (5.0 at this time) uses a far better way of arranging labels so there's no clashing (unless you have oodles of labels).
There's a demo page that shows this new method quite nicely here:
https://www.rgraph.net/demos/pie-basic.html
And the code for this is no different to what you might be used to:
labels = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ];
new RGraph.Pie({
id: 'cvs',
data: [20,1,1,1,1,1,1],
options: {
tooltips: labels,
labels: labels,
shadow: false,
colorsStroke: 'rgba(0,0,0,0)',
exploded: 0
}
}).roundRobin();

Can we remove bar chart line on click on pie chart legend label?

I am trying to remove/show the particular 'horizontalBar' line after clicking on legend of pie chart:
On legend call back function i can easily get the index value and text value by the below code
legend: {
display : true,
onClick: function(e, legendItem) {
var index = legendItem.index;
var chart = this.chart;
console.log(legendItem);
var i, ilen, meta;
for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
meta = chart.getDatasetMeta(i);
// toggle visibility of index if exists
if (meta.data[index]) {
meta.data[index].hidden = !meta.data[index].hidden;
}
}
chart.update();
}
}
below code is used to generate the pie chart.
var ctx = document.getElementById('myChart');
var mychart = new Chart(ctx, {
// The type of chart we want to create
type: 'pie',
// The data for our dataset
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: 'My First dataset',
backgroundColor: [
'rgb(255, 99, 132)',
'rgb(155, 10, 132)',
'rgb(55, 20, 132)',
'rgb(85, 30, 132)',
'rgb(69, 20, 132)',
'rgb(20, 100, 132)',
],
borderColor: 'rgb(255, 99, 132)',
data: [0, 10, 5, 2, 20, 30, 45]
}]
},
// Configuration options go here
options: {
legend: {
display : true,
onClick: function(e, legendItem) {
var index = legendItem.index;
var chart = this.chart;
console.log(legendItem);
var i, ilen, meta;
for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
meta = chart.getDatasetMeta(i);
// toggle visibility of index if exists
if (meta.data[index]) {
meta.data[index].hidden = !meta.data[index].hidden;
}
}
chart.update();
}
},
}
});
and the below chart is used to generate the bar chart as below:
var ctx2 = document.getElementById('myChart2');
var myChart2 = new Chart(ctx2, {
type: 'horizontalBar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: '# of Votes',
data: [0, 10, 5, 2, 20, 30, 45],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
legend: {
display : true,
},
scales: {
yAxes: [{
stacked: true
}],
xAxes: [{
stacked: true
}]
},
}
});
Is it possible to hide/show the particular horizontal line if check/unchecked the pie chart legend.
Please help me here.
use below code on legend in chart2 that is Horizontal bar(legend onClick event)
legend: {
display : true,
onClick: function(e, legendItem) {
var index = legendItem.index;
var chart = this.chart;
console.log(legendItem);
var i, ilen, meta;
for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
meta = chart.getDatasetMeta(i);
// toggle visibility of index if exists
if (meta.data[index]) {
meta.data[index].hidden = !meta.data[index].hidden;
}
}
chart.update();
//if legend is hidden hide the below data from the list also remove the data from the list items
var __text = legendItem.text;
var __split_text = __text.split(" ").join('_').toLowerCase();
var checked_unchecked_data_value = myChart2.data['datasets'][0]['data'][legendItem.index];
var checked_unchecked_date_label_value = myChart2.data['labels'][legendItem.index];
/*
my chart index and label value getting for the delete purpose
becz on delete index value is changed so doing the same
*/
//var __delete_checked_unchecked_data_value = myChart.data['datasets'][0]['data'][legendItem.index];
//var __delete_checked_unchecked_date_label_value = myChart.data['labels'][legendItem.index];
if(!legendItem.hidden){
$(".serial_"+legendItem.index).hide();
$(".section_"+__split_text).hide();
addSerialNumberAPCSUSelect();
/*var index_dataset = myChart.data.datasets[0].data.indexOf(__delete_checked_unchecked_data_value);
if(index_dataset > -1){
myChart.data.datasets[0].data.splice(index_dataset,1);
}
var index_label = myChart.data.labels.indexOf(__delete_checked_unchecked_date_label_value);
console.log("index data at " + index_dataset + " label index at " + index_label);
if(index_label > -1){
myChart.data.labels.splice(index_label,1);
}*/
myChart.data.datasets[0].data[legendItem.index] = 0;
myChart.data.labels[legendItem.index] = '';
myChart.update();
//console.log(" bar chart index changed at after remove" );
//console.log(myChart.data);
}else{
$(".serial_"+legendItem.index).show();
$(".section_"+__split_text).show();
addSerialNumberAPCSUSelect();
//myLineChart.data.datasets[0].data[2] = 50;
/*var data = [];
label = legendItem.text;
data[checked_unchecked_data_value] = checked_unchecked_date_label_value;
addData(myChart, label, data);*/
//myChart.data.datasets[0].data[checked_unchecked_data_value] = checked_unchecked_date_label_value;
myChart.data.datasets[0].data[legendItem.index] = checked_unchecked_data_value;
myChart.data.labels[legendItem.index] = checked_unchecked_date_label_value;
myChart.update();
}
}
}

the graph in the view is not displayed - Chart.js Angularjs

The graph in the view is not displayed:
<canvas class="chart chart-line" chart-data="data" chart-labels="labels"
chart-series="series" chart-click="onClick"></canvas>
test-controller.js:
(function () {
'use strict';
angular
.module('app.test')
.controller('TestController', TestController);
function TestController( $scope, $timeout) {
initialize();
function initialize() {
$scope.labels = ["January", "February", "March", "April", "May", "June", "July"];
$scope.series = ['Series A', 'Series B'];
$scope.data = [
[65, 59, 80, 81, 56, 55, 40],
[28, 48, 40, 19, 86, 27, 90]
];
$scope.onClick = function (points, evt) {
console.log(points, evt);
};
// Simulate async data update
$timeout(function () {
$scope.data = [
[28, 48, 40, 19, 86, 27, 90],
[65, 59, 80, 81, 56, 55, 40]
];
}, 3000);
}
}
})();
index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js">
</script>
I use the example
https://github.com/jtblin/angular-chart.js#example
I do not know why the graph is not displayed
You can use the same way, make sure that angular-charts and chart.js should have the correct versioned library references.
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-chart.js/1.0.3/angular-chart.min.js"></script>
DEMO
(function(angular) {
'use strict';
angular.module('myApp', ['chart.js'])
.controller('myController', [function() {
var ctrl = this;
ctrl.socialChart = {
options : {
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
},
type: 'StackedBar',
labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
series: ['FACEBOOK', 'GOOGLE', 'TWITTER', 'INSTAGRAM'],
colors: ['#ED402A', '#F0AB05', '#A0B421', '#00A39F'],
data : [
[65, 59, 90, 81, 56, 55, 40],
[28, 48, 40, 19, 96, 27, 100]
]
}
}]);
})(window.angular);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Multi Slot Transclude</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-chart.js/1.0.3/angular-chart.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="myApp" ng-controller="myController as ctrl">
<canvas id="outreach" class="chart chart-bar" chart-labels="ctrl.socialChart.labels" chart-data="ctrl.socialChart.data" chart-series="ctrl.socialChart.series" chart-colors="ctrl.socialChart.colors" chart-options="ctrl.socialChart.options"></canvas>
</body>
</html>

Get selected row of angularjs ui-grid

I've looked at multiple articles on this ui-grid and its giving me fits. I'm trying to get the selected row object. I'm either getting an undefined or can not read property of 'getSelectedRows'. Any help is greatly appreciated.
I started with this article here and the documentation doesnt seem to be all that great either.
Here is my code:
vm.gridOptions = {
enableRowSelection: false,
enableSelectAll: false,
showGridFooter:true
};
vm.gridOptions.columnDefs = [
{ name: 'productName' },
{ name: 'unitPrice' }
];
vm.gridOptions.multiSelect = false;
vm.getSelectedRows = function () {
vm.mySelectedRows = vm.gridApi.selection.getSelectedRows();
}
productDataService.getProductList()
.then(function (result) {
vm.gridOptions.data = result.data;
vm.mySelectedRows = vm.gridApi.selection.getSelectedRows();<--Property undefined error here
$timeout(function() {
if (vm.gridApi.selection.selectedRow) {
vm.gridApi.selection.selectRow(vm.gridOptions.data[0]);
}
});
});
vm.gridOptions.onRegisterApi = function(gridApi) {
vm.gridApi = gridApi;
}
Hope this helps:
angular.module('app', ['ui.grid', 'ui.grid.selection'])
.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout) {
var vm = this;
vm.gridOptions = {
enableRowSelection: false,
enableSelectAll: false,
showGridFooter:true,
data: [{productName: "Moroni", unitPrice: 50},
{productName: "Tiancum", unitPrice: 43},
{productName: "Jacob", unitPrice: 27},
{productName: "Nephi", unitPrice: 29},
{productName: "Enos", unitPrice: 34}]
};
vm.gridOptions.columnDefs = [
{ name: 'productName' },
{ name: 'unitPrice' }
];
vm.gridOptions.multiSelect = false;
vm.getSelectedRows = function () {
vm.mySelectedRows = vm.gridApi.selection.getSelectedRows();
}
vm.getProductList = function() {
vm.gridOptions.data = vm.resultSimulatedData;
vm.mySelectedRows = vm.gridApi.selection.getSelectedRows(); //<--Property undefined error here
if (vm.mySelectedRows[0]) {
alert('Selected Row: ' + vm.mySelectedRows[0].productName + ', ' + vm.mySelectedRows[0].unitPrice + '.');
} else {
alert('Select a row first');
}
$timeout(function() {
if (vm.gridApi.selection.selectedRow) {
vm.gridApi.selection.selectRow(vm.gridOptions.data[0]);
}
});
};
vm.gridOptions.onRegisterApi = function(gridApi) {
vm.gridApi = gridApi;
};
vm.resultSimulatedData = [{productName: "Moroni1", unitPrice: 50},
{productName: "Tiancum1", unitPrice: 43},
{productName: "Jacob1", unitPrice: 27},
{productName: "Nephi1", unitPrice: 29},
{productName: "Enos1", unitPrice: 34}];
return vm;
}]);
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.2/ui-grid.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.2/ui-grid.min.css" />
<div ng-app="app" ng-controller="MainCtrl as vm">
<button ng-click="vm.getProductList()">Get Product List</button>
<div ui-grid="vm.gridOptions" ui-grid-selection class="gridStyle">
</div>
</div>
If you can share more of your code that might help me to further help you.
If you want to filter out and select a column from the selected row(s), you can run a small loop and filter the value which you require as follows:
$scope.Grid.onRegisterApi = function (gridApi) { $scope.Grid= gridApi; };
Then to a button outside the grid you can add the following method to it's ng-click event.
$scope.DoSomthing= function () {
var rows = $scope.Grid.selection.getSelectedRows();
angular.forEach(rows, function (row, key) {
angular.forEach(row, function (column, colKey) {
if (colKey == "Your Column binding string")
{
console.log(column);
}
});
});
Then probably you can create an array of the column values and use where ever you need it.
I hope this helps to anyone looking for a similar functionality !
The most easy way to get current "clicked, changed" and whatever event want is to add a cell template like this in gridOptions:
vm.gridOptions = {
enableColumnMenus: false,
enableHorizontalScrollbar: 0,
enableVerticalScrollbar: 0,
enableRowSelection: false,
enableRowHeaderSelection: false,
rowHeight: 30,
multiSelect: false,
appScopeProvider: vm,
onRegisterApi: function(gridApi) {
vm.gridApi = gridApi;
},
columnDefs: [{
{
displayName: "",
field: "delete",
enableSorting: false,
width: "80",
cellTemplate: '<div class="ui-grid-cell-contents"><span class="grid-cell-icon fa fa-trash" ng-click="grid.appScope.vm.deleteRowModal(row.entity)"></span></div>'
}
...
]
}
So row.entity is pass data from row in controller!
If you want to show grid data value from JSON and not delete icon like it is in this case put {{COL_FIELD}}
Hope now everybody can take values from cliked row from ui-grid.

Connect an Angular Bar chart to endpoint data

I am new to Angular Charts and don't have a clue how to to connect the endpoint JSON data to the graph. I followed the instructions in AngularCharts to populate the bar chart with rough data.
HTML :
<div class="row">
<div class="span12">
<div class="widget widget-nopad">
<div class="widget-header">
<i class="icon-list-alt"></i>
<h3> Skills</h3>
</div>
<!-- /widget-header -->
<div class="widget-content" style="padding:5px;" ng-controller="BarCtrl">
<canvas id="bar" class="chart chart-bar"
chart-data="data" chart-labels="labels" chart-series="series">
</canvas></div>
</div>
</div>
</div>
Controller :
myApp.controller('BarCtrl', ['$scope', 'reportServices', function ($scope, reportServices) {
reportServices.getSkillsReport().then(function (result) {
$scope.data = result.data;
$scope.labels = ['2006', '2007', '2008', '2009', '2010', '2011', '2012'];
$scope.series = ['Series A', 'Series B'];
$scope.data = [
[65, 59, 80, 81, 56, 55, 40],
[28, 48, 40, 19, 86, 27, 90]
];
});
}]);
The output of the endpoint is :
{
".Net": 4,
"Java": 3,
"JavaScript": 5,
"ASP.NET": 2,
"Banking": 2,
"Personal Skills": 6
}
Can someone please show me how to connect this data to the current default bar chart? Also I don't want the second series of bar in the chart.
Suppose, your endpoint object is myobject :
var myobject = { ".Net": 4, "Java": 3, "JavaScript": 5, "ASP.NET": 2,"Banking": 2,"Personal Skills": 6}
$scope.labels = [];
$scope.series = ['Series A'];
$scope.data = [];
$scope.datavalues = [];
for(i in myobject) {
$scope.labels.push(i)
$scope.datavlues.push(myobject[i])
}
$scope.data = [$scope.datavalues]

Resources