In Dygraphs, How to display AxisLabels as Text instead of Numbers/Date - axis-labels

I need to build a graph to show world's population by region and sample data would be
 
China 1,361,300,000
India 1,236,970,000
United States 317,148,000
Indonesia 237,641,326
Brazil 201,032,714
I am new to Dygraphs and I tried simple example on the same:
<html>
<head>
<script type="text/javascript"
src="http://dygraphs.com/dygraph-combined.js"></script>
</head>
<body>
<div id="demodiv" style="width:500px;height:500px"></div>
<script type="text/javascript">
var data = "Country,Population\n" +
"1,1361300000\n" +
"2,1236970000\n" +
"3,317148000\n" +
"4,237641326\n" +
"5,201032714\n";
g = new Dygraph(document.getElementById("demodiv"), data, {
title: "World's Population"
});
</script>
</body>
</html>
Now, How can I use Dygraphs to display country Name instead of numbers on x-Axis? Is it possible with Dygraphs?
Thanks in Advance.

You could use the valueFormatter and axisLabelFormatter options. See http://dygraphs.com/options.html
The following example will print 'text:' inside the legend and the x value from your data.
axes: {
x: {
valueFormatter: function(x) {
return 'text';
},
axisLabelFormatter: function(x) {
return x;
},
}
},
Example in jsfiddle: http://jsfiddle.net/JaM3S/

#user3020781 Those two options for the x-axis helped me as well, thank you! I also had an issue with having .5 steps between the whole numbers, and found the issue was I had the chart set too wide and I only had 6 groups plotted on the x-axis, so dygraph was automatically adding the half step.
Couple solutions:
1. Add cases in the switch statements for the .5 steps
2. use the pixelsPerLabel option inside the x axis. The default for the x axes is 60, I doubled to get 120 which fixed mine.
3. Make the whole graph smaller. Mine are all set to be 1000px wide.
Both worked for my problem. Here's the Dygraph code. I commented out the case statements because I went with the pixelsPerLabel fix.
g = new Dygraph(
document.getElementById("graphdiv"),
dataArray,
{
xlabel: "x something",
ylabel: "y something",
title: "The coolest chart ever!",
labels: ["FR", "Avg1", "Avg2"],
labelsDiv: document.getElementById("labelsdiv"),
labelsSeparateLines: true,
width:1000,
colors: ["#339933", "#990000"],
strokeWidth: 2.5,
valueRange: [4, 5.8],
axes: {
x: {
/*the space between grid lines on x axis: default is 60px*/
pixelsPerLabel: 120,
valueFormatter: function(FR) {
var ret;
switch (FR){
case 1:
ret = 'A';
break;
case 2:
ret = 'B';
break;
case 3:
ret = 'C';
break;
case 4:
ret = 'D';
break;
case 5:
ret = 'D';
break;
case 6:
ret = 'F';
break;
/*case 1.5:
ret = '';
break;
case 2.5:
ret = '';
break;
case 3.5:
ret = '';
break;
case 4.5:
ret = '';
break;
case 5.5:
ret = '';
break;
case 6.5:
ret = '';
break;*/
}//end switch
return ret;
},//end of label formatter,
axisLabelFormatter: function(FR) {
var ret;
switch (FR){
case 1:
ret = 'A';
break;
case 2:
ret = 'B';
break;
case 3:
ret = 'C';
break;
case 4:
ret = 'D';
break;
case 5:
ret = 'E';
break;
case 6:
ret = 'F';
break;
/*case 1.5:
ret = '';
break;
case 2.5:
ret = '';
break;
case 3.5:
ret = '';
break;
case 4.5:
ret = '';
break;
case 5.5:
ret = '';
break;
case 6.5:
ret = '';
break;*/
}//end switch
return ret;
}//end of axis label formatter
}//end of x axis
}//end of axis
} );

Related

Using a callback on click of react-date-range defined ranges

How can we add a callback when clicked the encircled ranges? I want to change the input placeholder based on the range picked. For example the user clicked "This week" so the placeholder also on the right should be changed to "This week". I've red the documentation but I cant find thing I need. Thank you so much for your help in advance! Here's a snippet of my code.
const [dateState, setDateState] = useState<any>([
{ startDate: null, endDate: null, key: "selection" },
]);
{openDateRange && (
<DateRangePicker
className="date-range"
editableDateInputs={true}
onChange={(item) => setDateState([item.selection])}
moveRangeOnFirstSelection={false}
ranges={dateState}
/>
)}
I had the same issue,
here is my workaround ;
while selecting ranges it updates both selection values in the very first click.
onDateRangeChanged= () => {
.....
if(ranges.selection.startDate !== ranges.selection.endDate){
const result = calculateDateRangeFromTwoDates(ranges);
if(result.specificTimeSpan === true)
toggleRangePicker();
}
.....
}
and with the calculator below u can extract whether your dates is defined range or not (of course code below can be refactored like reading from a Json file etc.)
export const calculateDateRangeFromTwoDates = (ranges: any) => {
const beginDate = moment(ranges.selection.startDate);
const endDate = moment(ranges.selection.endDate);
const today = moment();
let text = '';
let specificTimeSpan = true;
const duration = moment.duration(endDate.diff(beginDate));
const selectedDateDifference = duration.get('days');
switch (selectedDateDifference) {
case 30:
case 29:
text = moment(endDate).isSame(today, 'month') ? 'This Month' : 'Last Month';
break;
case 7:
case 6:
text = moment(endDate).isSame(today, 'week') ? 'This Week' : 'Last Week';
break;
case 1:
case 0:
text = moment(endDate).isSame(today, 'day') ? 'Today' : 'Yesterday';
break;
default:
text = `
${moment(ranges.selection.startDate).format('MM/DD/YYYY')} - ${moment(ranges.selection.endDate).format(
'MM/DD/YYYY',
)}
`;
specificTimeSpan = false;
break;
}
return ({
text,
specificTimeSpan
})
};

setting items disable on uncheck all

I am using a bootstrap-multiselect and same options on textbox
<label>Options:</label>
<div ng-model="val.options" ng-dropdown-multiselect="" options="array" extra-settings="settings2" events="events"> </div>
<label>Codes:</label>
<label>A:</label>
<input type="text" ng-model="val.A" ng-disabled="aDisable">
<label>B:</label>
<input type="text" ng-model="val.B" ng-disabled="bDisable">
<label>C:</label>
<input type="text" ng-model="val.C" ng-disabled="cDisable">
<label>D:</label>
<input type="text" ng-model="val.D" ng-disabled="dDisable">
<label>E:</label>
<input type="text" ng-model="val.E" ng-disabled="eDisable">
</div>
Directive code:-
(function () {
'use strict';
angular.module('myApp.components')
.directive('options', options);
options.$inject = ['$http' , '$timeout];
function branch($http, $timeout) {
return {
restrict: 'EA',
scope: {
},
controller: function ($scope) {
$scope.disable = function(){
$scope.aDisable = true;
$scope.bDisable = true;
$scope.cDisable = true;
$scope.dDisable = true;
$scope.eDisable = true;
};
$scope.disable();
$scope.array = [{
name: "A"
}, {
name: "B"
}, {
name: "C"
}, {
name: "D"
}, {
name: "E"
}];
$scope.settings = {
smartButtonMaxItems: 11,
scrollable: true,
displayProp: "name",
idProp: "name",
externalIdProp: "name"
};
$scope.settings2 = {
smartButtonMaxItems: 7,
scrollable: true,
displayProp: "name",
idProp: "name",
externalIdProp: "name",
};
$scope.enabling = function(e){
switch(e) {
case 'A': $scope.aDisable = false;
break;
case 'B': $scope.bDisable = false;
break;
case 'C': $scope.cDisable = false;
break;
case 'D': $scope.dDisable = false;
break;
case 'E': $scope.eDisable = false;
break;
}
};
$scope.events = {
onItemSelect: function(item){
switch(item.name) {
case 'A': $scope.aDisable = false;
break;
case 'B': $scope.bDisable = false;
break;
case 'C': $scope.cDisable = false;
break;
case 'D': $scope.dDisable = false;
break;
case 'E': $scope.eDisable = false;
break;
}
},
onItemDeselect: function(item){
switch(item.name) {
case 'A': $scope.aDisable = true;
break;
case 'B': $scope.bDisable = true;
break;
case 'C': $scope.cDisable = true;
break;
case 'D': $scope.dDisable = true;
break;
case 'E': $scope.eDisable = true;
break;
}
}
};
}
},
templateUrl: ''
};
}
})();
The issue I am facing here is when I click 'check all' all the textboxes are getting enabled but when I click on 'uncheck all' they are not disabling back. What should I do here?

ui-grid cellTypeCondition possible?

Does anyone know if it is possible in ui-grid to set type of cell using condition like cellEditableCondition ?
I need to set some editable rows type to text instead of number.
Thanks
u should define algoritm to specify columns in columnDef
here is part from my working solution:
var type = '';
var cellFilter = '';
var widthLength = 100;
switch (value.Type) {
case "int":
case "bigint":
case "numeric":
type = 'number';
widthLength = 120;
break;
case "date":
type = 'dateStr';
cellFilter = "date: 'dd.MM.yyyy'";
widthLength = 90;
break;
case "datetime":
type = 'dateStr';
cellFilter = "date: 'dd.MM.yyyy HH:mm' : 'UTC'";
widthLength = 120;
break;
case "bit":
type = 'boolean';
break;
default:
type = 'string';
widthLength = 150;
break;
}
var item = {
name: value.Name,
displayName: value.Name,
minWidth: widthLength,
width: '*',
type: type
};
and when u fully define needed column just push it to columnDefs array.
$scope.yourGridName.columnDefs.push(item);
or
vm.yourGridName.columnDefs.push(item);
if u r using view model instead of $scope.

Ionic/Angular custom directive and ionic list thumbnail

I created a custom directive, chess-board, showing a chess position. With Ionic framework, I generate a list of chess-board, and would like to thumbnail chess-board on the left. Though I followed documentation, but using svg instead, as my directive generate svg, I can't get the desired layout.
Here is my JsBin (don't worry for missing pictures).
Here is index.html :
<!DOCTYPE html>
<html>
<head>
<script src="//code.ionicframework.com/1.0.0-beta.13/js/ionic.bundle.min.js"></script>
<link href="//code.ionicframework.com/1.0.0-beta.13/css/ionic.min.css" rel="stylesheet" type="text/css" />
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"> </script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-app="static-board">
<ion-pane>
<ion-header-bar class="bar-dark">
<h1 class="title">Chess Positions Archiver</h1>
</ion-header-bar>
<ion-content>
<div class="list">
<a class="item item-thumbnail-left" href="#">
<chess-board cells-size="30" fen="3rr1k1/pb5p/1qp3pB/1pn1Q3/8/7P/PPP3P1/R3KR2 b - - 0 1" show-coords> </chess-board>
<h3>Exercise 1</h3>
</a>
<a class="item item-thumbnail-left" href="#">
<chess-board cells-size="30" show-coords></chess-board>
<h3>Exercise 2</h3>
</a>
</div>
</ion-content>
</ion-pane>
</body>
</html>
Here is my script
(function(){
var chessPieces = {
'P': 'wp',
'N': 'wn',
'B': 'wb',
'R': 'wr',
'Q': 'wq',
'K': 'wk',
'b': 'bb',
'p': 'bp',
'n': 'bn',
'r': 'br',
'q': 'bq',
'k': 'bk'
};
angular.module('static-board', ['ionic'])
.factory('chessPictures', [function(){
return {
getPicture: function(pieceFen){
return chessPieces[pieceFen];
}
}
}])
.directive('chessBoard', [function(){
function getBoardHtml(cellsSize, positionFen, showCoords){
// taken from http://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format
function sprintf() {
var args = arguments,
string = args[0],
i = 1;
return string.replace(/%((%)|s|d)/g, function (m) {
// m is the matched format, e.g. %s, %d
var val = null;
if (m[2]) {
val = m[2];
} else {
val = args[i];
// A switch statement so that the formatter can be extended. Default is %s
switch (m) {
case '%d':
val = parseFloat(val);
if (isNaN(val)) {
val = 0;
}
break;
}
i++;
}
return val;
});
}
function fenToPosition(){
function getSingleLine(lineFen){
var result = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '];
var column = 0;
for (var index in lineFen){
var currElem = lineFen[index];
var isDigit = !isNaN(parseInt(currElem));
if (isDigit){
column += parseInt(currElem);
}
else {
result[column] = currElem;
column++;
}
}
return result;
}
var result = [];
var parts = positionFen.split(" ")[0].split("/");
for (var partIndex in parts){
var currPart = parts[partIndex];
result.push(getSingleLine(currPart));
}
return result;
}
function getBackground(size){
return sprintf("<rect x='0' y='0' width='%d' height='%d' fill='#BAA' />", size, size);
};
function getCells(){
function getSingleCell(cellX, cellY){
var x = cellX*cellsSize + cellsSize/2;
var y = cellY*cellsSize + cellsSize/2;
var color = (cellX+cellY)%2 === 0 ? "#E9E637" : "#7C4116";
return sprintf("<rect x='%d' y='%d' width='%d', height='%d' fill='%s' />",
x,y, cellsSize, cellsSize, color);
}
var result = "";
for (var line = 0; line < 8; line++){
for (var col = 0; col < 8; col++){
result += getSingleCell(col, line)+'\n';
}
}
return result;
}
function getPieces(positionPieces){
function getSinglePiece(cellX, cellY){
var x = cellX*cellsSize + cellsSize/2;
var y = cellY*cellsSize + cellsSize/2;
var pieceFen = positionPieces[cellY][cellX];
var piecePictureRef = chessPieces[pieceFen];
var path = sprintf("../img/chess_pieces/%s.svg", piecePictureRef);
return piecePictureRef ? sprintf("<image x='%d' y='%d' width='%d' height='%d' xlink:href='%s' />",
x, y, cellsSize, cellsSize, path
) : undefined;
}
var result = "";
for (var rank = 0; rank < 8; rank++){
for (var file = 0; file < 8; file++){
var line = getSinglePiece(file, rank);
if (line) {
result += line+'\n';
}
}
}
return result;
}
function getPlayerTurn(){
var turnStr = positionFen.split(" ")[1];
var color = turnStr === "w" ? "#FFF" : "#000";
var location = parseInt(8.5*cellsSize);
var size = cellsSize / 2;
return sprintf("<rect x='%d' y='%d' width='%d' height='%d' fill='%s'/>",
location, location, size, size, color);
}
function getCoordinates(){
result = "";
var files = "ABCDEFGH";
for (var index in files){
var currFile = files[index];
result += sprintf("<text x='%d' y='%d' fill='#000' font-size='%d'>%s</text>",
parseInt(cellsSize*index + cellsSize*.8), parseInt(cellsSize*.45),
parseInt(cellsSize*.4), currFile);
result += sprintf("<text x='%d' y='%d' fill='#000' font-size='%d'>%s</text>",
parseInt(cellsSize*index + cellsSize*.8), parseInt(cellsSize*8.9),
parseInt(cellsSize*.4), currFile);
}
var ranks = "87654321";
for (var index in ranks){
var currRank = ranks[index];
result += sprintf("<text x='%d' y='%d' fill='#000' font-size='%d'>%s</text>",
parseInt(cellsSize*.1), parseInt(cellsSize*1.25+cellsSize*index),
parseInt(cellsSize*.4), currRank);
result += sprintf("<text x='%d' y='%d' fill='#000' font-size='%d'>%s</text>",
parseInt(cellsSize*8.7), parseInt(cellsSize*1.25+cellsSize*index),
parseInt(cellsSize*.4), currRank);
}
return result;
}
var size = 9*cellsSize;
var result = sprintf("<svg width='%d' height='%d'>\n%s\n%s\n%s\n%s\n%s\n</svg>",
size, size, getBackground(size), getCells(), getPieces(fenToPosition()),
getPlayerTurn(), showCoords ? getCoordinates() : "");
return result;
}
return {
restrict: 'E',
link: {
post : function(scope, element, attrs){
var cellsSize = attrs.cellsSize || 20;
var positionFen = attrs.fen || 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w';
var showCoords = attrs.showCoords !== undefined ? true : false;
var newElem = angular.element(getBoardHtml(cellsSize, positionFen, showCoords));
element.replaceWith(newElem);
}
}
}
}])
})();
So what's wrong ?
Is that the fact that I am using an <svg> instead of an <img> ?
Or is it something else ?
you will need to do several things:
wrap svg into a div, and give it class item-image
<div class="item-image">
<chess-board cells-size="30"></chess-board>
</div>
then, when you create the SVG, you will need to set properties like this:
width="100%" height="100%" viewBox="0,0,270,270"
width and hight will tell it how to behave inside it's container, while viewBox property sets the size of canvas, on which the image will be drawn.
this line
var result = sprintf("<svg width='%d' height='%d'>\n%s\n%s\n%s\n%s\n%s\n</svg>", size, size, getBackground(size), getCells(), getPieces(fenToPosition()), getPlayerTurn(), showCoords ? getCoordinates() : "");
should look like this
var result = sprintf("<svg width='100%%' height='100%%' viewBox='0,0,%d,%d'>\n%s\n%s\n%s\n%s\n%s\n</svg>", size, size, getBackground(size), getCells(), getPieces(fenToPosition()), getPlayerTurn(), showCoords ? getCoordinates() : "");
You can see it here http://jsbin.com/basimodufa/1/edit?html,js,output
there is a good resource on SVG sizing/containing here

How to filter the grid data(Ng-grid) on the basis of selection date range via AngularJS

Actually I have a combo box with values "Last seven days", "Last three days" and "Today", I want to apply the filter on the basis of selected value date range by current date
If the filterOptions of the grid are not working for you then try keeping your full set of data in one array and the filtered set in another. Set the gridOptions.data to your filtered set. Apply a function when the user makes a selection from the dropdown that sets your filtered set to whatever you want. Something like this:
<select ng-model="filterValue"><option value=1>Last 7 days</option></select>
$scope.allItems = [{someDate:'10/21/14'},{someDate:'11/2/14'},{someDate:'10/24/14'}];
$scope.filteredItems = [];
$scope.filterValue;
$scope.$watch("filterValue", function() {
// filter your dataset here
if($scope.filterValue == 1) { // Last 7 days
angular.forEach(allItems,function(value) {
// Use something like moment.js to do date arithmetic
if(date in last 7 days) {
$scope.filteredItems.push(value);
}
});
}
};
$scope.gridOptions = { data: 'filteredItems' ....};
Below is the solution for filtering the data of the grid view on the basis of selected Date options from the combo box as described in the problem statement:
Here durationFilter() is the function call on the change of the value in the combo box
$scope.durationFilter = function () {
var currentDate = new Date();
var difDate = new Date();
$scope.filteredItems = [];
switch ($scope.selectedItem.id) {
case 1:
$scope.range = 1;
break;
case 2:
$scope.range = 3;
break;
case 3:
$scope.range = 7;
break;
default:
$scope.range = 0;
$scope.filteredItems = [{ 0: new Date() }];
$scope.gridOptions.filterOptions.filterText = '';
break;
}
for (var i = 0; i < $scope.range; i++) {
currentDate.subtractDays(i);
difDate = currentDate;
$scope.difDate = $filter('date')(difDate, 'MM/dd/yyyy');
$scope.filteredItems.push($scope.difDate);
currentDate = new Date();
}
$scope.searchingFilters.filteredDate = $scope.filteredItems;
$scope.setFilterText();
};
$scope.setFilterText = function () {
$scope.gridOptions.filterOptions.filterText = 'Submit Time:' + $scope.searchingFilters.filteredDate[0] + '|' + $scope.searchingFilters.filteredDate[1] + '|' +
$scope.searchingFilters.filteredDate[2] + '|' + $scope.searchingFilters.filteredDate[3] + '|' + $scope.searchingFilters.filteredDate[4] +
'|' + $scope.searchingFilters.filteredDate[5] + '|' + $scope.searchingFilters.filteredDate[6] + ';';
}

Resources