Kendo NumericTextBox with step and rounding - kendo-ui

I want to setup kendoNumericTextBox to allow user input any integer number and set step to 1000. But when user enters any value and use spinner, it should update to next multiple of step.
For example:
enter 123, press spin up, value will be 1000
enter 1234, press spin up, value vill be 2000
Is it possible or only way is to handle spin event and modify value from there?
UPDATE:
Ok, guys, thnx for help.
I have this spin handler now and it seems to be working as expected.
function onSpin(e)
{
var currentvalue = kendo.parseInt(this.value());
if (currentvalue > 0)
{
this.value(Math.floor(currentvalue / this.step()) * this.step());
}
if (currentvalue < 0)
{
this.value(Math.ceil(currentvalue / this.step()) * this.step());
}
}

I have provided a dojo below with a potential solution for you:
https://dojo.telerik.com/UQohUjaP/2
I have created a function that will work on the spin and on change value so that it will step the value up/down on the value that you set e.g. 1000
the function is fairly simple and for brevity I have taken out the log statements here:
function onChange() {
var currentvalue = kendo.parseInt(this.value());
if (currentvalue > 0) {
currentvalue = Math.ceil(currentvalue / this.step()) * this.step();
} else if (currentvalue < 0) {
currentvalue = Math.floor(currentvalue / this.step()) * this.step();
} else {
currentvalue = 0;
}
this.value(currentvalue);
}
Unfortunately there doesn't seem to be a simple way of figuring out if the value has gone up or down so I am basically checking to see if the value is greater than 1 or less than 1 and then calculating the ceiling or the floor for the value and then stepping it in the right direction. in order to cater for zero we have a special condition which just sets the value to 0 assuming that is a valid value in your scenario

As you say, it's possible by listening to the spin event:
$("#numerictextbox").kendoNumericTextBox({
min: 0,
spin: function(e) {
var isUp = e.sender._key === 38,
isDown = e.sender._key === 40;
var m = Math.trunc(this.value()/1000),
value = isUp ? m + 1 : m;
this.value(value * 1000);
}
});
I doubt there's something out of the box, because your needs seem somewhat unusual.

Related

Building a map with coloring condition

I am trying to build a choropleth that is not exactly a choropleth in dc.js. What I am trying to do is color the map base on coloring condition and ultimately this will interact with other charts and filters as well. My csv looks like this:
country,id,condition,value
AU,1,yes,19
US,2,no,23
US,2,no,30
US,2,no,4
IN,3,yes,14
SG,4,yes,2
NZ,5,no,6
NZ,5,no,20
and this is my approach so far, producing the count of occurrences.
var ndx = crossfilter(data)
var countryDimension = ndx.dimension(function (d){
return d.country
});
var colors = d3.scale.ordinal().domain(['yes','no']).range(["green","blue"])
worldMap.width(mapWidth)
.height(mapHeight)
.dimension(countryDimension)
.group(countryDimension.group())
.projection(project)
.colors(colors)
.colorCalculator(function(d){
return d ? worldMap.colors()(d) : '#d8d8d8';
})
.overlayGeoJson(geoJson.features, "id", function(d){
return d.id;
})
.title(function(d){
return 'Country: ' + d.key + '\nCondition: ' + d.value;
});
I am quite new to this amazing world of d3 and dc.js. Although I have been reading the documentation and forums I cannot figure out how I could make it so that a map is drawn, and the countries with the condition 'yes' is colored green and countries with the condition 'no' is colored blue. So pretty much if i do console.log(d.value) it should return either 'yes' or 'no'. I don't get what I have to do with my 'group'.
If every country has the same value for condition every time it is listed in the data, then in some sense the data is denormalized. That's fine, because crossfilter works best with a single array of data.
Of course it means that the choropleth won't respond to brushing on other charts, since the value is not affected by how many rows are currently filtered. But it will be able to filter other charts.
Count yesses
There are a couple of ways to do this. One way to do it is to count the number of yesses, and set the value according the count:
var yesnoGroup = countryDimension.group().reduceSum(function(d) {
return d.condition === 'yes' ? 1 : 0;
});
worldMap.valueAccessor(function(kv) {
return kv.value ? 'yes' : 'no';
})
Grab first value
However this would probably cause countries to turn blue when they are filtered out by the other charts. So you could also use a "grab first value and hold onto it" strategy like this:
var yesnoGroup = countryDimension.group().reduce(
function(p, v) { // add
return v.condition;
},
function(p, v) { // remove
return p; // ignore remove event
},
function() { // initialize
return null; // no value
});
A little bit ugly and a weird way to use crossfilter, but that's just because crossfilter expects the data to have some effect on the reduced value, and it doesn't here.
EDIT: Three states
Based on the conversation below, I understand you're actually looking for three states: no, zero, and yes. (This makes more sense than the solutions above, but I'll leave those for posterity.) Here are two completely different ways to solve the no/zero/yes problem.
Both of these solutions use the following three-way color scale:
var colors = d3.scale.ordinal().domain(['no', 'zero', 'yes']).range(["blue", "grey", "green"])
No/zero/yes as negative/positive numbers
This is clever and simple: we'll just count each no as -1 and each yes as +1. If the sum is zero, we'll draw in grey. The only caveat here is if there are contradictions in the data, you could get a false zero. But that might be better than a false no or yes (?)
var nozeroyesGroup = countryDimension.group().reduceSum(function(d) {
return d.condition === 'no' ? -1 : d.condition === 'yes' : +1 : 0;
});
worldMap.valueAccessor(function(kv) {
return kv.value < 0 ? 'no' : kv.value > 0 ? 'yes' : 'zero';
})
No/yes polarity
We could also remember a count and polarity separately. This is maybe safer but also maybe slower. (Not that you'd notice unless your data is huge.) It's a bit more complicated. Kind of a matter of preference.
var nozeroyesGroup = countryDimension.group().reduce(
function(p, v) { // add
if(p.polarity && p.polarity != v.condition)
console.warn('inconsistent');
p.polarity = v.condition;
++p.count;
return p;
},
function(p, v) { // remove
if(p.polarity != v.condition || p.count <= 0)
console.warn('inconsistent');
--p.count;
return p;
},
function() { // initialize
return {count: 0, polarity: null}; // no value
});
worldMap.valueAccessor(function(kv) {
return kv.value.count ? kv.value.polarity : 'zero';
})

How do I put this into code?

I'm struggling on how I can put this into code.
int a=500;
By default x = a-100
I am trying to find a way where when one button is clicked, it sets the x-coordinate to x=a-100 , and then when the same button is pressed again, it sets x=0.
How would i logically put this into code?
Thanks a lot!
Somewhere, have a variable keep track of whether or not the button has been previously pressed. Since you haven't indicated what language you're using, I'll have to make this very generic, and assume the typical interface that's used to handle button press events.
var button = (some GUI button object);
var a = 500;
var x = 2;
var buttonHasBeenPressed = false;
button.onPress = function() {
if (buttonHasBeenPressed) {
x = 0;
} else {
x = a - 100;
}
buttonHasBeenPressed = true;
};
Where you store the flag (buttonHasBeenPressed) depends on your skill level, the size of your program and many other factors. This is just a rough example using pseudo-javascript.

In processing , why movie.jump() function not work during movie reverse?

I am working on movie in processing. The move.jump() function not working during movie reverse play. And I have reverse code:
(The reverse is global boolean variable)
float playSpeed = 1.0;
//After click reverse button
if(reverse == false){
playSpeed = playSpeed * -1;
movie.speed(playSpeed);
reverse = true;
}
else{
playSpeed = playSpeed * -1;
movie.speed(playSpeed);
reverse = false;
}
During reverse == true I click some button, and jump to a time, for example 5.0, code is show below:
//after click button
if(reverse == true){
movie.jump(5.0);
}
And this jump function is not work. It not jump to the movie frame which at 5.0 second. And show some error:
ast_segment_set_seek: assertion 'start <= stop' failed
Can anybody tell me why the jump function not work and how to fix it?
Thank you.
EDIT: more reasonable answer: Could it be that jump calculates the position in relation to the frame rate which becomes negative when playing backwards and then end is before start? In this case my workaround should work.
Not sure what classes you are using, but couldn't you just make a workaround? Should be so fast the user won't notice:
if (reverse) {
movie.speed(1f);
// jump();
movie.speed(playSpeed);
} else {
// jump();
}
Btw reverse can be written as (no if needed):
reverse = !reverse;
playSpeed = -playSpeed;
movie.speed(playSpeed);
I know the answer, I figure out by myself.
If movie play speed is less 0, the star will less than stop.
So, if the play speed is less 0, just * -1, let greater than 0, than jump, than * -1, let speed less than 0.
if(reverse == true){
m.speed(playSpeed*-1);
m.jump(5.0);
m.speed(playSpeed*-1);
}

Slickgrid - Move rows with arrow links

I am trying to create a function, that when an arrow link (up or down) is clicked on a certain row, the row will move up or down.
Is there a way to dynamically move rows in the data this way?
(I know there is the RowMoveManager but the requirements request arrow links instead of drag-able)
I found a way to do it, although it might not be the most efficient way. I have a column in my data, rank and I added an onClick function on an arrow moveOneUp(index);
function moveOneUp(rowIndex) {
_grid.dataView.getItem(rowIndex).rank = parseInt(_grid.dataView.getItem(rowIndex).rank)-1 ;
_grid.dataView.getItem(rowIndex-1).rank = parseInt(_grid.dataView.getItem(rowIndex-1).rank)+1;
_grid.dataView.fastSort('rank');
}
If anyone needs the rest of the arrow functions:
function moveOneDown(rowIndex) {
_grid.dataView.getItem(rowIndex).rank = parseInt(_grid.dataView.getItem(rowIndex).rank)+1 ;
_grid.dataView.getItem(rowIndex+1).rank = parseInt(_grid.dataView.getItem(rowIndex+1).rank)-1;
_grid.dataView.fastSort('rank');
}
function moveTop(rowIndex) {
_grid.dataView.getItem(rowIndex).rank = 0 ;
_grid.dataView.fastSort('rank');
}
function moveBottom(rowIndex) {
_grid.dataView.getItem(rowIndex).rank = parseInt(_grid.dataView.getLength())+1;
_grid.dataView.fastSort('rank');
}
function moveOneUp(rowIndex) {
dataViewReorder.beginUpdate();
rowIndex = rowIndex - 1;
dataViewReorder.getItem(rowIndex).intOrd0 = parseInt(dataViewReorder.getItem(rowIndex).intOrd0) - 1;
dataViewReorder.getItem(rowIndex - 1).intOrd0= parseInt(dataViewReorder.getItem(rowIndex - 1).intOrd0) + 1;
dataViewReorder.fastSort('intOrd0');
dataViewReorder.setItems(dataReorder);
dataViewReorder.endUpdate();
gridReorder.setData(dataViewReorder);
gridReorder.render();
}
function moveOneDown(rowIndex) {
dataViewReorder.beginUpdate();
rowIndex = rowIndex - 1;
dataViewReorder.getItem(rowIndex).intOrd0= parseInt(dataViewReorder.getItem(rowIndex).intOrd0) + 1;
dataViewReorder.getItem(rowIndex + 1).intOrd0= parseInt(dataViewReorder.getItem(rowIndex + 1).intOrd0) - 1;
dataViewReorder.fastSort('intOrd0');
dataViewReorder.setItems(dataReorder);
dataViewReorder.endUpdate();
gridReorder.setData(dataViewReorder);
gridReorder.render();
}

jqGrid - grouping + custom summarytype function

I have a jqGrid on my page that has grouping and contains several columns (A,B,C,D). How do I make the summary (i.e. total row) for column D within each group be the following: sum(D)/Sum(A) * 100?
I know I can define a custom function for the summaryType such as: summaryType: mysum but I am not quite sure, how I can use this to do the above formula? Note, columns A,B, and C all have summaryType set as follows: summaryType: 'sum' so they get calculated using the built in summing functionality. I am also wondering if I can somehow pull this off on the loadComplete event of the jqGrid?
I managed to achieve this by doing the following:
I define global variables for the current value of column A and Column C, and the current group by
var tColA = 0.0;
var tColD = 0.0;
var tCurrentGroupBy;
Then in my function, I do the following:
function mysum(a, b, c) {
if (tCurrentGroupBy!= c.GroupByCol) {
tColA= 0.0;
tColD = 0.0;
tCurrentGroupBy= c.GroupByCol;
tColA= tColA + parseFloat(c.ColA);
tColD = tColD + parseFloat(c.ColD);
}
else {
tColA= tColA + parseFloat(c.ColA);
tColD = tColD + parseFloat(c.ColD);
}
return ((tColD / tColA) * 100);
}
not sure if there is a better way to do this, but this seems to work. Are there any other suggestions? thanks.
A little bit late, but...
I have a column D that shows the individual percentage of column C with respect to column B. So I've implemented a formatter that adds the ' %' sign to D column. Column A is the identifier.
But the formatter function is applied to the summary row, too. So the formatter detects if it is the summary row, and if it is, do the calculations and return the value.
function percentage_format(cellValue, options, rowObject) {
var a=$(rowObject).attr('A');
if(!a || a='')
cellValue=Math.round($(rowObject).attr('C')*10000/$(rowObject).attr('B'))/100;
return "<span originalValue='"+cellValue+"'>"+cellValue+" %"+"</span>";
}
function unformatCampo(cellValue, options, cellObject) {
return $(cellObject.html()).attr("originalValue");
}
I hope this still helps.
Place this formatter function on each cell involved in the percent calculation.
In this example, cell a,cell b and cell c need the formatter function.
The function is in a and b to grap the value and on c to calulate the percent using the saved values.
It’s important to note 3 things with the formatter event:
1.The cell value is modifiable. Even though it’s a formatting event the value may be changed.
2.The event is fired in the order or the column model
3.Athough, rwdat is row data it is only the column model for the cell being formatter, not the whole row. That’s why the function needs to be on each cell to get all the values.
<script>
var cnt = 0;
var a = 0.0;
var b= 0.0;
function linePercent(cellval, opts, rwdat, act)
{
// rowed==”” means it’s a summary line(total)
if (opts.rowId =="")
{
// save the 2 values used in the calculation
if (rwdat.nm == "a"){totexec=cellval;}
if (rwdat.nm == "b"){planamt=cellval;}
// when the calculated cell is formatted, perform the calculation and set cellval
if (rwdat.nm == "c"){cellval=(a/b)*100;}
}
// call formatter to format cellval
return $.fn.fmatter('number', cellval,opts, rwdat, act);
};
</script>
Do it on the server. It'll be far simpler, you'll have complete control.

Resources