You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(util): provide helper functions to deal with gridPos and rows (#155)
* feat(util): provide helper functions to deal with gridPos and rows
* fix: correct infunc ref
* feat(row): add sane defaults to row constructor and gridPos
* test: add unit tests for various util functions
* fix: small bugs that surfaced with unit tests
Copy file name to clipboardExpand all lines: custom/util/panel.libsonnet
+233-1Lines changed: 233 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,5 @@
1
1
local d = import'github.com/jsonnet-libs/docsonnet/doc-util/main.libsonnet';
2
+
local xtd = import'github.com/jsonnet-libs/xtd/main.libsonnet';
2
3
3
4
{
4
5
local this = self,
@@ -29,7 +30,8 @@ local d = import 'github.com/jsonnet-libs/docsonnet/doc-util/main.libsonnet';
29
30
else0),
30
31
31
32
panels+: [
32
-
panel + { id: acc.index }
33
+
panel
34
+
+ { id: acc.index }
33
35
+ (
34
36
if panel.type == 'row'
35
37
&& 'panels'in panel
@@ -48,4 +50,234 @@ local d = import 'github.com/jsonnet-libs/docsonnet/doc-util/main.libsonnet';
48
50
{ index: start, panels: [] }
49
51
).panels;
50
52
infunc(panels),
53
+
54
+
'#sanitizePanel':: d.func.new(
55
+
|||
56
+
`sanitizePanel` ensures the panel has a valid `gridPos` and row panels have `collapsed` and `panels`. This function is recursively applied to panels inside row panels.
57
+
58
+
The default values for x,y,h,w are only applied if not already set.
`groupPanelsInRows` ensures that panels that come after a row panel in an array are added to the `row.panels` attribute. This can be useful to apply intermediate functions to only the panels that belong to a row. Finally the panel array should get processed by `resolveCollapsedFlagOnRows` to "unfold" the rows that are not collapsed into the main array.
128
+
|||,
129
+
[
130
+
d.arg('panels', d.T.array),
131
+
]
132
+
),
133
+
groupPanelsInRows(panels):
134
+
// Add panels that come after a row to row.panels
135
+
local grouped =
136
+
xtd.array.filterMapWithIndex(
137
+
function(i, p) p.type == 'row',
138
+
function(i, p)
139
+
p + {
140
+
panels+:
141
+
this.getPanelsBeforeNextRow(panels[i + 1:]),
142
+
},
143
+
panels,
144
+
);
145
+
146
+
// Get panels that come before the rowGroups
147
+
local panelsBeforeRowGroups = this.getPanelsBeforeNextRow(panels);
148
+
149
+
panelsBeforeRowGroups + grouped,
150
+
151
+
'#getPanelsBeforeNextRow':: d.func.new(
152
+
|||
153
+
`getPanelsBeforeNextRow` returns all panels in an array up until a row has been found. Used in `groupPanelsInRows`.
154
+
|||,
155
+
[
156
+
d.arg('panels', d.T.array),
157
+
]
158
+
),
159
+
getPanelsBeforeNextRow(panels):
160
+
local rowIndexes =
161
+
xtd.array.filterMapWithIndex(
162
+
function(i, p) p.type == 'row',
163
+
function(i, p) i,
164
+
panels,
165
+
);
166
+
ifstd.length(rowIndexes) != 0
167
+
then panels[0:rowIndexes[0]]
168
+
else panels[0:], // if no row panels found, return all remaining panels
169
+
170
+
'#resolveCollapsedFlagOnRows':: d.func.new(
171
+
|||
172
+
`resolveCollapsedFlagOnRows` should be applied to the final panel array to "unfold" the rows that are not collapsed into the main array.
173
+
|||,
174
+
[
175
+
d.arg('panels', d.T.array),
176
+
]
177
+
),
178
+
resolveCollapsedFlagOnRows(panels):
179
+
std.foldl(
180
+
function(acc, panel)
181
+
acc + (
182
+
if panel.type == 'row'
183
+
&& !panel.collapsed
184
+
then// If not collapsed, then move panels to main array below the row panel
185
+
[panel + { panels: [] }]
186
+
+ panel.panels
187
+
else [panel]
188
+
),
189
+
panels,
190
+
[],
191
+
),
192
+
193
+
'#normalizeY':: d.func.new(
194
+
|||
195
+
`normalizeY` applies negative gravity on the inverted Y axis. This mimics the behavior of Grafana: when a panel is created without panel above it, then it'll float upward.
196
+
197
+
This is strictly not required as Grafana will do this on dashboard load, however it might be helpful when used when calculating the correct `gridPos`.
198
+
|||,
199
+
[
200
+
d.arg('panels', d.T.array),
201
+
]
202
+
),
203
+
normalizeY(panels):
204
+
std.foldl(
205
+
function(acc, i)
206
+
acc + [
207
+
panels[i] + {
208
+
gridPos+: {
209
+
y: this.calculateLowestYforPanel(panels[i], acc),
210
+
},
211
+
},
212
+
],
213
+
std.range(0, std.length(panels) - 1),
214
+
[]
215
+
),
216
+
217
+
'#calculateLowestYforPanel':: d.func.new(
218
+
|||
219
+
`calculateLowestYforPanel` calculates Y for a given `panel` from the `gridPos` of an array of `panels`. This function is used in `normalizeY`.
220
+
|||,
221
+
[
222
+
d.arg('panel', d.T.object),
223
+
d.arg('panels', d.T.array),
224
+
]
225
+
),
226
+
calculateLowestYforPanel(panel, panels):
227
+
local x1 = panel.gridPos.x;
228
+
local x2 = panel.gridPos.x + panel.gridPos.w;
229
+
xtd.number.maxInArray( // the new position is highest value (max) on the Y-scale
230
+
std.filterMap(
231
+
function(p) // find panels that overlap on X-scale
0 commit comments