Using Neo4j I would like to plot Neo4j nodes with a different size in a graph with X- and y-axes, like an Excel bubble-chart.
Example data;
label = '1A', node diameter = big, x=5, y=3
label = '1B', node diameter = small, x=5, y=1
Label = '2A', node diameter = big, x=4, y=5
Label = '2B', node diameter = small, x=2, y=1
How could I represent these data in a Neo4j graph?
Regards,
Ralph
As from this https://stackoverflow.com/a/36534323 answer, I guess you can not change the size of a bubble programmatically or by data. So I guess you should try to look for a nother solution. Furthermore you may not persist the location of a bubble.
All in all, Neo4j is mainly for storing relation-based data, not for visualizing it, while it is still possible in a rudimentary manner.
Related
I am using qgraph package to plot network of correlations, which show both positive and negative values. I need a gray scale plot due to journal restrictions, so color of nodes can be easily set but I'm having difficulties with edges. I would like to set a different line type for positive ("solid") and negative ("dashed") correlations, so we don't need gray code for nodes and also for edges. The argument lty in ´qgraph`only allows for one type of line for the whole plot, how can I get it to work?
Here's a tentative solution
qgraph(polys$rho, groups = structure_hscl,
color= c("white","gray","gray25"),
borders=TRUE, trans=FALSE, details=TRUE,
bonf=TRUE, alpha=.05,
normalize =TRUE, vsize=3,
threshold= .2, labels=labels_hscl,
layout="spring", graph="pcor",
lty = c("solid","dashed") # this obviously doesn't work )
Thanks a lot beforehand!
It seems that lty needs to be a vector of suitable values. So how do we know which edges should be dashed and which solid? I'll demonstrate one way to get the job done using the bfi data from the psych package.
library(psych)
library(qgraph)
data(bfi)
persvars <- bfi[,1:25]
Let's then create a temporary graph and infer which lines to draw as dashed based on the colors:
hackgraph <- qgraph(cor(persvars,use = "pa"), fade = FALSE, layout = "spring", graph = "pcor")
edgecolor <- hackgraph$graphAttributes$Edges$color
unique(hackgraph$graphAttributes$Edges$color)
Setting fade = FALSE above reduced the colors to a manageable number: now we know that positive edges are either "#009900" or "darkgreen" in color. So all we need to do is to form a new vector as:
linetype <- ifelse( (edgecolor == "#009900" | edgecolor =="darkgreen"), 1, 2)
We can then draw the desired graph based on these line types:
qgraph(cor(persvars,use = "pa"), layout = "spring", graph = "pcor", lty = linetype)
I would like draw a curved line and attach an object to it. Is it possible to create fraction (from 0.0 to 1.0) which makes move my object on the path? When fraction is 0 then object is on the beginning, when 0.5 is on half way and finally when is on 1.0 it is at the end. Of course i want a curved path, not a straight line :) Is it possible to do in PaintCode?
If you need it only as a progress bar, it is possible in PaintCode. The trick is to use dashed stroke with very large Gap and then just change the Dash.
Then just attach a Variable and you are done.
Edit: Regarding the discussion under the original post, this solution uses points as the unit, so it will be distributed equally along the curve, no matter how curved the bezier is.
Based on the fact that you're going to walk along the curve using linear distance, a thing Bezier curves are terrible for, you need to build the linear mapping yourself. That's fairly simple though:
When you draw the curve, also build a look-up table that samples the curve once, at say 100 points (t=0, t=0.01, t=0.02, etc). In pseudocode:
lut = [];
lut[0] = 0;
tlen = curve.length();
for(v=0; v<=100; v++) {
t = v/100;
clen = curve.split(0,t).length();
percent = 100*clen/tlen;
lut[percent] = t;
}
This may leave gaps in your LUT - you can either fix those as a secondary step, or just leave them in and do a binary scan on your array to find the nearest "does have a value" percentage.
Then, when you need to show your progress as some percentage value, you just look up the corresponding t value: say you need to show 83%, you look up lut[83] and draw your object at the value that gives you.
Is there a way of getting the closest nodes to a node?
I'm just about to write a method to iterate all nodes and calculate distances etc... but wondered if there is a better way?
I have 30 nodes and need the 2 nearest nodes to each of the 30 nodes (if that makes sense).
As of iOS 10, you can use the Spatial Partitioning features of GampelayKit. In 2D either GKQuadtree or GKRTree depending on your needs.
From the docs:
Quadtrees and R-trees have different performance tradeoffs for different tasks: quadtrees can be faster when objects are more uniformly distributed in space or when their positions change frequently, and R-trees can be faster when searching for all objects in a given region.
Add your enemies to the tree:
let minX = Float(enemy.frame.minX)
let minY = Float(enemy.frame.minY)
let maxX = Float(enemy.frame.maxX)
let maxY = Float(enemy.frame.maxY)
var enemiesRTree = GKRTree(maxNumberOfChildren: 3)
enemiesRTree.addElement(enemy,
boundingRectMin: vector2(minX, minY),
boundingRectMax: vector2(maxX, maxY),
splitStrategy: GKRTreeSplitStrategy.linear)
Then you can search by area.
let enemiesInProximity = enemiesRTree.elements(
inBoundingRectMin: vector2(0, 0),
rectMax: vector2(100, 100))
You can then create the search area e.g. relative to the player's position.
I believe that your approach is the most appropriate for this situation. If you stored all the nodes in an array style there may be a relatively efficient way to do what you mentioned above.
In any situation, you still may be tasked with having three nodes closest. If this is not a problem, you use a method that takes a nodes position and then use for loop to project "invisible circles" of increasing radius until a circle finally contains exactly 2 nodes. Then just return those nodes.
How to make a 2d world with fixed size, which would repeat itself when reached any side of the map?
When you reach a side of a map you see the opposite side of the map which merged togeather with this one. The idea is that if you didn't have a minimap you would not even notice the transition of map repeating itself.
I have a few ideas how to make it:
1) Keeping total of 3x3 world like these all the time which are exactly the same and updated the same way, just the players exists in only one of them.
2) Another way would be to seperate the map into smaller peaces and add them to required place when asked.
Either way it can be complicated to complete it. I remember that more thatn 10 years ago i played some game like that with soldiers following each other in a repeating wold shooting other AI soldiers.
Mostly waned to hear your thoughts about the idea and how it could be achieved. I'm coding in XNA(C#).
Another alternative is to generate noise using libnoise libraries. The beauty of this is that you can generate noise over a theoretical infinite amount of space.
Take a look at the following:
http://libnoise.sourceforge.net/tutorials/tutorial3.html#tile
There is also an XNA port of the above at: http://bigblackblock.com/tools/libnoisexna
If you end up using the XNA port, you can do something like this:
Perlin perlin = new Perlin();
perlin.Frequency = 0.5f; //height
perlin.Lacunarity = 2f; //frequency increase between octaves
perlin.OctaveCount = 5; //Number of passes
perlin.Persistence = 0.45f; //
perlin.Quality = QualityMode.High;
perlin.Seed = 8;
//Create our 2d map
Noise2D _map = new Noise2D(CHUNKSIZE_WIDTH, CHUNKSIZE_HEIGHT, perlin);
//Get a section
_map.GeneratePlanar(left, right, top, down);
GeneratePlanar is the function to call to get the sections in each direction that will connect seamlessly with the rest of your world.
If the game is tile based I think what you should do is:
Keep only one array for the game area.
Determine the visible area using modulo arithmetics over the size of the game area mod w and h where these are the width and height of the table.
E.g. if the table is 80x100 (0,0) top left coordinates with a width of 80 and height of 100 and the rect of the viewport is at (70,90) with a width of 40 and height of 20 you index with [70-79][0-29] for the x coordinate and [90-99][0-9] for the y. This can be achieved by calculating the index with the following formula:
idx = (n+i)%80 (or%100) where n is the top coordinate(x or y) for the rect and i is in the range for the width/height of the viewport.
This assumes that one step of movement moves the camera with non fractional coordinates.
So this is your second alternative in a little bit more detailed way. If you only want to repeat the terrain, you should separate the contents of the tile. In this case the contents will most likely be generated on the fly since you don't store them.
Hope this helped.
I have been working on a project that requires a bar graph to be populated with price results. The chart displays the number of items within a given price range. For instance, if on amazon there are 9 items within the price range of $0-$10 the x-axis would display $0-$10 and the y-axis would be populated with a value of 9.
My bar graph has 8 bars, all with similar price ranges. $0-$10, $10-$20, $20-$30... etc.
My question is this: What is the best way to define those individual points? There is no common price range between these items, so the x-axis cannot be static numbers. They must be dynamically calculated within the range of results.
As such, currently I am creating the x-axis points as follows:
I take the lowest result:
#numbers[0] = results[0];
And I take the highest result:
#numbers[8] = results[-1];
Then I find the median of the two:
#numbers[4] = (#numbers[0]+#numbers[8])/2;
I then repeat the process 6 more times
#numbers[2] = (#numbers[0]+#numbers[4])/2; #numbers[6] = (#numbers[4]+#numbers[8])/2; #numbers[1] = (#numbers[0]+#numbers[2])/2; #numbers[3] = (#numbers[2]+#numbers[4])/2; #numbers[5] = (#numbers[4]+#numbers[6])/2; #numbers[7] = (#numbers[6]+#numbers[8])/2;
This gives me the results I need, but it seems awfully repetitive and I would imagine there is a better way.
I tried creating a loop, but I could not write it in a less verbose manner.
Is there a quicker way to do this, or perhaps something more along the lines of DRY?
Are your bins always of equal size? In your example, all share range=10. If so, then you could do:
binspacing = overall range / (numberofbins-1);
and the position of bin n would be the x-axis position of numbers[0] plus n times the binspacing.