Assigning mouse events to svg:text in d3.js - javascript

I'm trying to pick up mouse events for svg:text elements. What I noticed is that .on("click", ...) works, but other events like "mouseover", "mousemove", and "mouseout" don't.
Looking at the Health & Wealth of Nations example, I see that the approach taken was to overlay the text with an invisible svg:rect and assign it the events instead. This is fine if there's one simple box, but if there are several it seems it would become tiresome and messy.
Is there a canonical way to handle mouse hover events for text?
For the sake of being as specific as possible, I'm trying to have a tag cloud and pick up on these hover events for each of the tags. I could probably just do it with divs and be done with it, but I'm wondering if there's an easy way to do it within an SVG container.

I suppose the problem with assigning events to the text elements is that they only fire on the actual text, i.e. not the bounding box. In theory it should work though (at least I'm not aware of any special handling of text in this respect) -- can you give a concrete example where it doesn't?
You could also try putting each text element inside an svg:g element and attaching the event handler to that.

Related

Angular CDK drag and drop - is it possible to create circular boundary?

Is it possible to restrict an Angular Drag and Drop element to a circular boundary?
Looking at the documentation below
Restricting movement within an element
If you want to stop the user from being able to drag a cdkDrag element outside of another element, you can pass a CSS selector to the cdkDragBoundary attribute. The attribute works by accepting a selector and looking up the DOM until it finds an element that matches it. If a match is found, it'll be used as the boundary outside of which the element can't be dragged. cdkDragBoundary can also be used when cdkDrag is placed inside a cdkDropList.
I tried changing the css (see stackblitz) to be circular but my understanding from the result is this only changes the appearance and not the boundary of the DOM element.
With everything in the DOM essentially being a rectangle does this mean circular or very close to a circle restriction is not possible?
https://stackblitz.com/edit/angular-gughvc
As far as I can tell, there's no direct way to do what you want.
However, you could probably monitor the drag, do a "hit test" for your circular boundary, and stop the drag yourself when the boundary is exceeded.
I did a quick-and-dirty test at https://stackblitz.com/edit/angular-ut9fgz
This stops the drag at the mid-point of the circle, but:
It doesn't just prohibit going past the boundary, it cancels the
drag.
Having a callback for every drag event (essentially every pixel
traversed) can be expensive - your "hit test" better be very
efficient.
So, this shows the general concept, but there's still a lot left to be worked out.
Besides the official documentation, the following pages might be helpful:
https://grokonez.com/frontend/angular/angular-7/angular-7-drag-and-drop-example-angular-material-cdk
Cancel drag on key press Angular cdk Drag and Drop

Filter a DC.js table with a link?

I have a simple DC.js bar chart. I have it set up so you can click on an element and it gets filtered. This is standard behavior. It remains lit up, and the others go dark. You can then select other elements and have them added to the filter.
I'm looking for a way to replicate that functionality without clicking on the element. So like, i click a link outside the chart and the chart acts like I just clicked on some element.
Has anyone seen this done before?
Thanks,
Edit:
The reason I'm trying to do this is for accessibility. There's no way for keyboard users to interact as far as I can tell.
A hacky way to do it is to use chart.select to get a d3 selection of the element you want, and then fire an artificial click event as described here:
How to invoke "click" event programmatically in d3?
A better way is to do what the base chart onClick does:
_chart.filter(filter);
_chart.redrawGroup();
https://github.com/dc-js/dc.js/blob/master/src/base-mixin.js#L610
where filter is the key you want to filter on.

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

Make DIV accept and handle drop via JavaScript possible?

I've been googling and trying this for a good while now, but comes nowhere. So here goes:
What I want to do is to drop text on a DIV tag and handle that with JavaScript. Something along these lines:
<script type="text/javascript">
function handleDrop(sender, args)
{
$('#theDiv').html(args.textfromdrop);
}
</script>
<div id="theDiv" ondrop="handleDrop()" />
<br/>
<p>
This is some simple text. Draggable?
</p>
So, on this page I want to be able to drag contents from the paragraph for example to the div and it would handle the drop and change it's appearance accordingly (Or maybe just display that text, as long as it would handle it!). I've been trying with jQuery, but it seems to be a whole other model, and I can't set all my potential draggables as such because they should be able to come from everywhere. Is this even possible?
EDIT: Please correct me if I'm wrong, but these droppables all require a draggable to be dropped at it, right? What I would want is that you can drop text, pure text, from a page that you don't have any control of. This might sound weird, but it's for a firefox extension where you can drag content from a page to another page that resides in the side bar.
I would recommend using an established Javascript Library such as jQuery or YUI.
Have you considered creating a hidden textarea (ie with css style visibility:hidden) overlapping the div in question? Then check for drops with the onchange JavaScript event, or if that doesn't work, periodically the textarea's value for non-empty strings. I'm guessing your mileage will vary depending on the browser and operating system.
Or if you prefer Prototype like I do: http://wiki.github.com/madrobby/scriptaculous/droppables
EDIT: Based on your revised question: No, there's no way to allow a user to drop text from one page to another page. Not unless you do decide to build a FireFox extension like you were saying. Even if you could find a way around the security issue where you cannot script a page that's not under the same domain, you can only drag and drop DOM elements within the window/iFrame they're in.
I have done this before and it CAN be done without any library with some effort.
I've built the following methods:
Method that tracks your mouse movements.
Method to read and pass the content when you drop.
Used onmousemove and onclick events for the drag and drop methods.
OnMouseOver for the div area where you'd like to drop the text - to detect whether the pointer is over the container (div) or not.
Finally after dropping the text I deleted the original content (if needed) using innerHTML so it looks like it has been moved.
You can pretty much achieve a Windows like drag and drop functionality with this. I used it for drag and drop images, icons, etc.
If you need help with the coding I can give you some guidance, but most of it you will find if you Google around a little, then all you need to do is make them work together.

Categories

Resources