找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1051|回复: 0

[教程] 【图表组件】雷达图

[复制链接]
发表于 2025-7-18 17:51:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 Maz马 于 2026-4-20 19:05 编辑

预览

                               
登录/注册后可看大图


图表组件
    雷达图
    折线图

B站魔理沙大佬已经出过视频讲过思路了
不过她似乎并没有给出源码,然后论坛也没有看到过,所以我发一下
可能细节和魔理沙佬的不太一样,但思路应该都一样

[RenPy] 纯文本查看 复制代码
init python:
    import math
    class RadarChart(renpy.Displayable):
        def __init__(self,values,max_value=10,size=None,points=None,levels=None,colors=None,**kwargs):
            super(RadarChart, self).__init__(**kwargs)
            self.texts = list(values.keys())
            self.nums = list(values.values())
            self.max_value = max_value
            self.size = size or 400
            self.points = points or len(self.texts)
            self.levels = levels or 1
            self.colors = colors or ["#a646ffd0", "#6085ffd0", "#ffffff"]

            self.text_size = self.size*0.05
             
        def render(self,width,height,st,at):
            render = renpy.Render(self.size,self.size)
            canvas = render.canvas()
             
            center = (self.size // 2, self.size // 2)
            # 绘制背景,动态计算顶点位置 (N边形)
            radius = self.size // 2 - 20
            points = []
            for i in range(self.points):
                angle = 2 * math.pi * i / self.points - math.pi / 2 # 保持顶部为起点
                x = center[0] + radius * math.cos(angle)
                y = center[1] + radius * math.sin(angle)
                points.append((x, y))
            canvas.polygon(self.colors[0],points)
 
            # 轴
            for point in points:
                canvas.line(self.colors[1],center,point,width=2)
            # 绘制蜘蛛网格
            for n in range(1, self.levels + 1):
                scale = n / self.levels # 缩放比例
                grid_points = []
                for i in range(self.points):
                    angle = 2 * math.pi * i / self.points - math.pi / 2
                    x = center[0] + (radius * scale) * math.cos(angle)
                    y = center[1] + (radius * scale) * math.sin(angle)
                    grid_points.append((x, y))
                canvas.polygon(self.colors[1],grid_points,width=2)
             
            # 绘制数据区域
            data_points = []
            for i, value in enumerate(self.nums):
                scaled_radius = radius * (value / self.max_value)
                angle = 2 * math.pi * i /len(self.nums) - math.pi / 2
                x = center[0] + scaled_radius * math.cos(angle)
                y = center[1] + scaled_radius * math.sin(angle)
                data_points.append((x, y))
            canvas.polygon(self.colors[1],data_points)
            # 描边
            canvas.polygon(self.colors[1],data_points,width=2)
 
            # 顶点上垂直排列的文本组
            group_radius = radius + self.text_size
            for i, (label, value) in enumerate(zip(self.texts, self.nums)):
                angle = 2 * math.pi * i / len(self.texts) - math.pi / 2
                x = center[0] + group_radius * math.cos(angle)
                y = center[1] + group_radius * math.sin(angle)
                 
                # 预计算文本尺寸
                label_text = Text(label, color=self.colors[2], size=self.text_size,align=(0.5,0.5))
                value_text = Text(str(value), color=self.colors[2], size=self.text_size,align=(0.5,0.5))
                label_width, label_height = label_text.size()
                value_width, value_height = value_text.size()
                 
                # 确定VBox总尺寸
                group_width = max(label_width, value_width)
                group_height = label_height + value_height
                 
                # 创建固定尺寸的VBox
                text_group = VBox(label_text,value_text,xysize=(group_width, group_height),align=(0.5,0.5))
                 
                # 渲染
                render.blit(renpy.render(text_group, width, height, st, at),(x - group_width/2, y - group_height/2))
             
            return render
 
# 示例数据,只有points和values是必要入参,其他的有默认
image radarchart = RadarChart(
    values={"攻击": 12,"防御": 6, "速度": 9,"技巧": 7,"耐力": 5,"智力": 1},  # 数值字典,以正N边形顺时针排列,如果数值的数量不对应
    max_value=10,                                                          # 图表最大数值,如果提供的数值超过最大数值,会出现有意思的错位效果
    size=400,                                                              # 整个图表的尺寸
    points=5,                                                              # 正N边形
    levels=6,                                                              # 雷达图中的蛛网纹路层级,是美化用的,这里是6层蛛网纹路
    colors=["#a646ffd0", "#6085ffd0", "#ffffff"])                    # 颜色列表,背景色,纹路色,文字色
 
label test:
    show radarchart:
        align(0.5,0.5)


#点击头像 查看我写的更多屎
粉身碎骨浑不怕,要留答辩在人间










评分

参与人数 1活力 +300 干货 +3 收起 理由
烈林凤 + 300 + 3 感谢分享!

查看全部评分

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|RenPy中文空间 ( 苏ICP备17067825号 )

GMT+8, 2026-5-1 22:38 , Processed in 0.024627 second(s), 9 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表