예제 #1
0
    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'}
예제 #2
0
    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'}
예제 #3
0
    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'}