I am implementing an Angular component which has many little areas where user can click.
I see 2 ways how to do it:
use background image and define map areas where user can click, add click handler on the image.
use div for each clickable part and attach the click handler to parent element (so I don't have many click handlers on each div). Use the CSS to style each div so it looks like the image in 1.
The problem with 1. is that when the image changes I have to change the map coordinates too.
The advantage here is that it should work without problem in many browsers.
The advantage of the 2. is that I can style the component as I need (so it can be smaller, bigger, different font, etc.), but it can have performance impact when I need to show more than one such component.
Which way would you choose and why? Or are there any other possibilities?
Edit:
forgot to mention that the component should also work on mobile devices
I don't remember where but i just read a nice article about:
div(webkit-transform) vs svg vs canvas
To make it simple:
1-50 elements = divs & images
50-500 elements = svg
500 and more elements = canvas
this are here just to give you an idea ...then everything depends on every element and device.
Canvas would be the best solution for everything.
The problem on canvas is the click handler.You need to create a collision detection script.
(i used a canvas with a background image(worldmap),to show the dots in real time of the current users.).but it's not clickable... (there is a clickable legend under/over the map)
SVG is prbably the best solution in your case
like #mainguy said u can draw stuff and add eventHandlers (or one like on the parent element).and the performance is better than divs.
DIVS
Most of the time i use div sets with one eventhanlder. they are so easy to use and style.. but only squares or circles.. and if you start to style them you loose alot performance (box-shadow..).
If you don't style the divs you can use alot of them.Especially if you put the eventhandler on the parentNode.
that way you can handle 1000's of elements without problems.(but don't use position:absolute)
Image Map
Again ... if there are not too many elements this is prolly also a good solution.. the simplest ... (the simplest way to draw your simple shapes).As soon you have you static MAP values you can then transform your imagesize recalculation the map with the ratio.. so thats not a problem.
I would go for the image map if there are not to many elements.
else SVG.
Everything depends on how many elements you have.
is that when the image changes I have to change the map coordinates too
if you use divs you don't have to change coords?
** Mobile devices support more than ie browsers.
I would do this with a SVG library which are fast, easy to style and suporrted by most browsers.
D3.js
is available for Angular as directive. Have not worked with his one yet. But it seems to be very popular. Just look on their homepage for a WOW! effect.
Raphaël JS
Was used by me in many projects. It has the big advantage that it supports even old IEs (sic!).
Just make a search for Angular SVG and/or JS and you will find a lot of solutions.
Not knowing the exact requirements, my default choice would be 2.
There are drawbacks, such us inability to easily map non-rectangular areas. The advantages however are huge, including easy maintenance, possible responsiveness, more robust styling possibilities and more.
The sole amount of divs shouldn't cause any problems and I wouldn't worry about it.
There are cases in which I would look for different implementation, though.
Related
I'm developing a D3 application that utilizes a lot of text. Since there is alot of text elements, panning around using D3 zoom causes some lag. Is there a way in which I can improve the performance of my application? I'm happy to hear any suggestions, you guys might have. I've been thinking about paginating my data and detecting pan events but my UI is very complex and the user has the freedom of placing things the way he wants so I am not sure how to go about implementing a pan/pagination solution.
Such an open question is bound to get very opinion-based answers, and without more context you're also bound to get some useless ones, but here you go: it depends on what you want and what you mean by "a significant amount".
Supposing that significant amount is > 1000 elements, consider using canvas instead of SVG. Sure, if you can click on individual text nodes, that's more of a hassle, but it should be really good at panning/zooming.
If that is not possible, look at your code. Are you repositioning all text nodes individually? If so, place them all inside one g node and give that node a transform and zoom. In other words, make that node responsible for all global movement, and place the text nodes only relative to each other.
If that is also not possible, consider removing text nodes if they're outside the bounds of the SVG. Repositioning invisible nodes takes a lot of computation power, be smart about it. This is probably the most complex solution, so try it last.
I'm pretty new to event-handling inside svgs and there is a little weirdness happening here. I'm doing an infovis where I build an interface and want to display different column-graphs.
That's rather easy and working pretty nicely.
But I'm using hover-events to show the actual numbers when hovering a rect. it works with the one chart I'm generating first. But even though that chart is hidden (I tried both: visibility: hidden and display: none properties) the one that's drawn first still gets the event.
Do I need to remove that one completely in order to generate a new one? So should I better work with separate SVGs and have an external interface, hiding the different svgs?
Any advice/best-practice would be welcome!
Thanks already!
Suse
The other way of hiding things is to push them off the screen, as with hidden iframes. Just give them a negative x/y position. That should take care of mouse-over issues.
How would I create a DIV containing an IMG where the DIV cuts the image into a triangle, thereby displaying only part of the image though a triangle.
so..
<div>
<img src='some_image' />
</div>
Where the image is a square, but the DIV containing the image is a triangle.
http://www.script-tutorials.com/creating-kaleidoscope-using-jquery-and-css/ solves this very well except this solution is not x-browser friendly (non-ie).
http://css3pie.com/ looks interesting, however this relies on PHP.
You can't create a non-rectangular DOM element.
There are a few ways to hack it.
Firstly, there is a method of using CSS borders with varying widths on each side of the element to make it look triangular. It will still be a rectangle, but it will look like a triangle.
There's a tutorial on this here: http://www.russellheimlich.com/blog/pure-css-shapes-triangles-delicious-logo-and-hearts/
The down-side of this approach is that it is limited to creating right-angled triangles. You can join several of them together to get around this, but then you don't have a single container for your image.
An alternative hacky way of doing it would be to place rotated elements on top of the main element so that they cover the appropriate parts of the image and make it look triangular. This works in all browsers, although IE does have some very nasty syntax to do rotation, and it's quite heavy on the browser, considering that you'd only be using it to make shapes.
Another option might be to use CSS transforms. However this is only supported by a minority of up-to-date browsers, so it won't work for most users.
A better approach might be to use a proper graphics library for this, rather than trying to shoe-horn it into a <div> element.
I'd recommend using Raphael. It's a Javascript library which can draw directly into the browser using SVG (or VML for IE). It's trivial to create triangles using it and to fill them with a graphic. See the examples on the Raphael home page to get you started.
Depending on what you want the outcome to be, as far as i'm aware you cant make a triangle DIV without Transform:; However one solution would be having a div positioned inside the div in question with a PNG cutting of half the image showing only the transparent part through. Not sure if this is a viable option for you though.
The 2nd part of the question is, which javascript library is better/easier to manipulate images with? I won't be actually drawing any shapes or anything. Other info: I'll be using jQuery and don't need to support all browsers, just webkit.
Edit:
More information: the current design is to layout/draw several rows/columns of images in a grid-like layout, with the image in the center being in "focus" (a little larger, with a border or something and some text next to it). The tricky thing is that we want the whole canvas of images to appear to slide/glide over to bring another random image into focus. So obviously the number of images in this grid needs to exceed what is visible in the viewport so that when the transition occurs there are always images occupying the canvas. Other than moving the images around, I won't be blurring them or otherwise modifying them. Eventually we will add user interactions like clicking/touching on a visible image to bring it to focus manually.
Let me know if this is not clear or still confusing.
I ran across scripty2 which seems like an alternative to using canvas/SVG for my purposes. I also started farting around with EaselJS last night, and it seems like this might work, but I'm wondering if it'll end up being more work/complex than just using standard HTML/CSS and a tool like Scripty2 to aid with animations and click/touch events. Just looking for any suggestions. Thanks!
The answer depends on your manipulation and animation.
If it's just translations, CSS wins for speed compared to canvas. I haven't tested, but I feel confident it easily beats SVG for the same sort of thing.
If you're going to be doing non-affine transformations or otherwise messing with the images (e.g. blurring them) you clearly want Canvas.
If you need event handlers per object, you clearly want a retained-mode drawing system like SVG or HTML+CSS. I haven't done enough CSS3 transforms to say how they compare in terms of speed to SVG, but they clearly do not have the robust transformation DOM of SVG.
This is a rather subjective question (or suite of questions) and you haven't yet given sufficient information for a clear answer to be possible.
Generally speaking - is it possible to draw with javascript two diagonal lines inside of a specific div on a website? It should basically look like a placeholder image … e.g. http://wightwildflowers.com/assets/images/placeholder.png
I'm just curious. If it's possible how would it be done?
You could add tags for each specific div with the correct size to your DOM and link the image. It will be a bit distorted.
OTO you can also try to create a canvas over each such div and draw the lines there.
there isn't a good native way to do this. the only pure javascript solution is to build a 2d array of some html element (table cells or divs or whatever) and treat them as pixels, coloring specific cells.
providing/generating an image is probably a good alternative.
the next option is using something like raphaeljs to generate browser supported vector images. this should work fairly reliably but adds a lot of weight to your page to draw two lines.
Is it reasonable to dynamically add and size the placeholder image you just showed? That might be your best bet.
You could also try working with the canvas element.