d3 drag behavior low performance on chrome with huge dataset - javascript

I implemented d3 slider control allowing to navigate through data serie displayed along time axis.
I'm trying to isolate/solve problem with drag events coming too seldom (more than one second interval), when data set is large enough (entire data array is inlined in html page, so page weights about 13 megabytes).
http://javaeedemo.pragmasoft.cloudbees.net/test/isolated-test1.html
Drag looks jumpy in chrome, but is smooth in firefox.
data array has only about 300 elements, and elements contains lot of data including nested arrays, but I only use one property in every element named 'end'.
I tried to reduce data array size, leaving same amount of elements, but only left 'end' property in every element, so this change doesn't impact functionality, only page size.
http://javaeedemo.pragmasoft.cloudbees.net/test/isolated-test2.html
With these changes drag looks much more smoothly on chrome.
Appreciate any help, including ideas about how to isolate problem. I tried to use Chrome Timeline, what I see there is that my onDrag handler executes very fast (matter of 1 ms) yet I still have substantial gaps between onmousemove calls.
Added:
I managed to find some almost working solution - I added drag behavior event listeners to raw mouse events instead, like
//var dragBehavior = d3.behavior.drag()
// .on("dragstart", onDrag.bind(this))
g.on("mousedown", onDragStart.bind(this));
...
Now it works much more smoothly, which makes me thinking that problem is somewhere in drag behavior code. isolated-test3.html has workaround to compare:
Of course I'd prefer using drag behavior, as it solves number of problems and supports touch events as well.

Related

Animated network graph with javascript / react

I am using React
I want to animate a series of chronological events occurring in network graph.
Requirements as follows;
Network graph displayed is statically drawn (i.e: nodes and edges never change)
Given a dynamic list of chronological events (which come from an api), animation shows the nodes in the network highlighted one after another for the given times
There is a play/pause slider to play/pause and scroll through the animation
The events are shown in a table and table rows can be clicked on to jump to the time in the animation they occured
Would also be nice to be able to play animation at 2x, 4x ... speeds
My questions
How can this be implemented in react?
Is there any library that can help me with this?
Or any similar project which may be a good starting point?
My thoughts
I am totally open to any open source solution as long as it can be implemented using react.
I am thinking of using d3 (though I have no prior experience). The following examples seem somewhat similar to what I want to do.
http://www.claudiobellei.com/2017/02/04/viznetworks/
https://observablehq.com/#stwind/raft-consensus-simulator

Model aggregating in viewer - coordinate issue

I am dynamically aggregating models in the Viewer (coming from multiple BIM files). Basically, I initialize the viewer, and then LoadDocument and LoadModel for each model that user chooses to view, dynamically.
These are mostly NVC files (what I used for testing), which are sharing the coordinate system. Models getting dynamically loaded and getting 'stitched' correctly.
However, coordinate system is getting screwed up when the second model gets loaded - not always but in some cases (in v6.3 - haven't checked previous versions). When this happens, I can notice the followings:
When I click 'home' icon in the viewer, it doesn't show the full aggregated model but only shows the first loaded model in the center and rest go outside screen.
When I click an element to select, it selects something else (with an offset), and some cases selects nothing (meaning, clicked coordinates has been interpreted incorrectly).
I have tried multiple combinations and this problem seems to happen when first loaded model is not occupying full size of the aggregated model (say, one floor of the building).
I figured out a solution though. After loading the models (every time when user choose some), if I 'hide' all models and 'show' them again, it fixes the problems with click and AGGREGATED_SELECTION event.
This is not a nice user experience because I want to be able to load the models in the background while user is moving around the previously aggregated model-set. If I hide/show after loading the new one, it will be annoying to user.
Is there a way to 'reset' the coordinate system of the viewer (to the same effect what happens when hide/show the models)?
I would appreciate some help to get around this issue.
Thanks
Bandu
ok, so there is a massive offset, causing a precision issue. Which is why you are seeing lots of 'jittering' of the camera.
To fix this... we need to correct the massive offset, by returning all the geometry closer to origin manually. (or fixing the original navisworks file).
First, let's roughly figure out the offset value...
Hold down ALT-key and click anywhere on an object. This sets a green dot, the pivot point. Then use viewer.navigation.getPivotPoint() to get the x,y,z value. (details: https://github.com/wallabyway/markupExt/issues/2).
You should see an xyz value like this...
Z.Vector3 {x: 1296285.515098644, y: 14995636.431742325, z: 364.26238179027337}
Now, adjust set the global offset using this value, to correctly move all the models closer to 0,0,0. like this...
line 70:
var modelOptions = {
sharedPropertyDbPath: doc.getPropertyDbPath(),
globalOffset: {x:1296285.515098644, y: 14995636.431742325, z:0}
};
viewer.loadModel(svfUrl, modelOptions, onLoadModelSuccess);
`
This reverses the effect of this big offset. The result is the geometry stops flickering and the camera movement stops 'jittering' due to precision issues.
Let me know if that works for you.
Michael
ps. you can pull the 'exact' global-offset out of the small side-file AECModelData.json, see blog: forge.autodesk.com/blog/add-revit-levels-and-2d-minimap-your-3d

New SVG elements in DOM, added through JavaScript, not rendered until mouseup

Pure JavaScript (no JQuery, D3, or other external libraries). I'm dragging SVG objects that look like columns of rectangles around. They have connecting lines between the rectangles, and when I drag one rectangle across another, I remove all elements from the DOM, check whether each rectangle in a column corresponds to a rectangle in neighboring column, and draw a new connecting line between them if that condition is true. In the console I can see that the elements are created immediately, but they aren't rendered until I release the mouse and stop the drag. Because I may drag across more than one column and need to compare the results at each position before deciding where to drop, I need to force the new elements not just to be created immediately, but also to be rendered immediately, without being blocked until I release the mouse.
[Edit: In response for downvote for "not showing research," note the following (original) paragraph. Tried all suggestions I could find, mentioning the most common ones explicitly. Perhaps my research methods are unsophisticated; can you advise so that I could do a better job next time?]
Following suggestions on this site and elsewhere, I've tried adding and deleting an element from the DOM and toggling the display property of various elements, but without success.
Sample files are at https://github.com/obdurodon/drag. To run, clone and then open textual_correspondence_static_sample/test.xhtml in a browser (from the file system, so that it can find the CSS and JavaScript files to which it's linked). Grab a drag icon at the top of a column and pull left or right. Connecting lines repaint only on drop, but I need them to repaint immediately after every crossing (I'll worry about stretching them on mousemove later).
I think the reason is because you are giving the lines a stroke colour in endMove() (after your drawLines() call). But you are not doing that in the swapColumns() function. New elements in SVG have no stroke by default.

Issue with jquery-ui .draggable and jqQuery events on a Marionette App

I have made a small app that allows the user to create rectangles, and drag them around.
The implementational details are that the "green" workspace area you see is a Marionette CollectionView
and when you are drawing boxes, you're essentially instantiating new rectangle models and rendering views for them. HTML-wise, the rectangles are child nodes of #workspace.
Here's a working demo (on dropbox since jsfiddle keeps failing me all the time)
From what I know,in order to avoid the creation of a new rectangle while I'm moving around an already existing one, I need to stopPropagation of the mousedown/mousemove/mouseup events (That's what I'm using in the first place to determine if the user is dragging, to acquire mouse pointer position, calculate rectangle properties, and append the rectangle view on mouseup)
The problem is that although I stopPropagation for mousedown/mousemove/mouseup, apparently the mouseup event doesn't fire and the rectangle keeps following the cursor even after the mouse button has been released.
Also dragging a rectangle around is not as smooth as I would expect, but a bit glitchy. I'm suspecting that there must be either something horrible that I've done (most likely), or a conflict between how I'm handling events and how jQuery and jQuery UI are. (I need to comply, but I don't know how).
Please enlighten me!
In the end I've decided to write a short jQuery UI plugin that would take care of all the calculations and would allow me better control over event handling.
For more information about what I ended up doing check this post

Link Elements to Keep Their Appearance In Sync

I'm developing an iPad app using PhoneGap and jQuery Mobile and I'd like to create a preview pane in a carousel. The preview pane would include a smaller version of each of the other panes, scaled so they fit inside the single pane. The panes are not static and can be updated at any time using WebSockets, and the preview should be updated simultaneously. There can also be any number of panes (although to keep things simple, assume an upper limit of 9). For performance purposes, assume each pane can have upwards of 200 DOM objects attached to it. To make it slightly more complicated, the carousel can exist on more than one different page.
I've been contemplating the best way to go about implementing this preview pane, and, before inventing a pair of Complicator's Gloves, would like to hear back from the community on any possible better strategies.
A couple methods I have been considering include:
Cloning each pane and then using a CSS transform to scale it to an appropriate size, based on how many panes there are, and then attaching the clones to the preview pane.
Store each pane as a jQuery object in a variable and draw each pane and the preview pane using that object (possibly necessitating redrawing the entire carousel every time there is an update, depending on how much effort I want to make identifying and updating deltas).
Repositioning all the panes so that they exist inside the preview pane when the preview pane is active (this might break the carousel, or at least make it look slightly bizarre as a user swipes a pane over but hasn't actually moved on to that pane yet).
Is there anything I'm missing? It would be nice if there was an easy way to "link" two elements together to make one mirror the other, but apply different CSS to one or the other (for zooming). I suppose it might be possible to do this by creating an event that would fire and then adding a listener to its clone, which would then copy the html of the updated element to itself (probably wouldn't be too terribly to difficult to write a jquery plugin to manage this).
Any better suggestions?
I am not sure what phonegap allows for as far as rendering options go, but my first instinct would be to take a screen shot of the relevant pane. Perhaps phonegap has this built in?
Another option is a javascript library which will clone the DOM and create an HTML5 canvas element. You can either then display the canvas natively, or convert the canvas data in to image data.
Here is one such library: http://html2canvas.hertzen.com/
Given the large number of elements needed, I would hesitate to clone those over and over again. However, if live previews are a necessity, that might be more efficient than using image files or the canvas. You could fire off the canvas draw function after major changes, but probably wouldn't want to do it after the end of every frame of animation.

Categories

Resources