You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pharo10中Roassal3多折线图如何在线条末端添加水平标签

Pharo 10 Roassal3 多序列折线标签实现方案

问题说明

在Pharo 10中使用Roassal3做多序列折线可视化时,三类常规标签实现都存在明显缺陷:

  • 直接使用RSLegend生成的默认图例尺寸过大,会自动压缩绘图区适配画布
  • 将RSLabel绑定到折线markerEnd属性时,标签会跟随折线末端的倾斜角度旋转,无法保持水平
  • 基于RSYLabelDecoration实现的侧边标签偏移逻辑繁琐,显示效果达不到折线末端直连标签的预期
  • 目前Roassal3官方文档尚未完善,没有对应场景的公开示例。

方案1:折线末端水平标签(推荐,匹配旧版Roassal展示效果)

markerEnd属性的设计逻辑就是跟随附着的路径端点旋转,所以直接给它传RSLabel必然会出现倾斜,不需要在这个属性上硬改。
正确的实现逻辑是等图表完成所有坐标映射(执行完build方法)后,直接读取每条折线终点的画布像素坐标,在该位置做微小偏移后添加独立的水平文本标签即可,标签不会受折线角度影响。
可直接运行的实现代码:

| chart dates values firstDate labels |
chart := RSChart new.
dates := (20 to: 1 by: -1) collect: [ :i | Date today subtractDays: i ]. 
firstDate := dates first.
values := #(
    #(4.29 4.01 3.82 3.91 4.01 3.73 4.47 4.28 4.18 4.00 3.72 4.27 3.99 4.91 5.09 4.91 5.09 4.91 4.44 4.91)
    #(2.0 1.98 1.98 1.98 1.99 1.96 2.07 1.96 1.90 1.95 1.98 2.04 2.12 2.12 2.21 2.27 2.27 2.10 2.19 1.95)
).
labels := #('series 1' 'series 2').

" 先绘制所有基础折线,不设置markerEnd "
values with: labels do: [ :series :label | 
   | plot |
   plot := RSLinePlot new.
   plot 
       x: (dates collect: [ :date | date julianDayNumber - firstDate julianDayNumber ])
       y: series.
   chart addPlot: plot.
].

chart addDecoration: (RSHorizontalTick new 
    labelConversion: [ :value | Date julianDayNumber: firstDate julianDayNumber + value ]; 
    useDiagonalLabel; 
    yourself).
chart addDecoration: RSVerticalTick new.
chart ylabel: 'The values'.
" 必须先完成build,此时所有折线的像素坐标才会计算完成 "
chart build.

" 遍历折线,在终点位置添加水平标签 "
chart plots with: labels do: [ :plot :label |
    | endPoint lineColor textLabel |
    endPoint := plot points last.
    lineColor := chart colorFor: plot.
    textLabel := RSLabel new
        text: label;
        fontSize: 12;
        color: lineColor;
        " 右侧偏移3像素,垂直方向和终点对齐,避免和折线端点重叠 "
        position: (endPoint x + 3) @ endPoint y;
        yourself.
    chart canvas add: textLabel.
].

^chart canvas open

如果出现标签和其他折线交叉的情况,可以给标签加一个同色描边的白色背景,或者微调垂直偏移量即可,调整成本远低于装饰器方案。


方案2:优化RSLegend布局避免压缩绘图区

如果更习惯传统图例的展示形式,不需要修改图例本身的样式,只要把图例设置为悬浮定位,就不会触发绘图区的自动收缩逻辑:

" 原有chart build逻辑不变,替换原来的legend初始化代码即可 "
legend := RSLegend new.
legend container: chart canvas.
labels with: chart plots do: [ :text :plot |
    legend text: text withBoxColor: (chart colorFor: plot)
].
legend layout vertical.
" 设置图例悬浮在画布右上角,不占用绘图区空间 "
legend location
    outer;
    right;
    top;
    offset: 10@10.
legend build.

可以根据实际需求把图例调整到左上、右下等任意位置,不会再出现压缩折线显示区域的问题。


内容的提问来源于stack exchange,提问作者Tony Weddle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 23:00:17