# charts.layout Three pieces of chart layout that have nothing to do with the data: where the plot goes, where the legend items go, and which labels to leave out so none overlap. Pixels in, pixels out, rounded to 2 decimal places by `math.round-float`, the same in every language. This is a group; install only what you use, e.g. `require charts.layout ^1.0.0 only=plotArea`. ## plotArea The d3 margin convention: the chart is `width` by `height`, the margins are taken off each side, and what is left is where the data is drawn. `x` and `y` are its top-left corner (the left and top margins). Margins that leave no width or height are an error, since a zero or negative plot area either draws nothing or draws the data mirrored; negative margins are an error too. ## legendRows Places legend entries left to right, each a colour swatch, 4 pixels, then the label, with `gap` between entries, wrapping to a new row when the next entry would pass `maxWidth`. An entry that ends exactly at `maxWidth` stays on the row. An entry wider than the whole legend is placed on a row of its own rather than leaving an empty row before it. Row `r` has its top at `r x rowHeight`; offset the whole legend wherever it belongs. Nothing here can measure text, so a label's width is estimated as its number of characters (Unicode code points, so "Café" is 4, not its 5 UTF-8 bytes) times `charWidth`. About 0.55-0.6 of the font size suits common sans-serif fonts (7 for 12px); a renderer with real metrics can pass its own average. The estimate is deliberately simple so every language places the legend the same. ## avoidCollisions Given label boxes, decides which to show so that no two overlap, greedily: the most important label first (higher `priority`, then earlier in the list), and each further label only if it is at least `padding` clear of every label already shown. Boxes that merely touch do not overlap. The answer is one flag per box, in input order. Greedy is not optimal (it can show fewer labels than the best possible choice), but it is predictable, fast and stable as data changes, and it always keeps the labels you rank highest, such as the first and last tick or the largest value. It does not move labels; to try alternative positions, pass each candidate as a box with a lower priority. 1.0.1 adds tests; behaviour unchanged.