In the previous installment, a foundation was laid for “parameterizing” fonts, colors and overall slopegraph size. However, a big failing in all this code (up until now) was the reliance on character string length to determine label width. When working with fonts, the font metrics are more important since a lowercase ‘l’ will have a smaller font width than an uppercase ‘D’. So, while ‘llll’ is “longer” than ‘DDD’, it may not be wider (especially in a sans-serif font, but likely in any font):
To solve this problem, we need to use a temporary Cairo surface to compute font metrics for each label & value so we know what the maximum width of both for the starting and ending points. It’s a simple concept & calculation, but very important to ensure everything lines up well.
# find the *real* maximum label width (not just based on number of chars)
maxLabelWidth = 0
maxNumWidth = 0
for k in sorted(startKeys):
s1 = starts[k]
xbearing, ybearing, sWidth, sHeight, xadvance, yadvance = (cr.text_extents(s1))
if (sWidth > maxLabelWidth) : maxLabelWidth = sWidth
xbearing, ybearing, startMaxLabelWidth, startMaxLabelHeight, xadvance, yadvance = (cr.text_extents(str(k)))
if (startMaxLabelWidth > maxNumWidth) : maxNumWidth = startMaxLabelWidth
sWidth = maxLabelWidth
startMaxLabelWidth = maxNumWidth
maxWidth = 0
maxNumWidth = 0
for k in sorted(endKeys):
e1 = ends[k]
xbearing, ybearing, eWidth, eHeight, xadvance, yadvance = (cr.text_extents(e1))
if (eWidth > maxLabelWidth) : maxLabelWidth = eWidth
xbearing, ybearing, endMaxLabelWidth, endMaxLabelHeight, xadvance, yadvance = (cr.text_extents(str(k)))
if (endMaxLabelWidth > maxNumWidth) : maxNumWidth = endMaxLabelWidth
eWidth = maxLabelWidth
endMaxLabelWidth = maxNumWidth
I tossed some “anomalies” into the sample data set to show both how adaptable the vertical scale is as well as demonstrate the label alignments:
Updates are in github.