LiveCharts2:如何隐藏K线图X轴刻度上的间隔?
问题描述
当前用LiveCharts2绘制的K线图中,K线柱之间存在间隔空白。原因是X轴采用5分钟时间框架,且每个交易日仅包含9点至18点的数据(具体时段依所选标的而定)。
需求
如何隐藏/消除K线柱之间的这些间隔?
版本信息
- LiveCharts2 20.0-rc2(适配AvaloniaUI 11.0.5)
- 运行环境:Windows 11
现有代码
ViewModel代码
Series = new ISeries[] { new CandlesticksSeries<FinancialPoint> { MaxBarWidth = 24, //12 Values = data } }; XAxes = new[] { new Axis { CrosshairLabelsBackground = SKColors.DarkOrange.AsLvcColor(), CrosshairLabelsPaint = new SolidColorPaint(SKColors.DarkRed, 1), CrosshairPaint = new SolidColorPaint(SKColors.DarkOrange, 1), ShowSeparatorLines = false, Position = LiveChartsCore.Measure.AxisPosition.Start, LabelsRotation = 0, LabelsPaint = new SolidColorPaint(SKColors.LightSlateGray), TextSize = 12, SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray) { StrokeThickness = 1, PathEffect = new DashEffect(new float[] { 3, 3 }) }, Labeler = value => (string) new DateTime((long)value).ToString("dd/MM/yyyy") + new DateTime((long)value).ToString("HH:mm"), UnitWidth = TimeSpan.FromMinutes(5).Ticks } }; SKColor s_crosshair = new(255, 171, 145); Func<double, string> formatFunc = (x) => string.Format("{0:0.00}", x); YAxes = new[] { new Axis { TextSize = 12, LabelsPaint = new SolidColorPaint(SKColors.LightSlateGray), CrosshairLabelsBackground = SKColors.DarkOrange.AsLvcColor(), CrosshairLabelsPaint = new SolidColorPaint(SKColors.DarkRed, 1), CrosshairPaint = new SolidColorPaint(SKColors.DarkOrange, 1), CrosshairSnapEnabled = false, // snapping is also supported SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray) { StrokeThickness = 1, }, ShowSeparatorLines = true, Position = LiveChartsCore.Measure.AxisPosition.End } };
AXAML代码
<lvc:CartesianChart AutoUpdateEnabled="True" Series="{Binding Series}" XAxes="{Binding XAxes}" YAxes="{Binding YAxes}" ZoomMode="X" > <lvc:CartesianChart.ContextMenu> <ContextMenu> <MenuItem Header="Menu item 1" /> <MenuItem Header="Menu item 2" /> <Separator /> <MenuItem Header="Menu item 3" /> </ContextMenu> </lvc:CartesianChart.ContextMenu> </lvc:CartesianChart>
解决方法
问题根源是X轴按实际时间值(DateTime的Ticks)渲染,非交易时段的空白时间会占据X轴空间。改成索引轴即可消除间隔:
- 修改X轴配置,启用索引模式,同时调整标签生成逻辑:
XAxes = new[] { new Axis { CrosshairLabelsBackground = SKColors.DarkOrange.AsLvcColor(), CrosshairLabelsPaint = new SolidColorPaint(SKColors.DarkRed, 1), CrosshairPaint = new SolidColorPaint(SKColors.DarkOrange, 1), ShowSeparatorLines = false, Position = LiveChartsCore.Measure.AxisPosition.Start, LabelsRotation = 0, LabelsPaint = new SolidColorPaint(SKColors.LightSlateGray), TextSize = 12, SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray) { StrokeThickness = 1, PathEffect = new DashEffect(new float[] { 3, 3 }) }, // 关键:启用索引轴,按数据点顺序排列 IsIndexed = true, // 根据索引获取对应数据点的时间生成标签 Labeler = index => { if (index >= 0 && index < data.Count) { var pointTime = new DateTime(data[(int)index].X); return $"{pointTime:dd/MM/yyyy} {pointTime:HH:mm}"; } return string.Empty; } // 移除原有的UnitWidth配置 } };
- 调整K线柱宽度,让其填满索引轴的间隔:
new CandlesticksSeries<FinancialPoint> { MaxBarWidth = 1, // 索引轴下设置为1,最大化填充间隔 Values = data }
原理说明
启用IsIndexed = true后,X轴不再依据数据点的实际时间值计算位置,而是直接按数据点在集合中的顺序排列。非交易时段因无数据点,不会占据X轴空间,自然消除空白间隔。标签生成逻辑通过索引匹配对应数据点的时间,保证X轴显示的仍是正确的时间信息。
内容的提问来源于stack exchange,提问作者Henrry
相关产品推荐
相关产品推荐

