I have a table of data with some hover-activated popups. These popups are simply div elements with position: absolute and display: none initially set; a few lines of JavaScript then hide or show them based on mouse hovering. A flot line graph is attached to each popup.
This works great and fast, except for one hitch. Flot has a bug which causes the x-axis and y-axis labels to overlap at the lower-left corner when the graph is part of a popup like this. In short, the solution is to display the containing div before generating the graph.
I tried a solution in which I eliminated the initial display: none from the CSS for each popup div. I also eliminated the background-color and border style elements, effectively making these divs invisible. Then some simple jQuery generates the graphs and does the proper CSS styling for these popups (setting the background-color, border, etc.). This works, functionally. The graph labels are now correctly positioned. But it's slow. It easily triples the loading time of the page, which is unacceptable.
Simply adding display: none back into the initial CSS for the popup divs solves all the performance problems. So the jQuery code itself cannot be the bottleneck. But that of course causes the label formatting to be messed up again.
Does anybody know how to overcome this issue?
As you discovered, Flot must draw into a div that's attached to the DOM. I can't say for sure without an example, but I would guess that your slow performance is probably due to the fact that the divs, even if they have no content, are still on-screen, and so you're triggering a redraw whenever you change them.
Instead of hiding the background and border, simply absolute-position the div far off-screen, e.g. top:-9999px; left:-9999px. That way it's still in layout, so Flot can make its measurements, but the browser is smart enough not to redraw something off-screen.
I've solved the problem by just deferring the generation of each graph until the initial corresponding mouse hover event is fired. I also had to initially set the z-index of the containing divs to be -1 and then change this to 1 upon generation of the graph; otherwise the invisible div would "cover up" other page content, making it impossible to, say, click on links "behind" the div before the graph was generated.
Related
I've came across wunderlist.com site and just fell in love with the zoom-like pop-up they have on the image just beneath the header "Learn more about Wunderlist".
I'd love to implement something like this on my site.
Can somebody tell me how this is done? I tried to reverse-engineer, but with no luck :)
I'm not hoping for the whole ready code, but maybe some guidelines on how to achieve this with CSS/jQuery.
Or maybe you know some jQuery plugin that I could use?
They are using all CSS. Pretty simple really.. I would code a full js fiddle example for you but I don't have the time, so instead I will list out the different elements you need and how they interact.
First the large image is just a div with a background image with set
dimensions.
The circular images themselves are generated from one large image containing all of the circles in one spot, this is called a sprite. The circles are just div's with background images and background positioning to position the correct circle inside the box from the sprite image.
The text boxes themselves are also div's with a standard H2 and P tags for the text.
Everything is absolute positioned in order to achieve the proper layout.
The small circles are div's with :hover states that are absolute positioned over their respective targeted areas.
The animation on :hover is achieved by the use of css3 transition and css3 transforms.
This should get you started.
Comment if you have questions.
Had some time to have some fun: http://khill.mhostiuckproductions.com/siteLSSBoilerPlate/fun-experiment-mh/
Try looking at two main aspects:
Open up your inspector tool of choice and look at what happens to body.login .feature
...more specifically, look at what happens to its transform: scale and opacity values upon :hover.
Hint: the transition is mainly on them.
Still in your inspector, change the scale to (1) and the opacity to 1. How it smoothly gets from one state to the other is dictated by the transition property.
This isn't meant to tell you exactly how to achieve it, but to get you on your way :)
It's not that hard actually. The Wunderlist team has even made it easier. They have a large sprite image with the zoomed images cropped and ready with rounded corners, borders and shadows. You can see it here: https://wunderlist2.s3.amazonaws.com/179510ff7c929bfcc6e9819f3c2539baca5d3325/images/welcome-screen.png
What you do is on mouseover you show a half transparent black background (can be position: fixed with full width and height). Then you create a element with the sprite as the background image (even better, have a class ready in your css and append it to your newly created element). Set position to the position of the hovered element.
When added to the dom animate the transform scale of the element (starting with something like scale(.24) as they do).
Well since you tried reverse engineering. I'll try and guide you along that path.
There is only one div with id overlay which is changes it's place & content, on hover of any div with class feature. Work your way further from their app js, it's not minified.
The content of the popup in this case is an image moved to different positions.
I have this problem where I am trying to show multiple graphs (based on jsPlumb) on a single page. Since I want each graph to be side by side on one row no matter how much space is available I am using a table (if I used divs with float:left, if not enough space is available some of the divs move down on a separate row).
Now each table cell contains a main div which in turn contains two or more node-divs. The way jsPlumb works is by creating a separate div for each node. I need to position each node at a particular top/left relative to its parent div.
The problem I have is that the main graphDiv in each table cell does not expand to fit its content. Some of the graph-node divs are outside of it. I understand that when you have "absolute" positioned divs they are not taken into account. But I am using "relative" positioned divs with top/left coordinates. Does the same thing apply?
If so, what would be the best way for me to expand the table-cell/graphDiv to cover its content? (i have tried all the clear fixes and went thru all stack-overflow related posts but could not find a solution).
Here is a link to the jsfiddle page I set up: http://jsfiddle.net/7QkB2/28/
I'm a little rusty but I share your pain in trying to get divs to properly expand to contain their contents.
As explained by this page http://reference.sitepoint.com/css/relativepositioning when you use relative positioning you're actually leaving behind a hole where the content used to be. I'd think of it almost as an optical illusion - The object is still reserving an invisible block in its old position, but it appears as if it has moved.
So in your case, the 3 nodes are still stacked in the upper left corner of the graph even though they look like they're floating outside of it. If you get rid of all the absolute and relative positioning on the nodes you'll see the table is sized to be big enough to fit their original positions.
I'd recommend usually only using position relative if you're only moving your content by a few pixels. Why they designed the css to work this way is a mystery to me, but maybe its something to do with the limitations of the rendering engines? When you use position absolute the object no longer has a "box" taking up space in the document. It's easy to position, but won't affect the spacing of anything else as you observed.
I'm not sure your exact application, but you may need to get creative with how you specify the spacing. If you know the dimensions you can always specify them, but I'm guessing you're not that lucky. Do you really want to set the position relative to the top-left corner, or just relative to the other nodes? I'd probably just use old-fashioned margins. That should allow you to specify the positions of the content that needs to fit in the table while maintaining the block model. Then if you need one of the nodes to overlap, position it using absolute positioning.
Have you tried displaying each div as an inline-block and turning off line wrapping on the enclosing div? You don't have to resort to tables if you want content with a dynamic width to display horizontally without wrapping.
div.graph {
display: inline-block;
}
div.graph-container {
white-space: nowrap;
}
For example; if I had a flot canvas graph and I wanted to be able to view a closeup of one of the areas, I want to be able to zoom into a specific area and have a scrollbar appear for horizontal and vertical panning so every section can be viewed. Is this possible?
You may want to use the zoom CSS property. Here is a little example of it in action.
As for the scroll bars, you could try placing the zoomed element within a parent which has overflow: scroll; set.
I hope this helps.
Anything is possible, but flot doesn't support that by itself. Your best bet would be to use the panning and zooming functions built into flot (via the navigate plugin), but then for the scrollbars, you might have to overlay some fake scrollbars (perhaps using a div with overflow:scroll, as #Wolfy87 suggested) and hook them up to the flot graph.
Flot triggers plotpan and plotzoom events when the graph has moved, so you would use them to keep your scrollbars in sync.
I haven't seen anyone do this before, so I can't point you towards an example. But the code doesn't seem unreasonable to put together.
I am building an Webpage that uses SVG, Canvas and, of course, HTML. The idea of this page is to animate the redrawing of some of svg-paths on the canvas. The paths I like to redraw are annotated with an namespace Attribute, all other paths are just displayed as they are. That is all working fine! The performance leak appeared the last two hours while I was adding some content to the page.
But at first a little illustration of the page setup:
The SVG and the Canvas are both 4000 * 4000 px wide and lie directly over each other in one container div. Going from one "page" to another means to tween the upper left edge of this container. This was also working fine since the discussion of inserting text turned in the direction of using html div container, instead of the svg itself.
So i inserted a third container div in which all the texts are stored and after svg is loaded they are positioned absolutly.
With every div I added the "pan-tween" and even the drawing performance decreased to a Point that is just too low.
I am searching for way to bring the performance back to a level that is acceptable for the user. One of my ideas is to set text divs to display : none, or visibility : hidden, as long as they are not displayed actually. Another option is to tween only svg and canvas, after this is finished placing the text-div-container in one step. But I am currently not sure which solution is better, or if there isn't something much better. So if anybody has an Idea, please let me know.
Thanks for reading!
Greetings Philipp
Try to pan the outer "text div" in intervals(say 10ms or 50ms). I this with a lot with rendering, in HTML usually I use greater values like 100ms or 150ms(I use to do this with canvas).
Didn't understand if you pan the outer div or all the "text divs".
I tried googling, but didn't come up with much. I'm building a horizontal carousel which displays images in a LI, floated. The issue I want to solve is, everytime I add thumbnails to the carousel (I'm lazy loading), I need to recalculate the width of the carousel (so that all the floated thumbnails line up nicely side by side).
For one, I rather not have to do these kinds of calculations in JS, and for two, I found that it's hard to find a cross browser way to ensure that the width will be properly calculated (I end up having to add or remove pixels from the total width depending on the browser).
So my question is, is there any way without JS, to be able to add content to a div, and have the width adjust as needed, the same way a div's height would?
And if not, have you found a more efficient way to handle this scenario than recalculating the width every time?
I'm not new to web dev, and for as long as I've been in this field, to my knowledge this has never been possible. But with the advent of new technologies cropping up, I thought maybe there was an obscure way of achieving this now.
Thanks in advance!
[EDIT] (for clarification, but simplified): If my carousel is 500px wide with overflow hidden. There's a slideable section containing thumbnails, each is 100px wide, floated, they fit 5 across in the carousel. When a user clicks Next, it lazy loads the next set of 5 thumbnails, and appends it to the slider area after the first set of 5. But since this div was 500px wide to accommodate 5 thumbnails, adding another 5, I need to recalculate the width to get the new thumbnails to show up side by side. Ideally I'd like to find a way to have the div autoresize its width to fit horizontal content, the same way it naturally does for vertical content.
I've found that using a containing carousel div with white-space: nowrap and overflow: hidden has worked. I then have display: inline-block for each item in the div.
Using this class for each individual item:
.eachItem {
display: inline-block;
}
Will work (I've done something similar to that).
The problem is that in IE7 it won't work! and you'll have to use JavaScript anyway :(
EDIT: I meant inline-block... and as you may know, IE7 doesn't "like" it.