diff --git a/docs/figure_file_format.rst b/docs/figure_file_format.rst
index 77cac2c44..e6039c65b 100644
--- a/docs/figure_file_format.rst
+++ b/docs/figure_file_format.rst
@@ -129,6 +129,15 @@ Optional settings for each panel::
"size": "12",
"position": "topright",
"color": "FFFFFF"
+ },
+ {
+ // for 'time', 'x', 'y', 'width' and 'height', decimal precision
+ // parameter can be passed (here 2)
+ // 'time' can also be passed an offset parameter (relative to a frame, here n°3)
+ "text": "Time (s): [time.secs; precision=2; offset=3]",
+ "size": "12",
+ "position": "topright",
+ "color": "FFFFFF"
}
],
diff --git a/omero_figure/scripts/omero/figure_scripts/Figure_To_Pdf.py b/omero_figure/scripts/omero/figure_scripts/Figure_To_Pdf.py
index 06736cb46..ff79e737a 100644
--- a/omero_figure/scripts/omero/figure_scripts/Figure_To_Pdf.py
+++ b/omero_figure/scripts/omero/figure_scripts/Figure_To_Pdf.py
@@ -1087,34 +1087,36 @@ def get_crop_region(self, panel):
return {'x': cropx, 'y': cropy, 'width': tile_w, 'height': tile_h}
- def get_time_label_text(self, delta_t, format):
+ def get_time_label_text(self, delta_t, format, dec_prec=0):
""" Gets the text for 'live' time-stamp labels """
# format of "secs" by default
is_negative = delta_t < 0
delta_t = abs(delta_t)
- text = "%d s" % int(round(delta_t))
+ npad = 2 + dec_prec + (dec_prec > 0)
if format in ["milliseconds", "ms"]:
- text = "%s ms" % int(round(delta_t * 1000))
+ text = "%.*f ms" % (dec_prec, delta_t * 1000)
elif format in ["secs", "seconds", "s"]:
- text = "%d s" % int(round(delta_t))
+ text = "%.*f s" % (dec_prec, delta_t)
elif format in ["mins", "minutes", "m"]:
- text = "%s mins" % int(round(delta_t / 60))
+ text = "%.*f mins" % (dec_prec, delta_t / 60)
elif format in ["mins:secs", "m:s"]:
m = int(delta_t // 60)
- s = round(delta_t % 60)
- text = "%s:%02d" % (m, s)
+ s = delta_t % 60
+ text = "%s:%0*.*f" % (m, npad, dec_prec, s)
elif format in ["hrs:mins", "h:m"]:
h = int(delta_t // 3600)
- m = int(round((delta_t % 3600) / 60))
- text = "%s:%02d" % (h, m)
+ m = (delta_t % 3600) / 60
+ text = "%s:%0*.*f" % (h, npad, dec_prec, m)
elif format in ["hrs:mins:secs", "h:m:s"]:
h = int(delta_t // 3600)
m = (delta_t % 3600) // 60
- s = round(delta_t % 60)
- text = "%s:%02d:%02d" % (h, m, s)
+ s = delta_t % 60
+ text = "%s:%02d:%0*.*f" % (h, m, npad, dec_prec, s)
else: # Format unknown
return ""
- if text in ["0 s", "0:00", "0 mins", "0:00:00"]:
+ dec_str = "" if dec_prec == 0 else "." + "0" * dec_prec
+ if text in ["0"+dec_str+" s", "0:00"+dec_str,
+ "0"+dec_str+" mins", "0:00:00"+dec_str]:
is_negative = False
return ('-' if is_negative else '') + text
@@ -1162,24 +1164,45 @@ def draw_labels(self, panel, page):
last_idx = 0
for item in parse_re.finditer(l['text']):
new_text.append(l['text'][last_idx:item.start()])
- expr = item.group()[1:-1].split(".")
label_value = ""
- if expr[0] in ["time", "t"]:
+ expr = item.group()[1:-1].split(";")
+ prop_nf = expr[0].strip().split(".")
+ param_dict = {}
+ for value in expr[1:]:
+ try:
+ kv = value.split("=")
+ if len(kv) > 1:
+ param_dict[kv[0].strip()] = int(kv[1].strip())
+ except ValueError:
+ pass
+
+ offset = param_dict.get("offset", None)
+ precision = param_dict.get("precision", None)
+
+ if prop_nf[0] in ["time", "t"]:
the_t = panel['theT']
timestamps = panel.get('deltaT')
# default to index
- if len(expr) == 1 or expr[1] == "index":
+ if len(prop_nf) == 1 or prop_nf[1] == "index":
label_value = str(the_t + 1)
else:
+ d_t = 0
if timestamps and the_t < len(timestamps):
d_t = timestamps[the_t]
- else:
- d_t = 0
- label_value = self.get_time_label_text(d_t, expr[1])
+ if offset is not None:
+ if 1 <= offset <= len(timestamps):
+ d_t -= timestamps[offset-1]
+
+ # Set the default precision value (0) if not given
+ precision = 0 if precision is None else precision
+
+ label_value = self.get_time_label_text(d_t,
+ prop_nf[1],
+ precision)
- elif expr[0] == "image":
- format = expr[1] if len(expr) > 1 else "name"
+ elif prop_nf[0] == "image":
+ format = prop_nf[1] if len(prop_nf) > 1 else "name"
if format == "name":
label_value = panel['name'].split('/')[-1]
elif format == "id":
@@ -1187,8 +1210,8 @@ def draw_labels(self, panel, page):
# Escaping "_" for markdown
label_value = label_value.replace("_", "\\_")
- elif expr[0] == "dataset":
- format = expr[1] if len(expr) > 1 else "name"
+ elif prop_nf[0] == "dataset":
+ format = prop_nf[1] if len(prop_nf) > 1 else "name"
if format == "name":
if panel['datasetName']:
label_value = panel['datasetName']
@@ -1196,18 +1219,18 @@ def draw_labels(self, panel, page):
label_value = "No/Many Datasets"
elif format == "id":
if panel['datasetId']:
- label_value = panel['datasetName']
+ label_value = str(panel['datasetId'])
else:
label_value = "null"
# Escaping "_" for markdown
label_value = label_value.replace("_", "\\_")
- elif expr[0] in ['x', 'y', 'z', 'width', 'height',
- 'w', 'h', 'rotation', 'rot']:
- format = expr[1] if len(expr) > 1 else "pixel"
+ elif prop_nf[0] in ['x', 'y', 'z', 'width', 'height',
+ 'w', 'h', 'rotation', 'rot']:
+ format = prop_nf[1] if len(prop_nf) > 1 else "pixel"
if format == "px":
format = "pixel"
- prop = expr[0]
+ prop = prop_nf[0]
if prop == "w":
prop = "width"
elif prop == "h":
@@ -1215,12 +1238,16 @@ def draw_labels(self, panel, page):
elif prop == "rot":
prop = "rotation"
+ # Set the default precision value (2) if not given
+ precision = 2 if precision is None else precision
+
if prop == "z":
size_z = panel.get('sizeZ')
pixel_size_z = panel.get('pixel_size_z')
z_symbol = panel.get('pixel_size_z_symbol')
if pixel_size_z is None:
pixel_size_z = 0
+ z_symbol = "\xB5m"
if ("z_projection" in panel.keys()
and panel["z_projection"]):
@@ -1229,8 +1256,10 @@ def draw_labels(self, panel, page):
label_value = (str(z_start + 1) + "-"
+ str(z_end + 1))
elif format == "unit" and size_z:
- z_start = f"{(z_start * pixel_size_z):.2f}"
- z_end = f"{(z_end * pixel_size_z):.2f}"
+ z_start = "%.*f" % (precision,
+ (z_start * pixel_size_z))
+ z_end = "%.*f" % (precision,
+ (z_end * pixel_size_z))
label_value = (z_start + " " + z_symbol + " - "
+ z_end + " " + z_symbol)
else:
@@ -1239,7 +1268,8 @@ def draw_labels(self, panel, page):
label_value = str(the_z + 1)
elif (format == "unit" and size_z
and the_z < size_z):
- z_pos = f"{(the_z * pixel_size_z):.2f}"
+ z_pos = "%.*f" % (precision,
+ (the_z * pixel_size_z))
label_value = (z_pos + " " + z_symbol)
elif prop == "rotation":
@@ -1252,14 +1282,17 @@ def draw_labels(self, panel, page):
label_value = str(int(value))
elif format == "unit":
if prop in ['x', 'width']:
- scale = panel['pixel_size_x']
+ scale = panel.get('pixel_size_x')
elif prop in ['y', 'height']:
- scale = panel['pixel_size_y']
- rounded = f"{(value * scale):.2f}"
+ scale = panel.get('pixel_size_y')
+ if scale is None:
+ scale = 0
+ rounded = "%.*f" % (precision,
+ (value * scale))
label_value = ("" + rounded +
" " + panel['pixel_size_x_symbol'])
- elif expr[0] in ["channels", "c"]:
+ elif prop_nf[0] in ["channels", "c"]:
label_value = []
for channel in panel["channels"]:
if channel["active"]:
diff --git a/omero_figure/templates/figure/index.html b/omero_figure/templates/figure/index.html
index be8960037..6eae81088 100644
--- a/omero_figure/templates/figure/index.html
+++ b/omero_figure/templates/figure/index.html
@@ -516,7 +516,7 @@
Import from JSON
Label Formatting
-
+
Markdown formatting
You can use "Markdown" syntax to add formatting to plain text. For example,
@@ -580,6 +580,21 @@
Dynamic properties
*Height*: **[height.pixel]** |
Height: 300 |
+
+ Width with decimal precision of 3 |
+ Width: [width.unit; precision=3] |
+ Width: 4.450 µm |
+
+
+ Time relative to the 3rd frame |
+ Time: [time.milliseconds; offset=3] |
+ Time: -58 ms |
+
+
+ Time with decimal precision 2, relative to the 3rd frame |
+ Time: [time.seconds; precision=2; offset=3] |
+ Time: -0.06 s |
+
Image ID |
Image ID: [image.id] |
diff --git a/src/js/models/panel_model.js b/src/js/models/panel_model.js
index 56c7340a4..7e3c02a67 100644
--- a/src/js/models/panel_model.js
+++ b/src/js/models/panel_model.js
@@ -277,7 +277,7 @@
else text = text + " " + c.label
}
});
- return text?text:" ";
+ return text ? text : " ";
},
getDeltaT: function() {
@@ -285,42 +285,50 @@
return this.get('deltaT')[theT] || 0;
},
- get_time_label_text: function(format) {
+ get_time_label_text: function(format, ref_idx, dec_prec) {
var pad = function(digit) {
var d = digit + "";
return d.length === 1 ? ("0"+d) : d;
};
var theT = this.get('theT'),
deltaT = this.get('deltaT')[theT] || 0,
- isNegative = (deltaT < 0),
text = "", h, m, s;
+
+ if (ref_idx) {
+ var shift = this.get('deltaT')[parseInt(ref_idx)-1];
+ deltaT = shift==null ? deltaT : deltaT-shift;
+ }
+ var isNegative = (deltaT < 0);
deltaT = Math.abs(deltaT);
+
+ var padlen = dec_prec>0 ? dec_prec+3 : 2;
if (format === "index") {
isNegative = false;
text = "" + (theT + 1);
} else if (['milliseconds', 'ms'].includes(format)) {
- text = Math.round(deltaT*1000) + " ms";
+ text = (deltaT*1000).toFixed(dec_prec) + " ms";
} else if (['seconds', 'secs', 's'].includes(format)) {
- text = Math.round(deltaT) + " s";
+ text = deltaT.toFixed(dec_prec) + " s";
} else if (['minutes', 'mins', 'm'].includes(format)) {
- text = Math.round(deltaT / 60) + " mins";
+ text = (deltaT / 60).toFixed(dec_prec) + " mins";
} else if (["mins:secs", "m:s"].includes(format)) {
m = parseInt(deltaT / 60);
- s = pad(Math.round(deltaT % 60));
+ s = ((deltaT % 60).toFixed(dec_prec)).padStart(padlen, "0");
text = m + ":" + s;
} else if (["hrs:mins", "h:m"].includes(format)) {
h = parseInt(deltaT / 3600);
- m = pad(Math.round((deltaT % 3600) / 60));
+ m = (((deltaT % 3600) / 60).toFixed(dec_prec)).padStart(padlen, "0");
text = h + ":" + m;
} else if (["hrs:mins:secs", "h:m:s"].includes(format)) {
h = parseInt(deltaT / 3600);
m = pad(parseInt((deltaT % 3600) / 60));
- s = pad(Math.round(deltaT % 60));
+ s = ((deltaT % 60).toFixed(dec_prec)).padStart(padlen, "0");
text = h + ":" + m + ":" + s;
} else { // Format unknown
return ""
}
- if (["0 s", "0:00", "0 mins", "0:00:00"].indexOf(text) > -1) {
+ var dec_str = dec_prec>0 ? "."+"0".repeat(dec_prec) : "";
+ if (["0"+dec_str+" s", "0"+dec_str+" mins", "0:00"+dec_str, "0:00:00"+dec_str].indexOf(text) > -1) {
isNegative = false;
}
return (isNegative ? '-' : '') + text;
@@ -335,7 +343,7 @@
var pathnames = this.get('name').split('/');
text = pathnames[pathnames.length-1];
}
- } else if (property === "dataset"){
+ } else if (property === "dataset") {
if (format === "id") {
text = ""+this.get('datasetId');
} else if (format === "name") {
@@ -345,7 +353,7 @@
return text;
},
- get_view_label_text: function(property, format) {
+ get_view_label_text: function(property, format, dec_prec) {
if (format === "px") format = "pixel";
if (property === "w") property = "width";
@@ -353,24 +361,29 @@
else if (property === "rot") property = "rotation";
- x_symbol = this.get('pixel_size_x_symbol');
- z_symbol = this.get('pixel_size_z_symbol');
- z_symbol = z_symbol?z_symbol:x_symbol // Using x symbol when z not defined
- x_size = this.get('pixel_size_x');
- y_size = this.get('pixel_size_y');
- z_size = this.get('pixel_size_z');
- z_size = z_size?z_size:0
+ var x_symbol = this.get('pixel_size_x_symbol'),
+ z_symbol = this.get('pixel_size_z_symbol');
+ z_symbol = z_symbol ? z_symbol : x_symbol // Using x symbol when z not defined
+ var x_size = this.get('pixel_size_x'),
+ y_size = this.get('pixel_size_y'),
+ z_size = this.get('pixel_size_z');
+ z_size = z_size ? z_size : 0
+ x_size = x_size ? x_size : 0
+ y_size = y_size ? y_size : 0
+
+ dec_prec = parseInt(dec_prec)
+ dec_prec = dec_prec==null ? 2 : dec_prec; // 2 is the default precision
var text = "";
if (property === "z") {
if (this.get('z_projection')) {
- start = this.get('z_start');
- end = this.get('z_end');
+ var start = this.get('z_start'),
+ end = this.get('z_end');
if (format === "pixel") {
text = "" + (start+1) + " - " + (end+1);
- } else if (format === "unit"){
- start = (start * z_size).toFixed(2)
- end = (end * z_size).toFixed(2)
+ } else if (format === "unit") {
+ start = (start * z_size).toFixed(dec_prec)
+ end = (end * z_size).toFixed(dec_prec)
text = ""+ start +" "+ z_symbol
+ " - " + end +" "+ z_symbol
}
@@ -379,21 +392,21 @@
var theZ = this.get('theZ');
if (format === "pixel") {
text = "" + (theZ + 1);
- } else if (format === "unit"){
- text = ""+ (theZ * z_size).toFixed(2) +" "+ z_symbol
+ } else if (format === "unit") {
+ text = ""+ (theZ * z_size).toFixed(dec_prec) +" "+ z_symbol
}
}
return text
}
- viewport = this.getViewportAsRect();
- value = viewport[property];
+
+ var value = this.getViewportAsRect()[property];
if (property === "rotation") {
return ""+parseInt(value)+"°";
} else if (format === "pixel") {
return ""+parseInt(value);
} else if (format === "unit") {
- scale = ['x', 'width'].includes(property) ? x_size : y_size
- text = ""+ (value * scale).toFixed(2) +" "+ x_symbol
+ var scale = ['x', 'width'].includes(property) ? x_size : y_size
+ text = ""+ (value * scale).toFixed(dec_prec) +" "+ x_symbol
}
return text
},
@@ -447,9 +460,9 @@
this.save('channels', chs);
},
- toggle_channel: function(cIndex, active){
+ toggle_channel: function(cIndex, active ) {
- if (typeof active == "undefined"){
+ if (typeof active == "undefined") {
active = !this.get('channels')[cIndex].active;
}
this.save_channel(cIndex, 'active', active);
@@ -504,7 +517,7 @@
// a resize of the rectangle x1, y1, w1, h1 => x2, y2, w2, h2
// will resize the Panels within it in proportion.
// This might be during a drag, or drag-stop (save=true)
- multiselectdrag: function(x1, y1, w1, h1, x2, y2, w2, h2, save){
+ multiselectdrag: function(x1, y1, w1, h1, x2, y2, w2, h2, save) {
var shift_x = function(startX) {
return ((startX - x1)/w1) * w2 + x2;
diff --git a/src/js/views/panel_view.js b/src/js/views/panel_view.js
index 7f0e9cdc5..55be217e4 100644
--- a/src/js/views/panel_view.js
+++ b/src/js/views/panel_view.js
@@ -196,23 +196,43 @@
var last_idx = 0;
for (const match of matches) {// Loops on the match to replace in the ljson.text the expression by their values
var new_text = new_text + ljson.text.slice(last_idx, match.index);
- expr = match[0].slice(1,-1).split(".");
- var label_value = ""
- if (['time', 't'].includes(expr[0])) {
- label_value = self.model.get_time_label_text(expr[1] ? expr[1] : "index");
- } else if (['image', 'dataset'].includes(expr[0])){
- label_value = self.model.get_name_label_text(expr[0], expr[1] ? expr[1] : "name");
+
+ // Label parsing in three steps:
+ // - split label type.format from other parameters (;)
+ // - split label type and format (.)
+ // - grab other parameters (key=value)
+ var expr = match[0].slice(1,-1).split(";");
+ var prop_nf = expr[0].trim().split(".");
+ var param_dict = {};
+ expr.slice(1).forEach(function(value) {
+ var kv = value.split("=");
+ if (kv.length > 1) {
+ param_dict[kv[0].trim()] = parseInt(kv[1].trim());
+ }
+ });
+
+ var label_value = "",
+ format, precision;
+ if (['time', 't'].includes(prop_nf[0])) {
+ format = prop_nf[1] ? prop_nf[1] : "index";
+ precision = param_dict["precision"] !== undefined ? param_dict["precision"] : 0; // decimal places default to 0
+ label_value = self.model.get_time_label_text(format, param_dict["offset"], precision);
+ } else if (['image', 'dataset'].includes(prop_nf[0])){
+ format = prop_nf[1] ? prop_nf[1] : "name";
+ label_value = self.model.get_name_label_text(prop_nf[0], format);
//Escape the underscore for markdown
label_value = label_value.replaceAll("_", "\\_");
- } else if (['x', 'y', 'z', 'width', 'height', 'w', 'h', 'rotation', 'rot'].includes(expr[0])){
- label_value = self.model.get_view_label_text(expr[0], expr[1] ? expr[1] : "pixel");
- } else if (['channels', 'c'].includes(expr[0])) {
+ } else if (['x', 'y', 'z', 'width', 'height', 'w', 'h', 'rotation', 'rot'].includes(prop_nf[0])){
+ format = prop_nf[1] ? prop_nf[1] : "pixel";
+ precision = param_dict["precision"] !== undefined ? param_dict["precision"] : 2; // decimal places default to 2
+ label_value = self.model.get_view_label_text(prop_nf[0], format, precision);
+ } else if (['channels', 'c'].includes(prop_nf[0])) {
label_value = self.model.get_channels_label_text();
}
- //If label_value hasn't been created (invalid expr[0])
- // or is empty (invalid expr[1]), the expr is kept unmodified
- new_text = new_text + (label_value?label_value:match[0]);
+ //If label_value hasn't been created (invalid prop_nf[0])
+ // or is empty (invalid prop_nf[1]), the expression is kept intact
+ new_text = new_text + (label_value ? label_value : match[0]);
last_idx = match.index + match[0].length;
}
ljson.text = new_text + ljson.text.slice(last_idx);
diff --git a/test/integration/test_figure_scripts.py b/test/integration/test_figure_scripts.py
index e35317785..55d0ef685 100644
--- a/test/integration/test_figure_scripts.py
+++ b/test/integration/test_figure_scripts.py
@@ -131,25 +131,134 @@ def get_panel_json(image, index, page_x):
"radiusX": size_x/3, "radiusY": size_y/2, "rotation": 45,
"strokeWidth": 10, "strokeColor": "#00FF00"}]
+ labels = (get_time_test_labels() + get_view_test_labels()
+ + get_obj_test_labels() + get_other_test_labels())
+
+ # This works if we have Units support (OMERO 5.1)
+ px = image.getPrimaryPixels().getPhysicalSizeX()
+ py = image.getPrimaryPixels().getPhysicalSizeY()
+ pz = image.getPrimaryPixels().getPhysicalSizeZ()
img_json = {
- "labels": [],
- "channels": [channel],
- "height": 100 * (index + 1),
+ "imageId": image.getId().getValue(),
+ "name": "test_image", # image.getName().getValue()
"width": 100 * (index + 1),
- "sizeT": pix.getSizeT().val,
+ "height": 100 * (index + 1),
"sizeZ": pix.getSizeZ().val,
+ "theZ": 0,
+ "sizeT": pix.getSizeT().val,
+ "theT": 0,
+ # rdef -> used at panel creation then deleted
+ "channels": [channel],
"orig_width": size_x,
"orig_height": size_y,
+ "x": page_x,
+ "y": index * 200,
+ 'datasetName': "TestDataset",
+ 'datasetId': 123,
+ 'pixel_size_x': None if px is None else px.getValue(),
+ 'pixel_size_y': None if py is None else py.getValue(),
+ 'pixel_size_z': None if pz is None else pz.getValue(),
+ 'pixel_size_x_symbol': '\xB5m' if px is None else px.getSymbol(),
+ 'pixel_size_z_symbol': None if pz is None else pz.getSymbol(),
+ 'pixel_size_x_unit': None if px is None else str(px.getUnit()),
+ 'pixel_size_z_unit': None if pz is None else str(pz.getUnit()),
+ 'deltaT': [],
+ "zoom": 100 + (index * 50),
"dx": 0,
"dy": 0,
+ "labels": labels,
"rotation": 100 * index,
- "imageId": image.getId().getValue(),
- "name": "test_image",
- "zoom": 100 + (index * 50),
+ "rotation_symbol": '\xB0',
+ "max_export_dpi": 1000,
"shapes": shapes,
- "y": index * 200,
- "x": page_x,
- "theZ": 0,
- "theT": 0
}
return img_json
+
+
+def get_time_test_labels(size=12, position="top", color="000000"):
+ """Create test labels about the time"""
+ time_props = ["time", "t"]
+ time_formats = ["", ".index", ".milliseconds", ".ms", ".seconds", ".secs",
+ ".s", ".minutes", ".mins", ".m", ".hrs:mins:secs",
+ ".h:m:s", ".hrs:mins", ".h:m", ".mins:secs", ".m:s"]
+
+ precisions = ["", ";precision=0", ";precision=2",
+ " ; precision = abc "] # abc and spaces for resilience test
+ offsets = ["", ";offset=0", ";offset=1",
+ " ; offset = abc "] # 0, abc and spaces for resilience test
+
+ label_text = []
+ for prop in time_props:
+ tmp = [f"[{prop}{format}]" for format in time_formats]
+ label_text.append(" or ".join(tmp))
+ for precision in precisions:
+ tmp = [f"[t{precision}{offset}]" for offset in offsets]
+ label_text.append(" or ".join(tmp))
+ tmp = [f"[t.s{precision}{offset}]" for offset in offsets]
+ label_text.append(" or ".join(tmp))
+
+ labels = []
+ for text in label_text:
+ labels.append({"text": text, "size": size,
+ "position": position, "color": color})
+ return labels
+
+
+def get_view_test_labels(size=12, position="top", color="000000"):
+ """Create test labels for about the view"""
+
+ view_props = ["x", "y", "z", "width", "w", "height", "h"]
+ view_formats = ["", ".pixel", ".px", ".unit"]
+
+ precisions = ["", ";precision=0", ";precision=2",
+ "; precision = abc "] # abc and spaces for resilience test
+
+ label_text = []
+ for prop in view_props:
+ tmp = [f"[{prop}{format}]" for format in view_formats]
+ label_text.append(" or ".join(tmp))
+ tmp = [f"[x{precision}]" for precision in precisions]
+ label_text.append(" or ".join(tmp))
+ tmp = [f"[x.unit{precision}]" for precision in precisions]
+ label_text.append(" or ".join(tmp))
+
+ labels = []
+ for text in label_text:
+ labels.append({"text": text, "size": size,
+ "position": position, "color": color})
+ return labels
+
+
+def get_obj_test_labels(size=12, position="top", color="000000"):
+ """Create test labels for about the image or dataset"""
+
+ obj_props = ["image", "dataset"]
+ obj_formats = ["", ".id", ".name"]
+
+ label_text = []
+ for prop in obj_props:
+ tmp = [f"[{prop}{format}]" for format in obj_formats]
+ label_text.append(" or ".join(tmp))
+
+ labels = []
+ for text in label_text:
+ labels.append({"text": text, "size": size,
+ "position": position, "color": color})
+ return labels
+
+
+def get_other_test_labels(size=12, position="top", color="000000"):
+ """Create test labels for other labels and markdown"""
+ other_props = ["rotation", "rot", "channels", "c"]
+ markdowns = ["", "*", "**"]
+
+ label_text = []
+ for prop in other_props:
+ tmp = [f"{md}[{prop}]{md}" for md in markdowns]
+ label_text.append(" or ".join(tmp))
+
+ labels = []
+ for text in label_text:
+ labels.append({"text": text, "size": size,
+ "position": position, "color": color})
+ return labels