Android使用GraphView从文本文件中读取和绘制数据

时间:2015-01-08 23:35:27

标签: java android graphing android-graphview

在我的Android应用程序中,我试图从包含我希望绘制的数据点的文本文件中读取。每个文件中的数据点数预计在24,000到150,000之间。

目前,我已经实现了一个异步任务,它从压缩文本文件中读取数据并将其存储在本地向量中。在完成任务时,将数据点添加到数据集中以便绘制图形。

异步任务的代码实现如下:

class ReadFileService extends AsyncTask<Void, String, Boolean> {

    @Override
    protected Boolean doInBackground(Void... args) {        
        Scanner strings = null;
        InputStream stream = null;
        ZipInputStream zipInput = null;
        try {
            System.out.println(externalStorageDirectory + Constants.APP_DIRECTORY + recordingName + Constants.ZIP_FILE_EXTENTION);
            File file = new File(externalStorageDirectory + Constants.APP_DIRECTORY, recordingName + Constants.ZIP_FILE_EXTENTION);
            ZipFile zipFile = new ZipFile(file);
            Enumeration<? extends ZipEntry> entries = zipFile.entries();

            while (entries.hasMoreElements()) {
                ZipEntry zipEntry = entries.nextElement();
                stream = zipFile.getInputStream(zipEntry);
                strings = new Scanner(stream);

                // Extract the value of sampling frequency from header
                System.out.println("Extracting value of sampling frequency.");
                String regexPattern = "\"ColumnLabels\"";
                strings.useDelimiter(regexPattern);
                String extracted = strings.next();
                Pattern pattern = Pattern.compile("\"SamplingFrequency\": \"(\\d+)\"");
                Matcher matcher = pattern.matcher(extracted);
                if (matcher.find()) {
                    samplingFrequency = Integer.parseInt(matcher.group(1));
                    System.out.println(samplingFrequency);
                }

                // Locate the end of the header and use tabs as the delimiter
                strings.findWithinHorizon(endOfHeader,0);           
                strings.useDelimiter("\t *");
                strings.next();
            }
        }
        catch (FileNotFoundException error) {
            System.out.println("@IOERROR: " + error);
            return false;
        }
        catch (IOException error) {
            System.out.println("@IOERROR: " + error);
            return false;
        }
        while (strings.hasNext())
        {
            // Get raw value of data point
            double dataPoint = Double.parseDouble(strings.next());
            // Convert data point into the proper scale
            dataSet.add(SensorDataConverter.scaleEMG(dataPoint));
            // Skip the index value if it exists and break from loop if it does not
            if (strings.hasNext())
                strings.next();
            else
                break;
        }
        System.out.println("Closing strings.");
        try {
            stream.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        strings.close();            
        return true;
    }

    protected void onProgressUpdate(String...progress) {
        //called when the background task makes any progress
    }

    protected void onPreExecute() {
        //called before doInBackground() is started
        super.onPreExecute();
        // Show Progress Bar Dialog before calling doInBackground method
        prgDialog.setTitle("Opening File");
        prgDialog.setMessage("Opening " + recordingName + "\nPlease wait...");
        prgDialog.show();
    }

    //called after doInBackground() has finished
    protected void onPostExecute(Boolean readFileSuccess) { 
        // If unable to read from file, print error and generate a random set of sample data
        if(!readFileSuccess) {
            Random randomGenerator = new Random();          
            System.out.println("@IOERROR: Unable to read from file. Creating random dataset");
            for(int i=0; i<100; i++)
            {
                dataSet.add(randomGenerator.nextDouble());
            }
        }
        // Create a set of graph data to use with GraphView
        exampleSeries1 = new GraphViewSeries(new GraphViewData[] {
        });
        for (int i=0; i<dataSet.size(); i++) {
            double pointX = i;
            double pointY = dataSet.get(i);
            exampleSeries1.appendData(new GraphViewData(pointX, pointY), true, dataSet.size());
        }
        // Plot the data points
        graphData();
        prgDialog.dismiss();
        prgDialog = null;
    }
}

在保存和加载大约10,000个数据点并且加载大约需要15秒时,这似乎有效。但是,当数据点数量跃升至20,000时,加载时间最多需要45秒。

我的主要问题是:是否有其他方法可以更有效地处理所有这些数据,以最大限度地缩短加载数据所需的时间?例如,是否可以动态绘制数据图表点取决于视口范围?

非常感谢任何帮助和建议。

1 个答案:

答案 0 :(得分:0)

您必须重新采样数据以获得较少的数据点。通常情况下,在单个视口中绘制100多个数据点是没有意义的。

并使用手动视口和手动标签宽度/高度来提高性能