mirror of
https://github.com/Relintai/pandemonium_engine_easy_charts.git
synced 2024-11-20 10:47:22 +01:00
update drawing options + example
This commit is contained in:
parent
86359cf83f
commit
f7864e4755
@ -13,14 +13,12 @@ var _point_box_rad: int = 10
|
||||
func _ready():
|
||||
pass
|
||||
|
||||
func plot(x: Array, y: Array, drawing_options: DrawingOptions = null, chart_properties: ChartProperties = null) -> void:
|
||||
func plot(x: Array, y: Array, properties: ChartProperties = self.chart_properties) -> void:
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
if chart_properties != null:
|
||||
self.chart_properties = chart_properties
|
||||
if drawing_options != null:
|
||||
self.drawing_options = drawing_options
|
||||
if properties != null:
|
||||
self.chart_properties = properties
|
||||
|
||||
update()
|
||||
|
||||
@ -63,29 +61,29 @@ func _input(event: InputEvent):
|
||||
func _draw_point(point: Point, function_index: int) -> void:
|
||||
points.append(point)
|
||||
|
||||
match drawing_options.get_point_shape(function_index):
|
||||
match chart_properties.get_point_shape(function_index):
|
||||
Point.Shape.CIRCLE:
|
||||
draw_circle(point.position, drawing_options.point_radius, drawing_options.get_function_color(function_index))
|
||||
draw_circle(point.position, chart_properties.point_radius, chart_properties.get_function_color(function_index))
|
||||
Point.Shape.SQUARE:
|
||||
draw_rect(_get_point_box(point, drawing_options.point_radius), drawing_options.get_function_color(function_index), true, 1.0, false)
|
||||
draw_rect(_get_point_box(point, chart_properties.point_radius), chart_properties.get_function_color(function_index), true, 1.0, false)
|
||||
Point.Shape.TRIANGLE:
|
||||
draw_colored_polygon(
|
||||
PoolVector2Array([
|
||||
point.position + (Vector2.UP * drawing_options.point_radius * 1.3),
|
||||
point.position + (Vector2.ONE * drawing_options.point_radius * 1.3),
|
||||
point.position - (Vector2(1, -1) * drawing_options.point_radius * 1.3)
|
||||
]), drawing_options.get_function_color(function_index), [], null, null, false
|
||||
point.position + (Vector2.UP * chart_properties.point_radius * 1.3),
|
||||
point.position + (Vector2.ONE * chart_properties.point_radius * 1.3),
|
||||
point.position - (Vector2(1, -1) * chart_properties.point_radius * 1.3)
|
||||
]), chart_properties.get_function_color(function_index), [], null, null, false
|
||||
)
|
||||
Point.Shape.CROSS:
|
||||
draw_line(
|
||||
point.position - (Vector2.ONE * drawing_options.point_radius),
|
||||
point.position + (Vector2.ONE * drawing_options.point_radius),
|
||||
drawing_options.get_function_color(function_index), drawing_options.point_radius, true
|
||||
point.position - (Vector2.ONE * chart_properties.point_radius),
|
||||
point.position + (Vector2.ONE * chart_properties.point_radius),
|
||||
chart_properties.get_function_color(function_index), chart_properties.point_radius, true
|
||||
)
|
||||
draw_line(
|
||||
point.position + (Vector2(1, -1) * drawing_options.point_radius),
|
||||
point.position + (Vector2(-1, 1) * drawing_options.point_radius),
|
||||
drawing_options.get_function_color(function_index), drawing_options.point_radius / 2, true
|
||||
point.position + (Vector2(1, -1) * chart_properties.point_radius),
|
||||
point.position + (Vector2(-1, 1) * chart_properties.point_radius),
|
||||
chart_properties.get_function_color(function_index), chart_properties.point_radius / 2, true
|
||||
)
|
||||
|
||||
# # (debug)
|
||||
|
@ -14,7 +14,6 @@ var x_labels: Array = []
|
||||
var y_labels: Array = []
|
||||
|
||||
###### STYLE
|
||||
var drawing_options: DrawingOptions = DrawingOptions.new()
|
||||
var chart_properties: ChartProperties = ChartProperties.new()
|
||||
|
||||
#### INTERNAL
|
||||
@ -46,7 +45,7 @@ var _x_ticklabel_offset: int = 5 # offset only on the X axis
|
||||
var _x_tick_size: int = 7
|
||||
|
||||
###########
|
||||
func plot(x: Array, y: Array, drawing_options: DrawingOptions = DrawingOptions.new(), chart_properties: ChartProperties = ChartProperties.new()) -> void:
|
||||
func plot(x: Array, y: Array, properties: ChartProperties = self.chart_properties) -> void:
|
||||
pass
|
||||
|
||||
func _map_pair(val: float, rel: Pair, ref: Pair) -> float:
|
||||
@ -132,10 +131,10 @@ func _pre_process_drawings() -> void:
|
||||
var offset: Vector2 = _padding_offset
|
||||
|
||||
### if @labels drawing is enabled, calcualte offsets
|
||||
if drawing_options.labels:
|
||||
if chart_properties.labels:
|
||||
### labels (X, Y, Title)
|
||||
_x_label_size = drawing_options.font.get_string_size(chart_properties.x_label)
|
||||
_y_label_size = drawing_options.font.get_string_size(chart_properties.y_label)
|
||||
_x_label_size = chart_properties.font.get_string_size(chart_properties.x_label)
|
||||
_y_label_size = chart_properties.font.get_string_size(chart_properties.y_label)
|
||||
|
||||
### tick labels
|
||||
|
||||
@ -144,7 +143,7 @@ func _pre_process_drawings() -> void:
|
||||
# calculate the string length of the largest value on the Y axis.
|
||||
# remember that "-" sign adds additional pixels, and it is relative only to negative numbers!
|
||||
var x_max_formatted: String = ("%.2f" if x_has_decimals else "%s") % x_min_max.right
|
||||
_x_ticklabel_size = drawing_options.font.get_string_size(x_max_formatted)
|
||||
_x_ticklabel_size = chart_properties.font.get_string_size(x_max_formatted)
|
||||
|
||||
offset.y += _x_label_offset + _x_label_size.y + _x_ticklabel_offset + _x_ticklabel_size.y
|
||||
|
||||
@ -157,16 +156,16 @@ func _pre_process_drawings() -> void:
|
||||
# negative number
|
||||
var y_min_formatted: String = ("%.2f" if y_has_decimals else "%s") % y_min_max.left
|
||||
if y_min_formatted.length() >= y_max_formatted.length():
|
||||
_y_ticklabel_size = drawing_options.font.get_string_size(y_min_formatted)
|
||||
_y_ticklabel_size = chart_properties.font.get_string_size(y_min_formatted)
|
||||
else:
|
||||
_y_ticklabel_size = drawing_options.font.get_string_size(y_max_formatted)
|
||||
_y_ticklabel_size = chart_properties.font.get_string_size(y_max_formatted)
|
||||
else:
|
||||
_y_ticklabel_size = drawing_options.font.get_string_size(y_max_formatted)
|
||||
_y_ticklabel_size = chart_properties.font.get_string_size(y_max_formatted)
|
||||
|
||||
offset.x += _y_label_offset + _y_label_size.y + _y_ticklabel_offset + _y_ticklabel_size.x
|
||||
|
||||
### if @ticks drawing is enabled, calculate offsets
|
||||
if drawing_options.ticks:
|
||||
if chart_properties.ticks:
|
||||
offset.x += _y_tick_size
|
||||
offset.y += _x_tick_size
|
||||
|
||||
@ -204,7 +203,7 @@ func _draw_borders() -> void:
|
||||
draw_rect(node_box, Color.red, false, 1, true)
|
||||
|
||||
func _draw_bounding_box() -> void:
|
||||
draw_rect(bounding_box, drawing_options.colors.bounding_box, false, 1, true)
|
||||
draw_rect(bounding_box, chart_properties.colors.bounding_box, false, 1, true)
|
||||
|
||||
# # (debug)
|
||||
# var half: Vector2 = (bounding_box.size) / 2
|
||||
@ -216,7 +215,7 @@ func _draw_origin() -> void:
|
||||
var yorigin: float = _map_pair(0.0, y_min_max, y_sampled_domain)
|
||||
draw_line(Vector2(xorigin, bounding_box.position.y), Vector2(xorigin, bounding_box.position.y + bounding_box.size.y), Color.black, 1, 0)
|
||||
draw_line(Vector2(bounding_box.position.x, yorigin), Vector2(bounding_box.position.x + bounding_box.size.x, yorigin), Color.black, 1, 0)
|
||||
draw_string(drawing_options.font, Vector2(xorigin, yorigin) - Vector2(15, -15), "O", drawing_options.colors.bounding_box)
|
||||
draw_string(chart_properties.font, Vector2(xorigin, yorigin) - Vector2(15, -15), "O", chart_properties.colors.bounding_box)
|
||||
|
||||
func _draw_background() -> void:
|
||||
draw_rect(node_box, Color.white, true, 1.0, false)
|
||||
@ -247,7 +246,7 @@ func _draw_grid() -> void:
|
||||
)
|
||||
|
||||
# Draw V labels
|
||||
if drawing_options.labels:
|
||||
if chart_properties.labels:
|
||||
var tick_lbl: String = ""
|
||||
if x_labels.empty():
|
||||
tick_lbl = ("%.2f" if x_has_decimals else "%s") % x_val
|
||||
@ -255,22 +254,22 @@ func _draw_grid() -> void:
|
||||
tick_lbl = x_labels[clamp(x_labels_spacing * _x, 0, x_labels.size() - 1)]
|
||||
|
||||
draw_string(
|
||||
drawing_options.font,
|
||||
chart_properties.font,
|
||||
p2 + Vector2(
|
||||
- drawing_options.font.get_string_size(tick_lbl).x / 2,
|
||||
- chart_properties.font.get_string_size(tick_lbl).x / 2,
|
||||
_x_label_size.y + _x_tick_size
|
||||
),
|
||||
tick_lbl,
|
||||
drawing_options.colors.bounding_box
|
||||
chart_properties.colors.bounding_box
|
||||
)
|
||||
|
||||
# Draw V Ticks
|
||||
if drawing_options.ticks:
|
||||
draw_line(p2, p2 + Vector2(0, _x_tick_size), drawing_options.colors.bounding_box, 1, true)
|
||||
if chart_properties.ticks:
|
||||
draw_line(p2, p2 + Vector2(0, _x_tick_size), chart_properties.colors.bounding_box, 1, true)
|
||||
|
||||
# Draw V Grid Lines
|
||||
if drawing_options.grid:
|
||||
draw_line(p1, p2, drawing_options.colors.grid, 1, true)
|
||||
if chart_properties.grid:
|
||||
draw_line(p1, p2, chart_properties.colors.grid, 1, true)
|
||||
|
||||
# draw horizontal lines
|
||||
var h_lines: float = (y_sampled.min_max.right - y_sampled.min_max.left) / (chart_properties.y_scale - 1)
|
||||
@ -287,7 +286,7 @@ func _draw_grid() -> void:
|
||||
)
|
||||
|
||||
# Draw H labels
|
||||
if drawing_options.labels:
|
||||
if chart_properties.labels:
|
||||
var tick_lbl: String = ""
|
||||
if y_labels.empty():
|
||||
tick_lbl = ("%.2f" if y_has_decimals else "%s") % y_val
|
||||
@ -295,29 +294,29 @@ func _draw_grid() -> void:
|
||||
tick_lbl = y_labels[clamp(y_labels * _y, 0, y_labels.size() - 1)]
|
||||
|
||||
draw_string(
|
||||
drawing_options.font,
|
||||
p1 - Vector2(drawing_options.font.get_string_size(tick_lbl).x + _y_ticklabel_offset + _y_tick_size, - _y_ticklabel_size.y * 0.35),
|
||||
chart_properties.font,
|
||||
p1 - Vector2(chart_properties.font.get_string_size(tick_lbl).x + _y_ticklabel_offset + _y_tick_size, - _y_ticklabel_size.y * 0.35),
|
||||
tick_lbl,
|
||||
drawing_options.colors.bounding_box
|
||||
chart_properties.colors.bounding_box
|
||||
)
|
||||
|
||||
# Draw H Ticks
|
||||
if drawing_options.ticks:
|
||||
if chart_properties.ticks:
|
||||
draw_line(
|
||||
p1,
|
||||
p1 - Vector2(_y_tick_size, 0),
|
||||
drawing_options.colors.bounding_box, 1, true)
|
||||
chart_properties.colors.bounding_box, 1, true)
|
||||
|
||||
# Draw H Grid Lines
|
||||
if drawing_options.grid:
|
||||
draw_line(p1, p2, drawing_options.colors.grid, 1, true)
|
||||
if chart_properties.grid:
|
||||
draw_line(p1, p2, chart_properties.colors.grid, 1, true)
|
||||
|
||||
func _create_canvas_label(text: String, position: Vector2, rotation: float = 0.0) -> Label:
|
||||
var lbl: Label = Label.new()
|
||||
$Canvas.add_child(lbl)
|
||||
lbl.set("custom_fonts/font", drawing_options.font)
|
||||
lbl.set("custom_fonts/font", chart_properties.font)
|
||||
lbl.set_text(text)
|
||||
lbl.modulate = drawing_options.colors.bounding_box
|
||||
lbl.modulate = chart_properties.colors.bounding_box
|
||||
lbl.rect_rotation = rotation
|
||||
lbl.rect_position = position
|
||||
return lbl
|
||||
@ -341,7 +340,7 @@ func _draw_xaxis_label() -> void:
|
||||
func _draw_title() -> void:
|
||||
_create_canvas_label(
|
||||
chart_properties.title,
|
||||
Vector2(node_box.size.x / 2, _padding_offset.y*2) - (drawing_options.font.get_string_size(chart_properties.title) / 2)
|
||||
Vector2(node_box.size.x / 2, _padding_offset.y*2) - (chart_properties.font.get_string_size(chart_properties.title) / 2)
|
||||
)
|
||||
|
||||
func _clear_points() -> void:
|
||||
@ -361,27 +360,27 @@ func _draw():
|
||||
_clear()
|
||||
_pre_process()
|
||||
|
||||
if drawing_options.background:
|
||||
if chart_properties.background:
|
||||
_draw_background()
|
||||
|
||||
if drawing_options.borders:
|
||||
if chart_properties.borders:
|
||||
_draw_borders()
|
||||
|
||||
if drawing_options.labels:
|
||||
if chart_properties.labels:
|
||||
_draw_xaxis_label()
|
||||
_draw_yaxis_label()
|
||||
_draw_title()
|
||||
|
||||
if drawing_options.grid or drawing_options.ticks or drawing_options.labels:
|
||||
if chart_properties.grid or chart_properties.ticks or chart_properties.labels:
|
||||
_draw_grid()
|
||||
|
||||
if drawing_options.bounding_box:
|
||||
if chart_properties.bounding_box:
|
||||
_draw_bounding_box()
|
||||
|
||||
if drawing_options.origin:
|
||||
if chart_properties.origin:
|
||||
_draw_origin()
|
||||
|
||||
if drawing_options.points:
|
||||
if chart_properties.points:
|
||||
_draw_points()
|
||||
|
||||
func _validate_sampled_axis(x_data: SampledAxis, y_data: SampledAxis) -> int:
|
||||
|
49
addons/easy_charts/examples/scatter_chart/Control.gd
Normal file
49
addons/easy_charts/examples/scatter_chart/Control.gd
Normal file
@ -0,0 +1,49 @@
|
||||
extends Control
|
||||
|
||||
func _ready():
|
||||
# Let's create our @x values
|
||||
var x: Array = ArrayOperations.multiply_float(range(-10, 10, 1), 0.5)
|
||||
# And our y values. It can be an n-size array of arrays.
|
||||
# NOTE: `x.size() == y.size()` or `x.size() == y[n].size()`
|
||||
var y: Array = [
|
||||
ArrayOperations.multiply_int(ArrayOperations.cos(x), 20),
|
||||
ArrayOperations.add_float(ArrayOperations.multiply_int(ArrayOperations.sin(x), 20), 20)
|
||||
]
|
||||
|
||||
# Add some labels for the x axis, we don't want to use our x values array
|
||||
# they will be printed on the chart ticks instead of the value of the x axis.
|
||||
var x_labels: Array = ArrayOperations.suffix(x, "s")
|
||||
|
||||
# Let's customize the chart properties, which specify how the chart
|
||||
# should look, plus some additional elements like labels, the scale, etc...
|
||||
var cp: ChartProperties = ChartProperties.new()
|
||||
cp.grid = true
|
||||
cp.origin = false
|
||||
cp.title = "Air Quality Monitoring"
|
||||
cp.x_label = ("Time")
|
||||
cp.x_scale = 10
|
||||
cp.y_label = ("Sensor values")
|
||||
cp.y_scale = 10
|
||||
|
||||
# Set the x_labels
|
||||
$ScatterChart.x_labels = x_labels
|
||||
|
||||
# Plot our data
|
||||
$ScatterChart.plot(x, y, cp)
|
||||
|
||||
# Uncommenting this line will show how real time data plotting works
|
||||
set_process(false)
|
||||
|
||||
func _process(delta: float):
|
||||
# This function updates the values of chart x, y, and x_labels array
|
||||
# and updaptes the plot
|
||||
var new_val: float = $ScatterChart.x.back() + 1
|
||||
$ScatterChart.x.append(new_val)
|
||||
$ScatterChart.y[0].append(cos(new_val) * 20)
|
||||
$ScatterChart.y[1].append(20 + sin(new_val) * 20)
|
||||
$ScatterChart.x_labels.append(str(new_val) + "s")
|
||||
$ScatterChart.update()
|
||||
|
||||
|
||||
func _on_CheckButton_pressed():
|
||||
set_process(not is_processing())
|
49
addons/easy_charts/examples/scatter_chart/Control.tscn
Normal file
49
addons/easy_charts/examples/scatter_chart/Control.tscn
Normal file
@ -0,0 +1,49 @@
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://addons/easy_charts/control_charts/ScatterChart/scatter_chart.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://addons/easy_charts/examples/scatter_chart/Control.gd" type="Script" id=2]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=1]
|
||||
content_margin_right = 5.0
|
||||
content_margin_bottom = 5.0
|
||||
draw_center = false
|
||||
border_width_right = 2
|
||||
border_width_bottom = 2
|
||||
border_color = Color( 0, 0, 0, 1 )
|
||||
|
||||
[node name="Control" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
script = ExtResource( 2 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": true
|
||||
}
|
||||
|
||||
[node name="ScatterChart" parent="." instance=ExtResource( 1 )]
|
||||
|
||||
[node name="CheckButton" type="CheckButton" parent="."]
|
||||
margin_right = 223.0
|
||||
margin_bottom = 40.0
|
||||
custom_colors/font_color_disabled = Color( 0, 0, 0, 1 )
|
||||
custom_colors/font_color_focus = Color( 0, 0, 0, 1 )
|
||||
custom_colors/font_color_hover_pressed = Color( 0, 0, 0, 1 )
|
||||
custom_colors/font_color = Color( 0, 0, 0, 1 )
|
||||
custom_colors/font_color_hover = Color( 0, 0, 0, 1 )
|
||||
custom_colors/font_color_pressed = Color( 0, 0, 0, 1 )
|
||||
text = "Start Relatime Plotting"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -159.0
|
||||
margin_top = -19.0
|
||||
custom_colors/font_color = Color( 0, 0, 0, 1 )
|
||||
custom_styles/normal = SubResource( 1 )
|
||||
text = "Try to scale the window!"
|
||||
__meta__ = {
|
||||
"_edit_lock_": true
|
||||
}
|
||||
|
||||
[connection signal="pressed" from="CheckButton" to="." method="_on_CheckButton_pressed"]
|
@ -7,3 +7,28 @@ var y_label: String
|
||||
|
||||
var x_scale: float = 5.0
|
||||
var y_scale: float = 2.0
|
||||
|
||||
var points: bool = true
|
||||
var grid: bool = false
|
||||
var bounding_box: bool = true
|
||||
var background: bool = true
|
||||
var borders: bool = false
|
||||
var ticks: bool = true
|
||||
var labels: bool = true
|
||||
var origin: bool = true
|
||||
|
||||
var colors: Dictionary = {
|
||||
bounding_box = Color.black,
|
||||
grid = Color.gray,
|
||||
functions = [Color.red, Color.green, Color.blue, Color.black]
|
||||
}
|
||||
|
||||
var shapes: Array = [Point.Shape.CIRCLE, Point.Shape.SQUARE, Point.Shape.TRIANGLE, Point.Shape.CROSS]
|
||||
var point_radius: float = 3.0
|
||||
var font: BitmapFont = Label.new().get_font("")
|
||||
|
||||
func get_function_color(function_index: int) -> Color:
|
||||
return colors.functions[function_index] if function_index < colors.functions.size() else Color.black
|
||||
|
||||
func get_point_shape(function_index: int) -> int:
|
||||
return shapes[function_index] if function_index < shapes.size() else Point.Shape.CIRCLE
|
||||
|
@ -1,27 +0,0 @@
|
||||
extends Reference
|
||||
class_name DrawingOptions
|
||||
|
||||
var points: bool = true
|
||||
var grid: bool = false
|
||||
var bounding_box: bool = true
|
||||
var background: bool = true
|
||||
var borders: bool = false
|
||||
var ticks: bool = true
|
||||
var labels: bool = true
|
||||
var origin: bool = true
|
||||
|
||||
var colors: Dictionary = {
|
||||
bounding_box = Color.black,
|
||||
grid = Color.gray,
|
||||
functions = [Color.red, Color.green, Color.blue, Color.black]
|
||||
}
|
||||
|
||||
var shapes: Array = [Point.Shape.CIRCLE, Point.Shape.SQUARE, Point.Shape.TRIANGLE, Point.Shape.CROSS]
|
||||
var point_radius: float = 3.0
|
||||
var font: BitmapFont = Label.new().get_font("")
|
||||
|
||||
func get_function_color(function_index: int) -> Color:
|
||||
return colors.functions[function_index] if function_index < colors.functions.size() else Color.black
|
||||
|
||||
func get_point_shape(function_index: int) -> int:
|
||||
return shapes[function_index] if function_index < shapes.size() else Point.Shape.CIRCLE
|
@ -0,0 +1,56 @@
|
||||
extends Reference
|
||||
class_name ArrayOperations
|
||||
|
||||
static func add_int(array: Array, _int: int) -> Array:
|
||||
var t: Array = array.duplicate(true)
|
||||
for ti in t.size():
|
||||
t[ti] = int(t[ti] + _int)
|
||||
return t
|
||||
|
||||
static func add_float(array: Array, _float: float) -> Array:
|
||||
var t: Array = array.duplicate(true)
|
||||
for ti in t.size():
|
||||
t[ti] = float(t[ti] + _float)
|
||||
return t
|
||||
|
||||
static func multiply_int(array: Array, _int: int) -> Array:
|
||||
var t: Array = array.duplicate(true)
|
||||
for ti in t.size():
|
||||
t[ti] = int(t[ti] * _int)
|
||||
return t
|
||||
|
||||
static func multiply_float(array: Array, _float: float) -> Array:
|
||||
var t: Array = array.duplicate(true)
|
||||
for ti in t.size():
|
||||
t[ti] = float(t[ti] * _float)
|
||||
return t
|
||||
|
||||
static func pow(array: Array, _int: int) -> Array:
|
||||
var t: Array = array.duplicate(true)
|
||||
for ti in t.size():
|
||||
t[ti] = float(pow(t[ti], _int))
|
||||
return t
|
||||
|
||||
static func cos(array: Array) -> Array:
|
||||
var t: Array = array.duplicate(true)
|
||||
for val in array.size():
|
||||
t[val] = cos(t[val])
|
||||
return t
|
||||
|
||||
static func sin(array: Array) -> Array:
|
||||
var t: Array = array.duplicate(true)
|
||||
for val in array.size():
|
||||
t[val] = sin(t[val])
|
||||
return t
|
||||
|
||||
static func affix(array: Array, _string: String) -> Array:
|
||||
var t: Array = array.duplicate(true)
|
||||
for val in array.size():
|
||||
t[val] = str(t[val]) + _string
|
||||
return t
|
||||
|
||||
static func suffix(array: Array, _string: String) -> Array:
|
||||
var t: Array = array.duplicate(true)
|
||||
for val in array.size():
|
||||
t[val] = _string + str(t[val])
|
||||
return t
|
Loading…
Reference in New Issue
Block a user