SVG text disappears on larger label - css

I am using Morris.js for making charts. Morris.js uses SVG to draw the graphs. I have set up a JSbin here: JSbin example
Morris.js uses Raphael to draw the svg graphs. The issue is with the labels on the X-Axis. They disappear when the size of labels is too large. I tinkered around with the size of the div element holding the graph and font size of the labels but since the labels are dynamically generated for various users I cannot decide on a fixed value. An ideal solution would be to have the text wrapped up. What can be done to counter the situation?
Morris.js uses the following snippet to make the text svg element.
this.raphael.text(xPos, yPos, text).attr('font-size', '11').attr('font-family', 'calibri').attr('fill', this.options.gridTextColor);

It seems raphael supports multiline strings by putting "\n" in the text. This could be a cheap solution for you, systematically replacing " " by "\n" in your labels.
The other (more tricky) solution would be to replace the "text" element in the SVG generated by raphael by a foreign element that allows word wrapping:
<foreignObject x="20" y="10" width="150" height="200">
<p xmlns="http://www.w3.org/1999/xhtml">Wrapping text using some foreignObject in SVG!</p>
</foreignObject>
or if you need a fallback:
<switch>
<foreignObject x="160" y="10" width="150" height="200"><p xmlns="http://www.w3.org/1999/xhtml">Wrapping text using some foreignObject in SVG!</p></foreignObject>
<text x="20" y="20">Your SVG viewer cannot display html.</text>
</switch>
I don't know the best way to do this replacement of "text" by a foreign object: either after the Morris rendering or by hacking Morris/Raphael.

I think the problem definition need more clarification,
at my end the code you have sent works fine, also I have replicated the same in JSFIDDLE that is also working fine..
I think the label problem is done automatically as I have tested the default size you have kept was carrying width 385px when looking in to CSS and 518px when looking the same, in both case the rendered labels were different, in-fact the label exceeding certain width were not rendered. SO there is no meaning to set style and override.
I think the things are built in library. So its a long way to go, or change the library.
let me know which will be convenient way, I will help you accordingly :)
Edit:
However, you can change property of GridTextSize: that is 16 by default
Fiddle2 here I have updated
'gridTextSize:8' that displays all text in size 8.
Not perfect but will do :)

Download not minimized morris.js from there. In zip-archive you can find a file morris.js. Open it in edit mode and change value of default label angle parameter (line 133):
133 | xLabelAngle: 90,//original value 0
Now, if you really need it minimized, you can compress file by any online js compress tool.

Related

How to float text around image in react native

I am trying to achieve a very common effect in react native of having text wrap around an image. On the web you would assign a float property to the image and follow it with a p tag. .
Here is a RNPlay example I've been working on. I think the method I currently have is a bit hackish, and doesn't properly work since the text does not align with the top of the image and flow down. Is there a proper and clean way to accomplish this?
You can use a Text as container instead of the typical View.
<Text style={{flex: 1}}>
<Image source={Images.IconExplore} style={{ width: 16, height: 16 }} />
<Text> Your past has been in control for far too long. It's time to shift to a higher expression of what you are capable of so you can create the life you want to live.</Text>
</Text>
Unfortunately, there is still no easy way to do it, even after the introduction of nested Views inside Text. Surprisingly in the iOS community this seems to be non-trivial.
iphone - How to implement the effect of "float" for image, just like in CSS style
https://github.com/Cocoanetics/DTCoreText/issues/438
One idea that comes to mind that would be worth tinkering around with is measuring the text, dimensions and/or character count, and depending on the size of the image, divide the text into two Text components, one that goes to the right/left and the other that goes below the image.
There is this under-promoted React Native library that might help, which allows you to measure the width and height of a Text component based on its content:
https://github.com/alinz/react-native-swiss-knife/blob/master/lib/text/index.ios.js

SVG styling of text with NVD3 library

I have created a very simple chart with NVD3.js as can be seen on this fiddle.
The problem lies with the title (text in the middle) which consists of a number and a symbol (%).
I need both those parts to be styled separate but this seems to be a real pain.
I have discovered I can only style an SVG through inline style tags so I already applied :
<div id="svgDiv"><svg id="test2" fill='#58B957' letter-spacing='-3px'></svg></div>
to get the color and spacing right. Now I still need the %-symbol to be a lot smaller than the number. Which I can't apply to the full svg, because this would make everything smaller.
I have tried all manners of adding classes, id's, wrapping them in tspan's etc; yet I can't figure it out.
Please tell me there's a straightforward solution for this?
I dont think there is a direct way in nvd3 but you can do this trick to empty the text and fill with tspan.
var text1 = d3.select(".nv-pie-title").text("");//get the title clear it
text1.append("tspan").attr("class", "number").text("85")//make first tspan
text1.append("tspan").attr("class", "percent").text("%")//make second tspan
working code here

How do I scale a group of text tags relative to the size of a page?

I've been messing with this for weeks, so I'm just gonna flat out ask how to do it.
I've been working on a little SVG countdown clock just for the hell of it. But when I try and position things relative to how the page might be sized, I get stuck. I can't seem to size text tags relative to the page, and I can't find a way to put them into a group for sizing.
I've tried putting them into symbol tags, and using viewBox, but I can't seem to get that to work either.
My intended goal is to have this working on any sized screen from monitors to smartphones. So I wanted to do something with a min, and max width/height, or something along those lines, and apply it to a combination of the number and it's associated label. So I would have one group for days with both the number of days(being changed by the script), and then the word "days" underneath it.
Here is what I'm working with if it helps:
http://jsfiddle.net/2P9qV/
Does anyone have any ideas? I've been stumped for weeks.
Ok, so I finally figured it out. Luckily, I was able to use multiple SVGs within an SVG to create content, and then display it using use tags.
So I had each set as part of it's own symbol in defs. From there, I used the viewBox on the symbol tag to limit the draw space to the exact width and height of the content created, which I found by inspecting the element, and using the height and width it had been made as(without the 'px'). This way, I could center the whole set in the SVG that had the use tag, then set the width of the SVG to 100%, and the height to the percentage I wanted to scale it to. Since these are set as percentages, the page will limit the SVG's size to whichever is most limiting, while still maintaining scale, so it won't skew.
So one of the symbols would be:
<symbol id="daysSymbol" viewBox="0 0 110 156">
<g>
<text id="days" y="0" x="50%" font-size="100" class="time big">00</text>
<text id="daysT" y="100" x="50%" font-size="40" class="text bigText">DAYS</text>
</g>
</symbol>
and the SVG for this would be
<svg id="daysSVG" height="50%" width="100%" y="30%">
<use xlink:href="#daysSymbol" height="100%"/>
</svg>
It also let me get creative with how I managed the contents on the page. As something happened, I was able to dynamically remove content, and scale other elements to take up the new space.
For those curious, here is the final product
https://hostr.co/file/PLCY7lodb7Lk/xboxCountdown.svg
It won't last for that long, since it was a countdown clock. But I won't take it down(as long as it doesn't get automatically deleted), and if you wanted to see how it worked, you cold just download it and change the date it counted down to.

Background color of tspan element

Is it possible to give SVG <tspan> element background color? If not, what would be the best way to simulate it?
My goal is to give text background color, and I figured that filling <tspan> elements would be perfect — they already "outline" text chunks (<tspan> elements) that represent lines in multiline text.
The example I'm working with:
<text x="100" y="100" font-size="30">
<tspan>hello</tspan>
<tspan x="100" dy="1.2em">world</tspan>
</text>
I tried "fill" attribute but it seems to affect fill (color) of text, not the area behind it:
<tspan fill="yellow">hello</tspan>
I also tried setting background-color via CSS:
<style type="text/css">tspan { background-color: yellow }</tspan>
..but that doesn't work (in at least Chrome 17 and Firefox 12).
Wrapping tspan in <g> (or text itself in <g>) with "fill" doesn't work either:
<g fill="yellow"><tspan>hello</tspan></g>
<tspan><g fill="yellow">hello</g></tspan>
Aside from creating a <rect> element positioned at the same location — something I'd like to avoid — is there another way to achieve this?
A rect is probably the best way to do that (assuming you are only dealing with the simplest forms of text).
The tspans have no "background" themselves in SVG 1.1, the background is whatever gets painted before the tspan. There are many cases to consider, such as the case where a tspan is inside a textPath that has the shape of a circle. Also note that it's not as simple as a continous rectangle in all cases, a single tspan can be skewed, rotated and partitioned into several intersecting and non-intersecting shapes due to transforms, glyph positioning, etc.
There's another way I can think of that would do this without scripting, but then you'd need to know the width of the string in advance (e.g by using a monospaced font). If you have that then you can add another tspan element using the Ahem font, placing it before the other tspan in the document and giving it the same x,y position as the tspan you want to give a "background".
Otherwise the way to do this is through scripting, and adding rectangles (or tspans with an Ahem-like font).
SVG does not support directly specifying an image background color...but you can adjust the four values of the viewBox attribute (complicated). I know it's something you want to avoid, but CSS wouldn't help you.
...or you can use getBBox and getCTM...it would give you advantages for rotated text.
EXAMPLE:
http://srufaculty.sru.edu/david.dailey/svg/getCTM.svg

Flex custom button component

I want my custom button to look like the button sample below.
More specifically, I want the width of the button to be determined by the width of the largest word in the label (i.e. width of "Elongated" in my example). The label must wrap, not truncate.
And I want only one pixel between the top edge of the icon and my button's top edge.
I have tried lots of things but to no avail so far. I have reduced the horizontalGap and verticalGap to zero and padding to zero. But still nothing. Please help.
Here's what I have right now:
<mx:Button top="0" cornerRadius="2" paddingLeft="0" paddingRight="0" leading="0" letterSpacing="0" paddingTop="0" paddingBottom="0" verticalGap="0" horizontalGap="0" textAlign="center" labelPlacement="bottom" icon="{MyIcon}" height="60" width="75" label="Elongated Label" fontSize="10" />
That's not at all simple.
You will need to create your own button,
public class Mybutton extends Button {...}
override createChildren and set the word wrap of the IUITextField used for the label to true.
override measure and use your own line metrics to determine the width that the button should be. If you get the measure right, the button will lay itself out properly.
I don't have a dev environment in front of me at the moment, but something along these lines should work:
Set truncateToFit property of the Label to false (OR use a TextField with wordWrap set to true - I think this should keep the words together as much as possible).
I haven't had the need to use any of the above yet, and hopefully you haven't tried them yet because it would be an easy solution to a part of your problem. Without any code, I'm not sure why padding didn't work, but maybe it's something to do with the word truncation.
As an alternative, why not use a Button, embed or specify a source for your icon and decide where to place the text by specifying the object's labelPlacement property?
EDIT: Since there's no property in Button about wordWrap, as they would recommend in the Adobe Flex forums for such questions regarding sizing based on content where there is no automatic feature to do that, you have to find the longest word and adjust the width of the button (i.e.: in the creationComplete event). Experimenting to find the font to pixel ratio would be my best bet (or you can use a Monospace font where all the characters are given the same space thereby simplifying the estimation):
creationComplete="event.target.width=returnMyWidth();"
As for the padding, it may be related to the custom width that you had set or it may be from embedding the image automatically setting a padding by being included - I'm not really sure, so it would be good if someone can offer a comment based on experience with this.

Resources