arbor.js for annotated illustration - javascript

I'm hoping to use arbor.js as a way of creating annotated illustrations.
The plan:
Fixed size canvas
Draw image to canvas – as an example i've used the silhouette of head.
Then have a mixture of fixed and floating nodes.
var data = {
nodes:{
brain-position:{},
brain-text:{'color':'green','shape':'dot','label':'brain'},
mouth-position:{},
mouth-text{'color':'green','shape':'dot','label':'mouth'},
},
edges:{
brain-position:{ brain-text },
mouth-position:{mouth-text}
}
};
sys.graft(data);
The problems i'm having is that when I try to create a statically positioned nodeBox eg.
nodeBoxes[node.name] = [50,50, w,w] it breaks the link to other linked nodes.
I'm tinkering with halfvis/src/renderer.js file from the downloaded arbor file.
Many thanks
EDIT
Below is an additional image that hopefully visualises the functionality I'm attempting. Probably should have done this first :)

nodeBoxes, in the halfvis example, is an array used to work out where to start drawing edges so the arrows don't overlap with the boxes - is that what you're using it for?
Are you trying to find a way of forcing the 'brain-position' node inside an area?
Please provide a bit more detail of what you're planning and we can probably do this.

Related

DC.js brush to select range not working with scaleTime

PROLOGUE
This is my first time posting to stackoverflow and i'm a noob with dc.js. Apologies in advance for etiquette transgressions (feedback welcome on this too)
PROBLEM
I have defined a barchart and it displays perfectly, but brushOn(true) is not letting me filter the data. In the past, this seemed to work perfectly with a crosshair appearing as soon as i hovered over the bargraph. Now it is not. Any idea why?! or what i can do to fix it? I'm on day 3 of trying to figure out what is happening. The help is MUCH appreciated!
PREREQS:
https://d3js.org/d3.v5.min.js
crossfilter.min.js
https://unpkg.com/dc#3.0.4/dc.js
CODE FOR BARCHART
I have defined a barchart as follows:
filterDim = cross.dimension(function(d){return d3.timeWeek(d.date);});
var filterGroup = filterDim.group().reduceSum(function(d){
if(d.isTrue){return 1;}
else {return 0;} });
height=400;
if(width == 0){
width = $(dom_id).parent().innerWidth();
}
var hitsbarChart = dc.barChart(dom_id);
hitsbarChart
.width(width).height(height)
.dimension(sentDimension)
.group(allGroups[0].data,allGroups[0].name)
.xUnits(d3.timeWeeks);
hitsbarChart
.x(d3.scaleTime())
.valueAccessor(function(d){return d.value;})
.keyAccessor(function(d){return d.key;})
.round(d3.timeWeek.round)
.yAxis().ticks(d3.format('.3s'));
function calc_domain(chart) {
var min = d3.min(chart.group().all(), function(kv) { return kv.key; }),
max = d3.max(chart.group().all(), function(kv) { return kv.key; });
max = d3.timeMonth.offset(max, 1);
chart.x().domain([min, max]);
}
hitsbarChart.on('preRender', calc_domain);
hitsbarChart.on('preRedraw', calc_domain);
hitsbarChart.brushOn(true);
dc.renderAll();
RESEARCH
I found this example which demonstrates something different but outputs a graph with time-series as the x-axis and working brush to select a range of dates.
Also, there this bug with work-around but the work around did not work. I can't imagine that time-series data works more like an ordinal scale than a numerical scale.
It's likely that you have some CSS inadvertently affecting your chart when it was supposed to be control some other part of the page.
This could happen either because you used a generic name which is also used by dc.js or d3.js, or because a style sheet from another library does. All of dc.js's style rules are carefully scoped so that they shouldn't affect anyone else, but many common words are used for class names, so interference the other way is common.
The brushing behavior comes from d3, so I'd try looking at d3's g.brush rect.overlay in the inspector of your developer tools. You should be able to bring it up by right-clicking the background of the chart and selecting Inspect.
If it has something like
pointer-events: none;
or
display: none;
applied to it, find out what applied that (hopefully CSS you control) and try to make the rules more specific.
Of course it's also possible for JavaScript from another library to cause such troubles, but interference from CSS is much more common.

How can I access the paper object created by raphael?

I'm working on an HTML display for some phylogenetic analysis. I create a div, and there's this lovely javascript package called jsPhyloSVG that draws me a nice tree in that div. That package uses raphael to do its drawing, but it doesn't return me the raphael paper object. I'd like to make a few additions to this image using raphael, but I don't know how because I don't have a reference to that paper object. I can access the svg that raphael generates, but is there some way to work backwards to find paper?
If that doesn't work, I could always just add circle or path objects directly to the svg using jquery, right?
Well, after most of a day smashing my head into a wall, I've solved my issue. It turns out you can reuse the paper object that has been created by some other library, if you can find a reference to the object itself. For anyone else that is using jsPhyloSVG, this can be found by:
var dataObject = {phyloxml: tree_data};
var phylocanvas = new Smits.PhyloCanvas(
dataObject,
'svgCanvas',
1000, 1000,
'circular'
);
var paper = phylocanvas.getSvg().svg;
You can then proceed as normal: paper.circle(100, 100, 15);.
What I think Ian was getting at, is that you cannot reuse the svg that has been created by raphael. I could always access that element, but using jQuery to append circle elements didn't work.
They would show up in the svg object in the inspection panel, but would not display on the screen. There are a few workarounds discussed in another question here, which mostly worked for me. However they broke the connection between the raphael object and the svg element on screen; most mouseover functionality stops working.

Drag and mouseover in snap.svg

I'm relatively new to javascript, and am learning about drag and drop using snap.svg. My problem is in the drop. I can't tell if the dragged element is over the drop target. In this code, I want to drag the circle over the square, and thought I could use mouseover. My (distilled) example may also be a simpler version of this post.
var paper = Snap(300, 300);
var square = paper.rect(100, 100, 40, 40).attr({fill:"blue"});
var circle = paper.circle(50, 50, 20).attr({fill:"red"});
circle.drag();
square.mouseover(
function() {
console.log("Over the square");
}
);
As written, the mouseover will fire when you move the pointer over the blue square, but not when you drag the red circle over the blue square. If you reverse the creation of the square and circle, the mouseover fires either way, but of course the circle is behind the square.
Evidently the event gets caught in the view hierarchy (or something) and doesn't propagate. There must be an easy way around this. Any help?
(And if the best answer is, "use jQuery," fine, but I'd love to learn how to make this work directly, since snap.svg makes dragging so easy.)
Addition: The direction I'm hoping for: the snap.svg documentation for Element.drag() says, in part, "When Element is dragged over another element, drag.over.<id> fires as well." A fine, event-based direction, which would let me (for example) highlight the drop target without a lot of fuss.
But I haven't figured out how to listen for that event! Any help or advice?
Only quick way without collision or element detection from points that I can think of, is to place an almost invisible clone in front of the object, later in the DOM that you can't really see, eg ...
paper.append( square.clone().attr({ opacity: 0.000001 }) )
jsfiddle
Depends how complex your svgs are going to be as to whether this would work I guess, you also have a slight issue if you drop the element over it, your redrag start won't get picked up, so you would need to code around that as well. I think some testing is probably going to be the most bug free solution (there are a few solutions on S.O for getElementFromPoint or hit detection type solutions).
jsfiddle workaround for point above

Needing Specific Kinetic.Transform Example using KineticJS?

I am wondering how to transform text using KineticJS in order to mirror or reflect Simple Text. I see that the class is documented at this location:
http://kineticjs.com/docs/Kinetic.Transform.html
There is no sample code, or tutorial, on how to actually perform this demonstration. I know that HTML5 Canvas has a tutorial that simply applies a negative scale in the x direction to flip the context horizontally.
I would like to apply "scale(sx, sy)" or scale(-1, 1) here, but using KineticJS-specific code:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-text-tutorial/
Any code example on how to mirror "Simple Text" to read "txeT elpmiS" would be greatly appreciated. My question, on Stackoverflow, is not the only question being asked about KineticJS's undocumented functionality, so I am hoping that being more specific in purpose would generate a more helpful response for overall guidance on using the Transform Class.
Don't use Transform class. It is "private".
You can apply negative scale at text as well:
simpleText.scale({
x : -1
});
http://jsbin.com/sevoko/1/edit

I would like to reposition a circle created through Raphael js, and to use it as a letter in a title

I have created a vector graphic using Raphael JS - specifically a circle.
I would now like to use this circle as the letter "O" in a title. It is also a circle that will animate upon click. I would like to know if this is at all possible.
Here is a fiddle to explain better what I'm trying to say.
The html is very simple:
<h2>N<span id="canvas_cont"></span>OTRE APPROCHE :</h2>
Here is the jsfiddle
Basically the circle will act as the second letter in "Notre", and when clicked will move to the right of the screen. Other things will happen after, but this effect is what I'm trying to get....
Placing the Raphael canvas in a span is clever, but at the end of the day I suspect you'll regret mixing native HTML with Raphael in this way. Doing so would probably require a lot of absolute positioning and z-indexes that are better handled and supported in Raphael.
I recommend you simple draw the text in Raphael:
var text = r.set();
text.push(
r.text(10,20,"N"),
r.text(70,20,"TRE APPROCHE :")
);
text.attr({
'text-anchor': 'start',
'font-size':'36px'
});
If the SVG/VML styling is inadequate, you could also just use an image. Again, I would recommend placing that image on the canvas using Raphael (paper.image());
Note that, in the updated fiddle, I made the canvas a div the width of the logo.
Updated fiddle.

Categories