[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)