Make each event fit the bounding box by date - kendo-ui

Taking the example from here
I want to make the events look like this:
instead of how it is on the page:
Notice how there is a space between the event and the bounding box.
It seems the element style is auto generated by the scheduler and calculates a width. How would I go about widening the event to fit exactly in the bounding box?

I found the answer on another stackedoverflow question.
This is her code diving by columns.length instead of 2
//Override kendo function for deciding events with
kendo.ui.MultiDayView.fn._arrangeColumns = function (element, top, height, slotRange) {
var startSlot = slotRange.start;
element = { element: element, slotIndex: startSlot.index, start: top, end: top + height };
var columns,
slotWidth = startSlot.clientWidth,
eventRightOffset = slotWidth * 0.10,
columnEvents,
eventElements = slotRange.events(),
slotEvents = kendo.ui.SchedulerView.collidingEvents(eventElements, element.start, element.end);
slotRange.addEvent(element);
slotEvents.push(element);
columns = kendo.ui.SchedulerView.createColumns(slotEvents);
//This is where the magic happens
var columnWidth = slotWidth / columns.length;
//Original code: var columnWidth = (slotWidth - eventRightOffset) / columns.length;
//This is where the magic ends
for (var idx = 0, length = columns.length; idx < length; idx++) {
columnEvents = columns[idx].events;
for (var j = 0, eventLength = columnEvents.length; j < eventLength; j++) {
columnEvents[j].element[0].style.width = columnWidth - 4 + "px";
columnEvents[j].element[0].style.left = (this._isRtl ? this._scrollbarOffset(eventRightOffset) : 0) + startSlot.offsetLeft + idx * columnWidth + 2 + "px";
}
}
};

Related

How to simplify shapes for triangulation with three.js and jsclipper

I try to display geometry which is constructed by constructpath commands like moveto lineto beziercurveto in Three.js.
Therefore I create a THREE.ShapePath(); and execute the command toShapes(isClockwise).
After this I use THREE.ExtrudeBufferGeometry to create the 3D shape.
Unfortunately the shapes are sometimes really complex and are not created correctly which means they are distorted.
Using libtess as triangulation library solves some issues. But I have still distorted geometry.
Now I want to use jsclipper to simplify the shapes prior triangulation.
I modified three.js in such way:
in the method addShape in ExtrudeBufferGeometry I have added:
$.each(vertices, function(index, item) {
vertices[index]['X'] = vertices[index]['x'];
vertices[index]['Y'] = vertices[index]['y'];
delete vertices[index]['x'];
delete vertices[index]['y'];
});
if (holes[0]) {
for (i = 0; i < holes.length; i++ ) {
$.each(holes[i], function(index, item) {
holes[i][index]['X'] = holes[i][index]['x'];
holes[i][index]['Y'] = holes[i][index]['y'];
delete holes[i][index]['x'];
delete holes[i][index]['y'];
});
}
}
var scale = 100;
ClipperLib.JS.ScaleUpPaths([vertices], scale);
if (holes[0]) {
ClipperLib.JS.ScaleUpPaths(holes, scale);
}
vertices = ClipperLib.Clipper.SimplifyPolygons([vertices], ClipperLib.PolyFillType.pftNonZero);
// or ClipperLib.PolyFillType.pftEvenOdd
if (holes[0]) {
holes = ClipperLib.Clipper.SimplifyPolygons(holes, ClipperLib.PolyFillType.pftNonZero);
// or ClipperLib.PolyFillType.pftEvenOdd
}
// var cleandelta = 0.1; // 0.1 should be the appropriate delta in different cases
// vertices = ClipperLib.Clipper.CleanPolygons([vertices], cleandelta * scale);
// if (holes[0]) {
// holes = ClipperLib.Clipper.CleanPolygons(holes, cleandelta * scale);
// }
ClipperLib.JS.ScaleDownPaths(vertices, scale);
if (holes[0]) {
ClipperLib.JS.ScaleDownPaths(holes, scale);
}
for (i = 0; i < vertices.length; i++ ) {
$.each(vertices[i], function(index, item) {
vertices[i][index]['x'] = vertices[i][index]['X'];
vertices[i][index]['y'] = vertices[i][index]['Y'];
delete vertices[i][index]['X'];
delete vertices[i][index]['Y'];
});
}
if (holes[0]) {
for (i = 0; i < holes.length; i++ ) {
$.each(holes[i], function(index, item) {
holes[i][index]['x'] = holes[i][index]['X'];
holes[i][index]['y'] = holes[i][index]['Y'];
delete holes[i][index]['X'];
delete holes[i][index]['Y'];
});
}
}
Now I can see that the vertices are "reduced".
But var faces = ShapeUtils.triangulateShape( vertices, holes ); doesn't generate faces for some examples anymore.
Please can one help how to simplify the shapes correctly?
A bit hard to figure out what the problem is actually. Clipper (also when using SimplifyPolygons or SimplifyPolygon) can only produce weakly-simple polygons, which means that there can be pseudo-duplicate points: although sequential coordinates are quaranteed to be not indentical, some of the next points can share the same coordinate. Also a coordinate can be on the line between two points.
After simplifying (or any other boolean operation) you could make a cleaning step using Offsetting with a small negative value: https://sourceforge.net/p/jsclipper/wiki/documentation/#clipperlibclipperoffsetexecute.
This possibly removes all of the pseudo-duplicate points.
I have made also a float version of Clipper (http://jsclipper.sourceforge.net/6.4.2.2_fpoint/). It is extensively tested, but because Angus Johnson, the author of the original C# Clipper (of which JS-version is ported from), has thought that using floats causes robustness problems although according to my tests the are no such, the original C# float version does not exists. The float version is simpler to use and you can try there a small negative offset: eg. -0.001 or -0.01.
You could also give a try to PolyTree or ExPolygons (https://sourceforge.net/p/jsclipper/wiki/ExPolygons%20and%20PolyTree%206/). ExPolygons can be used to get holes and contours and PolyTree can be used to get the full parent-child-relationship of holes and contours.
The last resort is a broken-pen-nib -function. It detects all pseudo-duplicate points and make a broken-pen-nib -effect to them, so that the result is free of any duplicates. The attached images shows what this effect means using large nib-effect-value to make the effect meaning clearer. Three.js polygon triangulation fails in pseudo duplicate points. There are a discussion https://github.com/mrdoob/three.js/issues/3386 of this subject.
// Make polygons to simple by making "a broken pen tip" effect on each semi-adjacent (duplicate) vertex
// ORIGPOLY can be a contour
// or exPolygon structure
function BreakPenNibs(ORIGPOLY, dist, scale)
{
if (!dist || dist < 0) return;
var sqrt = Math.sqrt;
var allpoints = {}, point = {};
var key = "";
var currX = 0.0,
currY = 0.0;
var prevX = 0.0,
prevY = 0.0;
var nextX = 0.0,
nextY;
var x = 0.0,
y = 0.0,
length = 0.0,
i = 0,
duplcount = 0,
j = 0;
var prev_i = 0,
next_i = 0,
last_i;
var extra_vertices = new Array(100),
moved_vertices = new Array(100);
// Get first all duplicates
var duplicates = new Array(100),
indexi = "",
indexstr = "",
arraystr = "",
polys, outer, holes;
if (ORIGPOLY instanceof Array)
{
outer = ORIGPOLY;
}
else if (ORIGPOLY.outer instanceof Array)
{
outer = ORIGPOLY.outer;
}
else return;
if (ORIGPOLY.holes instanceof Array) holes = ORIGPOLY.holes;
else holes = [];
polys = [outer].concat(holes);
var polys_length = polys.length;
// Get first max lenght of arrays
var max_index_len = 0;
var arr_len;
i = polys_length;
while (i--)
{
arr_len = polys[i].length;
if (arr_len > max_index_len) max_index_len = arr_len;
}
max_index_len = max_index_len.toString().length;
var max_polys_length = polys_length.toString().length;
var poly;
j = polys_length;
var scaling = scale/10;
while (j--)
{
poly = polys[j];
ilen = poly.length;
i = ilen;
while (i--)
{
point = poly[i];
//key = Math.round(point.X) + ":" + Math.round(point.Y);
key = (Math.round(point.X / scaling) * scaling)
+ ":" + (Math.round(point.Y / scaling) * scaling);
indexi = allpoints[key];
if (typeof (indexi) != "undefined")
{
// first found duplicate
duplicates[duplcount] = indexi;
duplcount++;
arraystr = j.toString();
while (arraystr.length < max_polys_length) arraystr = "0" + arraystr;
indexstr = i.toString();
while (indexstr.length < max_index_len) indexstr = "0" + indexstr;
duplicates[duplcount] = arraystr + "." + indexstr;
duplcount++;
}
arraystr = j.toString();
while (arraystr.length < max_polys_length) arraystr = "0" + arraystr;
indexstr = i.toString();
while (indexstr.length < max_index_len) indexstr = "0" + indexstr;
allpoints[key] = arraystr + "." + indexstr;
}
}
if (!duplcount) return;
duplicates.length = duplcount;
duplicates.sort();
//console.log(JSON.stringify(duplicates));
var splitted, poly_index = 0,
nth_dupl = 0;
var prev_poly_index = -1;
poly_index = 0;
for (j = 0; j < duplcount; j++)
{
splitted = duplicates[j].split(".");
poly_index = parseInt(splitted[0], 10);
if (poly_index != prev_poly_index) nth_dupl = 0;
else nth_dupl++;
i = parseInt(splitted[1], 10);
poly = polys[poly_index];
len = poly.length;
if (poly[0].X === poly[len - 1].X &&
poly[0].Y === poly[len - 1].Y)
{
last_i = len - 2;
}
else
{
last_i = len - 1;
}
point = poly[i];
// Calculate "broken pen tip" effect
// for current point by finding
// a coordinate at a distance dist
// along the edge between current and
// previous point
// This is inlined to maximize speed
currX = point.X;
currY = point.Y;
if (i === 0) prev_i = last_i; // last element in array
else prev_i = i - 1;
prevX = poly[prev_i].X;
prevY = poly[prev_i].Y;
x=0;y=0;
if (!point.Collinear)
{
length = sqrt((-currX + prevX) * (-currX + prevX) + (currY - prevY) * (currY - prevY));
//console.log(length);
x = currX - (dist * (currX - prevX)) / length;
y = currY - (dist * (currY - prevY)) / length;
}
// save the found (calculated) point
moved_vertices[j] = {
X: x,
Y: y,
Collinear:point.Collinear,
index: i,
poly_index: poly_index
};
// "broken nib effect" for next point also
if (i == len - 1) next_i = 0;
else next_i = i + 1;
nextX = poly[next_i].X;
nextY = poly[next_i].Y;
x=0;y=0;
if (!point.Collinear)
{
length = sqrt((-currX + nextX) * (-currX + nextX) + (currY - nextY) * (currY - nextY));
x = currX - (dist * (currX - nextX)) / length;
y = currY - (dist * (currY - nextY)) / length;
}
// save the found (calculated) point
extra_vertices[j] = {
X: x,
Y: y,
Collinear:point.Collinear,
index: i + nth_dupl,
poly_index: poly_index
};
prev_poly_index = poly_index;
}
moved_vertices.length = extra_vertices.length = duplcount;
//console.log("MOVED:" + JSON.stringify(moved_vertices));
//console.log("EXTRA:" + JSON.stringify(extra_vertices));
// Update moved coordinates
i = duplcount;
var point2;
while (i--)
{
point = moved_vertices[i];
x = point.X;
y = point.Y;
// Faster than isNaN: http://jsperf.com/isnan-alternatives
if (x != x || x == Infinity || x == -Infinity) continue;
if (y != y || y == Infinity || y == -Infinity) continue;
point2 = polys[point.poly_index][point.index];
point2.X = point.X;
point2.Y = point.Y;
point2.Collinear = point.Collinear;
}
// Add an extra vertex
// This is needed to remain the angle of the next edge
for (i = 0; i < duplcount; i++)
{
point = extra_vertices[i];
x = point.X;
y = point.Y;
// Faster than isNaN: http://jsperf.com/isnan-alternatives
if (x != x || x == Infinity || x == -Infinity) continue;
if (y != y || y == Infinity || y == -Infinity) continue;
polys[point.poly_index].splice(point.index + 1, 0,
{
X: point.X,
Y: point.Y,
Collinear: point.Collinear
});
}
// Remove collinear points
// and for some reason coming
// sequential duplicates
// TODO: check why seq. duplicates becomes
j = polys.length;
var prev_point = null;
while (j--)
{
poly = polys[j];
ilen = poly.length;
i = ilen;
while (i--)
{
point = poly[i];
if(prev_point!=null && point.X == prev_point.X && point.Y == prev_point.Y) poly.splice(i, 1);
else
if(point.Collinear) poly.splice(i, 1);
prev_point = point;
}
}
//console.log(JSON.stringify(polys));
// because original array is modified, no need to return anything
}
var BreakPenNipsOfExPolygons = function (exPolygons, dist, scale)
{
var i = 0,
j = 0,
ilen = exPolygons.length,
jlen = 0;
for (; i < ilen; i++)
{
//if(i!=4) continue;
BreakPenNibs(exPolygons[i], dist, scale);
}
};

Slickgrid paging issue for search - page number is wrong when pagesize = search item count on second page

If I do a search on a page greater than 1 and if the number of items returned from the search are equal to the pagesize then the page does not flip back to the previous page and says the wrong page number.
For example if I have 5 items and the page size is set to 4. If I do a search on the second page that returns 4 items then the page won't flip back to page 1 and the grid says Page 2 of 1.
I also get the same error if I change example4 -
http://mleibman.github.io/SlickGrid/examples/example4-model.html
Replace this code -
for (var i = 0; i < 50000; i++) {
var d = (data[i] = {});
d["id"] = "id_" + i;
d["num"] = i;
d["title"] = "Task " + i;
d["duration"] = "5 days";
d["percentComplete"] = Math.round(Math.random() * 100);
d["start"] = "01/01/2009";
d["finish"] = "01/05/2009";
d["effortDriven"] = (i % 5 == 0);
}
with this -
var x;
for (var i = 0; i < 5; i++) {
var d = (data[i] = {});
if (i == 0)
x = "1";
if (i == 1)
x = "11";
if (i == 2)
x = "111";
if (i == 3)
x = "1111";
if (i == 4)
x = "2";
d["id"] = "id_" + i;
d["num"] = i;
d["title"] = "Task " + x;
d["duration"] = "5 days";
d["percentComplete"] = Math.round(Math.random() * 100);
d["start"] = "01/01/2009";
d["finish"] = "01/05/2009";
d["effortDriven"] = (i % 5 == 0);
}
Add this line -
dataView.setPagingOptions({pageSize: 4});
Go to page 2 and search for Task 1. It should say Showing Page 2 of 1.
I think your rowCount was not updated. Have you added this on your script?
dataView.onRowCountChanged.subscribe(function (e, args) {
grid.updateRowCount();
grid.render();
});
dataView.onRowsChanged.subscribe(function (e, args) {
grid.invalidateRows(args.rows);
grid.render();
});
Update: Add this code on your slick.dataview.js. Find this around line 750
var paged;
if (pagesize) {
if (filteredItems.length < pagenum * pagesize) {
pagenum = Math.floor(filteredItems.length / pagesize);
}
//.. add this code
// START
if (filteredItems.length == pagenum * pagesize && pagenum > 0)
pagenum --;
// END
paged = filteredItems.slice(pagesize * pagenum, pagesize * pagenum + pagesize);
} else {
paged = filteredItems;
}

Inserting elements in a matrix spirally

Given a number x, insert elements 1 to x^2 in a matrix spirally.
e.g. For x = 3, matrix looks like [[1,2,3],[8,9,4],[7,6,5]].
For this I've written following snippet. However, I'm getting o/p as [[7,9,5],[7,9,5],[7,9,5]]
while(t<=b && l<=r){
System.out.print(t+" "+b+" "+l+" "+r+"\n");
if(dir==0){
for(int i = l;i<=r;i++){
arr.get(t).set(i,x);
x++;
}
t++;
}else if(dir==1){
for(int i = t;i<=b;i++){
arr.get(i).set(r,x);
x++;
}
r--;
}else if(dir==2){
for(int i = r;i>=l;i--){
arr.get(b).set(i,x);
x++;
}
b--;
}else if(dir==3){
for(int i = b;i>=t;i--){
arr.get(l).set(i,x);
x++;
}
l++;
}
dir = (dir+1)%4;
}
You can use the next code (which I developed for some implementation that handles huge martrix sizes). It will use width (columns) and height (rows) of any matrix size and produce the output you need
List<rec> BuildSpiralIndexList(long w, long h)
{
List<rec> result = new List<rec>();
long count = 0,dir = 1,phase = 0,pos = 0;
long length = 0,totallength = 0;
bool isVertical = false;
if ((w * h)<1) return null;
do
{
isVertical = (count % 2) != 0;
length = (isVertical ? h : w) - count / 2 - count % 2;
phase = (count / 4);
pos = (count % 4);
dir = pos > 1 ? -1 : 1;
for (int t = 0; t < length; t++)
// you can replace the next code with printing or any other action you need
result.Add(new rec()
{
X = ((pos == 2 || pos == 1) ? (w - 1 - phase - (pos == 2 ? 1 : 0)) : phase) + dir * (isVertical ? 0 : t),
Y = ((pos <= 1 ? phase + pos : (h - 1) - phase - pos / 3)) + dir * (isVertical ? t : 0),
Index = totallength + t
});
totallength += length;
count++;
} while (totallength < (w*h));
return result;
}
This solution walks from the top left to the top right, the top right to the bottom right, the bottom right to the bottom left and the bottom left up to the top left.
It is a tricky problem, hopefully my comments below assist in explaining.
Below is a codepen link to see it added to a table.
https://codepen.io/mitchell-boland/pen/rqdWPO
const n = 3; // Set this to a number
matrixSpiral(n);
function matrixSpiral(number){
// Will populate the outer array with n-times inner arrays
var outerArray = [];
for(var i = 0; i < number; i++){
outerArray.push([]);
}
var leftColumn = 0;
var rightColumn = number - 1;
var topRow = 0;
var bottomRow = number-1;
var counter = 1; // Used to track the number we are up to.
while(leftColumn <= rightColumn && topRow <=bottomRow){
// populate the top row
for(var i = leftColumn; i <= rightColumn; i++){
outerArray[leftColumn][i] = counter;
counter++;
}
// Top row is now populated
topRow ++;
// Populate the right column
for(var i = topRow ; i <= bottomRow; i++){
outerArray[i][rightColumn] = counter;
counter++;
}
// Right column now populated.
rightColumn--;
// Populate the bottom row
// We are going from the bottom right, to the bottom left
for(var i = rightColumn; i >= leftColumn; i--){
outerArray[bottomRow][i] = counter;
counter++;
}
// Bottom Row now populated
bottomRow--;
// Populate the left column
// We are going from bottom left, to top left
for(var i = bottomRow; i >= topRow ; i--){
outerArray[i][leftColumn] = counter;
counter++;
}
// Left column now populated.
leftColumn++;
// While loop will now repeat the above process, but a step in.
}
// Console log the results.
for(var i = 0; i < number; i++){
console.log(outerArray[i]);
}
}

RaphaelJS create rectangle using for loop with interval

Fiddle 1
In this fiddle I have created 5 rectangle shapes on a single row using a for loop. Also I have set an interval between each iteration so that instead of directly displaying 5 rectangles together, they are displayed one by one separated by a small interval. This is one part of my solution. And it is working as intended. Now the problem arises in the next part.
What I actually want to do is create multiple rows and that the rectangle should be displayed one by one on first row and then in the same way on the next row. But there is some mistake in my code due to which instead of displaying one rectangle at a time, entire column is displayed at a time.
Here is the Second Fiddle
I hope you understood what I want to do here. How can I correct the code and get the desired result of displaying rectangle one by one and then advancing to the next row?
for (var i = 0; i < 3 ; i++) {
for (var j = 0; j < 5; j++) {
window.setTimeout(
(function (i,j){
return function() {
var box = paper.rect(j*100,i*50,100,50);
box.attr({fill:'yellow'});
}
})(i,j),j * 500)
}
}
I think that this solves your problem:
window.onload = function() {
var ROWS = 3,
COLS = 5;
function drawGrid(paper) {
for (var i = 0; i < ROWS; i += 1) {
drawRow(i, paper);
}
}
function drawRow(row, paper) {
for (var i = 0; i < COLS; i += 1) {
drawRect(row, i, paper);
}
}
function drawRect(row, col, paper) {
setTimeout(function () {
var box = paper.rect(col*100,row*50,100,50);
box.attr({fill:'yellow'});
}, (row * COLS * 1000) + (col * 1000));
}
drawGrid(Raphael(0, 0, 1920, 1000));
}
​ ​
I just made a little refactoring and calculate the timeout depending on the current column and row.
Here is the fiddle: http://jsfiddle.net/dYRR2/6/
In other words the timeout should be i * 500 * 5 + j * 500 instead of j * 500.

modifying the lengthY of some cubes is slow

I want to write a 3d version of a fft. (Like this:https://wiki.mozilla.org/File:Fft.png)
So I created a few bars and in an outside function, my first aproach was to set the lengthY to a value. Then I call bar.modified() to force it to be repainted.
If I now use more than 50 bars, it is horrible slow (on my 4 core CPU). I guess there's a better way to do it, right?
Source:
var elements = new Array();
create3d = function(len) {
var r = new X.renderer3D();
r.init();
if(a.length == 0){
for ( var y = 0; y < len; y++) {
var c = new X.cube();
a.push(c);
}
}
for ( var i = 0; i < len; i++) {
a[i].center = [i*2 , 0, 0];
a[i].lengthX = 1;
a[i].lengthY = 20;
a[i].lengthZ = 1;
a[i].color = [i%2,0,0];
r.add(a[i]);
}
r.render();
};
function setVal(index,val){
var element = a[index];
element.lengthY = val;
element.modified();
}
I created a JSFiddle on how to do that and it is pretty fast for 1000 cubes
http://jsfiddle.net/haehn/6fVRC/

Resources