I want to get an event to handle when an rectangle object change its size.
I tried bounds_changed as follow:
google.maps.event.addListener(rectangle, "bounds_changed", function() {
Foo();
});
It works, the problem with bounds_changed is that it is called a lot of time before the user ends to resize the rectangle, so my function 'Foo' runs in any step making my page SLOW.
Is there an event like that I'm looking for? some approach to get it?
Thanks in advance.
Related
In the example below,
OnTouchEffectAction contains canvas.InvalidateSurface().
OnCanvasViewPaintSurface contains convas.DrawPath().
Questions:
Why OnTouchEffectAction requires InvalidateSurface()?
Why doesnt call InvalidateSurface after
drawing?
Complete Code is given here
InvalidateSurface causes the PainSurface event to be raised, which calls OnCanvasViewPaintSurface. InvalidateSurface is how you tell Skia that you've made changes to a canvas and that it's UI needs to be refreshed. OnTouchEffectAction is adding new polylines to the canvas, so calling InvalidateSurface causes the canvas to be redrawn with those new lines.
How's the page scrolling created on flashvhtml.com? How is the scrolling triggered by the links at the top and how the other 'sub animation' events tied in to the scrolling background?
This is what I have been able to gather:
Listeners for interactions are added in the Trackpad.js file. Listeners for events such as mouse dragging, keyboard events, touch etc. All of which calculating a value variable.
This value variable of the Trackpad.js is then
used to adjust camera position in the update method of main.js
file.
There are 3 main views that are being rendered if I understand
it correctly: ScrollView, ScaleView, RocketView. All of those
initiated inside the init method of main.js. But they are all
defined in the fvh.js file.
Each of these three views have an
updatePosition method taking camera.y or mainScrollPosition as
parameter. These updatePosition methods are called inside of the
same update method of main.js file.
Then there is a ScrollMap.js which contains loads of position data for all 3 views e.g. it contains ScrollView data in the format of:
mcxxx:{view:'nameofelement',depth:xx,startFrame:xxx,endFrame:xxx,position:[xxx,...]} etc.
Also there is a sectionLandPositions variable defined in the main.js file which is also very interesting because this is what is then used inside the onMenuItemPressed method in the same file to tween and bring a certain section into view.
So magic basically happens in the updatePosition methods of each views and how the value is computed in the Trackpad.js. And this is where I leave you to debug further and take it home. :)
Files under scrutiny are: Trackpad.js, fvh.js, ScrollMap.js, main.js. Hope you find it all useful.
P.S. Kudos to Waste-Creative for creating this informative and engaging website.
T
An easy way to do this, is by adding tweens and then using the scroll/drag input and links to move around in the tween's timeline.
Tween one : Pans Camera down slowly continuously.
Tween two : Wait's until x, fades sprite in untily y, fades sprite out, ..
Make sure, you dont 'play' the tween's after creating them, but adjust the time manually (based on the scroll position).
There are a few tweeing frameworks you can use for pixi: Greensocks, Impact, tween.js
And there's a discusion on it over at the html5gamedevs forum.
I am building a page which contains many charts, which are displayed one at a time depending on which tab you are looking at.
The chart in the initially active tab renders correctly. However when I click to another tab, the chart is not rendered properly.
Presumably this is because the hidden field does not have dimensions until it is made visible. In fact if I resize the window the chart will correct it's proportions, and render so that it fills the available width.
I can fix this problem by explicitly defining the chart size via css, but this defeats the responsive aspect of the charts.
Can anyone tell me how to trigger the same NVD3 event which gets activated when the window resizes? That way I can bind it to the selection of a new tab, and hopefully remedy the rendering issue.
I had the same issue (charts on multiple tabs), and this is the only thing that I could get to work.
$(function () {
$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
window.dispatchEvent(new Event('resize'));
});
});
I have a feeling, however, that all of the charts are being re-rendered, regardless of whether they are on the active tab (visible) or in the non-selected tabs (hidden).
Does anyone know how to ensure ONLY the active chart gets resized / redrawn?
I figured out how to trigger the resize event I needed. In my case the tabs are driven by bootstrap. So I simply modified my bootstrap show tab event to trigger a page resize event as well. It's a little indirect, but it gets the job done:
jQuery('#myTab a').click(function (e) {
e.preventDefault()
jQuery(this).tab('show')
jQuery(window).trigger('resize'); // Added this line to force NVD3 to redraw the chart
})
Just add this JavaScript:
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
window.dispatchEvent(new Event('resize'));
})
hidden.bs.tab is the event that fires after a new tab is shown as per the Bootstrap docs. This code fires a resize event after each tab change.
Reason For New Answer
Vanilla Javascript is necessary for a lot of people in 2018. As a lot of frameworks and Javascript libraries that exist today do not play well with jQuery. Once upon a time answering all Javascript problems with a jQuery solution was acceptable but it is no longer feasible.
Problem
When loading C3.js or D3.js graphs, if the viewport is not actively in site during page load the graphs do not render correctly.
Example
If you type in the URL then open a new tab and then go back after your page loads.
If you refresh the page that has your graphs on it then minimize the browser and open it back up after the page has loaded.
If you refresh or go to the page with the graphs then swipe away to a new window on your computer. Then go back to the page with the graphs after they have loaded.
In all these cases your C3.js / D3.js graphs will not render correctly. Typically you will see a blank canvas. So if you were expecting a bar chart, you would see a canvas without the bars being drawn.
Background
Although I have seen this question answered I needed an answer that did NOT use jQuery. Now that we have reached the days of everything can not be fixed with jQuery I thought it seemed fit to provide a vanilla Javascript answer to this question.
My team faced the issue that the C3.js / D3.js graphs would not load if you refreshed the page and swiped away or minimized. Basically if you did not stay on the page and keep it in site till it was done loading you would not see the graphs till you resized the page again. I know this is a problem that happens to everyone using C3.js / D3.js but we are specifically using Lightning in Salesforce.
Answer
Our fix was to add this in the controller function that initializes the charts. Anyone can use this in any function they write to initialize their C3.js / D3.js graphs regardless of their stack. This is not Salesforce dependent but it does indeed work if you are facing this issue in Salesforce.
document.addEventListener('visibilitychange', () => {
console.log(document.visibilityState);
window.dispatchEvent(new Event('resize'));
});
I was facing same issue. I was using ng-show to make div hidden . Once I replaced ng-show with ng-if I am able to see graph drawn in expected behavior. Explanation:
When we use ng-show or ng-hide to make div hidden it only changes it display property but div will be in dom.
When we use ng-if div is removed from dom and again added to dom so internally it performs redraw operation on nvd3 graph too. Hence we see correct graph instead of squished one.
The event that usually triggers a redraw is the window resize event -- NVD3 doesn't use a custom event for this. You can control this yourself though; the usual definition is
nv.utils.windowResize(function() { d3.select('#chart svg').call(chart); });
(where "#chart" is the element that contains the graph). There's nothing stopping you triggering the code on another event or even just running the redraw code explicitly when you change the tab.
a more efficient approach would be to use the chart.update() method
var chart_x = nv.models.somechart()
var chart_y = nv.models.somechart()
..... show charts
jQuery('#myTab a').click(function (e) {
e.preventDefault()
jQuery(this).tab('show')
if(jQuery(this)...something === '..x..')
chart_x.update(); //CALL THE UPDATE
else ...
})
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.
I have a simple slider, with only 3 options. It seems strange to force the user to drag the small thumbnail on the slider, when it would be a lot easier to click one of the 3 actual labels by the side of the slider. Does anyone know how to accomplish this?
This is a cool problem.
The Label object used by Slider turns out to be a subclass of Label (called SliderLabel). So, probably the best approach would be to subclass Slider and add event listeners to the labels.
I think you could successfully add event listeners in either the commitProperties method or the updateDisplayList method. I'm not sure if one would be preferable to the other, but commitProperties seems like the more correct choice.
So, in your subclass of Slider:
override protected function commitProperties():void
{
super.commitProperties();
for(var i:int = 0; i < labelObjects.numChildren; i++)
{
if(!SliderLabel(labelObjects.getChildAt(i)).hasEventListener(MouseEvent.CLICK))
{
SliderLabel(labelObjects.getChildAt(i)).addEventListener(MouseEvent.CLICK,sliderLabelClickListener);
}
}
}
and then maybe something like this for sliderLabelClickListener:
private function sliderLabelClickListener(e:MouseEvent):void
{
dispatchEvent( new SliderLabelClickEvent(e.target) );
}
I think you'd want a custom event there, rather than dispatching a regular Event, so you could include the name/id/value of the label.
Also, you may want to put in a 'dispose' method to remove the CLICK event listener from the labels when the Slider is removed from the stage. It's not an issue if you aren't going to be removing the Slider, but if you are, what I normally do is create a method called dispose and put all my manual removal logic there (removing event listeners, unwatching/removing ChangeWatchers). Then I assign a listener to the component's REMOVED_FROM_STAGE event and call the dispose method from that listener.
Are you sure a slider is the best component to use in this case? Generally speaking, sliders are to be used when the user has a large range of contiguous options to choose from, where the precision of a user's choice doesn't really matter (e.g. a volume slider - having volume at 51% as opposed to 50% really won't make much of a difference).
If you only have three options, and the user is only allowed to select one of those three options, I would suggest using either a combo box or a radio button group.