diff --git a/addons/easy_charts/LineChart/line_chart.gd b/addons/easy_charts/LineChart/line_chart.gd index 8b62061..fac5cec 100644 --- a/addons/easy_charts/LineChart/line_chart.gd +++ b/addons/easy_charts/LineChart/line_chart.gd @@ -48,7 +48,7 @@ func _get_property_list(): }, { "hint": PROPERTY_HINT_RANGE, - "hint_string": "0.1,10", + "hint_string": "0.1,100", "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Display/y_decim", "type": TYPE_REAL @@ -114,7 +114,7 @@ func _get_property_list(): }, { "hint": PROPERTY_HINT_ENUM, - "hint_string": PoolStringArray(TemplatesNames.keys()).join(","), + "hint_string": PoolStringArray(Utilities.templates.keys()).join(","), "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Style/template", "type": TYPE_INT @@ -142,7 +142,7 @@ func structure_datas(database: Array, are_values_columns: bool, x_values_index: if x_data.is_valid_float() or x_data.is_valid_integer(): x_datas.append(x_data as float) else: - x_datas.append(x_data.replace(",", ".") as float) + x_datas.append(x_data) else: if row != 0: var y_data = database[row][column] @@ -167,7 +167,7 @@ func structure_datas(database: Array, are_values_columns: bool, x_values_index: for data in y_datas: for value in data.size(): data[value] = data[value] as float - + # draw y labels var to_order: Array var to_order_min: Array @@ -175,7 +175,6 @@ func structure_datas(database: Array, are_values_columns: bool, x_values_index: # define x_chors and y_chors var ordered_cluster = y_datas[cluster] as Array ordered_cluster.sort() - ordered_cluster = PoolIntArray(ordered_cluster) var margin_max = ordered_cluster[ordered_cluster.size() - 1] var margin_min = ordered_cluster[0] to_order.append(margin_max) @@ -186,7 +185,7 @@ func structure_datas(database: Array, are_values_columns: bool, x_values_index: var margin = to_order.pop_back() if not origin_at_zero: y_margin_min = to_order_min.pop_front() - v_dist = y_decim * pow(10.0, str(margin).length() - 2) + v_dist = y_decim * pow(10.0, (str(margin).length() - 2 if typeof(margin) == TYPE_INT else str(margin).length() - 4 )) var multi = 0 var p = (v_dist * multi) + ((y_margin_min) if not origin_at_zero else 0) y_chors.append(p as String) @@ -221,15 +220,15 @@ func build_chart(): func calculate_pass(): if invert_chart: - x_chors = y_labels as PoolStringArray + x_chors = y_labels.duplicate(true) as PoolStringArray else: if show_x_values_as_labels: - x_chors = x_datas as PoolStringArray + x_chors = x_datas.duplicate(true) as PoolStringArray else: - x_chors = x_labels + x_chors = x_labels.duplicate(true) # calculate distance in pixel between 2 consecutive values/datas - x_pass = (SIZE.x - OFFSET.x) / (x_chors.size() - 1) + x_pass = (SIZE.x - OFFSET.x) / (x_chors.size()-1 if x_chors.size()>1 else x_chors.size() ) y_pass = origin.y / (y_chors.size() - 1) @@ -271,7 +270,7 @@ func calculate_coordinates(): else: x_coordinates.append((x_datas[x] - x_margin_min) * x_pass / h_dist) - for f in functions: + for f in range(0,functions): point_values.append([]) point_positions.append([]) diff --git a/addons/easy_charts/Utilities/ChartContainer.gd b/addons/easy_charts/Utilities/ChartContainer.gd deleted file mode 100644 index 53f283e..0000000 --- a/addons/easy_charts/Utilities/ChartContainer.gd +++ /dev/null @@ -1,40 +0,0 @@ -tool -extends Container - -var LineChart = preload("LineChart/LineChart.tscn") - -export (String,"None","LineChart","BoxChart") var chart_type : String setget set_type,get_type -var chart : Control setget set_chart,get_chart -var templates : Dictionary - -# Called when the node enters the scene tree for the first time. -func _ready(): - set_chart(get_child(0)) - var template_file : File = File.new() - template_file.open("res://addons/easy_charts/templates.json",File.READ) - templates = JSON.parse(template_file.get_as_text()).get_result() - template_file.close() - -func set_type(type : String): - chart_type = type - var new_node - if get_children().size(): - for child in get_children(): - child.queue_free() - if Engine.editor_hint: - match type: - "LineChart": - new_node = LineChart.instance() - add_child(new_node) - new_node.set_owner(owner) - "None": - set_chart(null) - -func get_type(): - return chart_type - -func set_chart(ch : Control): - chart = ch - -func get_chart(): - return chart diff --git a/addons/easy_charts/Utilities/ChartContainer2D.gd b/addons/easy_charts/Utilities/ChartContainer2D.gd deleted file mode 100644 index 5fec906..0000000 --- a/addons/easy_charts/Utilities/ChartContainer2D.gd +++ /dev/null @@ -1,40 +0,0 @@ -tool -extends Node2D - -var LineChart = preload("LineChart2D/LineChart2D.tscn") -var ColumnChart = preload("BarChart2D/BarChart2D.tscn") - -export (String,"None","LineChart2D","BarChart2D") var chart_type : String setget set_type,get_type -var chart : Node2D setget set_chart,get_chart - -# Called when the node enters the scene tree for the first time. -func _ready(): - set_chart(get_child(0)) - -func set_type(type : String): - chart_type = type - var new_node - if get_children().size(): - for child in get_children(): - child.queue_free() - if Engine.editor_hint: - match type: - "LineChart2D": - new_node = LineChart.instance() - add_child(new_node) - new_node.set_owner(owner) - "ColumnChart2D": - new_node = ColumnChart.instance() - add_child(new_node) - new_node.set_owner(owner) - "None": - set_chart(null) - -func get_type(): - return chart_type - -func set_chart(ch : Node2D): - chart = ch - -func get_chart(): - return chart diff --git a/addons/easy_charts/Utilities/Point/Point.gd b/addons/easy_charts/Utilities/Point/Point.gd index db52c21..dee7126 100644 --- a/addons/easy_charts/Utilities/Point/Point.gd +++ b/addons/easy_charts/Utilities/Point/Point.gd @@ -12,7 +12,7 @@ var function : String setget set_function, get_function var mouse_entered : bool = false enum SHAPES { - DOT, TRIANGLE, SQUARE, CROSS + Dot, Triangle, Square, Cross } var shape : int = 0 setget set_shape, get_shape @@ -31,20 +31,23 @@ func _draw(): draw_point(5,color) func draw_point(size : float, color : Color): + var factor : float match shape: - SHAPES.DOT: + SHAPES.Dot: draw_circle(OFFSET, size, color) - SHAPES.TRIANGLE: + SHAPES.Triangle: size+=6 + factor = 2 draw_colored_polygon([ - OFFSET-Vector2(0,size/2), OFFSET+Vector2(1,1)*size/2, OFFSET-Vector2(1,-1)*size/2 + OFFSET-Vector2(0,size/factor), OFFSET+Vector2(1,1)*size/factor, OFFSET-Vector2(1,-1)*size/factor ], color,[],null,null,false) - SHAPES.SQUARE: + SHAPES.Square: size+=4 + factor = 2 draw_colored_polygon([ - OFFSET-Vector2(1,1)*size/2, OFFSET-Vector2(-1,1)*size/2, OFFSET+Vector2(1,1)*size/2, OFFSET-Vector2(1,-1)*size/2 + OFFSET-Vector2(1,1)*size/factor, OFFSET-Vector2(-1,1)*size/factor, OFFSET+Vector2(1,1)*size/factor, OFFSET-Vector2(1,-1)*size/factor ], color,[],null,null,false) - SHAPES.CROSS: + SHAPES.Cross: size+=2 draw_line(OFFSET-Vector2(size,0), OFFSET+Vector2(size,0), color, size-5, true) draw_line(OFFSET-Vector2(0,size), OFFSET+Vector2(0,size), color, size-5, true) diff --git a/addons/easy_charts/Utilities/Point/PointData.tscn b/addons/easy_charts/Utilities/Point/PointData.tscn index 520bda4..b68dd90 100644 --- a/addons/easy_charts/Utilities/Point/PointData.tscn +++ b/addons/easy_charts/Utilities/Point/PointData.tscn @@ -19,15 +19,16 @@ corner_radius_bottom_right = 5 corner_radius_bottom_left = 5 corner_detail = 20 -[node name="PointData" type="CanvasLayer"] +[node name="CanvasLayer" type="CanvasLayer"] [node name="PointData" type="PanelContainer" parent="."] +visible = false anchor_right = 0.0694688 anchor_bottom = 0.067 -margin_left = -256.805 -margin_top = -36.1267 -margin_right = -256.941 -margin_bottom = -35.3267 +margin_left = 79.7858 +margin_top = -250.75 +margin_right = 79.6496 +margin_bottom = -249.95 grow_horizontal = 2 mouse_filter = 2 custom_styles/panel = SubResource( 1 ) diff --git a/addons/easy_charts/Utilities/Scripts/Chart.gd b/addons/easy_charts/Utilities/Scripts/Chart.gd index 9920288..ec647c0 100644 --- a/addons/easy_charts/Utilities/Scripts/Chart.gd +++ b/addons/easy_charts/Utilities/Scripts/Chart.gd @@ -2,6 +2,7 @@ extends Control class_name Chart # Classes +enum TYPES { Line, Bar, Scatter, Radar, Pie } # Signals .................................. signal chart_plotted(chart) # emit when a chart is plotted (static) or updated (dynamic) @@ -19,7 +20,6 @@ var LegendElement : PackedScene = preload("../Legend/FunctionLegend.tscn") # Enums ..................................... enum PointShapes { Dot, Triangle, Square, Cross } -enum TemplatesNames { Default, Clean, Gradient, Minimal, Invert } # Shared Variables ......................... var SIZE : Vector2 = Vector2() @@ -46,8 +46,8 @@ var y_chors : Array var x_coordinates : Array var y_coordinates : Array -# datas contained in file -var datas : Array +# data contained in file +var data : Array # amount of functions to represent var functions : int = 0 @@ -109,12 +109,17 @@ var font : Font setget set_font var bold_font : Font setget set_bold_font var font_color : Color = Color("#1e1e1e") setget set_font_color -var template : int = TemplatesNames.Default setget set_template +var template : int = 0 setget set_template # modifiers var rotation : float = 0 setget set_rotation var invert_chart : bool = false setget set_invert_chart +static func instance(chart_type : int): + var chart_t : String = Utilities.get_chart_type(chart_type) + var chart : String = "res://addons/easy_charts/%s/%s.tscn" % [chart_t, chart_t] + return load(chart).instance() + # .......................... Properties Manager .................................... func _get(property): match property: @@ -267,17 +272,16 @@ func plot(): Utilities._print_message("Can't plot a chart without a Source file. Please, choose it in editor, or use the custom function _plot().",1) return - datas = read_datas(source) - structure_datas(datas.duplicate(true),are_values_columns,labels_index) + data = read_datas(source) + structure_datas(data.duplicate(true),are_values_columns,labels_index) build_chart() count_functions() calculate_pass() - calculate_coordinates() calculate_colors() + calculate_coordinates() set_shapes() create_legend() emit_signal("chart_plotted",self) - connect("item_rect_changed", self, "redraw") func plot_from_csv(csv_file : String, _delimiter : String = delimiter): load_font() @@ -287,13 +291,13 @@ func plot_from_csv(csv_file : String, _delimiter : String = delimiter): Utilities._print_message("Can't plot a chart without a Source file. Please, choose it in editor, or use the custom function _plot().",1) return - datas = read_datas(csv_file, _delimiter) - structure_datas(datas.duplicate(true),are_values_columns,labels_index) + data = read_datas(csv_file, _delimiter) + structure_datas(data.duplicate(true),are_values_columns,labels_index) build_chart() count_functions() calculate_pass() - calculate_coordinates() calculate_colors() + calculate_coordinates() set_shapes() create_legend() emit_signal("chart_plotted",self) @@ -306,13 +310,34 @@ func plot_from_array(array : Array) -> void: Utilities._print_message("Can't plot a chart without an empty Array.",1) return - datas = array - structure_datas(datas.duplicate(true),are_values_columns,labels_index) + data = array + structure_datas(data.duplicate(true),are_values_columns,labels_index) build_chart() count_functions() calculate_pass() - calculate_coordinates() calculate_colors() + calculate_coordinates() + set_shapes() + create_legend() + emit_signal("chart_plotted",self) + + if not is_connected("item_rect_changed",self, "redraw"): connect("item_rect_changed", self, "redraw") + +func plot_from_dataframe(dataframe : DataFrame) -> void: + load_font() + PointData.hide() + + data = dataframe.get_dataset() + if data.empty(): + Utilities._print_message("Can't plot a chart without an empty Array.",1) + return + + structure_datas(data.duplicate(true),are_values_columns,labels_index) + build_chart() + count_functions() + calculate_pass() + calculate_colors() + calculate_coordinates() set_shapes() create_legend() emit_signal("chart_plotted",self) @@ -324,8 +349,8 @@ func update_plot_data(array : Array) -> void: Utilities._print_message("Can't plot a chart without an empty Array.",1) return - datas.append(array) - structure_datas(datas.duplicate(true),are_values_columns,labels_index) + data.append(array) + structure_datas(data.duplicate(true),are_values_columns,labels_index) redraw() count_functions() calculate_colors() @@ -377,14 +402,14 @@ func read_datas(source : String, _delimiter : String = delimiter): func count_functions(): if are_values_columns: if not invert_chart: - functions = datas[0].size()-1 + functions = data[0].size()-1 else: - functions = datas.size()-1 + functions = data.size()-1 else: if invert_chart: - functions = datas[0].size()-1 + functions = x_datas.size() else: - functions = datas.size()-1 + functions = y_datas.size() func clear_points(): if $Points.get_children(): diff --git a/addons/easy_charts/Utilities/Scripts/utilities.gd b/addons/easy_charts/Utilities/Scripts/utilities.gd index d206eae..836b796 100644 --- a/addons/easy_charts/Utilities/Scripts/utilities.gd +++ b/addons/easy_charts/Utilities/Scripts/utilities.gd @@ -3,24 +3,35 @@ extends Node var plugin_name : String = "Easy Charts" var templates : Dictionary = {} +var chart_types : Dictionary = { + 0:"LineChart", + 1:"BarChart", + 2:"ScatterChart", + 3:"RadarChart", + 4:"PieChart" +} func _ready(): - templates = _load_templates() - _print_message("Templates loaded") + templates = _load_templates() + +# _print_message("Templates loaded") func _print_message(message : String, type : int = 0): - match type: - 0: - print("[%s] => %s" % [plugin_name, message]) - 1: - printerr("ERROR: [%s] => %s" % [plugin_name, message]) + match type: + 0: + print("[%s] => %s" % [plugin_name, message]) + 1: + printerr("ERROR: [%s] => %s" % [plugin_name, message]) func _load_templates() -> Dictionary: - var template_file : File = File.new() - template_file.open("res://addons/easy_charts/templates.json",File.READ) - var templates = JSON.parse(template_file.get_as_text()).get_result() - template_file.close() - return templates + var template_file : File = File.new() + template_file.open("res://addons/easy_charts/templates.json",File.READ) + var templates = JSON.parse(template_file.get_as_text()).get_result() + template_file.close() + return templates func get_template(template_index : int): - return templates.get(templates.keys()[template_index]) + return templates.get(templates.keys()[template_index]) + +func get_chart_type(chart_type : int): + return chart_types.get(chart_types.keys()[chart_type]) diff --git a/addons/easy_charts/Utilities/utilities.gd b/addons/easy_charts/Utilities/utilities.gd deleted file mode 100644 index 3323bd9..0000000 --- a/addons/easy_charts/Utilities/utilities.gd +++ /dev/null @@ -1,23 +0,0 @@ -tool -extends Node - -var plugin_name : String = "Easy Charts" -var templates : Dictionary = {} - -func _ready(): - templates = _load_templates() - _print_message("Templates loaded") - -func _print_message(message : String, type : int = 0): - match type: - 0: - print("[%s] => %s" % [plugin_name, message]) - 1: - printerr("ERROR: [%s] => %s" % [plugin_name, message]) - -func _load_templates() -> Dictionary: - var template_file : File = File.new() - template_file.open("res://addons/easy_charts/templates.json",File.READ) - var templates = JSON.parse(template_file.get_as_text()).get_result() - template_file.close() - return templates diff --git a/addons/easy_charts/plugin.cfg b/addons/easy_charts/plugin.cfg index f79b203..b020ed9 100644 --- a/addons/easy_charts/plugin.cfg +++ b/addons/easy_charts/plugin.cfg @@ -3,5 +3,5 @@ name="EasyCharts" description="" author="Nicolò \"fenix\" Santilio" -version="0.4.2" +version="0.4.5" script="plugin.gd"