indus / VLEX

Vector Layout Expressions
Other
322 stars 21 forks source link

add example for text #1

Open pajooh opened 10 years ago

pajooh commented 10 years ago

a common use case for svg responsiveness, is to have mixed text-graph SVGs. in my case, i'm using highcharts, and i have resizable panels (chart containers). i want to make texts bigger as the chart size grows (for better readability), and the non text element just scale to fit the new size

keep up the good work :+1:

indus commented 10 years ago

Hey - the first interaction :smile: Sooo let me see if I can help you.

First of all: Text in SVG is allways tricky!

But: The following is a quick shot that adresses your problem:

// put this in one of the examples
<text text-anchor="middle" vlex="x:{$cX};y:{$cY};font-size:{$x/20};bBoxProxy:{$bbox = $$getBBox()}">some Text</text>
<rect style="fill:transparent;stroke:#000" vlex="x:{$bbox.x-10};y:{$bbox.y-10};width:{$bbox.width+20};height:{$bbox.height+20};">some Text</rect>
// a centered text sourrounded by a rect with 10px padding

there is an undocumented $-property, named '$$' that gives access to the DOM-node. You can call in a vlexpression '$$getBBox()' and get an SVGRect of that element with its x,y,width and height. In the text-node I just used a fictional attribute called 'bBoxProxy' to run a vlexpression and added a property 'bbox' to $ to store the value (maybe we need a special key for stuff that is not used as an native attribute only). In the rect node I reused all the values from 'bbox' and added some padding.

A problem is the fixed z-ordering in SVGs. As you can see the rect has to follow the text. With an opaque rect the text will be hidden. I think we need something like a "pre-update and post-update" to compute values at nodes used by other nodes. In the moment you can work with use elements to rearrange the nodes in the DOM-tree. Put the text-node in a def-node and reference it with a use-element after the rect-element.

Finding a better flexpression for 'font-size' is up to you. Maybe you want some fixed breakingpoints; something like

($x<920)?(($x<600)?8:10):12 // untested

If you have suggestions for syntax that deals with problems mentioned above, you are welcome to make suggestions (in another issue)