SkiaSharp中如何为饼图扇形块绑定触摸点击事件以展示对应信息?
SkiaSharp 饼图扇形点击交互实现方案
SkiaSharp 本身没有提供绘制元素的内置事件绑定,你可以通过「存储扇形元数据+坐标碰撞检测」的方式实现需求,具体实现步骤如下:
- 步骤1:定义扇形数据结构,存储每个扇形的关联参数
绘制饼图时不要只做渲染逻辑,提前把每个扇形的核心参数、要绑定的业务数据存入自定义结构,方便后续碰撞检测调用:
public class PieSlice { // 扇形基础绘制参数 public float StartAngle { get; set; } // 起始角度,单位:度 public float SweepAngle { get; set; } // 扫过角度,单位:度 public SKPoint Center { get; set; } // 饼图圆心坐标 public float Radius { get; set; } // 饼图半径 // 如果是环形饼图可新增 InnerRadius 属性 public float? InnerRadius { get; set; } // 自定义绑定字段,存储扇形对应的关联信息 public object BindData { get; set; } }
绘制完成后将所有扇形实例存入全局的 List<PieSlice> 集合中备用。

- 步骤2:监听SKCanvasView的触摸事件
给承载绘制内容的SKCanvasView添加触摸事件监听,注意要将触摸点的视图坐标转换为画布实际坐标(如果画布有缩放、平移变换,需要用画布变换矩阵的逆矩阵做坐标转换):
// 注册触摸事件 canvasView.Touch += OnCanvasTouch; private void OnCanvasTouch(object sender, SKTouchEventArgs e) { // 推荐在抬手时触发点击,减少误触 if (e.ActionType != SKTouchAction.Released) return; SKPoint touchPoint = e.Location; // 若画布有缩放/平移,需额外做坐标转换,示例: // touchPoint = canvas.TotalMatrix.Invert().MapPoint(touchPoint); // 遍历所有扇形做碰撞检测 foreach (var slice in _pieSlices) { if (IsPointInSlice(slice, touchPoint)) { // 匹配到点击的扇形,触发自定义回调,传入绑定数据 OnSliceClicked(slice.BindData); e.Handled = true; break; } } }
- 步骤3:实现扇形区域碰撞检测逻辑
通过极坐标转换判断触摸点是否落在扇形范围内:
private bool IsPointInSlice(PieSlice slice, SKPoint point) { // 1. 计算触摸点到圆心的距离,判断是否在半径范围内 double dx = point.X - slice.Center.X; double dy = point.Y - slice.Center.Y; double distance = Math.Sqrt(dx * dx + dy * dy); if (distance > slice.Radius) return false; // 环形饼图额外判断内半径 if (slice.InnerRadius.HasValue && distance < slice.InnerRadius.Value) return false; // 2. 计算触摸点相对于圆心的角度,统一转换为0-360度范围 double radian = Math.Atan2(dy, dx); double degree = radian * 180 / Math.PI; degree = degree < 0 ? degree + 360 : degree; // 3. 判断角度是否落在扇形的角度区间内 float endAngle = slice.StartAngle + slice.SweepAngle; if (endAngle <= 360) { return degree >= slice.StartAngle && degree <= endAngle; } else { // 处理跨360度的扇形边界 return degree >= slice.StartAngle || degree <= endAngle - 360; } }
- 步骤4:实现自定义回调逻辑
在OnSliceClicked方法中处理你需要的业务逻辑,比如弹窗展示扇形对应的关联信息即可。
注意事项
如果你的饼图做了高亮、偏移等选中态效果,匹配到扇形后可以给对应扇形加标识,调用Invalidate()方法重绘画布展示选中效果。
内容的提问来源于stack exchange,提问作者Betsq9
相关产品推荐
相关产品推荐

