Can I animate visual attributes for multiple objects simultaneously in D3? - javascript

I’m trying to show a D3 hive plot animation representing internet attack data over time using d3.hive.min.js. The base view has 2 axes. Along one axis is a set of source IP addresses – the IP address from which the attack originated. The other axis shows destination IP addresses.
A static view showing the set of attacks (each involving one source and one destination IP) looks like this:
Hive Plot Source/Destination Network Paths - Static View
Each attack has a start time and an end time, which provides a temporal sequencing.
The desired visualization will cause the links to appear and disappear in temporal order, preferably with a variable duration computed from the start/end times. However, a constant time for the appearance of each link would suffice.
I’m using d3.hive.min.js to create the plot axes and links.
I’ve tried a number of approaches without success:
Creating all links with opactity 0, then cycling through a set of
“time steps” where I reset the opactity of each link based on it’s
state at that time. This has the advantage of having ultimate control
of the opacity values based on computations based on start and end
time. I've tried variations with and without transitions and delays.
Bringing the links in one at a time. The result is not the exact
desired result, as it would show build-up of links over time, rather
than them coming and disappearing over time.
Creating and removing the links as they occur over time. With this
approach I don’t understand how I would be able to show overlapping attack
events, where multiple links should appear at same time.
My question at this point is foremost “is this possible with D3”? I'm no expert with D3, but have spent well over 10 hours experimenting and searching. I would very much appreciate a suggestion of an approach with which I could experiment, or a pointer to a similar example.

Related

Best way to deliver dynamic video clips via web page... with interactivity

I have an animated character (half pig half woman) that plays an integral role in my client's brand. She performs several movements/actions such as walking/running/climbing in place, dancing in several different ways and gesturing with facial and body movements.
On the website, she will be displayed floating near the user's scroll position and will perform different actions (i.e. play a specified segment of this motion/action) based on what the user is doing at the time. For example, while scrolling, the page may be playing the climbing loop and or when focus is given to a lead-capture form, the character starts dancing and when the user is typing in the 'email' field of said form, we jump to the super-fun part of the dance... I'm not sure if it will be exactly those, but something along those lines.
With the exception of the dance, which will be around 60 seconds in its non-looped state, everything else will only be a couple seconds max. So I'm trying to figure out what the most efficient way to rig this is - by that I mean the best way to use JavaScript to control the character's action based on the user's actions.
I'm considering using animated GIFs for everything except the dancing and just switching out their src when appropriate (i.e. $pigImg.src='pig-smile.gif' when she is clicked on and $pigImg.src='pig-climb.gif' for scrolling...) and then hiding the GIF (or displaying something blank) and streaming the video at its appropriate timestamp when it's time for her to dance.
I think I'll do all this within a <canvas> element to maximize the flexibility:simplicity ratio but if for no other reason than to be able to use clips with a green-screen background to do things I haven't even planned yet in the future.
I know this is a pretty broad intro, so I'll try it focus this post on the question of whether or not there are any potential obstacles that I need to consider with my <canvas> and mix of video and GIFs approach? I know that switching between the 2 media types may cause some mis-registration issues (i.e. the character not lining up 100% on the nose).
I'm sure this will end up being FAR more complex in reality that it is in my head right now, so I guess making sure I'm not dreaming up something filled with numerous technical holes of which I am unaware is a good starting point.

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

How to call a JS function or Python method when a glyph is completely rendered?

I am using bokeh as a Server Application. When I make a selection in a plot I do some actions in python and I update some sources (CDS). This changes are reflected in the plot. Is there a way to check when the glyphs are completely rendered (after the update)? I want to call a JavaScript function when all is completely loaded? With that function I want to call other python method to update the CDS again.
If I do not wait for this profiles to be rendered probably the application breaks, and that´s what I want to avoid. Actually I did some tests in the past and I had to create a huge CDS instead of several smaller CDS to make it work properly.
My Use Case. Why do I want to make this?
I have many tabs in my layout, they can be 10 for example. And each tab has some plots (3-6 plots). If I update the entire ColumnDataSource at the same time, it will take a while. Then I want to make it more fluent, so I would like to update only the data of the current visible tab, it will render faster and the user would receive an immediate response. I can disable the rest of the tabs temporarily to prevent malfunctions. At this moment I would need to call the JS or python method in order to update the content of the rest of the tabs.
Here a drawing of what I want to achieve in order to speed up the process:
About the data
Basically I have two DataFrames, one to build the cloud of points (around 5000 row and 130 columns) and I extract from the selected points another DataFrame to know which lines I should draw (360 columns and 5 to 15 rows), making some filters and selections. The algorythm I have used is in the answer of a question I have written time ago. With this amount of data the algorythm takes 6 or 7 seconds to finish.
Any other idea of how to improve the performance or how to split or the computing?
To improve the rendering speed you could try the webgl JavaScript API. This Bokeh documentation page Speeding up with WebGL explains how to do it. webgl supports circles, lines and most of the markers. Application:
p = Plot(output_backend="webgl") # for the glyph API
p = figure(output_backend="webgl") # for the plotting API
Please be aware that users report issues with webgl like plot stuttering, etc... but it may work in your case depend on which type of glyphs your plot contains.
Also make sure your data passed to the plot doesn't include NaN's as it is known to slow down Bokeh performance.
To my knowledge there is no attribute that indicates that rendering is completed or is still ongoing but you may think about some other alternatives to speed things up like combination of Bokeh with Datashader (pre-rendering large datasets into a fixed-size raster image) or Dask (speed up data reading from multiple sources like multiple csv files)
For example you could have one standard Bokeh plot where you make a
selection and let the other plots being generated as Datashader images
and embed them in Bokeh plots.
This example shows how to combine Bokeh + Datashader which significantly improves performance especially when over-plotting takes place. Please note that each time a single point is added to the plot entire canvas area will be re-drawn in the browser. This is how browsers work. Datashader can provide a single image so updating the plot is much quicker while you can still use Toolbar tools like zoom, pan etc....
Also the Python code implementation details counts. Using e.g. gridplot to link many plots can slow down performance so it is better to add them one by one to the document root, etc...
Time ago I made a trick to check if my design would work if I could trigger some function if the plots were rendered:
First I updated the current tab. This worked very well and fast.
Then I set a timeout to update the data of the rest of the tabs. But, in the meantime this second algorythm was being executed I could not work with the plots of the current tab because they were frozen.
So, the approach of triggering a function when everything is rendered is not a good idea, because even with such a callback the app would not work as I was expecting.

Charting sporadic events over time on Highcharts (Dynamic Precision?)

How would you chart something like pageviews over time using Highcharts?
Given that page views take place at sporadic irregular intervals, how could you chart this as accurately and legibly as possible?
One way is to group pageviews into time intervals (like days), and then sum up all pageviews on any given day.
The obvious issue here is that if you are only looking at data for a few days, the intervals are too large, and the data fits basically into a few buckets (not really showing any trends).
Another solution I thought of is to have a minimum interval (say, 7 steps) and when less than 7 days of data are requested, (say 3) I could divide that time period into 7 intervals.
However this seems like too much fuss, especially on the backend, for the purpose of simply showing data.
Given that the underlying data does not change, only the manner in which it's rendered, I figured there must be a general solution to this problem.
It depends on what you are trying to discover in the data. If you want to compare it with another data set then use the same scheme it does ("pageviews per day" or whatever). If you want to spot trends over time you need to decide on your horizon and use an appropriate time period (so, for example, if you are trying to justify the purchase of a larger server then perhaps quarterly data comparing this year to last would be good). Designing visualizations for datasets is a huge topic.
So, in other words, I think you pretty much answered your own question.
It looks like the answer is forced Data Grouping
http://api.highcharts.com/highstock/#plotOptions.series.dataGrouping
forced: Boolean
When data grouping is forced, it runs no matter how small the
intervals are. This can be handy for example when the sum should be
calculated for values appearing at random times within each hour.
Defaults to false.
I'll try this and see if it works well
This could work for highstock, but it's not part of highcharts...

Why does the performance of this HTML5 app drop upon coordinate load

I wrote this Mandelbrot plotter in HTML5 and it has a reproducible performance bug that I can't figure out.
In the Plot Controls section, there's the ability to save coordinates into a pick list to be able to return directly there later. If I select a saved set of coordinates, however, and then click "Load", the performance suddenly becomes so slow that at first I thought it was hanging the script (it will eventually start to develop the image as it's supposed to).
I cannot figure out why. The onclick handler for the Load button (line #258) simply calls gotoCoord() (line #457). The gotoCoord function simply sets several of the plot parameters (xOff, yOff, fMag) and then calls initDisplay(). I do those exact things in several other places with no ill effects (mousedown on line 124, zoomOut on line 386, zoomIn on line 394). I can't figure out what's different about gotoCoord.
I've done repeated comparison testing, navigating to a plot and timing how long it takes to develop the image. Then I save the coords and load them. The performance hit is drastic.
Does anyone else see what I'm missing?
This question is answered, so just taking it out of the unanswered list.
#DCoder's comment solved it. The plot parameters are stored in localStorage and the pick list is loaded from there. Of course, when loading from localStorage, the values will all be strings. That's what was different about gotoCoord from the other functions. Since the parameters are used in the plot (lines 589 and 590), the text must be converted to a number for each calculation of each pixel in each frame!
Three little plus signs fixed it.

Categories

Resources