2021/11/2 更新
本篇的方法我已经弃用了。因为坐标轴的拼接很影响图片展示的速度。已更换成wpf原生的TextBlock,可以参考我这一篇:
wpf-利用装饰器制作 彩色字体+可选中+可复制 的textblock
TextBlock可以做更多精细控制,远比oxyplot的坐标轴更好用。。。
问题描述
绘图数据中,x的取值范围大概是0~20k,但是x轴只显示到5000,后面就不再显示了。
如上图所示,AreaSeries还是继续绘制的,但是x轴的label大于5000就不显示了。labelFormatter是这么写的,可以看出只到5000
LabelFormatter = delegate(double x) {
if (x > 5000) {
return "$";
}
if (x == 0)
{
return "0";
}
else if ((int)(x+5) % 100 == 0)
{
return (((int)(x+5) / 100 ) * 10).ToString();
}
else
return "x";
},
然后我加了一条辅助垂线,也是显示的,就是label不显示
ExtraGridlines = new double[] {
6000.0},
解决方案
目前用的是一种奇葩解法。
Axis有两个变量:StartPosition和EndPosition,调整这两个值可以控制轴的label从哪边开始编写。比如设置x轴的StartPosition=1,EndPosition=0,那么坐标轴的标签就从右边到左边,从0-5k这样。
所以我可以多画几条x轴,每条x轴都从前一条x轴结束的地方(5k处)开始即可。
- 固定Maxmum以确保所有x轴的间距一致
- 固定EndPosition = 1保证方向一致
- 使用Minimum和StartPosition控制轴的开始位置,Minimum每次增加5000
- StartPosition = Minimum / Maxmum
目前看来,数据量在1w+是完全ok的。如果数据量再大,我再研究别的方案。
int p = 0;
while (p < pureSeq.Length)
{
// 在实际数据量基础上加100长度
double s = p * 10.0 / (pointNum + 100);
//double e = max *
FixedCenterLinearAxis xAxis, seqAxis;
xAxis = CreateXAxisFragment(p * 10, pointNum + 100, s, 1);
// 设置x轴
_viewModel.SimplePlotModel.Axes.Add(xAxis);
// 设置bar的数值x轴
// max用pointNum是因为要映射到qualityVals的
LinearAxis barAxis = CreateBarXAxisFragment(p * 10, pointNum, s, 1);
_viewModel.BarPlotModel.Axes.Add(barAxis);
//
p += 500;
}
private FixedCenterLinearAxis CreateXAxisFragment(int min, int max, double start, double end) {
FixedCenterLinearAxis axis = new FixedCenterLinearAxis()
{
Position = AxisPosition.Bottom,
//TextColor = OxyColor.FromRgb(255, 0, 0),
Minimum = min,
Maximum = max,
StartPosition = start,
EndPosition = end,
IsAxisVisible = true,
IsPanEnabled = false,
IsZoomEnabled = false,
TickStyle = TickStyle.None,
MajorStep = 5,
AxislineStyle = LineStyle.Solid,
AxislineColor = OxyColor.Parse("#9C9C9C"),
AxislineThickness = 1,
//AxisTickToLabelDistance = 1,
LabelFormatter = delegate (double x) {
if (x == 0) {
return "0";
}
else if ((int)(x + 5) % 100 == 0)
{
return (((int)(x + 5) / 100) * 10).ToString();
}
else
return "";
},
};
return axis;
}