Google chart in angularjs ng-repeat - angularjs

I am new to AngularJs and Google charts. My requirement is to show Google charts dynamically in ng-repeat for each li.
<li ng-repeat="ques in surveyquestions">
<label for="{{ques['questions']}}">
{{ques['id']}} {{ques['questions']}}
</label>
<div ng-init="calltry(ques['option_array'],ques['id'])"></div>
<div id="chartdiv{{ques['id']}}"></div>
</li>
In above code through ng-init I pass the data to render the Google chart. In JavaScript I used as below but it's not working.
var chart = new google.visualization.ColumnChart(document.getElementById('chartdiv'+id));
It's working fine when id is static like below.
<div id="chartdiv"></div>
var chart = new google.visualization.ColumnChart(document.getElementById('chartdiv'));
Please help to sort out what is the issue.

Try with angular-google-chart,
Refer :https://angular-google-chart.github.io/angular-google-chart/docs/latest/examples/bar/
<div class="chartContainer" ng-repeat="data in arrayDiv">
<div layout-padding layout-margin google-chart chart="drawChart(data)">
</div>
</div>
$scope.drawChart = function (value) {
$scope.chartData = [];
var chartValue = {
c: [{
v: 'subject
}, {
v: 5,
f: " questions"
}, {
v: 6,
f: " questions"
}]
};
$scope.chartData.push(chartValue);
$scope.qaChart = {};
$scope.qaChart.type = "BarChart";
$scope.qaChart.data = {
"cols": [{
id: "Sections",
label: "Subject",
type: "string"
}, {
id: "Correct",
label: "Correct",
type: "number"
}, {
id: "Wrong",
label: "Wrong",
type: "number"
}],
"rows": $scope.chartData
};
$scope.qaChart.options = {
"isStacked": "true",
"fill": 20,
"displayExactValues": true,
"colors": ['#4CAF50', '#EF5350', '#00adee'],
"vAxis": {
"title": " Questions",
},
"hAxis": {
"title": "Details",
}
};
return $scope.qaChart;
};

Related

Preselected values for angular-schema-form

Does angular-schema-form have a method to show preselected values?
When the titleMap on the select will set an integer, preselected values will show. But if it will set an object, I found no way of showing the correct name.
Is there anything to tie the object to, like with ng-options where you can set an attribute to compare them with the "track by" clause?
ng-options="option as option.name for option in array track by option.id"
In my example code, cats1 will set an object, cats2 will set an integer.
HTML:
<body>
<div ng-controller="MainCtrl">
<div class="login-container">
<form name="myForm"
sf-schema="schema"
sf-form="form"
sf-model="model">
</form>
</div>
</div>
</body>
Controller:
app.controller('MainCtrl', ['$scope', function ($scope) {
$scope.form = [
{
key: 'cats1',
type: 'select',
titleMap: [
{value: {id: 0, name: "Leopard"}, name: "Leopard"},
{value: {id: 1, name: "Tiger"}, name: "Tiger"}
]
},
{
key: 'cats2',
type: 'select',
titleMap: [
{value: 0, name: "Leopard"},
{value: 1, name: "Tiger"}
]
}
];
$scope.schema = {
"type": "object",
"properties": {
"cats1": {
"title": "Cats",
"type": "object"
},
"cats2": {
"title": "Cats",
"type": "number"
}
}
};
$scope.model = {cats1: {id: 1, name: "Tiger"}, cats2: 1};
}]);
Here is a plunkr:
https://plnkr.co/edit/0hK5Hrc9GXklfRwa6fjE?p=preview

Export Google Chart to Excel Sheet in Angular

Im using ng-google-chart to create charts from data I receive from a database. I store the data in a table. I need to export both the table and the chart.
I'm using the following technique to export tables (where "exportable" is the div the contains the table):
$scope.export = function ()
{
var blob = new Blob([document.getElementById('exportable').innerHTML], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"
});
saveAs(blob, "Record.xls");
alert("export done");
};
I cannot find any way to add the chart to this file.
This is the code to generate a chart
var chart1 = {};
chart1.type = "ColumnChart";
chart1.cssStyle = "height:400px; width:500px;";
chart1.data = {
"cols": [
{ id: "gender", label: "Gender", type: "string" },
{ id: "number", label: "number", type: "number" }
], "rows": [
{
c: [
{ v: "male" },
{ v: $scope.male, f: $scope.male }
]
},
{
c: [
{ v: "female" },
{ v: $scope.female }
]
}
]
};
chart1.options = {
"title": "",
"isStacked": "true",
"fill": 20,
"displayExactValues": true,
"vAxis": {
"title": "Number", "gridlines": { "count": 6 }
},
"hAxis": {
"title": "gender"
}
};
chart1.formatters = {};
$scope.chart = chart1;
}
To getImageURI of the chart, wait for the ready event and call the function.
Then you can add the image somewhere on the page.
You can even hide the original chart if needed...
Following is an example of loading the image URI into another element.
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});
function drawChart() {
var data = google.visualization.arrayToDataTable([
["Element", "Density", { role: "style" } ],
["Copper", 8.94, "#b87333"],
["Silver", 10.49, "silver"],
["Gold", 19.30, "gold"],
["Platinum", 21.45, "color: #e5e4e2"]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2]);
var options = {
title: "Density of Precious Metals, in g/cm^3",
width: 600,
height: 400,
bar: {groupWidth: "95%"},
legend: { position: "none" },
};
var chart = new google.visualization.ColumnChart(document.getElementById("chart_div"));
google.visualization.events.addListener(chart, 'ready', function () {
document.getElementById("chart_image").insertAdjacentHTML('beforeEnd', '<img alt="Chart Image" src="' + chart.getImageURI() + '">');
});
chart.draw(view, options);
}
<script src="https://www.google.com/jsapi"></script>
<span>CHART</span>
<div id="chart_div"></div>
<br/>
<span>IMAGE</span>
<div id="chart_image"></div>

Dynamically binding custom directive to ng-repeat

my controller has the json for my form then i have a directive that gets repeated to produce the form elements. based on the 'type' passed to the directive, the directive should know how to render the element.
but i don't know why it's not rendering the form templates properly here but that's a separate issue.
my immediate issue is, i can't seen to pass the ng-model and bind it correctly to the template.
does anyone see my problem?
var myApp = angular.module('myApp', []);
myApp.directive('ioProductElement', ['$compile', function ($compile) {
var dropdownTemplate = '<select ng-model="model" ng-options="option.Text for option in data"></select>';
var textAreaTemplate = '<textarea ng-model="model" class="form-control">{{ data }}</textarea>';
var radioListTemplate = '<span ng-repeat="item in data.Items"><input ng-model="model" type="radio" name="{{ data.Name }}" ng-checked="item.Selected" /><label>{{ item.ProductLabel }}</label> </span>';
return {
restrict: 'E',
replace: true,
scope: {
model: '=',
type: '=',
data: '='
},
link: function (scope, element) {
var getTemplate = function (type) {
var template = '';
switch (type) {
case 'SelectListItem':
template = dropdownTemplate;
scope.model = _.find(scope.data, {
Selected: true
});
break;
case 'TextArea':
template = textAreaTemplate;
break;
case 'RadioList':
template = radioListTemplate;
break;
}
return template;
};
element.html(getTemplate(scope.type));
$compile(element.contents())(scope);
}
};
}]);
myApp.controller('DynamicFormController', function () {
this.productElement = {};
this.product = {
ProductName: 'Online Form',
Company: 'TEST',
Data: []
};
this.productItems = [{
ProductLabel: "Status",
ProductType: "SelectListItem",
ProductData: [{
"Text": "Item1",
"Value": "1",
Selected: true
}, {
"Text": "Item2",
"Value": "2"
}]
}, {
ProductLabel: "Publication",
ProductType: "SelectListItem",
ProductData: [{
Text: 'Item1',
Value: '1'
}, {
Text: 'Item2',
Value: '2',
Selected: true
}]
}, {
ProductLabel: "Caption",
ProductType: "TextArea",
ProductData: "this is some data for the textarea"
}, {
ProductLabel: "Display Advertising",
ProductType: "RadioList",
ProductData: {
Name: "classifiedAdvertising",
Items: [{
Text: 'Full Page',
Selected: true
}, {
Text: '1/2 Page'
}]
}
}, {
ProductLabel: "Status2",
ProductType: "SelectListItem",
ProductData: [{
"Text": "Item1",
"Value": "1"
}, {
"Text": "Item2",
"Value": "2"
}, {
"Text": "Item3",
"Value": "3",
Selected: true
}]
}, ];
this.save = function () {
this.product.Data = this.productItems;
console.log('in save', this.product);
};
});
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.4.0/lodash.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<div class="col-sm-12" ng-app="myApp">
<br />
<form class="form-horizontal" ng-controller="DynamicFormController as ctrl">
<div class="form-group" ng-repeat="item in ctrl.productItems">
<label class="col-sm-2 control-label">{{ item.ProductLabel }}</label>
<div class="col-sm-10">
<io-product-element data-model="ctrl.productElement[item.ProductLabel]" data-type="item.ProductType" data-data="item.ProductData"></io-product-element>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="button" class="btn btn-info" data-ng-click="ctrl.save()" value="Submit" />
product: {{ ctrl.product | json }}
</div>
</div>
</form>
</div>
Try To add a break statement in the first switch case
//[...]
switch (type) {
case 'SelectListItem':
template = dropdownTemplate;
scope.model = _.find(scope.data, {
Selected: true
});
break;
case 'TextArea':
template = textAreaTemplate;
break;
case 'RadioList':
template = radioListTemplate;
break;
}
//[...]

kendo ui angularjs grid edit

I'm doing a POC for AngularJS and Kendo UI and I need to know how to save updated data on a kendo grid. I have inline editing enabled but can't hook into kendo UI to get the updated data. I created a fiddle (http://jsfiddle.net/aMz7V/14/) but can't get the jsfiddle to work (sorry this is my first time creating a fiddle), so I have pasted the code below:
JavaScript (controller code):
var myApp = angular.module('myApp', ['kendo.directives']);
myApp.controller("gridCtrl", function($scope) {
$scope.assignments = {};
$scope.assignments.dataSource = new kendo.data.DataSource({
data: [
{ StudentName: "John Smith", HomeWork: 9, HomeWork1: 12 },
{ StudentName: "Kodjo Adu", HomeWork: 5, HomeWork1: 15 },
{ StudentName: "Patrick smith", HomeWork: 10, HomeWork1: 19 },
{ StudentName: "Richard lomax", HomeWork: 8, HomeWork1: 18 },
{ StudentName: "Aglade Bone", HomeWork: 7, HomeWork1: 20 }
],
schema: {
model: {
fields: {
StudentName: { type: "string" },
HomeWork: { type: "number" },
HomeWork1: { type: "number" },
}
}
},
pageSize: 3,
});
$scope.assignments.columns = [
{ field: 'StudentName', title: 'Student Name' },
{ field: 'HomeWork', title: 'Home Work / 10' },
{ field: 'HomeWork1', title: 'Home Work / 20' }
];
});
HTML:
<div ng:app="myApp">
<div ng-controller='gridCtrl'>
<div kendo-grid k-data-source="assignments.dataSource" k-selectable="'row'"
k-pageable='{ "refresh": true, "pageSizes": true }'
k-columns='{{assignments.columns}}' k-sortable="true" k-editable="true" k-toolbar="['save','cancel']"></div>
</div>
</div>
So i figured it out, to handle to the save changes event i needed to do this
k-on-save-changes="saveChanges(kendoEvent)"
and just add the saveChanges function to the $scope in the controller.

Creating a basic data grid with Kendo UI and AngularJS

I'm experimenting with AngularJS. I want to show a basic Kendo Grid. I'm trying to do this using pure directives. With that in mind, I've looked at the Kendo UI / Angular JS project (https://github.com/kendo-labs/angular-kendo). Unfortunately, my
index.html:
<div>Products: {{products.length}}</div>
<div kendo-grid k-data-source="products" k-selectable="'row'"
k-pageable='{ "refresh": true, "pageSizes": true }'
k-columns='[
{ "field": "Name", "title": "Name"},
{ "field": "Department", "title": "Department"},
{ "field": "LastShipment", "title": "Last Shipment" }
]'>
</div>
controllers.js
function myController($scope) {
console.log("initializing controller...");
$scope.products = [
{ id:1, name:'Tennis Balls', department:'Sports', lastShipment:'10/01/2013' },
{ id:2, name:'Basket Balls', department:'Sports', lastShipment:'10/02/2013' },
{ id:3, name:'Oil', department:'Auto', lastShipment:'10/01/2013' },
{ id:4, name:'Filters', department:'Auto', lastShipment:'10/01/2013' },
{ id:5, name:'Dresser', department:'Home Furnishings', lastShipment:'10/01/2013' }
];
}
I've verified that I've wired up the controller properly. The activity count shows properly. However, the grid does not appear. I can't figure out what I'm doing incorrectly.
Thank you for your help.
You can also setup a Kendo DataSource as an AngularJS Service using the Factory method and inject this into your Controller to conform to AngularJS best practices and patterns.
Full source code and live demo: http://goo.gl/6Z9jop
Customer.cshtml
#{
ViewBag.Title = "Index";
}
<div>
<h2 ng-cloak>{{title}}</h2>
<div>
<div class="demo-section">
<div class="k-content" style="width: 100%">
<div kendo-grid="grid"
k-sortable="true"
k-pageable="true"
k-filterable="true"
k-editable="'inline'"
k-selectable="true"
k-columns='[
{ field: "CustomerID", title: "ID", width: "75px" },
{ field: "CompanyName", title: "Company"},
{ field: "ContactName", title: "Contact" },
{ field: "ContactTitle", title: "Title" },
{ field: "Address" },
{ field: "City" },
{ field: "PostalCode" },
{ field: "Country" },
{ field: "Phone" },
{ field: "Fax" }]'
>
</div>
<style scoped>
.toolbar { padding: 15px; float: right; }
</style>
</div>
</div>
<script type="text/x-kendo-template" id="toolbar">
<div>
<div class="toolbar">
<button kendo-button ng-click="edit(this)"><span class="k-icon k-i-tick"></span>Edit</button>
<button kendo-button ng-click="destroy(this)"><span class="k-icon k-i-tick"></span>Delete</button>
<button kendo-button ng-click="details(this)"><span class="k-icon k-i-tick"></span>Edit Details</button>
</div>
<div class="toolbar" style="display:none">
<button kendo-button ng-click="save(this)"><span class="k-icon k-i-tick"></span>Save</button>
<button kendo-button ng-click="cancel(this)"><span class="k-icon k-i-tick"></span>Cancel</button>
</div>
</div>
</script>
</div>
</div>
customerController.js
'use strict';
northwindApp.controller('customerController',
function ($scope, $rootScope, $location, customerDataSource)
{
customerDataSource.filter({}); // reset filter on dataSource everytime view is loaded
var onClick = function (event, delegate)
{
var grid = event.grid;
var selectedRow = grid.select();
var dataItem = grid.dataItem(selectedRow);
if (selectedRow.length > 0)
{
delegate(grid, selectedRow, dataItem);
}
else
{
alert("Please select a row.");
}
};
$scope.toolbarTemplate = kendo.template($("#toolbar").html());
$scope.save = function (e)
{
onClick(e, function (grid)
{
grid.saveRow();
$(".toolbar").toggle();
});
};
$scope.cancel = function (e)
{
onClick(e, function (grid)
{
grid.cancelRow();
$(".toolbar").toggle();
});
},
$scope.details = function (e)
{
onClick(e, function (grid, row, dataItem)
{
$location.url('/customer/edit/' + dataItem.CustomerID);
});
},
$scope.edit = function (e)
{
onClick(e, function (grid, row)
{
grid.editRow(row);
$(".toolbar").toggle();
});
},
$scope.destroy = function (e)
{
onClick(e, function (grid, row, dataItem)
{
grid.dataSource.remove(dataItem);
grid.dataSource.sync();
});
},
$scope.onChange = function (e)
{
var grid = e.sender;
$rootScope.lastSelectedDataItem = grid.dataItem(grid.select());
},
$scope.dataSource = customerDataSource;
$scope.onDataBound = function (e)
{
// check if there was a row that was selected
if ($rootScope.lastSelectedDataItem == null)
{
return;
}
var view = this.dataSource.view(); // get all the rows
for (var i = 0; i < view.length; i++)
{
// iterate through rows
if (view[i].CustomerID == $rootScope.lastSelectedDataItem.CustomerID)
{
// find row with the lastSelectedProductd
var grid = e.sender; // get the grid
grid.select(grid.table.find("tr[data-uid='" + view[i].uid + "']")); // set the selected row
break;
}
}
};
});
customerDataSource.js
'use strict';
northwindApp.factory('customerDataSource',
function (customerModel)
{
var crudServiceBaseUrl = "/odata/Customer";
return new kendo.data.DataSource({
type: "odata",
transport: {
read: {
async: false,
url: crudServiceBaseUrl,
dataType: "json"
},
update: {
url: function (data)
{
return crudServiceBaseUrl + "(" + data.CustomerID + ")";
},
type: "put",
dataType: "json"
},
destroy: {
url: function (data)
{
return crudServiceBaseUrl + "(" + data.CustomerID + ")";
},
dataType: "json"
}
},
batch: false,
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize: 10,
schema: {
data: function (data) { return data.value; },
total: function (data) { return data["odata.count"]; },
model: customerModel
},
error: function (e)
{
alert(e.xhr.responseText);
}
});
});
It looks as if the field names are spelled wrong. The following works for me:
<div kendo-grid k-data-source="products" k-selectable="'row'"
k-pageable='{ "pageSize": 2, "refresh": true, "pageSizes": true }'
k-columns='[
{ "field": "name", "title": "Name"},
{ "field": "department", "title": "Department"},
{ "field": "lastShipment", "title": "Last Shipment" }
]'>
</div>
Here is a live demo: http://jsbin.com/odeQAfI/2/edit
To avoid the NaN message in the pager you need to make the products field to be a Kendo DataSource:
function MyController($scope) {
$scope.products = new kendo.data.DataSource({
data: [
{ id:1, name:'Tennis Balls', department:'Sports', lastShipment:'10/01/2013' },
{ id:2, name:'Basket Balls', department:'Sports', lastShipment:'10/02/2013' },
{ id:3, name:'Oil', department:'Auto', lastShipment:'10/01/2013' },
{ id:4, name:'Filters', department:'Auto', lastShipment:'10/01/2013' },
{ id:5, name:'Dresser', department:'Home Furnishings', lastShipment:'10/01/2013' }
],
pageSize: 2
});
}
Here is a live demo: http://jsbin.com/ODElUfO/2/edit

Resources