android – aChartEngine:如何显示实时更新

android – aChartEngine:如何显示实时更新,第1张

概述我目前正在使用achartengine来显示使用蓝牙接收的实时数据. 数据在特定线程上正确收集,并在Bundle中100ms发送到我的主要活动. 主要活动包含来自achartengine库(LineChart类)的4个图表,使用GraphicalView添加到其视图中 总而言之,每100毫秒,我的主要活动收到一个回调和 >复制捆绑包中的数据 >将其添加到4个不同的数据集中(XYMultipleSe 我目前正在使用achartengine来显示使用蓝牙接收的实时数据.
数据在特定线程上正确收集,并在Bundle中100ms发送到我的主要活动.

主要活动包含来自achartengine库(lineChart类)的4个图表,使用GraphicalVIEw添加到其视图中

总而言之,每100毫秒,我的主要活动收到一个回调和

>复制捆绑包中的数据
>将其添加到4个不同的数据集中(XYMultipleSerIEsDataset)
>在包含数据集的4个图表上调用repaint()

调用重绘时,数据集将不会更新,直到下一个包从另一个线程到达,100毫秒后.我假设100毫秒应该足以重绘视图.

我在这里发布了一个包含数据集和视图的小版本,
以及实施和使用的主要活动的一部分

/** This class contains the data and renderer used to draw a chart */public class lineChartData {public static enum SerIEs {X,Y,Z};public static final int MAX_NB_VALUES_PER_SERIE = 1000;private XYMultipleSerIEsDataset mDataset = new XYMultipleSerIEsDataset();private XYMultipleSerIEsRenderer mRenderer = new XYMultipleSerIEsRenderer();private int[] mcolors = new int[]{color.RED,color.GREEN,color.BLUE};private GraphicalVIEw mChartVIEw;private boolean mFollow = true;private boolean mtouchedDown = false;public lineChartData(Context context,String Title,String[] serIEsnames){    // Since we save only 3 colors,the programm will not support more than 3 serIEs per chart    for(int i = 0; i < serIEsnames.length; ++i)    {        XYSerIEs serIE = new XYSerIEs(serIEsnames[i].toString());        mDataset.addSerIEs(serIE);        XYSerIEsRenderer serIERenderer = new XYSerIEsRenderer();        serIERenderer.setcolor(mcolors[i]);        mRenderer.addSerIEsRenderer(serIERenderer);    }    mRenderer.setmargins(new int[] { 20,30,0 });    mRenderer.setLegendHeight(50);    //mRenderer.setShowLegend(true);    mRenderer.setChartTitle(Title);    mRenderer.setmarginscolor(color.WHITE);    mRenderer.setXAxisMax(SettingsActivity.DEFAulT_disPLAY_RANGE);    mRenderer.setXAxisMin(0);    mChartVIEw = ChartFactory.getlineChartVIEw(context,mDataset,mRenderer);    mChartVIEw.repaint();}public voID addData(int serIEID,double x,double y){    mDataset.getSerIEsAt(serIEID).add(x,y);}public voID repaint(){        mChartVIEw.invalIDate();}public voID updatedisplayWindow(int displayRange){    if(!mFollow)    {        return;    }    double maxX = mDataset.getSerIEs()[0].getMaxX();    if(maxX > displayRange)    {        mRenderer.setXAxisMax(maxX);        mRenderer.setXAxisMin(maxX-displayRange);    }    else    {        mRenderer.setXAxisMax(displayRange);        mRenderer.setXAxisMin(0);    }}public voID deleteoldestValues(){    XYSerIEs[] serIEs = mDataset.getSerIEs();    for(XYSerIEs serIE : serIEs)    {        while(serIE.getItemCount() > MAX_NB_VALUES_PER_SERIE)        {            serIE.remove(0);        }    }}}

创建4个图表:

protected voID onCreate(Bundle b){    mAccelChartVIEw    = new lineChartData(this,getString(R.string.Accel),new String[]            {getString(R.string.xAxis),getString(R.string.zAxis),getString(R.string.zAxis)});    mGyroChartVIEw    = new lineChartData(this,getString(R.string.Gyro),getString(R.string.zAxis)});    mPressureChartVIEw    = new lineChartData(this,getString(R.string.Pressure),new String[]            {getString(R.string.pressureAxis)});    mEcgChartVIEw    = new lineChartData(this,getString(R.string.ECG),new String[]            {getString(R.string.ecgAxis)});    linearLayout layoutAccel = (linearLayout) findVIEwByID(R.ID.accelChart);    linearLayout layoutGyro = (linearLayout) findVIEwByID(R.ID.gyroChart);    linearLayout layoutPressure = (linearLayout) findVIEwByID(R.ID.pressureChart);    linearLayout layoutEcg = (linearLayout) findVIEwByID(R.ID.ecgChart);    layoutAccel.addVIEw(mAccelChartVIEw.getVIEw(),0);    layoutGyro.addVIEw(mGyroChartVIEw.getVIEw(),0);    layoutPressure.addVIEw(mPressureChartVIEw.getVIEw(),0);    layoutEcg.addVIEw(mEcgChartVIEw.getVIEw(),0);}

更新图表

private voID updateVIEwUsingMessage(String action,Bundle newData) {       if(action.equals(BluetoothCollecterThread.MSG_UPDATE_CHART))    {        addFromBundle(newData,mLogger.isLogging());        mAccelChartVIEw.updatedisplayWindow(mdisplayRange);        mAccelChartVIEw.deleteoldestValues();        mGyroChartVIEw.updatedisplayWindow(mdisplayRange);        mGyroChartVIEw.deleteoldestValues();        mPressureChartVIEw.updatedisplayWindow(mdisplayRange);        mPressureChartVIEw.deleteoldestValues();        mEcgChartVIEw.updatedisplayWindow(mdisplayRange);        mEcgChartVIEw.deleteoldestValues();        mAccelChartVIEw.repaint();        mGyroChartVIEw.repaint();        mPressureChartVIEw.repaint();        mEcgChartVIEw.repaint();    }}

它可能看起来很大但实际上很容易.我有两个问题,我不知道是否有联系:
首先,每秒几次,一张图表中的第一个系列在另一张图表上绘制(见下图).我检查了我的代码,找不到任何解决方案.而且,它似乎真的是随机发生的,因此它看起来更像是来自achartengine库的并发问题.

这带来了我的第二个问题.日志显示来自垃圾收集器的消息过多,特别是WAIT_FOR_CONCURRENT_GC类型的消息被阻止,这显然是不好的.

我发现这个链接:http://www.voidcn.com/article/p-rembizwq-btn.html表明内存分配问题仍然存在于achartengine中,但最后一个版本应足以显示几个实时1000点的图形.即使我将数据更新设置为1秒而不是100毫秒,我仍然会遇到视觉故障

正确的行为:4个图表实时更新(两个第一个有3个系列,两个最后有1个系列)
http://s903.photobucket.com/user/bperreno/media/correct_zpsebd731f6.png.html?sort=3&o=1

错误:图表2中的红色系列显示在其他图表上
http://s903.photobucket.com/user/bperreno/media/wrong1_zpsd33eec83.png.html?sort=3&o=0

数据正在实时移动,但有时,第二张图片中显示的故障发生,一两帧,然后消失.
有没有人知道如何,至少,修复显示问题?也许希望告诉我如何解决achartengine垃圾收集的过度使用问题

非常感谢!

编辑04.12.2013
我现在使用achartengine源而不是.jar,所以我可以查看值.看到“setInScroll”不起作用后,我看了一下代码.在GraphicalVIEw.onDraw方法中,我比较了setInScroll为true或false时使用的值.

int top = mRect.top;int left = mRect.left;int wIDth = mRect.wIDth();int height = mRect.getheight();if(mRenderer.isInScroll()){    top = 0;    left = 0;    wIDth = getMeasureDWIDth();    height = getMeasuredHeight();}

从mRect或getMeasuredXXX()传来的值始终相同.在这两种情况下,顶部和左侧都是零.所以(至少在这种情况下),inScroll = true无效

解决方法 好的,我正在回答我的问题:

经过几次测试后,我发现当在achartengine lib上执行太多 *** 作时,这是一个很容易出现的问题.

繁重的行动似乎包括在内

>删除一个点
>设置X最大显示值
>清爽

所以我能做的最好的办法就是将X max位置设置得更远,所以我只需要偶尔更新一次(例如每秒一次)

向库中添加允许一次删除多个点的方法也很有用.删除当前是O(n)并且一个接一个地删除m个点因此是O(nm).

请注意,比我的galaxy S2更强大的设备(如S4mini)处理显示器没有毛刺.但效率仍然是更多图表和更高频率的问题.

4个图表达到10 FPS并不是我真正称之为实时的

总结

以上是内存溢出为你收集整理的android – aChartEngine:如何显示实时更新全部内容,希望文章能够帮你解决android – aChartEngine:如何显示实时更新所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1125056.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存