tool extends Chart class_name RadarChart """ [RadarChart] - General purpose node for Radar Charts A radar chart is a graphical method of displaying multivariate data in the form of a two-dimensional chart of three or more quantitative variables represented on axes starting from the same point. The relative position and angle of the axes is typically uninformative, but various heuristics, such as algorithms that plot data as the maximal total area, can be applied to sort the variables (axes) into relative positions that reveal distinct correlations, trade-offs, and a multitude of other comparative measures. / source : Wikipedia / """ func _get_property_list(): return [ # Chart Properties { "hint": PROPERTY_HINT_NONE, "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Properties/are_values_columns", "type": TYPE_BOOL }, { "hint": PROPERTY_HINT_RANGE, "hint_string": "-1,100,1", "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Properties/labels_index", "type": TYPE_INT }, { "hint": PROPERTY_HINT_RANGE, "hint_string": "-1,100,1", "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Properties/function_names_index", "type": TYPE_INT }, { "hint": PROPERTY_HINT_NONE, "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Properties/use_height_as_radius", "type": TYPE_BOOL }, { "hint": PROPERTY_HINT_RANGE, "hint_string": "0,2000", "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Properties/radius", "type": TYPE_REAL }, # Chart Display { "hint": PROPERTY_HINT_RANGE, "hint_string": "0.1,100", "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Display/full_scale", "type": TYPE_REAL }, # Chart Style { "hint": 24, "hint_string": "%d/%d:%s"%[TYPE_INT, PROPERTY_HINT_ENUM, PoolStringArray(PointShapes.keys()).join(",")], "name": "Chart_Style/points_shape", "type": TYPE_ARRAY, "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE }, { "hint": PROPERTY_HINT_NONE, "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Style/function_colors", "type": TYPE_COLOR_ARRAY }, { "hint": PROPERTY_HINT_NONE, "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Style/outline_color", "type": TYPE_COLOR }, { "hint": PROPERTY_HINT_NONE, "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Style/grid_color", "type": TYPE_COLOR }, { "class_name": "Font", "hint": PROPERTY_HINT_RESOURCE_TYPE, "hint_string": "Font", "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Style/font", "type": TYPE_OBJECT }, { "class_name": "Font", "hint": PROPERTY_HINT_RESOURCE_TYPE, "hint_string": "Font", "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Style/bold_font", "type": TYPE_OBJECT }, { "hint": PROPERTY_HINT_NONE, "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Style/font_color", "type": TYPE_COLOR }, { "hint": PROPERTY_HINT_ENUM, "hint_string": PoolStringArray(TemplatesNames.keys()).join(","), "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Style/template", "type": TYPE_INT }, { "hint": PROPERTY_HINT_RANGE, "hint_string": "0,360", "usage": PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE, "name": "Chart_Modifiers/rotation", "type": TYPE_REAL }, ] func structure_datas(database : Array, are_values_columns : bool, labels_index : int): # @x_values_index can be either a column or a row relative to x values # @y_values can be either a column or a row relative to y values self.labels_index = labels_index self.are_values_columns = are_values_columns match are_values_columns: true: for row in database.size(): if row == labels_index: x_labels = database[row] as PoolStringArray else: if database[row].empty() or database[row].size() < 2: continue x_datas.append(PoolRealArray(database[row] as Array)) for column in database[row].size(): if column == function_names_index: y_labels.append(database[row][column]) false: for row in database.size(): if row == function_names_index: y_labels = database[row] as PoolStringArray var x_temp_datas : PoolRealArray = [] for column in database[row].size(): if column == labels_index: x_labels.append(database[row][column] as String) else: x_temp_datas.append(database[row][column] as float) x_datas.append(x_temp_datas) if labels_index == -1 : for data in x_datas[0].size(): x_labels.append("Element %s" % data) if function_names_index == -1 : for data in x_datas.size(): y_labels.append("Function %s" % data) func build_chart(): SIZE = get_size() origin = OFFSET + SIZE/2 var radar_polygon : Array func calculate_pass() : var ordered_max : Array for data in x_datas : var ordered_data : Array = (data as Array) ordered_data.sort() ordered_max.append(ordered_data.pop_back()) ordered_max.sort() var max_value : float = ordered_max.pop_back() var dist = full_scale * pow(10.0,str(max_value).length()-2) var multi = 0 var value = dist * multi x_chors.append(value as String) while value < max_value: multi+=1 value = dist * multi x_chors.append(value as String) func calculate_coordinates(): for chor in x_chors.size(): var inner_polyline : PoolVector2Array var scalar_factor : float = (x_chors[chor] as float/x_chors.back() as float) for function in functions: var angle : float = ((2 * PI * function) / functions) - PI /2 + deg2rad(rotation) var x_coordinate : float = (radius if (not use_height_as_radius and radius