I am populating a grid dynamically as mentioned in the below link.
Dynamic Kendo Grid
Is there any feature out of the box to freeze the first column?
Please try with the below code snippet.
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/dropdownlist/angular">
<style>
html {
font-size: 14px;
font-family: Arial, Helvetica, sans-serif;
}
</style>
<title></title>
<link rel="stylesheet" href="//kendo.cdn.telerik.com/2015.2.805/styles/kendo.common.min.css" />
<link rel="stylesheet" href="//kendo.cdn.telerik.com/2015.2.805/styles/kendo.default.min.css" />
<script src="//kendo.cdn.telerik.com/2015.2.805/js/jquery.min.js"></script>
<script src="//kendo.cdn.telerik.com/2015.2.805/js/angular.min.js"></script>
<script src="//kendo.cdn.telerik.com/2015.2.805/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script type="text/javascript">
//example data received from remote source via jQuery ajax merthod
var data = [{
"Name": "daya",
"Role": "Developer",
"Dept": "Dev",
"Date": "\/Date(836438400000)\/",
"Balance": 23
}, {
"Name": "siva",
"Role": "Developer",
"Dept": "Dev",
"Date": "\/Date(836438400000)\/",
"Balance": 23
}, {
"Name": "sivadaya",
"Role": "Developer",
"Dept": "Dev",
"Date": "\/Date(836438400000)\/",
"Balance": 23
}, {
"Name": "dayasiva",
"Role": "Developer",
"Dept": "Dev",
"Date": "\/Date(836438400000)\/",
"Balance": 23
}];
//in the success handler of the ajax method call the function below with the received data:
var dateFields = [];
generateGrid(data)
function generateGrid(gridData) {
var model = generateModel(gridData[0]);
var parseFunction;
if (dateFields.length > 0) {
parseFunction = function (response) {
for (var i = 0; i < response.length; i++) {
for (var fieldIndex = 0; fieldIndex < dateFields.length; fieldIndex++) {
var record = response[i];
record[dateFields[fieldIndex]] = kendo.parseDate(record[dateFields[fieldIndex]]);
}
}
return response;
};
}
var grid = $("#grid").kendoGrid({
dataSource: {
data: gridData,
schema: {
model: model,
parse: parseFunction
}
},
toolbar: ["create", "save"],
columns: getenerateColumn(model),
editable: true,
sortable: true
});
}
function getenerateColumn(gridData) {
var datas = gridData;
var columnArray = [];
var IsFirstColumn = true;
for (var i in datas.fields) {
if (IsFirstColumn) {
columnArray.push({ field: i, sortable: false, title: i, locked: true, width: 150 });
IsFirstColumn = false;
}
else {
columnArray.push({ field: i, sortable: false, title: i, width: 500 });
}
}
return columnArray;
}
function generateModel(gridData) {
var model = {};
model.id = "ID";
var fields = {};
for (var property in gridData) {
var propType = typeof gridData[property];
if (propType == "number") {
fields[property] = {
type: "number",
validation: {
required: true
}
};
} else if (propType == "boolean") {
fields[property] = {
type: "boolean",
validation: {
required: true
}
};
} else if (propType == "string") {
var parsedDate = kendo.parseDate(gridData[property]);
if (parsedDate) {
fields[property] = {
type: "date",
validation: {
required: true
}
};
dateFields.push(property);
} else {
fields[property] = {
validation: {
required: true
}
};
}
} else {
fields[property] = {
validation: {
required: true
}
};
}
}
model.fields = fields;
return model;
}
</script>
</body>
</html>
Let me know if any concern.
Related
i'm using datatables.net in my razor page and i have a dropdown which postback to change the data in the datatable
below is the code
$(document).ready(function () {
//$("#taskDt").DataTable();
var table = $("#taskDt").DataTable({
paging: true,
responsive: true,
searching: true,
ordering: true,
order: [[1, "asc"]]
});
$("#ddlGroup").change(function(){
var a= $("#ddlGroup Option:Selected").text();
var b= $("#ddlGroup Option:Selected").val();
//alert(b);
//this.form.submit();
$.ajax({
//dataType: 'json',
url: '/page/Index?handler=GET',
type: 'GET',
dataType: "text",
data: { "Id": b },
processing: true,
serverSide: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function (data) {
console.log(data);
//table.ajax.reload();
$('#taskDt').DataTable().ajax.reload(true)
//$('#taskDt').DataTable().ajax.reload();
},
error: function () {
alert("AJAX Request Failed, Contact Support");
}
});
})
well the data returned is the full html page and i get an error of invalid JSON
and when i set dataType: "JSON" if fails and alerts ajax request failed
any help will be much appreciated.
Here is a demo to show how to update datatable data when dropdown changes:
Model:
public class Test
{
public int Id { get; set; }
public string Name { get; set; }
}
TestDataTable.cshtml:
<select id="ddlGroup">
<option>Choose Id</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<table id="taskDt">
<thead>
<tr>
<td>Id</td>
<td>Name</td>
</tr>
</thead>
<tbody></tbody>
</table>
#section scripts{
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
<script>
var table;
function LoadData() {
table = $("#taskDt").DataTable({
"ajax": {
url: '?handler=GET',
type: 'GET',
processing: true,
serverSide: true,
},
"columns": [
{ "data": "id", "width": "50%" },
{ "data": "name", "width": "50%" },
],
paging: true,
responsive: true,
searching: true,
ordering: true,
order: [[1, "asc"]]
});
}
$(document).ready(function () {
LoadData();
})
$("#ddlGroup").change(function () {
table.ajax.url("?handler=GET&&Id=" + $("#ddlGroup Option:Selected").val()).load();
});
</script>
}
TestDataTable.cshtml.cs(I use fake data to test):
public class TestDataTableModel : PageModel
{
public void OnGet()
{
}
public JsonResult OnGetGet(int? Id)
{
List<Test> l = new List<Test>();
if (Id == null)
{
l = new List<Test> { new Test { Id = 1, Name = "1" }, new Test { Id = 2, Name = "2" },new Test { Id = 3, Name = "3" } };
}
else
{
l = new List<Test> { new Test { Id = Convert.ToInt32(Id), Name = Id+"" }};
}
return new JsonResult(new { draw = 1, recordsFiltered = l.Count(), recordsTotal = l.Count(), data = l });
}
}
result:
I am trying to use Datatable and I have an issue with Datatable populating data in my .net core project.When the page is loaded, DataTable records are empty.According to the picture below:
Controller:
public IActionResult ShowCategory()
{
return View();
}
public IActionResult CategoryList()
{
try
{
var draw = HttpContext.Request.Form["draw"].FirstOrDefault();
// Skiping number of Rows count
var start = Request.Form["start"].FirstOrDefault();
// Paging Length 10,20
var length = Request.Form["length"].FirstOrDefault();
// Sort Column Name
var sortColumn = Request.Form["columns[" + Request.Form["order[0][column]"].FirstOrDefault() + "][name]"].FirstOrDefault();
// Sort Column Direction ( asc ,desc)
var sortColumnDirection = Request.Form["order[0][dir]"].FirstOrDefault();
// Search Value from (Search box)
var searchValue = Request.Form["search[value]"].FirstOrDefault()
var data = _categoryRepository.GetCategories();
return Json(new { draw = 1, recordsFiltered = 4, recordsTotal = 4, data = data });
}
catch(Exception ex)
{
throw;
}
}
Due to a problem with the code, I have now passed the draw and ... to View as a hardcode.
GetCategories() method:
public List<CategoryViewModel> GetCategories()
{
var query = _CategoryRepo.GetAll();
var q = query.Select(s => new CategoryViewModel
{
Id = s.Id,
CaregoryParentId = s.CaregoryParentId,
Priority = s.Priority,
Title = s.Title
}).ToList();
return q;
}
view:
#{
Layout = null;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link href="~/css/admin/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdn.datatables.net/1.10.15/css/dataTables.bootstrap.min.css" rel="stylesheet" />
<link href="https://cdn.datatables.net/responsive/2.1.1/css/responsive.bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.15/js/dataTables.bootstrap4.min.js "></script>
<div class="container">
<br />
<div style="width:90%; margin:0 auto;">
<table id="example" class="table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing="0">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>CaregoryParentId</th>
<th>Priority</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
</table>
</div>
</div>
<script>
$(document).ready(function ()
{
$("#example").DataTable({
"processing": true, // for show progress bar
"serverSide": true, // for process server side
"filter": true, // this is for disable filter (search box)
"orderMulti": false, // for disable multiple column at once
"ajax": {
"url": "/Admin/Category/CategoryList",
"type": "POST",
"datatype": "json"
//"success": function (data) {
// alert(JSON.stringify(data));
//}
},
"columnDefs":
[{
"targets": [0],
"visible": false,
"searchable": false
}],
{ "data": "Id", "name": "Id", "autoWidth": true },
{ "data": "Title", "name": "Title", "autoWidth": true },
{ "data": "CaregoryParentId", "name": "CaregoryParentId", "autoWidth": true },
{ "data": "Priority", "name": "Priority", "autoWidth": true },
{
"render": function (data, type, full, meta)
{ return '<a class="btn btn-info" href="/DemoGrid/Edit/' + full.CustomerID + '">Edit</a>'; }
},
{
data: null, render: function (data, type, row)
{
return "<a href='#' class='btn btn-danger' onclick=DeleteData('" + row.CustomerID + "'); >Delete</a>";
}
},
]
});
});
function DeleteData(CustomerID)
{
if (confirm("Are you sure you want to delete ...?"))
{
Delete(CustomerID);
}
else
{
return false;
}
}
function Delete(CustomerID)
{
var url = '#Url.Content("~/")' + "DemoGrid/Delete";
$.post(url, { ID: CustomerID }, function (data)
{
if (data)
{
oTable = $('#example').DataTable();
oTable.draw();
}
else
{
alert("Something Went Wrong!");
}
});
}
</script>
when I debug, I receive data in Ajax success function, but it is not shown in the table.
can anybody help me?
Thanks a lot
when I debug, I receive data in Ajax success function, but it is not
shown in the table.
From the result above we can see, server return serializes JSON with camel case names by default.
Id => id
Title => title
CaregoryParentId => caregoryParentId
Priority => priority
But in your script, "data" is set as "Id".
Solution
Use the codes below to avoid camel case names by default.
services.AddControllersWithViews().AddJsonOptions(opts => opts.JsonSerializerOptions.PropertyNamingPolicy = null);
Codes of JS
$(document).ready(function ()
{
$("#example").DataTable({
"processing": true, // for show progress bar
"serverSide": true, // for process server side
"filter": true, // this is for disable filter (search box)
"orderMulti": false, // for disable multiple column at once
"ajax": {
"url": "/Admin/Category/CategoryList",
"type": "POST",
"datatype": "json",
//"success": function (data) {
// alert(JSON.stringify(data));
//}
},
"columnDefs":
[{
"targets": [0],
"visible": false,
"searchable": false
}],
"columns": [
{ "data": "Id", "name": "Id", "autoWidth": true },
{ "data": "Title", "name": "Title", "autoWidth": true },
{ "data": "CaregoryParentId", "name": "CaregoryParentId", "autoWidth": true },
{ "data": "Priority", "name": "Priority", "autoWidth": true },
{
"render": function (data, type, full, meta) { return '<a class="btn btn-info" href="/DemoGrid/Edit/' + full.CustomerID + '">Edit</a>'; }
},
{
data: null, render: function (data, type, row) {
return "<a href='#' class='btn btn-danger' onclick=DeleteData('" + row.CustomerID + "'); >Delete</a>";
}
}
]
});
});
Test of result
I'm trying to add badges to my cytoscape.js nodes. Badges are HTML elements. I'm using bootstrap badges
Here are elements with badges. (the colors of the badges are irrelevant)
When I zoom out, the position of the badges is not set correctly. They go down and right a bit. WHY IS THAT?
Here is my code to set the positions. I but badges to to top left of the node. But I remove width of the HTML element to make it look like inside the node
let z1 = cy.zoom() / 2; // badges look too big with normal size so I downscale them
// e is cytoscape.js element, a node
const p = e.renderedPosition();
const eW = e.renderedWidth() / 2;
const eH = e.renderedHeight() / 2;
// div is an HTML element which is the badge
const w = div.clientWidth;
div.style.transform = `translate(${p.x + eW - w * z1}px, ${p.y - eH}px) scale(${z1})`;
I would personally prefer a solution using cytoscape.js resources/extensions, namely the popper.js extension.
As far as I understand your problem, you add bootstrap elements to cytoscape.js in some way (you didn't specify this, so I have to guess).
Nomrally, a sticky popper div does the trick for this problem:
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
style: [{
selector: "node",
css: {
content: "data(id)",
"text-valign": "center",
"text-halign": "center",
height: "60px",
width: "160px",
shape: "round-rectangle"
}
},
{
selector: "edge",
css: {
"target-arrow-shape": "triangle"
}
}
],
elements: {
nodes: [{
data: {
id: "n0"
}
},
{
data: {
id: "n1"
}
},
{
data: {
id: "n2"
}
},
{
data: {
id: "n3"
}
},
{
data: {
id: "n4"
}
},
{
data: {
id: "n5"
}
},
{
data: {
id: "n6"
}
},
{
data: {
id: "n7"
}
},
{
data: {
id: "n8"
}
},
{
data: {
id: "n9"
}
},
{
data: {
id: "n10"
}
},
{
data: {
id: "n11"
}
},
{
data: {
id: "n12"
}
},
{
data: {
id: "n13"
}
},
{
data: {
id: "n14"
}
},
{
data: {
id: "n15"
}
},
{
data: {
id: "n16"
}
}
],
edges: [{
data: {
source: "n0",
target: "n1"
}
},
{
data: {
source: "n1",
target: "n2"
}
},
{
data: {
source: "n1",
target: "n3"
}
},
{
data: {
source: "n4",
target: "n5"
}
},
{
data: {
source: "n4",
target: "n6"
}
},
{
data: {
source: "n6",
target: "n7"
}
},
{
data: {
source: "n6",
target: "n8"
}
},
{
data: {
source: "n8",
target: "n9"
}
},
{
data: {
source: "n8",
target: "n10"
}
},
{
data: {
source: "n11",
target: "n12"
}
},
{
data: {
source: "n12",
target: "n13"
}
},
{
data: {
source: "n13",
target: "n14"
}
},
{
data: {
source: "n13",
target: "n15"
}
}
]
},
layout: {
name: "dagre",
padding: 5,
rankSep: 100
}
}));
var makeTippy = function(node, text) {
var ref = node.popperRef();
var dummyDomEle = document.createElement("div");
var tip = tippy(dummyDomEle, {
onCreate: function(instance) {
instance.popperInstance.reference = ref;
},
lazy: false, // mandatory
trigger: "manual", // mandatory
// dom element inside the tippy:
content: function() {
var div = document.createElement("div");
div.innerHTML = text;
return div;
},
// your own preferences:
arrow: false,
placement: 'top-end',
hideOnClick: false,
multiple: true,
sticky: true
});
return tip;
};
cy.ready(function() {
cy.zoom(0.75);
cy.center();
cy.ready(function() {
let nodes = cy.nodes();
nodes.each(function(node) {
let tippy = makeTippy(node, node.id());
tippy.show();
});
});
});
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
}
.tippy-popper {
transition: none !important;
}
<html>
<head>
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<script src="https://unpkg.com/dagre#0.7.4/dist/dagre.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-dagre#2.1.0/cytoscape-dagre.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-popper#1.0.6/cytoscape-popper.min.js"></script>
<script src="https://unpkg.com/tippy.js#5.1.3/dist/tippy-bundle.iife.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/tippy.js#5.1.3/dist/tippy.css" />
</head>
<body>
<div id="cy"></div>
</body>
</html>
This snippet cuts some of the container off, so try this in your application for better results and take a look at the extensions used here
The problem stems from CSS scale. When I scale the element, the center point of the element remains invariant. The below sample shows What I mean
div {
position: absolute;
}
span {
font-size: 64px;
}
.s1 {
transform: scale(1);
background: red;
}
.s2 {
transform: scale(0.5);
background: blue;
}
<div class="s1"><span>00</span></div>
<div class="s2"><span>00</span></div>
So I have to consider the center point of the div. Below code does that
let z1 = this._g.cy.zoom() / 2;
const bb = e.renderedBoundingBox({ includeLabels: false, includeOverlays: false });
const w = div.clientWidth;
const h = div.clientHeight;
const deltaW4Scale = (1 - z1) * w / 2;
const deltaH4Scale = (1 - z1) * h / 2;
div.style.transform = `translate(${bb.x2 - deltaW4Scale - w * z1}px, ${bb.y1 - deltaH4Scale}px) scale(${z1})`;
I'm trying to use the Drilldown in Map (vue-Highchart), but cannot get it working.
like this: https://www.highcharts.com/maps/demo/map-drilldown
Anyone have any examples of this in Vue.js? Please.
Tks.
Here is simple example of drilldown functionality(with vue-highcharts) which provides drilldown and drillup event from Vue-instance:
Vue.use(VueHighcharts, { Highcharts: Highcharts });
// helper script to load external script
let loadScript = function(url, onLoad){
var scriptTag = document.createElement('script');
scriptTag.src = url;
scriptTag.onload = onLoad;
scriptTag.onreadystatechange = onLoad;
document.body.appendChild(scriptTag);
};
// simple chart options
var options = {
chart: {},
title: {
text: 'Highcharts-Vue Map Drilldown Example'
},
subtitle: {
text: '',
floating: true,
align: 'right',
y: 50,
style: {
fontSize: '16px'
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
colorAxis: {
min: 0,
minColor: '#E6E7E8',
maxColor: '#005645'
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
plotOptions: {
map: {
states: {
hover: {
color: '#EEDD66'
}
}
}
},
drilldown: {
activeDataLabelStyle: {
color: '#FFFFFF',
textDecoration: 'none',
textOutline: '1px #000000'
},
drillUpButton: {
relativeTo: 'plotBox',
position: {
x: 70,
y: 280
}
}
},
series: [{
data: Highcharts.geojson(Highcharts.maps['countries/us/us-all']).map((d, i) => {
d.drilldown = true;
// set value just for example
d.value = i;
return d;
}),
name: 'USA',
dataLabels: {
enabled: true,
format: '{point.properties.postal-code}'
}
}]
};
let vm = new Vue({
el: '#app',
data: {
isLoading: false,
options: options
},
created() {
// prepare events for chart from Vue instance
this.options.chart.events = {
drilldown: this.drilldown.bind(this),
drillup: this.drillup.bind(this)
}
},
methods: {
drilldown(e) {
let { chart } = this.$refs.highcharts;
if (!e.seriesOptions) {
mapKey = 'countries/us/' + e.point.properties['hc-key'] + '-all';
if (Highcharts.maps[mapKey]) {
this.prepareDrilldownData(mapKey, e.point);
return;
}
this.isLoading = true;
loadScript('https://code.highcharts.com/mapdata/' + mapKey + '.js', () => {
this.isLoading = false;
this.prepareDrilldownData(mapKey, e.point);
});
}
chart.setTitle(null, { text: e.point.name });
},
drillup(e) {
let { chart } = this.$refs.highcharts;
chart.setTitle(null, { text: '' });
},
prepareDrilldownData(mapKey, point) {
let { chart } = this.$refs.highcharts;
data = Highcharts.geojson(Highcharts.maps[mapKey]).map((d, i) => {
// set value just for example
d.value = i;
return d;
});
chart.addSeriesAsDrilldown(point, {
name: point.name,
data: data,
dataLabels: {
enabled: true,
format: '{point.name}'
}
});
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<script src="https://code.highcharts.com/maps/highmaps.js"></script>
<script src="https://code.highcharts.com/maps/modules/drilldown.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-highcharts/dist/vue-highcharts.min.js"></script>
<script src="https://code.highcharts.com/mapdata/countries/us/us-all.js"></script>
<div id="app">
<highmaps ref="highcharts" :options="options"></highmaps>
<div v-if="isLoading" style="text-align: center; margin-top: 15px; font-size: 20px;">Loading...</div>
</div>
There is also jsfiddle if you want.
I want to show a summary of closed defects filtered by iteration with the total count of defects per resolution that looks similar to this:
Here is an example of a grid that does that. Replace '111' in
workspace: '/workspace/1111'
with ObjectID of your workspace. This post shows how to find OID of workspace.
<!DOCTYPE html>
<html>
<head>
<title>closed defects by iteration</title>
<script type="text/javascript" src="/apps/2.0rc1/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function () {
Ext.define('CustomApp', {
extend: 'Rally.app.TimeboxScopedApp',
componentCls: 'app',
scopeType: 'iteration',
comboboxConfig: {
fieldLabel: 'Select an Iteration:',
labelWidth: 100,
width: 300
},
addContent: function() {
this._arr = [];
var that = this;
console.log('_addContent');
Rally.data.ModelFactory.getModel({
type: 'Defect',
context: {
workspace: '/workspace/1111'
},
success: function(model) {
that._allowedValuesStore = model.getField( 'Resolution' ).getAllowedValueStore( );
console.log("allowed values count", that._allowedValuesStore.getCount());
that._getDropdownValues();
that._makeStore();
}
});
},
_getDropdownValues: function(){
var that = this;
this._allowedValuesStore.load({
scope: this,
callback: function(records, operation, success){
console.log(records[1].get('StringValue'));
Ext.Array.each(records, function(val) {
var s = val.get('StringValue');
that._arr.push(s);
});
console.log("arr[2]", this._arr[2])
}
});
},
_makeStore: function(){
console.log('_makeStore');
var filter = Ext.create('Rally.data.QueryFilter', {
property: 'Priority',
operator: '=',
value: 'Resolve Immediately'
});
filter = filter.or({
property: 'Priority',
operator: '=',
value: 'High Attention'
});
filter = filter.and({
property: 'State',
operator: '=',
value: 'Closed'
});
filter = filter.and(this.getContext().getTimeboxScope().getQueryFilter());
filter.toString();
Ext.create('Rally.data.WsapiDataStore', {
model: 'Defect',
fetch: ['FormattedID','Name','Tasks','State','Resolution','Priority'],
pageSize: 100,
autoLoad: true,
filters: [filter],
listeners: {
load: this._onDataLoaded,
scope: this
}
});
},
onScopeChange: function() {
console.log('onScopeChange');
this._makeStore();
},
_onDataLoaded: function(store, data){
console.log('_onDataLoaded');
var defects = [];
if (data.length === 0) {
this._createGrid(defects);
}
var countArchitecture=0;
var countCodeChange=0;
var countNotADefect=0;
var countNone = 0;
var countConfigurationChange =0;
var countDatabaseChange = 0;
var countDuplicate = 0;
var countNeedMoreInformation =0;
var countSoftwareLimitation =0;
var countUserInterface = 0;
Ext.Array.each(data, function(defect) {
var resolution = defect.get('Resolution');
switch(resolution)
{
case "Architecture":
countArchitecture++;
break;
case "Code Change":
countCodeChange++;
break;
case "Not a Defect":
countNotADefect++;
break;
case "None":
countNone++;
break;
case "Configuration Change":
countConfigurationChange++;
break;
case "Database Change":
countDatabaseChange++;
break;
case "Duplicate":
countDuplicate++;
break;
case "Need More Information":
countDuplicate++;
break;
case "Software Limitation":
countSoftwareLimitation++;
break;
case "User Interface":
countUserInterface++;
break;
default:
countNone++;
}
});
var d = {
'Architecture': countArchitecture,
'Code Change': countCodeChange,
'Not a Defect' : countNotADefect,
'' : countNone,
'Configuration Change': countConfigurationChange,
'Database Change': countDatabaseChange,
'Duplicate': countDuplicate,
'Need More Information': countNeedMoreInformation,
'Software Limitation': countSoftwareLimitation,
'User Interface':countUserInterface,
};
defects.push(d);
this._createGrid(defects);
},
_createGrid: function(defects) {
console.log('_createGrid');
console.log('this._arr[3]', this._arr[3]);
var that = this;
var myStore = Ext.create('Rally.data.custom.Store', {
data: defects,
pageSize: 100,
});
var columnConfig = [];
for (var i=0;i<this._arr.length; i++) {
var columnConfigElement = {};
columnConfigElement['text'] = that._arr[i];
columnConfigElement['dataIndex'] = that._arr[i];
columnConfig.push(columnConfigElement);
}
console.log('columnConfig', columnConfig);
if (!this.grid) {
this.grid = this.add({
xtype: 'rallygrid',
itemId: 'mygrid',
store: myStore,
columnCfgs: columnConfig
});
}else{
this.grid.reconfigure(myStore);
}
}
});
Rally.launchApp('CustomApp', {
name:"closed defects by iteration",
//parentRepos:""
});
});
</script>
<style type="text/css">
.app {
margin: 10px;
}
.header {
margin: 5px;
}
</style>
</head>
<body></body>
</html>
This is how it looks: