I am displaying several identical charts (showing different datasets) side-by-side. Upon brushing on one chart, the brush should be replicated on all others.
Currently, I do this by calling brush.move on a selection of all charts excluding the currently brushed chart, as soon as someone brushes on a chart. This happens in a brush-type eventListener.
However, this brush.move triggers the brush-type event attached to the brush, leading to an error (or, more generally, an infinite loop).
How can I prevent this?
You can use the d3.event object to check what caused the update of the brush. From the API docs on brush events:
Brush Events
When a brush event listener is invoked, d3.event is set to the current brush event. The event object exposes several fields:
…
sourceEvent - the underlying input event, such as mousemove or touchmove.
If your brush is modified programtically, i.e. by calling brush.move(), the d3.event.sourceEvent property will be null, because no input event caused this update. In your event handler you can check this property to skip execution for programmatic changes:
if (!d3.event.sourceEvent) return;
The same technique is employed by Mike Bostock in his Brush Snapping Block. While handling the actual input event the brush is modified again to snap to the nearest value, which, obviously, should not trigger another run of the event handler.
Related
I have two canvases and two stages in CreateJS / EaselJS. The first stage has autoClear set to false and I am doing dynamic drawing on it starting with a stagemousedown event. The second stage uses nextStage to send mouse events to the first stage. The second stage has interface such as a Bitmap that I want to press on to go to another page. When I click on the Bitmap, the stage beneath does the dynamic drawing. I want the click on the Bitmap not to go through to the first stage but stopImmediatePropagation does not work, nor does putting a clone of the Bitmap with mouseEnabled false on it underneath. I can just use mousedown on the Bitmap so the user does not notice as much, but was wondering if there is a way to disable mouse events from passing through the top stage if they are acting on an object with an event set to capture? Thanks in advance.
The stagemousedown and other stage events are decoupled from the EaselJS object event model. They are catch-all events, which basically represent mouse interaction with the . Because of this, catching and stopping these events won't interrupt the display list hierarchy.
Typically if you want to block other events in the same stage, you can create a canvas-size box (Shape, etc) that will block the interaction. When dealing with nextStage, this is especially true, since we are passing on events that are unhandled by objects in the EaselJS display list.
A better approach might be to toggle the nextStage on stagemousedown, so it is null during the click event. Not sure if this will work, but its a start.
Using c3.js, I have a line graph with many lines. The tooltip properly appears at individual data points, and I can use the mouseover property to fire on data point hover.
I need to change the color of a line on the graph on mouseover at any position of the line. It appears as though lines are obscured from hover events by other shapes as I can't even get pain JS or CSS to fire events. Is there any way to get c3.js to fire an event when the mouse moves over and out of a line?
It's a default js function method calling:
onmouseover: function () { ... }
I have been searching, on capturing the event or some property that tells that a shape (text Shape Object) is onfocus. as this will help in capturing the keyboard event, so that if the text changes the rectangle width can be increased.
as shown in the link http://s2.postimg.org/scxtx0ec9/Untitled.png
There aren't any such events. There's a SelectionChange event that's fired when the current selection changes; you can trap that then test to see what's currently selected (ie, Slides, Shapes, Text, etc) and react accordingly.
But is there some reason why you can't simply set the text container to automatically resize to fit text? That is, set the shape's .TextFrame.AutoSize property to ppAutoSizeShapeToFitText (Long = 1)
KineticJS seems to have an issue with handling clicks on background layers after redrawing the stage.
I have a jsfiddle with a minimal example of this problem. http://jsfiddle.net/Z2SJS/
On line 34 I have:
stage.draw()
If this is commented out, events fire as they should. When this is present, after dragging the click events to the background will stop firing.
I know that in this example I am not doing anything that would require me to redraw the stage, but in my project I am using the dragstart and dragmove events to manipulate objects on multiple layers, and I then lose reference to my background clicks.
Is there something I need to do to ensure that redrawing the stage does not cause my events to stop firing?
Instead of using stage.draw() use foreground.draw()
here is the updated fiddle
Alternately: set dragOnTop: false inside the circle instantiation. Fiddle2
In this thread, Mike Bostock explains that setting a brush's extent and redrawing the brush are two separate operations. I understand this, but I'm having trouble working out the details.
He says you need to do something like the following:
brush.extent([0.2, 0.8]);
svg.select(".brush").call(brush);
However, when I execute call(brush), it simply draws the brush rectangle on the new extent. The 'focus' chart never gets updated. However, if I call my brushed function (the function that I assigned to my brush), it works.
It seems like call(brush) doesn't execute brushed. How do I get it to execute this function?
UPDATE: Here's a fiddle with my code. When you run it, notice the brush is correctly drawn, but the focus is not updated. Uncomment line 180, and the focus gets redrawn too.
(Of course, eventually I will want to do this from outside the chart object, but for now I am doing it within just to try to figure out what's going wrong.)
Essentially, I'm asking: How can I trigger the brushed function from outside the object? How does the brush event handler do it?
Setting the extent of a brush explicitly doesn't trigger the event that causes the function associated with it to be called. In this case the simplest solution is to, as you already found out, call brushed() explicitly after setting the extent.