Bar Chart with Rally.data.lookback.calculator.TimeSeriesCalculator - extjs

I need to create bar chart showing up various values, such as "Created", "Closed", "Submitted" data with count on Y Axis and dates on x axis.
I am able to do this successfully, for any one criteria. However I am not able to get multiple bars being shown.
Below is the code I am using currently:
<!DOCTYPE html>
<html>
<head>
<title>Defect Trend App</title>
<script type="text/javascript" src="/apps/2.0rc1/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function () {
(function() {
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
return this.createTrendChart();
},
createTrendChart: function() {
var ProjectOid;
ProjectOid = this.getContext().getProject().ObjectID;
var ReleaseOID = <My Release ID>;
Ext.define('My.TrendCalc', {
extend: 'Rally.data.lookback.calculator.TimeSeriesCalculator',
getMetrics: function() {
return [
{
as: 'Defects',
display: 'column',
f: 'count'
}
];
}
});
this.myTrendChart = Ext.create('Rally.ui.chart.Chart', {
storeType: 'Rally.data.lookback.SnapshotStore',
storeConfig: {
find: {
_TypeHierarchy: "Defect",
State: {
$lt: "Closed"
},
_ProjectHierarchy: ProjectOid,
Release: ReleaseOID
},
fetch: ["_ValidFrom", "_ValidTo", "ObjectID"]
},
calculatorType: 'My.TrendCalc',
calculatorConfig: {},
chartConfig: {
chart: {
zoomType: 'x',
type: 'column'
},
title: {
text: 'Defects over Time'
},
xAxis: {
type: 'datetime',
minTickInterval: 1
},
yAxis: {
title: {
text: 'Number of Defects'
}
}
}
});
return this.add(this.myTrendChart);
}
});
}).call(this);
Rally.launchApp('CustomApp', {
name:"Defect Trend App",
parentRepos:""
});
});
</script>
<style type="text/css">
.app {
/* Add app styles here */
}
</style>
</head>
<body></body>
</html>

I do not consider myself an expert in this area, but I believe this will work for you...
I took your code as a base and modified it based on some other code to get what I think appears to be a working version of what you want. Below is a screenshot of the code running in Rally.
The data I had did not have a lot of variance in the series (most were released) so it looks uninteresting.
You will probably want to exclude the final state (as I believe you did in your code via the $lt:'Completed'... which i changed to $lte:'Completed' temporarily).
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"><html><head><title>
Defect Trend App </title>
<script type="text/javascript" src="/apps/2.0rc1/sdk.js"></script>
<script type="text/javascript">
var states = ['Accepted','Released']; // all enum values for 'State'
var field = 'ScheduleState'; // or 'State'
var ReleaseOID = XXXXXX; // your release Oid
Rally.onReady(function () {
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
return this.createTrendChart();
},
createTrendChart: function() {
var ProjectOid;
ProjectOid = this.getContext().getProject().ObjectID;
Ext.define('My.TrendCalc', {
extend: 'Rally.data.lookback.calculator.TimeSeriesCalculator',
getDerivedFieldsOnInput: function() {
var m = _.map(states, function(state) {
return {
"as": state,
"f" : function(snapshot) {
var value = (snapshot[field] == state) ? 1 : 0;
return value;
}
}
})
return m;
},
getMetrics : function() {
var m = _.map(states, function(state) {
return {
field: state,
as: state,
f: 'sum'
}
})
return m;
}
});
this.myTrendChart = Ext.create('Rally.ui.chart.Chart', {
storeType: 'Rally.data.lookback.SnapshotStore',
storeConfig: {
find: {
_TypeHierarchy: "Defect",
State: {$lte: "Closed" },
_ProjectHierarchy: ProjectOid,
Release: ReleaseOID
},
fetch: ["_ValidFrom", "_ValidTo", "ObjectID", field],
hydrate: [field],
sort: { "_ValidFrom" : 1}
},
calculatorType: 'My.TrendCalc',
calculatorConfig : {},
chartConfig: {
chart: {
zoomType: 'xy',
type:'column'
},
title: {
text: 'Defects over Time'
},
xAxis: {
type: 'datetime',
title: { text: 'When'},
minTickInterval: 5,
labels : { rotation: 90 }
},
yAxis: { title: { text: 'Count' } },
plotOptions: {
series: {
stacking: 'normal'
}
}
}
});
return this.add(this.myTrendChart);
}
});
});
console.log("launching application");
Rally.launchApp('CustomApp', {
name:'Defect Trend App',
parentRepos:""
});
</script>
</head>
<body>
</body>
Pastebin - http://pastebin.com/Vf6jniGZ

I'm not familiar with Rally's App SDK wrappers, but I'm the primary author of Lumenize where the TimeSeriesCalculator comes from. Your situation is exactly what the group-by functionality in Lumenize.TimeSeriesCalculator was designed for. See the documentation for a careful walkthrough of how the TimeSeriesCalculator works. Look at the second example titled, "Time-series group-by example". Also, here is a functioning jsfiddle of that group-by example.
The key bit that you need is:
metrics = [
...
{f: 'groupByCount', groupByField: 'ScheduleState', allowedValues: allowedValues, prefix: 'Count '},
...
]

Related

Highstock Navigator Displayed Twice

I am using highstock,5.0.10 with angularJS.
In my chart navigator got displayed twice, like below
As you can see, navigator has been rendered twice. However, if you refresh the page, everything looks fine.
Any ideas?
I have added my Highstock code here.
Highcharts.stockChart('FindComputerUsage', {
rangeSelector: {
selected: 1
},
credits: {
enabled: false
},
title: {
text: ''
},
yAxis: {
title: {
text: 'Percentage of time (%) '
}
},
tooltip: {
formatter: function() {
var date = new Date(requiredData[this.points[0].point.index][0]);
return date + '<br>' + 'Percentage:' + requiredData[this.points[0].point.index][1] + '%';
}
},
series: [{
name: 'Percentage (%)',
data: requiredData,
tooltip: {
valueDecimals: 2,
}
}],
lang :{
noData : "No data to display "
}
});
Here you can see a working example: https://plnkr.co/edit/OphM9wf8WyGm8U6HXfTy
You haven't show your HTML view, but I guess it's similar to this.
<div ng-controller="demoCtrl">
<div id="container" style="height: 400px; min-width: 310px"></div>
</div>
Concerning controller scope, I didn't change anything:
var app = angular.module('demoApp', []);
app.controller('demoCtrl', function($scope){
$scope.data = [
[1290729600000,45.00],
[1290988800000,45.27],
[1291075200000,44.45]
];
Highcharts.stockChart('container', {
rangeSelector: {
selected: 1
},
title: {
text: 'Qing Xu Example'
},
series: [{
name: 'Value',
data: $scope.data,
tooltip: {
valueDecimals: 2
}
}]
})
});

updating high chart on real time in angular js after a particular time

I want to update high chart on real time in angular js after a particular time span and it should get reflects on html without user interaction in angular JS.
Below are code for Controller,Directive and HTML. I am using rest web service to fetch the data from back end.
Controller :
function dashboardController($scope, $http) {
this.$scope = $scope;
$scope.init=function(){
_refreshPageData();
function _refreshPageData() {
$http({
method : 'GET',
url : 'http://localhost:8080/SpringWebApp/rest/employee/monthlydata'
}).then(function successCallback(response) {
$scope.data = response.data;
var data = $scope.data;
var a = [];
parseInt($scope.data[0].data);
angular.forEach(data, function(data, key) {
a.push(parseInt(data.data));
});
console.log($scope.data);
$scope.chartConfig = {
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
title: {
text: 'USD to EUR exchange rate from 2006 through 2008'
}, subtitle: {
text: document.ontouchstart === undefined ?
'Click and drag in the plot area to zoom in' :
'Pinch the chart to zoom in'
},
yAxis: { title: { text: 'Temperature (Celsius)' } },
tooltip: { valueSuffix: ' celsius' },
legend: { align: 'center', verticalAlign: 'bottom', borderWidth: 0 },
plotOptions: {
area: {
fillColor: {
linearGradient: { x1: 200, y1: 220, x2: 220, y2: 2221},
stops: [
[0, Highcharts.getOptions().colors[0]],
[1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
},
marker: {
radius: 2
},
lineWidth: 1,
states: {
hover: {
lineWidth: 1
}
},
threshold: null
}
},
series: [{
type:'area',
data :a
}]
};
}, function errorCallback(response) {
console.log(response.statusText);
});
}
}
}
Directive :
var chartDirective = function () {
return {
restrict: 'E',
replace: true,
template: '<div></div>',
scope: {
config: '='
},
link: function (scope, element, attrs) {
var chart;
var process = function () {
var defaultOptions = {
chart: { renderTo: element[0] },
};
var config = angular.extend(defaultOptions, scope.config);
chart = new Highcharts.Chart(config);
};
process();
scope.$watch("config.series", function (loading) {
process();
});
scope.$watch("config.loading", function (loading) {
if (!chart) {
return;
}
if (loading) {
chart.showLoading();
} else {
chart.hideLoading();
}
});
}
};
};
Html :
<!DOCTYPE html>
<html lang="en">
<head>
<script data-require="angular.js#*" data-semver="1.2.5" src="http://code.angularjs.org/1.2.5/angular.js"></script>
<script data-require="jquery#*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script data-require="highcharts#*" data-semver="2.3.5" src="//cdnjs.cloudflare.com/ajax/libs/highcharts/2.3.5/highcharts.js"></script>
<script src="chartDirective.js"></script>
<script src="dashboardController.js"></script>
<script src="app.js"></script>
<meta charset="utf-8">
</head>
<body ng-app="app">
<div ng-controller="dashboardController">
<div ng-init="init()"></div>
<chart config="chartConfig"></chart>
</div>
</body>
</html>
You can make a request based on the interval using $interval
$interval(function() {
YourApi.response.then,
series.addPoint([whatever);
}, 1000);

Angular formly multicheckbox

I have been looking for an example for 'multicheckbox' type in 'angular formly form', where the check-boxes are selected or unselected based on corresponding value in form model, when the form is loaded,but could not find any.Can some one please help me with an example?
I shall explain my exact case :
Following is my formly form.Its a multicheckbox with key as 'selectedAnswer'.Initial value for 'selectedAnswer' in the forms model is "ee,dd".But the correspondig values are not getting checked in the check box on loading the form.
[
{
"key":"selectedAnswer",
"type":"multiCheckbox",
"templateOptions":{
"label":"fsdfsdf",
"options":[
{
"name":"ee",
"value":"ee"
},
{
"name":"dd",
"value":"dd"
},
{
"name":"tg",
"value":"tg"
}
]
}
}
]
Please help me to fix this issue.
Thanks,
Deepthy.
click this DEMO for example
HTLM/VIEW
<form novalidate>
<formly-form model="vm.model" fields="vm.Fields" form="vm.rentalForm">
</formly-form>
</form>
Script Code
var vm = this;
vm.model = {
check1: true,
check2:false,
check3:false
};
vm.Fields = [
{
key: 'check1',
type: 'checkbox',
templateOptions: { label: '' },
expressionProperties: {
'templateOptions.label': function(viewValue, modelValue, scope) {
return "check1"
}
}
},{
key: 'check2',
type: 'checkbox',
templateOptions: { label: '' },
expressionProperties: {
'templateOptions.label': function(viewValue, modelValue, scope) {
return "check2"
}
}
},{
key: 'check3',
type: 'checkbox',
templateOptions: { label: '' },
expressionProperties: {
'templateOptions.label': function(viewValue, modelValue, scope) {
return "check3"
}
}
}
];
Hope this works for you.
You can use this type of check box list -
Updated Answer
HTML/View
<form novalidate>
<formly-form model="vm.model" fields="vm.Fields" form="vm.rentalForm">
</formly-form>
</form>
Controller
function MainController(province) {
var vm = this;
vm.model = {
selectedAnswer: ["dd","ee"],
};
vm.Fields =[
{
"key":"selectedAnswer",
"type":"multiCheckbox",
"templateOptions":{
"label":"fsdfsdf",
"options":[
{
"name":"ee",
"value":"ee"
},
{
"name":"dd",
"value":"dd"
},
{
"name":"tg",
"value":"tg"
}
]
}
}
] }
For better understanding check this Fiddle
I have forked the plunk of Santhosh kesavan's answer for providing the better answer.
Hope it will work for you.
For nested keys like below:
{
key: 'domains',
templateOptions: { label: 'Domains' },
fieldGroup: [
{
key: 'domainsCheckbox',
type: 'multicheckbox',
templateOptions: {
options: [
{
key: 'Option1',
value: 'Option1'
},
{
key: 'Option2',
value: 'Option2'
},
]
},
}
]
}
You can specify the model as:
model = {'domains': {'domainsCheckbox': { 'Option1': true }}};
I didn't work for me, in latest version the type has been updated. like type: multiCheckbox --> multicheckbox and options.name --> options.key
[
{
"key":"selectedAnswer",
"type":"multicheckbox",
"templateOptions":{
"label":"fsdfsdf",
"options":[
{
"key":"ee",
"value":"ee"
},
{
"key":"dd",
"value":"dd"
},
{
"key":"tg",
"value":"tg"
}
]
}
}
]
Below code will give you the idea
index.html
<!doctype html>
<html lang="en" ng-app="checkBx">
<head>
<meta charset="UTF-8">
<title>Example - example-ng-selected-production</title>
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="myCtrl">
<label>Check me to select: <input type="checkbox" ng-model="isSelected"></label><br/>
<label>Check me to select: <input type="checkbox" ng-model="isSecSelected"></label><br/>
</body>
</html>
script.js
var app = angular.module('checkBx', [])
app.controller('myCtrl', ['$scope', myCtrl]);
function myCtrl($scope){
$scope.isSelected = true;
$scope.isSecSelected = false;
}

Highcharts- Unable to change yAxis label

I am trying to render charts using the Highcharts js-library. As I am working with AngularJS, I am using an AngularJS directive for HighCharts.
I made everything work fine but due to some weird reason, I am unable to change the yAxis label value.
I get the default value "Values" shown on the chart's y-axis, which I checked is defined in the highcharts.js file under "defaultYAxisOptions".
Html:
<div ng-app="myapp">
<div ng-controller="myctrl">
<highchart id="chart1" config="chart"></highchart>
</div>
</div>
Javascript:
var myapp = angular.module('myapp', ["highcharts-ng"]);
myapp.controller('myctrl', function ($scope) {
$scope.chart = {
options: {
chart: {
type: 'bar'
}
},
xAxis: {
title: {
text: 'x-axix-label'
}
},
yAxis: {
title: {
text: 'y-axix-label'
}
},
series: [{
data: [10, 15, 12, 8, 7]
}],
title: {
text: 'Hello'
},
loading: false
}
});
Sample implementation: http://jsfiddle.net/VwTCn/9/
Can someone please point out the mistake here.
Took me a while, to understand, that highcharts-ng doesn't work, using the original highcharts options structure.
Anyway, for some reason it works, if you put you yAxis config into the options object, like this:
...
options: {
chart: {
type: 'bar'
},
yAxis: {
title: {
text: 'y-axis label'
}
}
},
xAxis: {
title: {
text: 'x-axis label'
}
},
series: [{
...
See example: http://jsfiddle.net/martinczerwi/VwTCn/13/

Sencha touch 2 - Display current location on map

I want to display my current location and get location coordinates to search nearby. Starting with the code below to display my location on the map, but its not working.
{
xtype: 'map',
useCurrentLocation: true
}
I defined a custom map class:
Ext.define("FindMyMoney.view.MapView", {
extend: "Ext.Map",
xtype: 'mapview',
config: {
useCurrentLocation: true,
listeners: {
maprender : function(comp, map){
new google.maps.Marker({
position: new google.maps.LatLng(this._geo.getLatitude(), this._geo.getLongitude()),
map: map
});
}
}
}
});
So it would render a marker on my current position. Simple.
Here is the code. It will show multiple markers with bounds:
Ext.define("iME.view.Maps", {
extend: "Ext.Map",
xtype: 'mapview',
config: {
mapOptions: {
center: new google.maps.LatLng(28.80010128657071, 77.28747820854187),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false
},
listeners: {
maprender: function (comp, map) {
var markersll = [
['Noida', 28.80010128657071, 77.28747820854187],
['Coogee Beach', 24.80010128565, 73.2874782084457],
['Cronulla Beach', 25.80010128657071, 76.28747820854187],
['Manly Beach', 28.80010128657071, 72.28747820854187],
['Maroubra Beach', 9.052234, 75.243685]
];
var infowindow = new google.maps.InfoWindow();
var marker, i, pos;
var bounds = new google.maps.LatLngBounds();
for (i = 0; i < markersll.length; i++) {
pos = new google.maps.LatLng(markersll[i][1], markersll[i][2]);
bounds.extend(pos);
marker = new google.maps.Marker({
position: pos,
animation: google.maps.Animation.BOUNCE,
icon: 'http://thumb10.shutterstock.com/thumb_small/429058/131292377/stock-vector-map-super-marker-icon-131292377.jpg',
map: map,
title: 'Click Me ' + i
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(markersll[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
map.fitBounds(bounds);
}
}
}
}
});
I think this is a bug in ST2. I asked (I think you did :-) ) this question also in Sencha Forums: http://www.sencha.com/forum/showthread.php?156501-Maps-with-sencha-touch
My code in that forum did not worked. The code that I was using is as follows:
The index.html file looks like this:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Sample app</title>
<script type="text/javascript" src="lib/touch/sencha-touch-all-debug.js"></script>
<link href="lib/touch/resources/css/sencha-touch.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript">
Ext.Loader.setConfig({
enabled : true,
path : {
PPL : 'ppl.js'
}
});
Ext.setup({
tabletStartupScreen : 'tablet_startup.png',
phoneStartupScreen : 'phone_startup.png',
icon : 'phone_startup.png',
onReady : function() {
Ext.create('PPL.App', {
fullscreen : true
});
}
})
</script>
</head>
<body>
</body>
</html>
And my ppl.js looks like this:
Ext.define('PPL.App', {
extend: 'Ext.Panel',
layout: 'vbox',
config: {
items: [{
xtype: 'toolbar',
title: 'Sample MAP'
}, {
xtype: 'panel',
layout: 'fit',
items: [{
xtype: 'map',
useCurrentLocation: true
}]
}]
}
});
If I change my ppl.js into the following:
Ext.define('PPL.App', {
extend: 'Ext.Map',
layout: 'fit',
config: {
items: [{
xtype: 'map',
useCurrentLocation: false
}]
}
});
Then it is working!
So, I think we need to wait untill next release, in the mean time learn ST2 :-)
Cheers!
Here is the code to show location current location
var geo = Ext.create('Ext.util.Geolocation', {
autoUpdate: false,
listeners: {
locationupdate: function(geo) {
var currentLat = geo.getLatitude();
var currentLng = geo.getLongitude();
var altitude = geo.getAltitude();
var speed = geo.getSpeed();
var heading= geo.getHeading();
},
locationerror: function(geo, bTimeout, bPermissionDenied, bLocationUnavailable, message) {
if(bTimeout)
Ext.Msg.alert('Timeout occurred',"Could not get current position");
else
alert('Error occurred.');
}
}
}
});
geo.updateLocation();

Resources