Displaying crossover only in d3.js Slankey (Dynamic, Interactive) - javascript

I am aiming to create a d3.js visualisation dashboard that shows the flow of mutual connections based on a selection for 'a', that provides a statistic for 'b', shaped like a Sankey/Parallel Set. For instance, if 'a' is the user selection, where they select 3 of 11 characteristics of people, then b would be a count of how many people in our sample have all three characteristics.
Think of this like a Sankey/Parallel Set diagram where on the left we see the characteristics (Happy, Loyal, Calm), flowing into one container (200/1000 (with characteristics selected/total population).
I am wondering if anyone knows a pre-established way to JUST displays the crossover that the user defines in a navbar pre-selection.
Thanks.
Data:
![It's a boolean array, with totals. It's like a permutations and combinations spreadsheet
]1

try this for a variety of sankey's,
https://observablehq.com/search?query=sankey

So if you're looking to make a crossover slankey like me, I recommend modelling here:
http://sankeymatic.com/build/
Once you get into it, it's very easy to label what the final node should be, and encourage output to flow to that node.
Hope this helps!

Related

Sankey-diagram PowerBI custom visual with color nodes and ordering

The sankey diagram of PowerBI has many possibilities but as you can read on the github site there are some important limitations. The first is that it is not possible to color the nodes. In addition, it is also not possible to change the order of the nodes (both source and destination).
Attached is an example PowerBI file in which a sankey is displayed. In this file is indicated which colors the nodes should have and what the order of the nodes should be.
The best solution is of course to use PowerBI to indicate the colors as in this example with the links. But probably it is easier to indicate the colors of the nodes (names) in the code itself with a hard value this would also be a nice alternative. Same holds for the ordering of the nodes
I looked at the colorscale function of d3 to link it to fillcolor. But I got an error message that the string values cannot be linked to colorscale.
The Github page with the code can be found here:
https://github.com/microsoft/powerbi-visuals-sankey
I think this line of code should change:
nodeFillColor = this.colorHelper.isHighContrast ? this.colorHelper.getThemeColor() : this.colorPalette.getColor(index.toString()).value;
console.log(nodeFillColor);
nodeStrokeColor = this.colorHelper.getHighContrastColor("foreground", nodeFillColor);
The colors are now based on a theme color. Hopefully it is possible to link the nodes (name) to a color instead of a theme.
Hopefully you can help me and other users of the Sankey.
It looks like if you need to inject some 3rd party color values (whether hex or some other format) you can use the ColorHelper instance at play in the code you highlighted to "cheat". The following example can be found in the powerbi documentation here: https://github.com/microsoft/powerbi-visuals-utils-colorutils/blob/master/docs/api/colorUtils.md#calculatehighlightcolor
import ColorUtility = powerbi.extensibility.utils.color;
let yellow = "#FFFF00",
yellowRGB = ColorUtility.parseColorString(yellow);
ColorUtility.calculateHighlightColor(yellowRGB, 0.8, 0.2);
// returns: '#CCCC00'
Ultimately I think it comes down to this one helper method:
ColorUtility.parseColorString('<colorhex>')
I don't know exactly the best way to plug it in to what you're doing, but you might try generating a random hex color and plugging it in to see what comes out the other side.
// thanks Paul Irish: https://www.paulirish.com/2009/random-hex-color-code-snippets/
let randcolor = '#'+Math.floor(Math.random()*16777215).toString(16)
// Then to replace the example code you had in your question...
nodeFillColor = this.colorHelper.parseColorString(randcolor)
nodeStrokeColor = this.colorHelper.getHighContrastColor("foreground", nodeFillColor);

Dc-sunburst, dc-Menuslect, dc-Non interactive graph

I'm new on dc.js and I have some questions about flexibility of dc.
First, I have looked for answers but haven't yet found any of them.
1) I'm using dc.sunburst chart. I was wondering if it was possible to create Zoomable sunburst as it is actually the case with d3.js. If yes, can you provide a piece of code please..?
2) I'm using crossfilter for interacting several graphs together. However I would like that one of them would not be possible to filter with. I mean that it updates with his dimension/group when filtering on other chart but that filtering other chart clicking on it would be impossible. Any ideas ?
Like: dc.rowChart().on("click", Do not filter)
3) I want to create a dropdown (using dc.menuSelect and crossfilter) on a two-dimension. When I create this chart the dropdown is like:
Bâle, A1
Bâle, A2
...
Bâle, N2
And I would like something more like:
Bâle
A1
A2
...
N2
Zürich
A1
...
N2
Thanks for your answer !!
I'll answer just question number 2, since I know the answer to that one.
dc.js does not provide an option to disable the click behavior for the row chart. However, in this case you can just override the handler:
rowChart.onClick = function() {};
The greatest strength of dc.js is also its greatest weakness: there have been a lot of contributors, which means the library has a ton of features. However, the interface may not always be consistent. In this case, many of the charts can have filtering disabled by calling .brushOn(false) - but not the row chart!
At the same time, dc.js is designed with an open architecture and there is almost always a way to workaround or patch in extra features.

How to determine SVG path neighbours?

I've been working with the great JVectorMap library. When the user selects a particular country on the map, I'd like to be able to determine which countries are neighbouring or sharing a border.
My searches for calculating distances between SVG paths hasn't gotten me anywhere. Can anyone suggest a good solution to determine which countries are neighbours and which aren't?
Thanks!
I think the best approach would be an array that lists a country and its bordering country names. Then use the array to filter your results. Creating the array would not be difficult since the following site lists bordering countries in a table:
Land borders
This could take a few hours, but I'm sure others would appreciate your work:)
Supposing that Country shapes are svg path elements you could check those Countries (paths) have coinciding vertices or with a distance within a given threshold.
There isn't a functionality to do this directly in jvectormaps. But what you can do is apply a and incrementing value on each horizontal or vertical strip of regions (call it something like data-adj), and you can do something like:
for( i in regions ){
if (Math.abs(this.data-adj - region[i].data-adj) <= 1){
//is adjacent so do something
}
}
This would really only work if you're looking for adjacency and not something like how many regions over a region is.
I needed to find out the same thing, so i made this: https://github.com/FnTm/country-neighbors
It mainly contains a single json file, that describes land-based neighbors for most of the world.
For most cases, it should do what you need to do.

How to generate level for a laser game in Javascript?

I am trying to generate a random level for my silly game. The game consists of having laser/detector pairs around a square field of possible mirrors. Like this:
/*
LLLLLLLLLL
LmmmmmmmmL
LmmmmmmmmL
LmmmmmmmmL
LLLLLLLLLL
*/
Now, I have an algorithm which generates a level, quite poorly, by relying on random placement, and rejecting bad positions. This is not very fast, and does not really generate the kind of fields I'd like to have. Please feel free to try it out at http://cmouse.desteem.org/laser/
Any suggestions are welcome.
The current algorithm looks something like this:
function createLevel:
for i=0 to mirrors:
mirrorLocation = pickRandomPosition
mirrorType = pickRandomType
if (verifyPosition(mirrorLocation, mirrorType)):
i = i - 1
next
else:
storeMirror(mirrorLocation, mirrorType)
In verifyPosition, we test the mirror that it reaches a laser in all four directions, in hope of avoiding undetectedable mirrors. It is somewhat boring code, so I omit it here.
One way to make sure it's not trying multiple fields more than once is to iterate over the fields and put a mirror or not based on some probability. The probability to put a mirror should be #mirros / #fields, so that the expected number of mirrors is #mirrors at the end.

Find in Multidiamentional Array

I have an multi dimensional array as
[
{"EventDate":"20110421221932","LONGITUDE":"-75.61481666666670","LATITUDE":"38.35916666666670","BothConnectionsDown":false},
{"EventDate":"20110421222228","LONGITUDE":"-75.61456666666670","LATITUDE":"38.35946666666670","BothConnectionsDown":false}
]
Is there any plugin available to search for combination of LONGITUDE,LATITUDE?
Thanks in advance
for (var i in VehCommLost) {
var item = VehCommLost[i];
if (item.LONGITUDE == 1 && item.LATITUDE == 2) {
//gotcha
break;
}
}
this is json string..which programming language u r using with js??
by the way try with parseJSON
Are the latitudes and longitudes completely random? or are they points along a path, so there is some notion of sequence?
If there is some ordering of the points in the array, perhaps a search algorithm could be faster.
For example:
if the inner array is up to 10,000 elements, test item 5000
if that value is too high, focus on 1-4999;
if too low, focus on 5001-10000, else 5000 is the right anwser
repeat until the range shrinks to the vicinity, making a straight loop through the remaining values quick enough.
After sleeping on it, it seems to me most likely that the solution to your problem lies in recasting the problem.
Since it is a requirement of the system that you are able to find a point quickly, I'd suggest that a large array is the wrong data structure to support that requirement. It maybe necessary to have an array, but perhaps there could also be another mechanism to make the search rapid.
As I understand it you are trying to locate points near a known lat-long.
What if, in addition to the array, you had a hash keyed on lat-long, with the value being an array of indexes into the huge array?
Latitude and Longitude can be expressed at different degrees of precision, such as 141.438754 or 141.4
The precision relates to the size of the grid square.
With some knowledge of the business domain, it should be possible to select a reasonably-sized grid such that several points fit inside but not too many to search.
So the hash is keyed on lat-long coords such as '141.4#23.2' with the value being a smaller array of indexes [3456,3478,4579,6344] using the indexes we can easily access the items in the large array.
Suppose we need to find 141.438754#23.2i7643 : we can reduce the precision to '141.4#23.2' and see if there is an array for that grid square.
If not, widen the search to the (3*3-1=) 8 adjacent grids (plus or minus one unit).
If not, widen to the (=5*5-9) 16 grid squares one unit away. And so on...
Depending on how the original data is stored and processed, it may be possible to generate the hash server-side, which would be preferable. If you needed to generate the hash client-side, it might be worth doing if you reused it for many searches, but would be kind of pointless if you used the data only once.
Could you comment on the possibility of recasting the problem in a different way, perhaps along these lines?

Categories

Resources