Tweak last-dotplot's label placement
authorMartin C. Frith
Thu Nov 02 22:18:05 2017 +0900 (2017-11-02)
changeset 9012003b209d750
parent 900 5ce3e786e05a
child 902 db84a7e4ff8a
Tweak last-dotplot's label placement
scripts/last-dotplot
     1.1 --- a/scripts/last-dotplot	Thu Nov 02 22:08:14 2017 +0900
     1.2 +++ b/scripts/last-dotplot	Thu Nov 02 22:18:05 2017 +0900
     1.3 @@ -432,13 +432,25 @@
     1.4      for layer, color, box in boxes:
     1.5          im.paste(color, box)
     1.6  
     1.7 -def make_label(labelData, range_start, range_size):
     1.8 -    '''Return an axis label with endpoint & sort-order information.'''
     1.9 -    text, text_width, text_height = labelData
    1.10 -    label_start = range_start + (range_size - text_width) // 2
    1.11 -    label_end   = label_start + text_width
    1.12 -    sort_key    = text_width - range_size
    1.13 -    return sort_key, label_start, label_end, text, text_height
    1.14 +def placedLabels(labels, rangePixBegs, rangePixLens, beg, end):
    1.15 +    '''Return axis labels with endpoint & sort-order information.'''
    1.16 +    maxWidth = end - beg
    1.17 +    for i, j, k in zip(labels, rangePixBegs, rangePixLens):
    1.18 +        text, textWidth, textHeight = i
    1.19 +        if textWidth > maxWidth:
    1.20 +            continue
    1.21 +        labelBeg = j + (k - textWidth) // 2
    1.22 +        labelEnd = labelBeg + textWidth
    1.23 +        sortKey = textWidth - k
    1.24 +        if labelBeg < beg:
    1.25 +            labelBeg = beg
    1.26 +            labelEnd = beg + textWidth
    1.27 +            sortKey += maxWidth
    1.28 +        if labelEnd > end:
    1.29 +            labelEnd = end
    1.30 +            labelBeg = end - textWidth
    1.31 +            sortKey += maxWidth
    1.32 +        yield sortKey, labelBeg, labelEnd, text, textHeight
    1.33  
    1.34  def nonoverlappingLabels(labels, minPixTweenLabels):
    1.35      '''Get a subset of non-overlapping axis labels, greedily.'''
    1.36 @@ -450,15 +462,13 @@
    1.37              out.append(i)
    1.38      return out
    1.39  
    1.40 -def axisImage(labelData, rangePixBegs, rangePixLens, textRot,
    1.41 +def axisImage(labels, rangePixBegs, rangePixLens, textRot,
    1.42                textAln, font, image_mode, opts):
    1.43      '''Make an image of axis labels.'''
    1.44      beg = rangePixBegs[0]
    1.45      end = rangePixBegs[-1] + rangePixLens[-1]
    1.46 -    margin = max(i[2] for i in labelData)
    1.47 -    labels = map(make_label, labelData, rangePixBegs, rangePixLens)
    1.48 -    labels = [i for i in labels if i[1] >= beg and i[2] <= end]
    1.49 -    labels.sort()
    1.50 +    margin = max(i[2] for i in labels)
    1.51 +    labels = sorted(placedLabels(labels, rangePixBegs, rangePixLens, beg, end))
    1.52      minPixTweenLabels = 0 if textRot else opts.label_space
    1.53      labels = nonoverlappingLabels(labels, minPixTweenLabels)
    1.54      image_size = (margin, end) if textRot else (end, margin)