@@ -62,53 +62,47 @@ abstract class LegendComponentLayout(
62
62
}
63
63
}
64
64
65
+ private fun indexToPosition (i : Int ): Pair <Int , Int > = if (isFillByRow) {
66
+ val row = i / colCount
67
+ val col = i % colCount
68
+ row to col
69
+ } else {
70
+ val col = i / rowCount
71
+ val row = i % rowCount
72
+ row to col
73
+ }
74
+
65
75
private fun doLayout () {
66
- val horizontalGap = PlotLabelSpecFactory .legendItem(theme).width(PlotLabelSpecFactory .DISTANCE_TO_LABEL_IN_CHARS )
67
- val intervalBetweenLabels = DoubleVector (horizontalGap, PlotLabelSpecFactory .legendItem(theme).height() / 3 )
68
-
69
- val contentOrigin = DoubleVector .ZERO
70
- var breakBoxBounds: DoubleRectangle ? = null
71
- for (i in breaks.indices) {
72
- val labelSize = labelSize(i).add(intervalBetweenLabels)
73
- val keySize = keySizes[i]
74
- val height = max(keySize.y, labelSize.y)
75
- val labelVOffset = keySize.y / 2
76
- val labelHOffset = keySize.x + horizontalGap / 2
77
- val breakBoxSize = DoubleVector (labelHOffset + labelSize.x, height)
78
- .let {
79
- // Not add a space for the last item in the row/column
80
- val xSpacing = if (i / rowCount != colCount - 1 ) {
81
- theme.keySpacing().x
82
- } else {
83
- 0.0
84
- }
85
- val ySpacing = if (i % rowCount != rowCount - 1 ) {
86
- theme.keySpacing().y
87
- } else {
88
- 0.0
89
- }
90
- it.add(DoubleVector (xSpacing, ySpacing))
91
- }
92
-
93
- breakBoxBounds = DoubleRectangle (
94
- breakBoxBounds?.let { breakBoxOrigin(i, it) } ? : contentOrigin,
95
- breakBoxSize
96
- )
76
+ val labelSpec = PlotLabelSpecFactory .legendItem(theme)
77
+ val keyLabelGap = labelSpec.width(PlotLabelSpecFactory .DISTANCE_TO_LABEL_IN_CHARS ) / 2.0
78
+ val defaultSpacing = DoubleVector (keyLabelGap, labelSpec.height() / 3.0 )
79
+ val spacingBetweenLabels = theme.keySpacing().add(defaultSpacing)
80
+
81
+ val colWidths = DoubleArray (colCount)
82
+ val rowHeights = DoubleArray (rowCount)
83
+
84
+ keySizes.forEachIndexed { i, keySize ->
85
+ val (row, col) = indexToPosition(i)
86
+ val labelSize = labelSize(i)
87
+ val labelOffset = DoubleVector (keySize.x + keyLabelGap, keySize.y / 2 )
88
+ myLabelBoxes + = DoubleRectangle (labelOffset, labelSize)
97
89
90
+ colWidths[col] = maxOf(colWidths[col], labelOffset.x + labelSize.x)
91
+ rowHeights[row] = maxOf(rowHeights[row], keySize.y, labelSize.y)
92
+ }
93
+
94
+ val colX = colWidths.runningFold(0.0 ) { acc, w -> acc + w + spacingBetweenLabels.x }
95
+ val rowY = rowHeights.runningFold(0.0 ) { acc, h -> acc + h + spacingBetweenLabels.y }
96
+
97
+ breaks.indices.forEach { i ->
98
+ val (row, col) = indexToPosition(i)
99
+ val breakBoxBounds = DoubleRectangle (colX[col], rowY[row], colWidths[col], rowHeights[row])
98
100
myKeyLabelBoxes.add(breakBoxBounds)
99
- myLabelBoxes.add(
100
- DoubleRectangle (
101
- labelHOffset, labelVOffset,
102
- labelSize.x, labelSize.y
103
- )
104
- )
105
101
}
106
102
107
- myContentSize = GeometryUtil .union(DoubleRectangle (contentOrigin, DoubleVector .ZERO ) , myKeyLabelBoxes).dimension
103
+ myContentSize = GeometryUtil .union(DoubleRectangle .ZERO , myKeyLabelBoxes).dimension
108
104
}
109
105
110
- protected abstract fun breakBoxOrigin (index : Int , prevBreakBoxBounds : DoubleRectangle ): DoubleVector
111
-
112
106
protected abstract fun labelSize (index : Int ): DoubleVector
113
107
114
108
private class MyHorizontal internal constructor(
@@ -126,10 +120,6 @@ abstract class LegendComponentLayout(
126
120
rowCount = 1
127
121
}
128
122
129
- override fun breakBoxOrigin (index : Int , prevBreakBoxBounds : DoubleRectangle ): DoubleVector {
130
- return DoubleVector (prevBreakBoxBounds.right, 0.0 )
131
- }
132
-
133
123
override fun labelSize (index : Int ): DoubleVector {
134
124
val label = breaks[index].label
135
125
return PlotLayoutUtil .textDimensions(label, PlotLabelSpecFactory .legendItem(theme))
@@ -175,36 +165,9 @@ abstract class LegendComponentLayout(
175
165
legendDirection : LegendDirection ,
176
166
theme : LegendTheme
177
167
) : LegendComponentLayout(title, breaks, keySizes, legendDirection, theme) {
178
- private var myMaxLabelWidth = 0.0
179
-
180
- init {
181
- for (br in breaks) {
182
- myMaxLabelWidth = max(
183
- myMaxLabelWidth,
184
- PlotLayoutUtil .textDimensions(br.label, PlotLabelSpecFactory .legendItem(theme)).x
185
- )
186
- }
187
- }
188
-
189
- override fun breakBoxOrigin (index : Int , prevBreakBoxBounds : DoubleRectangle ): DoubleVector {
190
- if (isFillByRow) {
191
- return if (index % colCount == 0 ) {
192
- DoubleVector (0.0 , prevBreakBoxBounds.bottom)
193
- } else DoubleVector (prevBreakBoxBounds.right, prevBreakBoxBounds.top)
194
- }
195
-
196
- // fill by column
197
- return if (index % rowCount == 0 ) {
198
- DoubleVector (prevBreakBoxBounds.right, 0.0 )
199
- } else DoubleVector (prevBreakBoxBounds.left, prevBreakBoxBounds.bottom)
200
-
201
- }
202
168
203
169
override fun labelSize (index : Int ): DoubleVector {
204
- return DoubleVector (
205
- myMaxLabelWidth,
206
- PlotLayoutUtil .textDimensions(breaks[index].label, PlotLabelSpecFactory .legendItem(theme)).y
207
- )
170
+ return PlotLayoutUtil .textDimensions(breaks[index].label, PlotLabelSpecFactory .legendItem(theme))
208
171
}
209
172
}
210
173
0 commit comments