If I have several lines (blocks, polygons, whatever) spread about the canvas, and I want their stroke-width to remain the same even when I zoom in ...
for example, I have a graph of temperature vs time, and there is a little line on the time axis to mark each hour - so the distance between them increases as I zoom in, but I don't want them to get any thicker ...
Then I can provide an attribute vector-effect="non-scaling-stroke" for the t-axis object.
But suppose I have several texts ...
for example, every 24th hour has a date written beside it ...
then there seems to be no way to prevent the text from being stretched; i.e. I cannot provide an attribute text-effect="non-scaling-text" ...
In my example, I am only zooming in one dimension, and stretched-out text is ugly, and squashed-in text is unreadable.
Is there any workaround for this?
Here are more details, as requested.
I am drawing a graph on a canvas much wider than the viewing area (and which will get even wider if it gets zoomed). Sliders are provided so the viewer can pan and zoom to inspect any part of it in detail.
So there are two objects graphobj which comes from the application data and tlineobj which is the time axis, and which consists of a line the length of the canvas, with short vertical lines to mark off the hours and bigger ones to mark the start of each day. So each time the viewer alters a slider it obeys something like
tlineobj.setAttribute("transform", 'translate('+someamount+',0), 'scale('+someamount+',1)')
ans similarly for graphobj.
So I am stretching it out horizontally, but not vertically.
Now tlineobj is constructed by a Javascript routine. For simplicity, forget about names of days and months, and let us just write daynos in the proper places. So I write a function like:
Function doDate(i) {
dayno = some_model.cloneNode(false)
dayno.appendChild(document.createTextNode(i))
dayno.setAttribute("x", i*some_factor)
tlineobj.appendChild(dayno)
}
But now when the tlineobj gets zoomed, not only does the distance between the daynos get increased (which is what we want), but each dayno itself gets stretched out, because there is no way to tell the SVG zooming machanism not to do this (although there is such a mechanism to do it for vector objects).
The only way I can see to do it is to cause the whole of the tlineobj to be regenerated from scratch each time the graph is re-zoomed, and that seems a very kludgy way to so it (or I could go though all the dayno objects and change some attribute within them, but that is just as bad).
Related
I've an svg dynamically created on a page. As things "happen" (user clicks) the svg expands and collapses certain elements. It may fit in the viewport, it may not. In the case that its too big to fit on a page, the user must scroll to where s(he) wants to go/see. Now this is fine, however I have a requirement that the last element "selected" becomes the center of the page/viewport. i.e. If they click on an item, thats what they need to see without scrolling.
Could anybody tell me the best way to attack this. I've googled around but can't find what I'm looking for (though I'm not long at all this so I might have been searching the wrong stuff).
Is there a way to do this purely programmatically with javascript? Or am I obliged to pass by CSS to get the solution I want. Any tips/links/advice much appreciated.
thanks and have a nice day
G
I had a similar thing and I used the viewBox property to handle this. You could also use a wrapping <g> element, which you translate. However, from my point of view the basic approach is the same and you basically need to do two things:
keep track of the x and y offset and the dimensions of the viewport. (Using the viewBox will give you that »for free«)
Compute the center of the Element. Therefore I used the getBoundingClientRect()method which yields the AABB of of the Element in absolute coordinate space, relative to top-left edge of the whole page.
With these things, all that remains is to calculate the vector from the viewport center to the object's center.
Here you can find the reference of the viewBox and here a nice tutorial about it, because it can be a bit confusing at the beginning.
Another pro for the »viewBox« approach is: There is no dependency on special DOM elements, it just works on the root <svg> element. I once implemented both methods, I started out using a wrapping <g> element, what worked fine but gave me some performance issues. So I decided to change and use the viewBox, with the result, that the performance in Firefox grow, but slowed down in Chromium.
Edit
Here you can find a little fiddle, that outlines the approach. But be aware of the following: getBoundingClientRect() yields the position of the Element on the whole Page, so if your <svg> is not positioned at (0,0) (top: 0px; left: 0px), than that will include the offset of the svg itself. The offset of the viewBox must not include this offset, so you need to cancel that out somehow. For sake of simplicity I just used the client Bounding Rect of the SVG, what works because there are no transformations applied.
I have a chart show info of apps, but when run it on devices android. The position of text on chart not consistently.
These images illustrate the problem: https://drive.google.com/folderview?id=0B7-CxJHQ5ZnjYjVlTlFQdElWRGM&usp=sharing
I use TextLabelWidget in AndroidPlot. How to keep position of TextLabelWidget on chart with the same image1 in link above on devices?
The problem appears to be that your plot area is set to fill the width of the screen and since the bars are evenly distributed in that space, their x positions are essentially fractions of the screen width.
At the same time you have labels that appear to be positioned using absolute positioning. As an example, this code will position 4 labels at 0%, 25%, 50% and 75% screen width, 80 pixels down from the top of the screen:
txtWidget1.position(0, XLayoutStyle.RELATIVE_TO_LEFT, PixelUtils.dpToPix(80), YLayoutStyle.ABSOLUTE_FROM_TOP, AnchorPosition.LEFT_TOP);
txtWidget2.position(0.25f, XLayoutStyle.RELATIVE_TO_LEFT, PixelUtils.dpToPix(80), YLayoutStyle.ABSOLUTE_FROM_TOP, AnchorPosition.LEFT_TOP);
txtWidget3.position(0.50f, XLayoutStyle.RELATIVE_TO_LEFT, PixelUtils.dpToPix(80), YLayoutStyle.ABSOLUTE_FROM_TOP, AnchorPosition.LEFT_TOP);
txtWidget4.position(0.75f, XLayoutStyle.RELATIVE_TO_LEFT, PixelUtils.dpToPix(80), YLayoutStyle.ABSOLUTE_FROM_TOP, AnchorPosition.LEFT_TOP);
There are some other factors that you are also probably going to need to deal with such as bar width but this should get you closer. You may find this doc useful as far as a guide for the different positioning methods.
Another tool to consider using if you aren't using it already is the Configurator. This will let you set your positions etc. inside xml and override values based on screen size, orientation, etc.
I have a multiviewport OpenGL modeler application. It has three different viewports : perspective, front and top. Now I want to paint a label for each viewport and not succeeding in doing it.
What is the best way to print a label for each different perspective?
EDITED : The result
Here is the result of my attempt:
I don't understand why the perspective viewport label got scrambled like that. And, Actually I want to draw it in the upper left corner. How do I accomplished this, because I think it want 3D coordinate... is that right? Here is my code of drawing the label
glColor3f(1,0,0);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glRasterPos2f(0,0);
glPushAttrib(GL_LIST_BIT); // Pushes The Display List Bits
glListBase(base - 32); // Sets The Base Character to 32
glCallLists(strlen("Perspective"), GL_UNSIGNED_BYTE, "Perspective"); // Draws The Display List Textstrlen(label)
glPopAttrib();
I use the code from here http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=13
thanks
For each viewport switch into a projection that allows you to supply "viewport space" coordinates, disable depth testing (glDisable(GL_DEPTH_TEST)) and depth writes (glDepthMask(GL_FALSE)) and draw the text using one of the methods used to draw text in OpenGL (texture mapped fonts, rendering the full text into a texture drawing that one, draw glyphs as actual geometry).
Along with #datenwolf's excellent answer, I'd add just one bit of advice: rather than drawing the label in the viewport, it's usually easier (and often looks better) to draw the label just outside the viewport. This avoids the label covering anything in the viewport, and makes it easy to get nice, cleanly anti-aliased text (which you can normally do in OpenGL as well, but it's more difficult).
If you decide you need to draw the text inside the viewport anyway, I'll add just one minor detail to what #datenwolf said: since you generally do want your text anti-aliased (even if the rest of the picture isn't) you generally want to draw the label after all the other geometry of the picture itself. If you haven't turned on anti-aliasing otherwise, you generally will want to turn it on for drawing the text.
I am making a game in Cocos2d. I want there to be a dotted line that follows the user's finger. I want the line to be straight. The problem is, how do I check to see how many 'dots' will fit in the distance between the ball and where the user is touching? And make it follow in a STRAIGHT line between the ball's position and the finger's position? So here's a re-clarification:
The ball sits still on the left side of the screen, and is halfway up the screen. The user drags their finger, and a dotted line is drawn between the ball's position and the touch's position. I have a 'dot' image to be used, and I would like it to be used as the dots in the line. So it will have to recreate the sprite as many times as it will fit in the area between the two points. Please tell me if you want me to clarify further, Thanks!!
I would make a CCNode object called dottedLine or something.
The dot image would be a sprite that gets added as a child of the node (multiple times).
I would work out the path from ball to finger touch using Trigonometry/Pythagoras theorem.
For creating the line:
From point 0, the ball, i would add 15-20 pixels towards the touch point along the path, and place a dot, I'd repeat this until I reached the end of the line.
Every dot that was placed I would increment a counter, and set that number as the integer tag of that sprite for use in an update method.
Every time the cctouchesmoved method gets called, i'd call an update method on the dottedLine object.
This method would check the distance between the ball and touch point, divide it by the number of dots currently children of the object and remove or add any that are needed. Recreating the sprites every time you move your finger would be messy and wasteful, so reusing your dots and just setting them new positions as the path between ball and touch point changes would probably be best.
I'm not going to provide you code, i think i've explained more than enough of the working out for you to do some googling and work this out.
I've been stumbling over this for a while and was wondering if anyone has run into this problem before.
The application I'm working on is divided into multiple data plots and a single timeline at the bottom of the screen. Each plot (which is actually multiple textures layered on top of each other) as well as the timeline is rendered to a separate texture. The timeline texture is rendered first, followed by each of the plot textures from the top of the screen to the bottom. I am using DXUT and DirectX9 (March 2009).
After adding time text to the timeline texture, I noticed that the text was repeated in the title bar of every data plot. Here's a screencap of a portion of the display, it shows just a single plot, but the text repeats on every plot opened:
It seems like it is tied directly to the DrawText being called in the timeline's render function. I do use relative coordinates as the rect being passed to DrawText, but since I've already set the render target to the desired texture it should only affect the current texture. Not every texture rendered afterward.
Has anyone ever run into any problems similar to this using D3DXFont?
EDIT: After some more experimentation, it looks like it has something to do with the Z buffer. By adding D3DCLEAR_ZBUFFER to the clear on each texture surface, the duplicate text is gone. While the problem seems bypassed for now, I'm still curious as to why the Z buffer for a completely separate texture was being written during my DrawText call.
The Z Buffer state is persistent.
For example,
SetDepthStencilSurface(X)
SetRenderTarget(A)
Draw()
SetRenderTarget(B)
Draw()
Both Draw calls will use the same depth buffer.
The DrawText is not changing the depth buffer that you have set. It assumes you meant to do what you did.