def execute(self, context): self.slices = [] self.materials = [] self.init_data() data_min = min(self.data, key=lambda entry: entry[1])[1] if data_min <= 0: self.report({'ERROR'}, 'Pie chart support only positive values!') self.create_container() # create cylinder from triangles rot = 0 rot_inc = 2.0 * math.pi / self.vertices scale = 1.0 / self.vertices * math.pi for i in range(0, self.vertices): cyl_slice = self.create_slice() cyl_slice.scale.y *= scale cyl_slice.rotation_euler.z = rot rot += rot_inc self.slices.append(cyl_slice) values_sum = sum(int(entry[1]) for entry in self.data) data_len = len(self.data) color_gen = ColorGen(self.color_shade, ColorType.str_to_type(self.color_type), (0, data_len)) prev_i = 0 for i in range(data_len): portion = self.data[i][1] / values_sum increment = round(portion * self.vertices) # Ignore data with zero value if increment == 0: print('Warning: Data with zero value i: {}, value: {}! Useless for pie chart.'.format(i, self.data[i][1])) continue portion_end_i = prev_i + increment slice_obj = self.join_slices(prev_i, portion_end_i) if slice_obj is None: raise Exception('Error occurred, try to increase number of vertices, i_from" {}, i_to: {}, inc: {}, val: {}'.format(prev_i, portion_end_i, increment, self.data[i][1])) break slice_mat = color_gen.get_material(data_len - i) slice_obj.active_material = slice_mat slice_obj.parent = self.container_object label_rot_z = (((prev_i + portion_end_i) * 0.5) / self.vertices) * 2.0 * math.pi label_obj = self.add_value_label((self.label_distance, 0, 0), (0, 0, label_rot_z), self.data[i][0], portion, self.data[i][1]) label_obj.rotation_euler = (0, 0, 0) prev_i += increment if self.header_settings.create: self.create_header((0, 0.7, 0.15), False) self.select_container() return {'FINISHED'}
def execute(self, context): self.init_data() if self.dm.predicted_data_type == DataType.Categorical and self.data_type_as_enum() == DataType.Numerical: self.report({'ERROR'}, 'Cannot convert categorical data into numerical!') return {'CANCELLED'} self.create_container() if self.data_type_as_enum() == DataType.Numerical: self.data = get_data_in_range(self.data, self.axis_settings.x_range) sorted_data = sorted(self.data, key=lambda x: x[0]) else: sorted_data = self.data tick_labels = [] if self.data_type_as_enum() == DataType.Numerical: normalized_vert_list = [(self.normalize_value(entry[0], 'x'), 0.0, self.normalize_value(entry[1], 'z')) for entry in sorted_data] else: normalized_vert_list = [(normalize_value(i, 0, len(self.data)), 0.0, self.normalize_value(entry[1], 'z')) for i, entry in enumerate(sorted_data)] tick_labels = list(zip(*sorted_data))[0] edges = [[i - 1, i] for i in range(1, len(normalized_vert_list))] self.create_curve(normalized_vert_list, edges) self.add_bevel_obj() if self.use_shader: mat = NodeShader(self.get_name(), self.color_shade, scale=self.container_size[2], location_z=self.container_object.location[2]).create_geometry_shader() else: mat = ColorGen(self.color_shade, ColorType.Constant, self.axis_settings.z_range).get_material() self.curve_obj.data.materials.append(mat) self.curve_obj.active_material = mat if self.axis_settings.create: AxisFactory.create( self.container_object, self.axis_settings, 2, self.chart_id, labels=self.labels, tick_labels=(tick_labels, [], []), container_size=self.container_size, ) if self.series_label: self.create_series_label(mat) if self.header_settings.create: self.create_header() self.select_container() return {'FINISHED'}
def execute(self, context): self.slices = [] self.materials = [] self.init_data() data_min = min(self.data, key=lambda entry: entry[1])[1] if data_min <= 0: self.report({'ERROR'}, 'Pie chart support only positive values!') return {'CANCELLED'} data_len = len(self.data) if data_len >= self.vertices: self.report({'ERROR'}, 'There are more data than possible slices, ' + 'please increase the vertices value!') return {'CANCELLED'} self.create_container() # create cylinder from triangles rot = 0 rot_inc = 2.0 * math.pi / self.vertices scale = 1.0 / self.vertices * math.pi for i in range(0, self.vertices): cyl_slice = self.create_slice() cyl_slice.scale.y *= scale cyl_slice.rotation_euler.z = rot rot += rot_inc self.slices.append(cyl_slice) values_sum = sum(float(entry[1]) for entry in self.data) color_gen = ColorGen(self.color_shade, ColorType.str_to_type(self.color_type), (0, data_len)) prev_i = 0 legend_data = {} for i in range(data_len): portion = self.data[i][1] / values_sum increment = round(portion * self.vertices) # Ignore data with zero value if increment == 0: print( 'Warning: Data with zero value i: {}, value: {}! Useless for pie chart.' .format(i, self.data[i][1])) continue portion_end_i = prev_i + increment slice_obj = self.join_slices(prev_i, portion_end_i) if slice_obj is None: raise RuntimeError( 'Error occurred, try to increase number of vertices, i_from" {}, i_to: {}, inc: {}, val: {}' .format(prev_i, portion_end_i, increment, self.data[i][1])) slice_mat = color_gen.get_material(data_len - i) slice_obj.active_material = slice_mat if self.scale_z_with_value: slice_obj.scale.z = self.slice_size * portion slice_obj.parent = self.container_object if self.create_labels: rotation_z = ((prev_i + portion_end_i) * 0.5) / self.vertices label_obj = self.add_value_label( self.label_distance, rotation_z * 2.0 * math.pi + math.pi, self.data[i][0], self.data[i][1], portion) label_obj.rotation_euler = (0, 0, 0) prev_i += increment legend_data[str(slice_mat.name)] = self.data[i][0] if self.header_settings.create: self.create_header(location=(0, 0.7, 0.15), rotate=False) if self.legend_settings.create: Legend(self.chart_id, self.legend_settings).create(self.container_object, legend_data) self.select_container() return {'FINISHED'}