如何在AndroidPlot中显示XYPlot的X轴和Y轴
背景 我正在为Android开发一个应用程序,它使用AndroidPlot将数据绘制成一个线图。由于数据的性质,它必须是可平移和可缩放的。我在bitbucket上使用AndroidPlot的示例代码,对其进行了修改,以允许在X和Y方向上进行平移和缩放 除了没有X轴和Y轴线外,其他一切都可以正常工作。在没有它们的情况下查看数据是非常令人迷惑的。网格有帮助,但不能保证网格线实际上会落在轴上 为了弥补这一点,我尝试添加了两个系列,一个只落在X轴上,另一个落在Y轴上。问题是,如果一个系列缩小得太远,轴只会结束,很明显,我已经应用了“hack” 问题 是否可以将X轴和Y轴线添加到AndroidPlot?还是我那可怜的黑客会这么做 编辑如何在AndroidPlot中显示XYPlot的X轴和Y轴,android,androidplot,Android,Androidplot,背景 我正在为Android开发一个应用程序,它使用AndroidPlot将数据绘制成一个线图。由于数据的性质,它必须是可平移和可缩放的。我在bitbucket上使用AndroidPlot的示例代码,对其进行了修改,以允许在X和Y方向上进行平移和缩放 除了没有X轴和Y轴线外,其他一切都可以正常工作。在没有它们的情况下查看数据是非常令人迷惑的。网格有帮助,但不能保证网格线实际上会落在轴上 为了弥补这一点,我尝试添加了两个系列,一个只落在X轴上,另一个落在Y轴上。问题是,如果一个系列缩小得太远,轴只
添加了标签我想出来了。这不是一件小事,需要与合作者共同努力,占用了我们很多小时的时间 从问题中提到的示例开始,我必须扩展XYPlot(我称之为GraphView)并重写onPreInit方法。请注意,我有两个PointF,minXY和maxXY,它们在被覆盖的XYPlot中定义,并在缩放或滚动时进行操作
@Override
protected void onPreInit() {
super.onPreInit();
final Paint axisPaint = new Paint();
axisPaint.setColor(getResources().getColor(R.color.MY_AXIS_COLOR));
axisPaint.setStrokeWidth(3); //or whatever stroke width you want
XYGraphWidget oldWidget = getGraphWidget();
XYGraphWidget widget = new XYGraphWidget(getLayoutManager(),
this,
new SizeMetrics(
oldWidget.getHeightMetric(),
oldWidget.getWidthMetric())) {
//We now override XYGraphWidget methods
RectF mGridRect;
@Override
protected void doOnDraw(Canvas canvas, RectF widgetRect)
throws PlotRenderException {
//In order to draw the x axis, we must obtain gridRect. I believe this is the only
//way to do so as the more convenient routes have private rather than protected access.
mGridRect = new RectF(widgetRect.left + ((isRangeAxisLeft())?getRangeLabelWidth():1),
widgetRect.top + ((isDomainAxisBottom())?1:getDomainLabelWidth()),
widgetRect.right - ((isRangeAxisLeft())?1:getRangeLabelWidth()),
widgetRect.bottom - ((isDomainAxisBottom())?getDomainLabelWidth():1));
super.doOnDraw(canvas, widgetRect);
}
@Override
protected void drawGrid(Canvas canvas) {
super.drawGrid(canvas);
if(mGridRect == null) return;
//minXY and maxXY are PointF's defined elsewhere. See my comment in the answer.
if(minXY.y <= 0 && maxXY.y >= 0) { //Draw the x axis
RectF paddedGridRect = getGridRect();
//Note: GraphView.this is the extended XYPlot instance.
XYStep rangeStep = XYStepCalculator.getStep(GraphView.this, XYAxisType.RANGE,
paddedGridRect, getCalculatedMinY().doubleValue(),
getCalculatedMaxY().doubleValue());
double rangeOriginF = paddedGridRect.bottom;
float yPix = (float) (rangeOriginF + getRangeOrigin().doubleValue() * rangeStep.getStepPix() /
rangeStep.getStepVal());
//Keep things consistent with drawing y axis even though drawRangeTick is public
//drawRangeTick(canvas, yPix, 0, getRangeLabelPaint(), axisPaint, true);
canvas.drawLine(mGridRect.left, yPix, mGridRect.right, yPix, axisPaint);
}
if(minXY.x <= 0 && maxXY.x >= 0) { //Draw the y axis
RectF paddedGridRect = getGridRect();
XYStep domianStep = XYStepCalculator.getStep(GraphView.this, XYAxisType.DOMAIN,
paddedGridRect, getCalculatedMinX().doubleValue(),
getCalculatedMaxX().doubleValue());
double domainOriginF = paddedGridRect.left;
float xPix = (float) (domainOriginF - getDomainOrigin().doubleValue() * domianStep.getStepPix() /
domianStep.getStepVal());
//Unfortunately, drawDomainTick has private access in XYGraphWidget
canvas.drawLine(xPix, mGridRect.top, xPix, mGridRect.bottom, axisPaint);
}
}
};
widget.setBackgroundPaint(oldWidget.getBackgroundPaint());
widget.setMarginTop(oldWidget.getMarginTop());
widget.setMarginRight(oldWidget.getMarginRight());
widget.setPositionMetrics(oldWidget.getPositionMetrics());
getLayoutManager().remove(oldWidget);
getLayoutManager().addToTop(widget);
setGraphWidget(widget);
//More customizations can go here
}
@覆盖
受保护的void onPreInit(){
super.onPreInit();
最终油漆=新油漆();
setColor(getResources().getColor(R.color.MY_AXIS_color));
axisPaint.setStrokeWidth(3);//或任意所需的笔划宽度
XYGraphWidget oldWidget=getGraphWidget();
XYGraphWidget=新的XYGraphWidget(getLayoutManager(),
这
新尺寸测量法(
oldWidget.getHeightMetric(),
oldWidget.getWidthMetric()){
//现在我们重写XYGraphWidget方法
RectF-mGridRect;
@凌驾
受保护的void doOnDraw(画布,RectF widgetrct)
抛出PlotRenderException{
//为了画x轴,我们必须得到gridRect。我相信这是唯一的
//这样做的方式,因为更方便的路线有私人而不是受保护的访问。
mGridRect=new RectF(widgetRect.left+((isRangeAxisLeft())?getRangeLabelWidth():1),
widgetRect.top+((isDomainAxisBottom())?1:getDomainLabelWidth()),
widgetRect.right-((isRangeAxisLeft())?1:getRangeLabelWidth()),
widgetRect.bottom-((isDomainAxisBottom())?getDomainLabelWidth():1));
super.doOnDraw(canvas,widgetRect);
}
@凌驾
受保护的void drawGrid(画布){
超级绘图网格(画布);
if(mGridRect==null)返回;
//minXY和maxXY是在别处定义的PointF。请参见我在答案中的注释。
如果(minXY.y=0){//绘制x轴
RectF paddedGridRect=getGridRect();
//注意:GraphView。这是扩展的XYPlot实例。
XYStep rangeStep=XYStepCalculator.getStep(GraphView.this,XYAxisType.RANGE,
paddedGridRect,getCalculatedMinY().doubleValue(),
getCalculatedMaxY().doubleValue());
double rangeOriginF=paddedGridRect.bottom;
float yPix=(float)(rangeOriginF+getRangeOrigin().doubleValue()*rangeStep.getStepPix()/
rangeStep.getStepVal());
//即使drawRangeTick是公共的,也要与图形y轴保持一致
//drawRangeTick(canvas,yPix,0,getRangeLabelPaint(),axisPaint,true);
画布绘制线(mGridRect.left、yPix、mGridRect.right、yPix、axisPaint);
}
如果(minXY.x=0){//绘制y轴
RectF paddedGridRect=getGridRect();
XYStep domianStep=XYStepCalculator.getStep(GraphView.this,XYAxisType.DOMAIN,
paddedGridRect,getCalculatedMinX().doubleValue(),
getCalculatedMaxX().doubleValue());
double domainOriginF=paddedGridRect.left;
float xPix=(float)(domainOriginF-getDomainOrigin().doubleValue()*domianStep.getStepPix())/
domianStep.getStepVal());
//不幸的是,drawDomainTick在XYGraphWidget中具有私有访问权限
画布绘制线(xPix,mGridRect.top,xPix,mGridRect.bottom,axisPaint);
}
}
};
setBackgroundPaint(oldWidget.getBackgroundPaint());
setMarginTop(oldWidget.getMarginTop());
setMarginRight(oldWidget.getMarginRight());
setPositionMetrics(oldWidget.getPositionMetrics());
getLayoutManager().remove(oldWidget);
getLayoutManager().addToTop(小部件);
setGraphWidget(小部件);
//更多的定制可以在这里进行
}
就这样。我真希望这是安卓的地盘;当它在AndroidPlot更新中中断时,试图修复它会很糟糕…我想出来了。这不是一件小事,需要与合作者共同努力,占用了我们很多小时的时间 从问题中提到的示例开始,我必须扩展XYPlot(我称之为GraphView)并重写onPreInit方法。请注意,我有两个PointF,minXY和maxXY,它们在被覆盖的XYPlot中定义,并在缩放或滚动时进行操作
@Override
protected void onPreInit() {
super.onPreInit();
final Paint axisPaint = new Paint();
axisPaint.setColor(getResources().getColor(R.color.MY_AXIS_COLOR));
axisPaint.setStrokeWidth(3); //or whatever stroke width you want
XYGraphWidget oldWidget = getGraphWidget();
XYGraphWidget widget = new XYGraphWidget(getLayoutManager(),
this,
new SizeMetrics(
oldWidget.getHeightMetric(),
oldWidget.getWidthMetric())) {
//We now override XYGraphWidget methods
RectF mGridRect;
@Override
protected void doOnDraw(Canvas canvas, RectF widgetRect)
throws PlotRenderException {
//In order to draw the x axis, we must obtain gridRect. I believe this is the only
//way to do so as the more convenient routes have private rather than protected access.
mGridRect = new RectF(widgetRect.left + ((isRangeAxisLeft())?getRangeLabelWidth():1),
widgetRect.top + ((isDomainAxisBottom())?1:getDomainLabelWidth()),
widgetRect.right - ((isRangeAxisLeft())?1:getRangeLabelWidth()),
widgetRect.bottom - ((isDomainAxisBottom())?getDomainLabelWidth():1));
super.doOnDraw(canvas, widgetRect);
}
@Override
protected void drawGrid(Canvas canvas) {
super.drawGrid(canvas);
if(mGridRect == null) return;
//minXY and maxXY are PointF's defined elsewhere. See my comment in the answer.
if(minXY.y <= 0 && maxXY.y >= 0) { //Draw the x axis
RectF paddedGridRect = getGridRect();
//Note: GraphView.this is the extended XYPlot instance.
XYStep rangeStep = XYStepCalculator.getStep(GraphView.this, XYAxisType.RANGE,
paddedGridRect, getCalculatedMinY().doubleValue(),
getCalculatedMaxY().doubleValue());
double rangeOriginF = paddedGridRect.bottom;
float yPix = (float) (rangeOriginF + getRangeOrigin().doubleValue() * rangeStep.getStepPix() /
rangeStep.getStepVal());
//Keep things consistent with drawing y axis even though drawRangeTick is public
//drawRangeTick(canvas, yPix, 0, getRangeLabelPaint(), axisPaint, true);
canvas.drawLine(mGridRect.left, yPix, mGridRect.right, yPix, axisPaint);
}
if(minXY.x <= 0 && maxXY.x >= 0) { //Draw the y axis
RectF paddedGridRect = getGridRect();
XYStep domianStep = XYStepCalculator.getStep(GraphView.this, XYAxisType.DOMAIN,
paddedGridRect, getCalculatedMinX().doubleValue(),
getCalculatedMaxX().doubleValue());
double domainOriginF = paddedGridRect.left;
float xPix = (float) (domainOriginF - getDomainOrigin().doubleValue() * domianStep.getStepPix() /
domianStep.getStepVal());
//Unfortunately, drawDomainTick has private access in XYGraphWidget
canvas.drawLine(xPix, mGridRect.top, xPix, mGridRect.bottom, axisPaint);
}
}
};
widget.setBackgroundPaint(oldWidget.getBackgroundPaint());
widget.setMarginTop(oldWidget.getMarginTop());
widget.setMarginRight(oldWidget.getMarginRight());
widget.setPositionMetrics(oldWidget.getPositionMetrics());
getLayoutManager().remove(oldWidget);
getLayoutManager().addToTop(widget);
setGraphWidget(widget);
//More customizations can go here
}
@覆盖
受保护的void onPreInit(){
super.onPreInit();
最终油漆=新油漆();
setColor(getResources().getColor(R.color.MY_AXIS_color));
axisPaint.setStrokeWidth(3);//或任意所需的笔划宽度
XYGraphWidget oldWidget=getGraphWidget();
XYGraphWidget=新的XYGraphWidget(getLayoutManager(),
这
新尺寸测量法(