Introduced Series object to represent one entry in the chart. Added functionality to draw multiple lines in one chart. Improved performance when drawing huge amounts of data. Started implementation on data reduction (Douglas-Peucker-Algorithm).
This commit is contained in:
parent
3a3c0ef9be
commit
846f5cca2d
16 changed files with 4297 additions and 4025 deletions
|
@ -1,5 +1,7 @@
|
|||
package com.example.mpchartexample;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
|
@ -10,161 +12,160 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.BarChart;
|
||||
import com.github.mikephil.charting.BarSeries;
|
||||
import com.github.mikephil.charting.ChartData;
|
||||
import com.github.mikephil.charting.ColorTemplate;
|
||||
import com.github.mikephil.charting.Series;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class BarChartActivity extends Activity implements OnSeekBarChangeListener {
|
||||
|
||||
private BarChart mChart;
|
||||
private SeekBar mSeekBarX, mSeekBarY;
|
||||
private TextView tvX, tvY;
|
||||
private BarChart mChart;
|
||||
private SeekBar mSeekBarX, mSeekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_barchart);
|
||||
|
||||
tvX = (TextView) findViewById(R.id.tvXMax);
|
||||
tvY = (TextView) findViewById(R.id.tvYMax);
|
||||
|
||||
mSeekBarX = (SeekBar) findViewById(R.id.seekBar1);
|
||||
mSeekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
mSeekBarY = (SeekBar) findViewById(R.id.seekBar2);
|
||||
mSeekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
mChart = (BarChart) findViewById(R.id.chart1);
|
||||
mChart.setColorTemplate(new ColorTemplate(ColorTemplate.getColors(this, ColorTemplate.FRESH_COLORS)));
|
||||
// mChart.setLegendDigits(2);
|
||||
// mChart.setValueDigits(2);
|
||||
|
||||
// mChart.setDrawFilled(true);
|
||||
// mChart.setRoundedYLegend(false);
|
||||
// mChart.setStartAtZero(true);
|
||||
mChart.setDrawYValues(false);
|
||||
mChart.set3DEnabled(false);
|
||||
// mChart.setSpacePercent(20, 10);
|
||||
mChart.setYLegendCount(5);
|
||||
mChart.setTouchEnabled(true);
|
||||
|
||||
mSeekBarX.setProgress(45);
|
||||
mSeekBarY.setProgress(100);
|
||||
}
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_barchart);
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.bar, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.actionToggleRound: {
|
||||
if (mChart.isYLegendRounded())
|
||||
mChart.setRoundedYLegend(false);
|
||||
else
|
||||
mChart.setRoundedYLegend(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
if (mChart.isDrawYValuesEnabled())
|
||||
mChart.setDrawYValues(false);
|
||||
else
|
||||
mChart.setDrawYValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggle3D: {
|
||||
if (mChart.is3DEnabled())
|
||||
mChart.set3DEnabled(false);
|
||||
else
|
||||
mChart.set3DEnabled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (mChart.isHighlightEnabled())
|
||||
mChart.setHighlightEnabled(false);
|
||||
else
|
||||
mChart.setHighlightEnabled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlightArrow: {
|
||||
if (mChart.isDrawHighlightArrowEnabled())
|
||||
mChart.setDrawHighlightArrow(false);
|
||||
else
|
||||
mChart.setDrawHighlightArrow(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleStartzero: {
|
||||
if (mChart.isStartAtZeroEnabled())
|
||||
mChart.setStartAtZero(false);
|
||||
else
|
||||
mChart.setStartAtZero(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAdjustXLegend: {
|
||||
if (mChart.isAdjustXLegendEnabled())
|
||||
mChart.setAdjustXLegend(false);
|
||||
else
|
||||
mChart.setAdjustXLegend(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
// mChart.saveToGallery("title"+System.currentTimeMillis());
|
||||
mChart.saveToPath("title"+System.currentTimeMillis(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
tvX = (TextView) findViewById(R.id.tvXMax);
|
||||
tvY = (TextView) findViewById(R.id.tvYMax);
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
ArrayList<String> xVals = new ArrayList<String>();
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
xVals.add((i)+"");
|
||||
}
|
||||
mSeekBarX = (SeekBar) findViewById(R.id.seekBar1);
|
||||
mSeekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
ArrayList<Series> yVals = new ArrayList<Series>();
|
||||
mSeekBarY = (SeekBar) findViewById(R.id.seekBar2);
|
||||
mSeekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
float mult = (mSeekBarY.getProgress()+1);
|
||||
float val = (float) (Math.random() * mult * 0.1) + 3;// + (float) ((mult * 0.1) / 10);
|
||||
yVals.add(new BarSeries(val));
|
||||
}
|
||||
|
||||
tvX.setText(""+ (mSeekBarX.getProgress() + 1));
|
||||
tvY.setText(""+ (mSeekBarY.getProgress() / 10));
|
||||
mChart = (BarChart) findViewById(R.id.chart1);
|
||||
mChart.setColorTemplate(new ColorTemplate(ColorTemplate.getColors(this, ColorTemplate.FRESH_COLORS)));
|
||||
// mChart.setLegendDigits(2);
|
||||
// mChart.setValueDigits(2);
|
||||
|
||||
mChart.setData(xVals, yVals);
|
||||
mChart.invalidate();
|
||||
}
|
||||
// mChart.setDrawFilled(true);
|
||||
// mChart.setRoundedYLegend(false);
|
||||
// mChart.setStartAtZero(true);
|
||||
mChart.setDrawYValues(false);
|
||||
mChart.set3DEnabled(false);
|
||||
// mChart.setSpacePercent(20, 10);
|
||||
mChart.setYLegendCount(5);
|
||||
mChart.setTouchEnabled(true);
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
mSeekBarX.setProgress(45);
|
||||
mSeekBarY.setProgress(100);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.bar, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.actionToggleRound: {
|
||||
if (mChart.isYLegendRounded())
|
||||
mChart.setRoundedYLegend(false);
|
||||
else
|
||||
mChart.setRoundedYLegend(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
if (mChart.isDrawYValuesEnabled())
|
||||
mChart.setDrawYValues(false);
|
||||
else
|
||||
mChart.setDrawYValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggle3D: {
|
||||
if (mChart.is3DEnabled())
|
||||
mChart.set3DEnabled(false);
|
||||
else
|
||||
mChart.set3DEnabled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (mChart.isHighlightEnabled())
|
||||
mChart.setHighlightEnabled(false);
|
||||
else
|
||||
mChart.setHighlightEnabled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlightArrow: {
|
||||
if (mChart.isDrawHighlightArrowEnabled())
|
||||
mChart.setDrawHighlightArrow(false);
|
||||
else
|
||||
mChart.setDrawHighlightArrow(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleStartzero: {
|
||||
if (mChart.isStartAtZeroEnabled())
|
||||
mChart.setStartAtZero(false);
|
||||
else
|
||||
mChart.setStartAtZero(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAdjustXLegend: {
|
||||
if (mChart.isAdjustXLegendEnabled())
|
||||
mChart.setAdjustXLegend(false);
|
||||
else
|
||||
mChart.setAdjustXLegend(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
// mChart.saveToGallery("title"+System.currentTimeMillis());
|
||||
mChart.saveToPath("title" + System.currentTimeMillis(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
ArrayList<String> xVals = new ArrayList<String>();
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
xVals.add((i) + "");
|
||||
}
|
||||
|
||||
ArrayList<Series> yVals = new ArrayList<Series>();
|
||||
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
float mult = (mSeekBarY.getProgress() + 1);
|
||||
float val = (float) (Math.random() * mult * 0.1) + 3;// + (float) ((mult * 0.1) / 10);
|
||||
yVals.add(new Series(val, i, 0));
|
||||
}
|
||||
|
||||
tvX.setText("" + (mSeekBarX.getProgress() + 1));
|
||||
tvY.setText("" + (mSeekBarY.getProgress() / 10));
|
||||
|
||||
ChartData data = new ChartData(xVals, yVals);
|
||||
|
||||
mChart.setData(data);
|
||||
mChart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.example.mpchartexample;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
|
@ -11,173 +13,172 @@ import android.widget.SeekBar;
|
|||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.ChartData;
|
||||
import com.github.mikephil.charting.LineChart;
|
||||
import com.github.mikephil.charting.LineSeries;
|
||||
import com.github.mikephil.charting.Series;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class LineChartActivity extends Activity implements OnSeekBarChangeListener {
|
||||
|
||||
private LineChart mChart;
|
||||
private SeekBar mSeekBarX, mSeekBarY;
|
||||
private TextView tvX, tvY;
|
||||
private LineChart mChart;
|
||||
private SeekBar mSeekBarX, mSeekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart);
|
||||
|
||||
tvX = (TextView) findViewById(R.id.tvXMax);
|
||||
tvY = (TextView) findViewById(R.id.tvYMax);
|
||||
|
||||
mSeekBarX = (SeekBar) findViewById(R.id.seekBar1);
|
||||
mSeekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
mSeekBarY = (SeekBar) findViewById(R.id.seekBar2);
|
||||
mSeekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
mChart = (LineChart) findViewById(R.id.chart1);
|
||||
// mChart.setColorTemplate(new ColorTemplate(ColorTemplate.getColors(this, ColorTemplate.LIBERTY_COLORS)));
|
||||
|
||||
// mChart.setDrawFilled(true);
|
||||
// mChart.setRoundedYLegend(false);
|
||||
// mChart.setStartAtZero(true);
|
||||
mChart.setDrawYValues(false);
|
||||
mChart.setLineWidth(4f);
|
||||
mChart.setCircleSize(4f);
|
||||
// mChart.setSpacePercent(20, 10);
|
||||
mChart.setYLegendCount(6);
|
||||
mChart.setTouchEnabled(true);
|
||||
mChart.setHighlightEnabled(true);
|
||||
// mChart.highlightValues(new int[] {2, 6});
|
||||
mChart.setDragEnabled(true);
|
||||
mChart.setTouchEnabled(true);
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart);
|
||||
|
||||
TextView textView = new TextView(this);
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
textView.setBackgroundColor(Color.WHITE);
|
||||
textView.setPadding(15, 15, 15, 15);
|
||||
textView.setText("Marker View");
|
||||
tvX = (TextView) findViewById(R.id.tvXMax);
|
||||
tvY = (TextView) findViewById(R.id.tvYMax);
|
||||
|
||||
mChart.setDrawMarkerView(true);
|
||||
mChart.setMarkerView(textView);
|
||||
|
||||
mSeekBarX.setProgress(45);
|
||||
mSeekBarY.setProgress(100);
|
||||
}
|
||||
mSeekBarX = (SeekBar) findViewById(R.id.seekBar1);
|
||||
mSeekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.line, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.actionToggleRound: {
|
||||
if (mChart.isYLegendRounded())
|
||||
mChart.setRoundedYLegend(false);
|
||||
else
|
||||
mChart.setRoundedYLegend(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
if (mChart.isDrawYValuesEnabled())
|
||||
mChart.setDrawYValues(false);
|
||||
else
|
||||
mChart.setDrawYValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (mChart.isHighlightEnabled())
|
||||
mChart.setHighlightEnabled(false);
|
||||
else
|
||||
mChart.setHighlightEnabled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleFilled: {
|
||||
if (mChart.isDrawFilledEnabled())
|
||||
mChart.setDrawFilled(false);
|
||||
else
|
||||
mChart.setDrawFilled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCircles: {
|
||||
if (mChart.isDrawCirclesEnabled())
|
||||
mChart.setDrawCircles(false);
|
||||
else
|
||||
mChart.setDrawCircles(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleStartzero: {
|
||||
if (mChart.isStartAtZeroEnabled())
|
||||
mChart.setStartAtZero(false);
|
||||
else
|
||||
mChart.setStartAtZero(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAdjustXLegend: {
|
||||
if (mChart.isAdjustXLegendEnabled())
|
||||
mChart.setAdjustXLegend(false);
|
||||
else
|
||||
mChart.setAdjustXLegend(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
// mChart.saveToGallery("title"+System.currentTimeMillis());
|
||||
mChart.saveToPath("title"+System.currentTimeMillis(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
mSeekBarY = (SeekBar) findViewById(R.id.seekBar2);
|
||||
mSeekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
ArrayList<String> xVals = new ArrayList<String>();
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
xVals.add((i)+"");
|
||||
}
|
||||
mChart = (LineChart) findViewById(R.id.chart1);
|
||||
// mChart.setColorTemplate(new ColorTemplate(ColorTemplate.getColors(this, ColorTemplate.LIBERTY_COLORS)));
|
||||
|
||||
ArrayList<Series> yVals = new ArrayList<Series>();
|
||||
// mChart.setDrawFilled(true);
|
||||
// mChart.setRoundedYLegend(false);
|
||||
// mChart.setStartAtZero(true);
|
||||
mChart.setDrawYValues(false);
|
||||
mChart.setLineWidth(4f);
|
||||
mChart.setCircleSize(4f);
|
||||
// mChart.setSpacePercent(20, 10);
|
||||
mChart.setYLegendCount(6);
|
||||
mChart.setTouchEnabled(true);
|
||||
mChart.setHighlightEnabled(true);
|
||||
// mChart.highlightValues(new int[] {2, 6});
|
||||
mChart.setDragEnabled(true);
|
||||
mChart.setTouchEnabled(true);
|
||||
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
float mult = (mSeekBarY.getProgress()+1);
|
||||
float val = (float) (Math.random() * mult * 0.1) + 3;// + (float) ((mult * 0.1) / 10);
|
||||
yVals.add(new LineSeries(val, 0, i));
|
||||
}
|
||||
|
||||
tvX.setText(""+ (mSeekBarX.getProgress() + 1));
|
||||
tvY.setText(""+ (mSeekBarY.getProgress() / 10));
|
||||
TextView textView = new TextView(this);
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
textView.setBackgroundColor(Color.WHITE);
|
||||
textView.setPadding(15, 15, 15, 15);
|
||||
textView.setText("Marker View");
|
||||
|
||||
mChart.setData(xVals, yVals);
|
||||
mChart.invalidate();
|
||||
}
|
||||
mChart.setDrawMarkerView(true);
|
||||
mChart.setMarkerView(textView);
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
mSeekBarX.setProgress(45);
|
||||
mSeekBarY.setProgress(100);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.line, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.actionToggleRound: {
|
||||
if (mChart.isYLegendRounded())
|
||||
mChart.setRoundedYLegend(false);
|
||||
else
|
||||
mChart.setRoundedYLegend(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
if (mChart.isDrawYValuesEnabled())
|
||||
mChart.setDrawYValues(false);
|
||||
else
|
||||
mChart.setDrawYValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (mChart.isHighlightEnabled())
|
||||
mChart.setHighlightEnabled(false);
|
||||
else
|
||||
mChart.setHighlightEnabled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleFilled: {
|
||||
if (mChart.isDrawFilledEnabled())
|
||||
mChart.setDrawFilled(false);
|
||||
else
|
||||
mChart.setDrawFilled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCircles: {
|
||||
if (mChart.isDrawCirclesEnabled())
|
||||
mChart.setDrawCircles(false);
|
||||
else
|
||||
mChart.setDrawCircles(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleStartzero: {
|
||||
if (mChart.isStartAtZeroEnabled())
|
||||
mChart.setStartAtZero(false);
|
||||
else
|
||||
mChart.setStartAtZero(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAdjustXLegend: {
|
||||
if (mChart.isAdjustXLegendEnabled())
|
||||
mChart.setAdjustXLegend(false);
|
||||
else
|
||||
mChart.setAdjustXLegend(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
// mChart.saveToGallery("title"+System.currentTimeMillis());
|
||||
mChart.saveToPath("title" + System.currentTimeMillis(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
ArrayList<String> xVals = new ArrayList<String>();
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
xVals.add((i) + "");
|
||||
}
|
||||
|
||||
ArrayList<Series> yVals = new ArrayList<Series>();
|
||||
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
float mult = (mSeekBarY.getProgress() + 1);
|
||||
float val = (float) (Math.random() * mult * 0.1) + 3;// + (float) ((mult * 0.1) / 10);
|
||||
yVals.add(new Series(val, 0, i));
|
||||
}
|
||||
|
||||
tvX.setText("" + (mSeekBarX.getProgress() + 1));
|
||||
tvY.setText("" + (mSeekBarY.getProgress() / 10));
|
||||
|
||||
ChartData data = new ChartData(xVals, yVals);
|
||||
|
||||
mChart.setData(data);
|
||||
mChart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.example.mpchartexample;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
|
@ -11,173 +13,189 @@ import android.widget.SeekBar;
|
|||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.Approximator;
|
||||
import com.github.mikephil.charting.ChartData;
|
||||
import com.github.mikephil.charting.LineChart;
|
||||
import com.github.mikephil.charting.LineSeries;
|
||||
import com.github.mikephil.charting.Point;
|
||||
import com.github.mikephil.charting.Series;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import com.github.mikephil.charting.Approximator.ApproximatorType;
|
||||
|
||||
public class MultiLineChartActivity extends Activity implements OnSeekBarChangeListener {
|
||||
|
||||
private LineChart mChart;
|
||||
private SeekBar mSeekBarX, mSeekBarY;
|
||||
private TextView tvX, tvY;
|
||||
private LineChart mChart;
|
||||
private SeekBar mSeekBarX, mSeekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart);
|
||||
|
||||
tvX = (TextView) findViewById(R.id.tvXMax);
|
||||
tvY = (TextView) findViewById(R.id.tvYMax);
|
||||
|
||||
mSeekBarX = (SeekBar) findViewById(R.id.seekBar1);
|
||||
mSeekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
mSeekBarY = (SeekBar) findViewById(R.id.seekBar2);
|
||||
mSeekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
mChart = (LineChart) findViewById(R.id.chart1);
|
||||
// mChart.setColorTemplate(new ColorTemplate(ColorTemplate.getColors(this, ColorTemplate.LIBERTY_COLORS)));
|
||||
|
||||
// mChart.setDrawFilled(true);
|
||||
// mChart.setRoundedYLegend(false);
|
||||
// mChart.setStartAtZero(true);
|
||||
mChart.setDrawYValues(false);
|
||||
mChart.setLineWidth(4f);
|
||||
mChart.setCircleSize(4f);
|
||||
// mChart.setSpacePercent(20, 10);
|
||||
mChart.setYLegendCount(6);
|
||||
mChart.setTouchEnabled(true);
|
||||
mChart.setHighlightEnabled(true);
|
||||
// mChart.highlightValues(new int[] {2, 6});
|
||||
mChart.setDragEnabled(true);
|
||||
mChart.setTouchEnabled(true);
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart);
|
||||
|
||||
TextView textView = new TextView(this);
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
textView.setBackgroundColor(Color.WHITE);
|
||||
textView.setPadding(15, 15, 15, 15);
|
||||
textView.setText("Marker View");
|
||||
tvX = (TextView) findViewById(R.id.tvXMax);
|
||||
tvY = (TextView) findViewById(R.id.tvYMax);
|
||||
|
||||
mChart.setDrawMarkerView(true);
|
||||
mChart.setMarkerView(textView);
|
||||
|
||||
mSeekBarX.setProgress(45);
|
||||
mSeekBarY.setProgress(100);
|
||||
}
|
||||
mSeekBarX = (SeekBar) findViewById(R.id.seekBar1);
|
||||
mSeekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.line, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.actionToggleRound: {
|
||||
if (mChart.isYLegendRounded())
|
||||
mChart.setRoundedYLegend(false);
|
||||
else
|
||||
mChart.setRoundedYLegend(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
if (mChart.isDrawYValuesEnabled())
|
||||
mChart.setDrawYValues(false);
|
||||
else
|
||||
mChart.setDrawYValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (mChart.isHighlightEnabled())
|
||||
mChart.setHighlightEnabled(false);
|
||||
else
|
||||
mChart.setHighlightEnabled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleFilled: {
|
||||
if (mChart.isDrawFilledEnabled())
|
||||
mChart.setDrawFilled(false);
|
||||
else
|
||||
mChart.setDrawFilled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCircles: {
|
||||
if (mChart.isDrawCirclesEnabled())
|
||||
mChart.setDrawCircles(false);
|
||||
else
|
||||
mChart.setDrawCircles(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleStartzero: {
|
||||
if (mChart.isStartAtZeroEnabled())
|
||||
mChart.setStartAtZero(false);
|
||||
else
|
||||
mChart.setStartAtZero(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAdjustXLegend: {
|
||||
if (mChart.isAdjustXLegendEnabled())
|
||||
mChart.setAdjustXLegend(false);
|
||||
else
|
||||
mChart.setAdjustXLegend(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
// mChart.saveToGallery("title"+System.currentTimeMillis());
|
||||
mChart.saveToPath("title"+System.currentTimeMillis(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
mSeekBarY = (SeekBar) findViewById(R.id.seekBar2);
|
||||
mSeekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
ArrayList<String> xVals = new ArrayList<String>();
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
xVals.add((i)+"");
|
||||
}
|
||||
mChart = (LineChart) findViewById(R.id.chart1);
|
||||
// mChart.setColorTemplate(new ColorTemplate(ColorTemplate.getColors(this, ColorTemplate.LIBERTY_COLORS)));
|
||||
|
||||
ArrayList<Series> yVals = new ArrayList<Series>();
|
||||
// mChart.setDrawFilled(true);
|
||||
// mChart.setRoundedYLegend(false);
|
||||
// mChart.setStartAtZero(true);
|
||||
mChart.setDrawYValues(false);
|
||||
mChart.setLineWidth(4f);
|
||||
mChart.setCircleSize(4f);
|
||||
// mChart.setSpacePercent(20, 10);
|
||||
mChart.setYLegendCount(6);
|
||||
mChart.setTouchEnabled(true);
|
||||
mChart.setHighlightEnabled(true);
|
||||
// mChart.highlightValues(new int[] {2, 6});
|
||||
mChart.setDragEnabled(true);
|
||||
mChart.setTouchEnabled(true);
|
||||
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
float mult = (mSeekBarY.getProgress()+1);
|
||||
float val = (float) (Math.random() * mult * 0.1) + 3;// + (float) ((mult * 0.1) / 10);
|
||||
yVals.add(new LineSeries(val, 0, i));
|
||||
}
|
||||
|
||||
tvX.setText(""+ (mSeekBarX.getProgress() + 1));
|
||||
tvY.setText(""+ (mSeekBarY.getProgress() / 10));
|
||||
TextView textView = new TextView(this);
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
textView.setBackgroundColor(Color.WHITE);
|
||||
textView.setPadding(15, 15, 15, 15);
|
||||
textView.setText("Marker View");
|
||||
|
||||
mChart.setData(xVals, yVals);
|
||||
mChart.invalidate();
|
||||
}
|
||||
mChart.setDrawMarkerView(true);
|
||||
mChart.setMarkerView(textView);
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
mSeekBarX.setProgress(45);
|
||||
mSeekBarY.setProgress(100);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.line, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.actionToggleRound: {
|
||||
if (mChart.isYLegendRounded())
|
||||
mChart.setRoundedYLegend(false);
|
||||
else
|
||||
mChart.setRoundedYLegend(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
if (mChart.isDrawYValuesEnabled())
|
||||
mChart.setDrawYValues(false);
|
||||
else
|
||||
mChart.setDrawYValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (mChart.isHighlightEnabled())
|
||||
mChart.setHighlightEnabled(false);
|
||||
else
|
||||
mChart.setHighlightEnabled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleFilled: {
|
||||
if (mChart.isDrawFilledEnabled())
|
||||
mChart.setDrawFilled(false);
|
||||
else
|
||||
mChart.setDrawFilled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCircles: {
|
||||
if (mChart.isDrawCirclesEnabled())
|
||||
mChart.setDrawCircles(false);
|
||||
else
|
||||
mChart.setDrawCircles(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleStartzero: {
|
||||
if (mChart.isStartAtZeroEnabled())
|
||||
mChart.setStartAtZero(false);
|
||||
else
|
||||
mChart.setStartAtZero(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAdjustXLegend: {
|
||||
if (mChart.isAdjustXLegendEnabled())
|
||||
mChart.setAdjustXLegend(false);
|
||||
else
|
||||
mChart.setAdjustXLegend(true);
|
||||
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
// mChart.saveToGallery("title"+System.currentTimeMillis());
|
||||
mChart.saveToPath("title" + System.currentTimeMillis(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
ArrayList<String> xVals = new ArrayList<String>();
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
xVals.add((i) + "");
|
||||
}
|
||||
|
||||
ArrayList<Series> yVals = new ArrayList<Series>();
|
||||
Approximator approximator = new Approximator(ApproximatorType.DOUGLAS_PEUCKER);
|
||||
|
||||
for (int z = 0; z < 1; z++) {
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
float mult = (mSeekBarY.getProgress() + 1);
|
||||
float val = (float) (Math.random() * mult * 0.1) + 3;// + (float) ((mult * 0.1) / 10);
|
||||
yVals.add(new Series(val, z, i));
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Series> filtered = approximator.filter(yVals);
|
||||
|
||||
for (int i = 0; i < filtered.size(); i++) {
|
||||
filtered.get(i).setType(1);
|
||||
}
|
||||
// yVals.addAll(filtered);
|
||||
|
||||
// for (int z = 0; z < 5; z++) {
|
||||
// for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
// float mult = (mSeekBarY.getProgress() + 1);
|
||||
// float val = (float) (Math.random() * mult * 0.1) + 3;// + (float) ((mult * 0.1) / 10);
|
||||
// yVals.add(new Series(val, z, i));
|
||||
// }
|
||||
// }
|
||||
|
||||
tvX.setText("" + (mSeekBarX.getProgress() + 1));
|
||||
tvY.setText("" + (mSeekBarY.getProgress() / 10));
|
||||
|
||||
ChartData data = new ChartData(xVals, filtered);
|
||||
|
||||
mChart.setData(data);
|
||||
mChart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.example.mpchartexample;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
@ -10,166 +12,166 @@ import android.widget.SeekBar;
|
|||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.ChartData;
|
||||
import com.github.mikephil.charting.ColorTemplate;
|
||||
import com.github.mikephil.charting.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.PieChart;
|
||||
import com.github.mikephil.charting.PieSeries;
|
||||
import com.github.mikephil.charting.Series;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PieChartActivity extends Activity implements OnSeekBarChangeListener, OnChartValueSelectedListener {
|
||||
|
||||
private PieChart mChart;
|
||||
private SeekBar mSeekBarX, mSeekBarY;
|
||||
private TextView tvX, tvY;
|
||||
private PieChart mChart;
|
||||
private SeekBar mSeekBarX, mSeekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_piechart);
|
||||
|
||||
tvX = (TextView) findViewById(R.id.tvXMax);
|
||||
tvY = (TextView) findViewById(R.id.tvYMax);
|
||||
|
||||
mSeekBarX = (SeekBar) findViewById(R.id.seekBar1);
|
||||
mSeekBarY = (SeekBar) findViewById(R.id.seekBar2);
|
||||
|
||||
mSeekBarX.setOnSeekBarChangeListener(this);
|
||||
mSeekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
mChart = (PieChart) findViewById(R.id.chart1);
|
||||
mChart.setColorTemplate(new ColorTemplate(ColorTemplate.getColors(this, ColorTemplate.COLORFUL_COLORS)));
|
||||
|
||||
mChart.setDrawYValues(true);
|
||||
mChart.setDrawCenterText(true);
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_piechart);
|
||||
|
||||
mChart.setDescription("This is a description.");
|
||||
mChart.setDrawHoleEnabled(true);
|
||||
mChart.setDrawXValues(true);
|
||||
mChart.setTouchEnabled(true);
|
||||
mChart.setUsePercentValues(false);
|
||||
mChart.setOnChartValueSelectedListener(this);
|
||||
|
||||
mSeekBarX.setProgress(5);
|
||||
mSeekBarY.setProgress(100);
|
||||
|
||||
// float diameter = mChart.getDiameter();
|
||||
// float radius = mChart.getRadius();
|
||||
//
|
||||
// Log.i("Piechart", "diameter: " + diameter + ", radius: " + radius);
|
||||
}
|
||||
tvX = (TextView) findViewById(R.id.tvXMax);
|
||||
tvY = (TextView) findViewById(R.id.tvYMax);
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.pie, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.actionToggleValues: {
|
||||
if (mChart.isDrawYValuesEnabled())
|
||||
mChart.setDrawYValues(false);
|
||||
else
|
||||
mChart.setDrawYValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePercent: {
|
||||
if (mChart.isUsePercentValuesEnabled())
|
||||
mChart.setUsePercentValues(false);
|
||||
else
|
||||
mChart.setUsePercentValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHole: {
|
||||
if (mChart.isDrawHoleEnabled())
|
||||
mChart.setDrawHoleEnabled(false);
|
||||
else
|
||||
mChart.setDrawHoleEnabled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionDrawCenter: {
|
||||
if (mChart.isDrawCenterTextEnabled())
|
||||
mChart.setDrawCenterText(false);
|
||||
else
|
||||
mChart.setDrawCenterText(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleXVals: {
|
||||
if (mChart.isDrawXValuesEnabled())
|
||||
mChart.setDrawXValues(false);
|
||||
else
|
||||
mChart.setDrawXValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
// mChart.saveToGallery("title"+System.currentTimeMillis());
|
||||
mChart.saveToPath("title"+System.currentTimeMillis(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
mSeekBarX = (SeekBar) findViewById(R.id.seekBar1);
|
||||
mSeekBarY = (SeekBar) findViewById(R.id.seekBar2);
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
ArrayList<Series> yVals = new ArrayList<Series>();
|
||||
mSeekBarX.setOnSeekBarChangeListener(this);
|
||||
mSeekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
float mult = (mSeekBarY.getProgress());
|
||||
float val = (float) (Math.random() * mult) + mult / 5;// + (float) ((mult * 0.1) / 10);
|
||||
yVals.add(new PieSeries(val));
|
||||
}
|
||||
|
||||
tvX.setText(""+ (mSeekBarX.getProgress()));
|
||||
tvY.setText(""+ (mSeekBarY.getProgress()));
|
||||
mChart = (PieChart) findViewById(R.id.chart1);
|
||||
mChart.setColorTemplate(new ColorTemplate(ColorTemplate.getColors(this, ColorTemplate.COLORFUL_COLORS)));
|
||||
|
||||
ArrayList<String> xVals = new ArrayList<String>();
|
||||
|
||||
for(int i = 0; i < yVals.size(); i++) xVals.add("Text"+(i+1));
|
||||
|
||||
mChart.setData(xVals, yVals);
|
||||
mChart.setCenterText("Total Value\n" + (int) mChart.getYValueSum() + "\n(all slices)");
|
||||
mChart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValuesSelected(float[] values, int[] indices) {
|
||||
StringBuffer a = new StringBuffer();
|
||||
|
||||
for(int i = 0; i < values.length; i++) a.append("val: " + values[i] + ", ind: " + indices[i] + "\n");
|
||||
|
||||
Log.i("PieChart", "Selected: " + a.toString());
|
||||
|
||||
// immediately unselect
|
||||
// mChart.highlightValues(null);
|
||||
}
|
||||
mChart.setDrawYValues(true);
|
||||
mChart.setDrawCenterText(true);
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
Log.i("PieChart", "nothing selected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
mChart.setDescription("This is a description.");
|
||||
mChart.setDrawHoleEnabled(true);
|
||||
mChart.setDrawXValues(true);
|
||||
mChart.setTouchEnabled(true);
|
||||
mChart.setUsePercentValues(false);
|
||||
mChart.setOnChartValueSelectedListener(this);
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
mSeekBarX.setProgress(5);
|
||||
mSeekBarY.setProgress(100);
|
||||
|
||||
// float diameter = mChart.getDiameter();
|
||||
// float radius = mChart.getRadius();
|
||||
//
|
||||
// Log.i("Piechart", "diameter: " + diameter + ", radius: " + radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.pie, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.actionToggleValues: {
|
||||
if (mChart.isDrawYValuesEnabled())
|
||||
mChart.setDrawYValues(false);
|
||||
else
|
||||
mChart.setDrawYValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePercent: {
|
||||
if (mChart.isUsePercentValuesEnabled())
|
||||
mChart.setUsePercentValues(false);
|
||||
else
|
||||
mChart.setUsePercentValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHole: {
|
||||
if (mChart.isDrawHoleEnabled())
|
||||
mChart.setDrawHoleEnabled(false);
|
||||
else
|
||||
mChart.setDrawHoleEnabled(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionDrawCenter: {
|
||||
if (mChart.isDrawCenterTextEnabled())
|
||||
mChart.setDrawCenterText(false);
|
||||
else
|
||||
mChart.setDrawCenterText(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleXVals: {
|
||||
if (mChart.isDrawXValuesEnabled())
|
||||
mChart.setDrawXValues(false);
|
||||
else
|
||||
mChart.setDrawXValues(true);
|
||||
mChart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
// mChart.saveToGallery("title"+System.currentTimeMillis());
|
||||
mChart.saveToPath("title" + System.currentTimeMillis(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
ArrayList<Series> yVals = new ArrayList<Series>();
|
||||
|
||||
for (int i = 0; i < mSeekBarX.getProgress(); i++) {
|
||||
float mult = (mSeekBarY.getProgress());
|
||||
float val = (float) (Math.random() * mult) + mult / 5;// + (float) ((mult * 0.1) / 10);
|
||||
yVals.add(new Series(val, i, 0));
|
||||
}
|
||||
|
||||
tvX.setText("" + (mSeekBarX.getProgress()));
|
||||
tvY.setText("" + (mSeekBarY.getProgress()));
|
||||
|
||||
ArrayList<String> xVals = new ArrayList<String>();
|
||||
|
||||
for (int i = 0; i < yVals.size(); i++)
|
||||
xVals.add("Text" + (i + 1));
|
||||
|
||||
ChartData data = new ChartData(xVals, yVals);
|
||||
mChart.setData(data);
|
||||
mChart.setCenterText("Total Value\n" + (int) mChart.getYValueSum() + "\n(all slices)");
|
||||
mChart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValuesSelected(float[] values, int[] indices) {
|
||||
StringBuffer a = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < values.length; i++)
|
||||
a.append("val: " + values[i] + ", ind: " + indices[i] + "\n");
|
||||
|
||||
Log.i("PieChart", "Selected: " + a.toString());
|
||||
|
||||
// immediately unselect
|
||||
// mChart.highlightValues(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
Log.i("PieChart", "nothing selected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
|
|
142
MPChartLib/src/com/github/mikephil/charting/Approximator.java
Normal file
142
MPChartLib/src/com/github/mikephil/charting/Approximator.java
Normal file
|
@ -0,0 +1,142 @@
|
|||
package com.github.mikephil.charting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Implemented according to Wiki-Pseudocode {@link} http://en.wikipedia.org/wiki/RamerÐDouglasÐPeucker_algorithm
|
||||
*
|
||||
* @author Philipp Baldauf & Phliipp Jahoda
|
||||
*/
|
||||
public class Approximator {
|
||||
|
||||
private ApproximatorType type = ApproximatorType.NONE;
|
||||
|
||||
public enum ApproximatorType {
|
||||
NONE, DOUGLAS_PEUCKER
|
||||
}
|
||||
|
||||
private boolean[] keep;
|
||||
|
||||
public Approximator(ApproximatorType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public ArrayList<Series> filter(ArrayList<Series> points) {
|
||||
keep = new boolean[points.size()];
|
||||
|
||||
switch (type) {
|
||||
case DOUGLAS_PEUCKER:
|
||||
return reduceWithDouglasPeuker(points, 1);
|
||||
case NONE:
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ArrayList<Series> reduceWithDouglasPeuker(ArrayList<Series> series, double epsilon) {
|
||||
// if a shape has 2 or less points it cannot be reduced
|
||||
if (epsilon <= 0 || series.size() < 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// first and last always stay
|
||||
keep[0] = true;
|
||||
keep[series.size() - 1] = true;
|
||||
|
||||
// first and last series are entry point to recursion
|
||||
algorithmDouglasPeucker(series, epsilon, 0, series.size() - 1);
|
||||
|
||||
// create a new array with series, only take the kept ones
|
||||
ArrayList<Series> reducedSeries = new ArrayList<Series>();
|
||||
for (int i = 0; i < series.size(); i++) {
|
||||
if (keep[i]) {
|
||||
Series curSeries = series.get(i);
|
||||
reducedSeries.add(new Series(curSeries.getVal(), curSeries.getType(), curSeries.getXIndex()));
|
||||
}
|
||||
}
|
||||
return reducedSeries;
|
||||
}
|
||||
|
||||
/**
|
||||
* apply the Douglas-Peucker-Reduction to an ArrayList of Series with a given epsilon (tolerance)
|
||||
*
|
||||
* @param series
|
||||
* @param epsilon
|
||||
* as y-value
|
||||
* @param start
|
||||
* @param end
|
||||
*/
|
||||
private void algorithmDouglasPeucker(ArrayList<Series> series, double epsilon, int start, int end) {
|
||||
if (end <= start + 1) {
|
||||
// recursion finished
|
||||
return;
|
||||
}
|
||||
|
||||
// find the greatest distance between start and endpoint
|
||||
int maxDistIndex = 0;
|
||||
double distMax = 0;
|
||||
|
||||
Series firstSeries = series.get(start);
|
||||
Series lastSeries = series.get(end);
|
||||
|
||||
for (int i = start + 1; i < end; i++) {
|
||||
double dist = pointToLineDistance(firstSeries, lastSeries, series.get(i));
|
||||
|
||||
// keep the point with the greatest distance
|
||||
if (dist > distMax) {
|
||||
distMax = dist;
|
||||
maxDistIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (distMax > epsilon) {
|
||||
// keep max dist point
|
||||
keep[maxDistIndex] = true;
|
||||
|
||||
// recursive call
|
||||
algorithmDouglasPeucker(series, epsilon, start, maxDistIndex);
|
||||
algorithmDouglasPeucker(series, epsilon, maxDistIndex, end);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate the distance between a line between two series and a series (point)
|
||||
*
|
||||
* @param startSeries
|
||||
* @param endSeries
|
||||
* @param seriesToInspect
|
||||
* @return
|
||||
*/
|
||||
public double pointToLineDistance(Series startSeries, Series endSeries, Series seriesToInspect) {
|
||||
double normalLength = Math.sqrt((endSeries.getXIndex() - startSeries.getXIndex())
|
||||
* (endSeries.getXIndex() - startSeries.getXIndex()) + (endSeries.getVal() - startSeries.getVal())
|
||||
* (endSeries.getVal() - startSeries.getVal()));
|
||||
return Math.abs((seriesToInspect.getXIndex() - startSeries.getXIndex())
|
||||
* (endSeries.getVal() - startSeries.getVal()) - (seriesToInspect.getVal() - startSeries.getVal())
|
||||
* (endSeries.getXIndex() - startSeries.getXIndex()))
|
||||
/ normalLength;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * calculate the distance between a line between two series and a series (point)
|
||||
// *
|
||||
// * @param seriesToInspect
|
||||
// * @param startSeries
|
||||
// * @param endSeries
|
||||
// * @return
|
||||
// */
|
||||
// private static double shortestDistToSegment(Series seriesToInspect, Series startSeries, Series endSeries) {
|
||||
// double area = Math.abs((startSeries.getVal() * endSeries.getXIndex() + endSeries.getVal()
|
||||
// * seriesToInspect.getXIndex() + seriesToInspect.getVal() * startSeries.getXIndex() - endSeries.getVal()
|
||||
// * startSeries.getXIndex() - seriesToInspect.getVal() * endSeries.getXIndex() - startSeries.getVal()
|
||||
// * seriesToInspect.getXIndex()) / 2.0);
|
||||
//
|
||||
// double bottom = Math.hypot(startSeries.getVal() - endSeries.getVal(),
|
||||
// startSeries.getXIndex() - endSeries.getXIndex());
|
||||
//
|
||||
// return (area / bottom * 2.0);
|
||||
// }
|
||||
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -14,416 +13,410 @@ import java.util.ArrayList;
|
|||
|
||||
public class BarChart extends BarLineChartBase {
|
||||
|
||||
/** space indicator between the bars 0.1f == 10 % */
|
||||
private float mBarSpace = 0.1f;
|
||||
/** space indicator between the bars 0.1f == 10 % */
|
||||
private float mBarSpace = 0.1f;
|
||||
|
||||
/** indicates the angle of the 3d effect */
|
||||
private float mSkew = 0.3f;
|
||||
/** indicates the angle of the 3d effect */
|
||||
private float mSkew = 0.3f;
|
||||
|
||||
/** indicates how much the 3d effect goes back */
|
||||
private float mDepth = 0.3f;
|
||||
/** indicates how much the 3d effect goes back */
|
||||
private float mDepth = 0.3f;
|
||||
|
||||
/** flag the enables or disables 3d bars */
|
||||
private boolean m3DEnabled = true;
|
||||
|
||||
/** flag that enables or disables the highlighting arrow */
|
||||
private boolean mDrawHighlightArrow = true;
|
||||
/** flag the enables or disables 3d bars */
|
||||
private boolean m3DEnabled = true;
|
||||
|
||||
public BarChart(Context context) {
|
||||
super(context);
|
||||
}
|
||||
/** flag that enables or disables the highlighting arrow */
|
||||
private boolean mDrawHighlightArrow = true;
|
||||
|
||||
public BarChart(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public BarChart(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public BarChart(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public BarChart(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
public BarChart(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mHighlightPaint.setStyle(Paint.Style.FILL);
|
||||
mHighlightPaint.setColor(Color.rgb(0, 0, 0));
|
||||
// set alpha after color
|
||||
mHighlightPaint.setAlpha(120);
|
||||
}
|
||||
|
||||
/** array that holds all the colors for the top 3D effect */
|
||||
private int[] mTopColors;
|
||||
|
||||
/** array that holds all the colors for the side 3D effect */
|
||||
private int[] mSideColors;
|
||||
|
||||
@Override
|
||||
protected void prepareDataPaints(ColorTemplate ct) {
|
||||
|
||||
// prepare the paints
|
||||
mDrawPaints = new Paint[ct.getColors().size()];
|
||||
|
||||
for (int i = 0; i < ct.getColors().size(); i++) {
|
||||
mDrawPaints[i] = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mDrawPaints[i].setStyle(Style.FILL);
|
||||
mDrawPaints[i].setColor(ct.getColors().get(i));
|
||||
}
|
||||
|
||||
// generate the colors for the 3D effect
|
||||
mTopColors = new int[mDrawPaints.length];
|
||||
mSideColors = new int[mDrawPaints.length];
|
||||
|
||||
float[] hsv = new float[3];
|
||||
|
||||
for (int i = 0; i < mSideColors.length; i++) {
|
||||
|
||||
// extract the color
|
||||
int c = mDrawPaints[i].getColor();
|
||||
Color.colorToHSV(c, hsv); // convert to hsv
|
||||
|
||||
// make brighter
|
||||
hsv[1] = hsv[1] - 0.1f; // less saturation
|
||||
hsv[2] = hsv[2] + 0.1f; // more brightness
|
||||
|
||||
// convert back
|
||||
c = Color.HSVToColor(hsv);
|
||||
|
||||
// assign
|
||||
mTopColors[i] = c;
|
||||
|
||||
// get color again
|
||||
c = mDrawPaints[i].getColor();
|
||||
|
||||
// convert
|
||||
Color.colorToHSV(c, hsv);
|
||||
|
||||
// make darker
|
||||
hsv[1] = hsv[1] + 0.1f; // more saturation
|
||||
hsv[2] = hsv[2] - 0.1f; // less brightness
|
||||
|
||||
// reassing
|
||||
c = Color.HSVToColor(hsv);
|
||||
|
||||
mSideColors[i] = c;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
@Override
|
||||
protected void calcMinMax() {
|
||||
super.calcMinMax();
|
||||
mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mHighlightPaint.setStyle(Paint.Style.FILL);
|
||||
mHighlightPaint.setColor(Color.rgb(0, 0, 0));
|
||||
// set alpha after color
|
||||
mHighlightPaint.setAlpha(120);
|
||||
}
|
||||
|
||||
// increase deltax by 1 because the bars have a width of 1
|
||||
mDeltaX++;
|
||||
}
|
||||
/** array that holds all the colors for the top 3D effect */
|
||||
private int[] mTopColors;
|
||||
|
||||
@Override
|
||||
protected void drawHighlights() {
|
||||
|
||||
// if there are values to highlight and highlighnting is enabled, do it
|
||||
if (mHighlightEnabled && valuesToHighlight()) {
|
||||
|
||||
// distance between highlight arrow and bar
|
||||
float offsetY = mDeltaY * 0.04f;
|
||||
|
||||
for (int i = 0; i < mIndicesToHightlight.length; i++) {
|
||||
|
||||
int index = mIndicesToHightlight[i];
|
||||
|
||||
// check outofbounds
|
||||
if (index < mYVals.size() && index >= 0) {
|
||||
|
||||
mHighlightPaint.setAlpha(120);
|
||||
|
||||
float y = mYVals.get(index).getVal();
|
||||
float left = index + mBarSpace / 2f;
|
||||
float right = index + 1f - mBarSpace / 2f;
|
||||
float top = y >= 0 ? y : 0;
|
||||
float bottom = y <= 0 ? y : 0;
|
||||
/** array that holds all the colors for the side 3D effect */
|
||||
private int[] mSideColors;
|
||||
|
||||
RectF highlight = new RectF(left, top, right, bottom);
|
||||
transformRect(highlight);
|
||||
|
||||
mDrawCanvas.drawRect(highlight, mHighlightPaint);
|
||||
|
||||
if(mDrawHighlightArrow) {
|
||||
|
||||
mHighlightPaint.setAlpha(200);
|
||||
|
||||
Path arrow = new Path();
|
||||
arrow.moveTo(index + 0.5f, y + offsetY * 0.3f);
|
||||
arrow.lineTo(index + 0.2f, y + offsetY);
|
||||
arrow.lineTo(index + 0.8f, y + offsetY);
|
||||
|
||||
transformPath(arrow);
|
||||
mDrawCanvas.drawPath(arrow, mHighlightPaint);
|
||||
}
|
||||
@Override
|
||||
protected void prepareDataPaints(ColorTemplate ct) {
|
||||
|
||||
// float[] pts = new float[] {
|
||||
// index + 0.5f, mYChartMax, index + 0.5f, mYChartMin,
|
||||
// 0, mYVals.get(index), mDeltaX, mYVals.get(index)
|
||||
// };
|
||||
//
|
||||
// transformPointArray(pts);
|
||||
// // draw the highlight lines
|
||||
// mDrawCanvas.drawLines(pts, mHighlightPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// prepare the paints
|
||||
mDrawPaints = new Paint[ct.getColors().size()];
|
||||
|
||||
private RectF mBarRect = new RectF();
|
||||
for (int i = 0; i < ct.getColors().size(); i++) {
|
||||
mDrawPaints[i] = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mDrawPaints[i].setStyle(Style.FILL);
|
||||
mDrawPaints[i].setColor(ct.getColors().get(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawData() {
|
||||
// generate the colors for the 3D effect
|
||||
mTopColors = new int[mDrawPaints.length];
|
||||
mSideColors = new int[mDrawPaints.length];
|
||||
|
||||
ArrayList<Path> topPaths = new ArrayList<Path>();
|
||||
ArrayList<Path> sidePaths = new ArrayList<Path>();
|
||||
float[] hsv = new float[3];
|
||||
|
||||
if (m3DEnabled) {
|
||||
for (int i = 0; i < mSideColors.length; i++) {
|
||||
|
||||
float[] pts = new float[] {
|
||||
0f, 0f, 1f, 0f
|
||||
};
|
||||
// extract the color
|
||||
int c = mDrawPaints[i].getColor();
|
||||
Color.colorToHSV(c, hsv); // convert to hsv
|
||||
|
||||
// calculate the depth depending on scale
|
||||
// make brighter
|
||||
hsv[1] = hsv[1] - 0.1f; // less saturation
|
||||
hsv[2] = hsv[2] + 0.1f; // more brightness
|
||||
|
||||
transformPointArray(pts);
|
||||
// convert back
|
||||
c = Color.HSVToColor(hsv);
|
||||
|
||||
pts[3] = pts[2] - pts[0];
|
||||
pts[2] = 0f;
|
||||
pts[1] = 0f;
|
||||
pts[0] = 0f;
|
||||
// assign
|
||||
mTopColors[i] = c;
|
||||
|
||||
Matrix invert = new Matrix();
|
||||
|
||||
mMatrixOffset.invert(invert);
|
||||
invert.mapPoints(pts);
|
||||
|
||||
mMatrixTouch.invert(invert);
|
||||
invert.mapPoints(pts);
|
||||
|
||||
mMatrixValueToPx.invert(invert);
|
||||
invert.mapPoints(pts);
|
||||
|
||||
float depth = Math.abs(pts[3] - pts[1]) * mDepth;
|
||||
|
||||
for (int i = 0; i < mYVals.size(); i++) {
|
||||
|
||||
float y = mYVals.get(i).getVal();
|
||||
float left = i + mBarSpace / 2f;
|
||||
float right = i + 1f - mBarSpace / 2f;
|
||||
float top = y >= 0 ? y : 0;
|
||||
|
||||
// create the 3D effect paths for the top and side
|
||||
Path topPath = new Path();
|
||||
topPath.moveTo(left, top);
|
||||
topPath.lineTo(left + mSkew, top + depth);
|
||||
topPath.lineTo(right + mSkew, top + depth);
|
||||
topPath.lineTo(right, top);
|
||||
|
||||
topPaths.add(topPath);
|
||||
|
||||
Path sidePath = new Path();
|
||||
sidePath.moveTo(right, top);
|
||||
sidePath.lineTo(right + mSkew, top + depth);
|
||||
sidePath.lineTo(right + mSkew, depth);
|
||||
sidePath.lineTo(right, 0);
|
||||
|
||||
sidePaths.add(sidePath);
|
||||
}
|
||||
|
||||
transformPaths(topPaths);
|
||||
transformPaths(sidePaths);
|
||||
}
|
||||
|
||||
// do the drawing
|
||||
for (int i = 0; i < mYVals.size(); i++) {
|
||||
|
||||
Paint paint = mDrawPaints[i % mDrawPaints.length];
|
||||
|
||||
float y = mYVals.get(i).getVal();
|
||||
float left = i + mBarSpace / 2f;
|
||||
float right = i + 1f - mBarSpace / 2f;
|
||||
float top = y >= 0 ? y : 0;
|
||||
float bottom = y <= 0 ? y : 0;
|
||||
|
||||
mBarRect.set(left, top, right, bottom);
|
||||
|
||||
transformRect(mBarRect);
|
||||
|
||||
mDrawCanvas.drawRect(mBarRect, paint);
|
||||
|
||||
if (m3DEnabled) {
|
||||
|
||||
int c = paint.getColor();
|
||||
|
||||
paint.setColor(mTopColors[i % mTopColors.length]);
|
||||
mDrawCanvas.drawPath(topPaths.get(i), paint);
|
||||
|
||||
paint.setColor(mSideColors[i % mSideColors.length]);
|
||||
mDrawCanvas.drawPath(sidePaths.get(i), paint);
|
||||
|
||||
paint.setColor(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawValues() {
|
||||
|
||||
// if values are drawn
|
||||
if (mDrawYValues && mYVals.size() < mMaxVisibleCount * mScaleX) {
|
||||
|
||||
float[] valuePoints = new float[mYVals.size() * 2];
|
||||
|
||||
for (int i = 0; i < valuePoints.length; i += 2) {
|
||||
valuePoints[i] = i / 2 + 0.5f; // add 0.5f too keep the values
|
||||
// centered on top of the bars
|
||||
valuePoints[i + 1] = mYVals.get(i / 2).getVal();
|
||||
}
|
||||
|
||||
transformPointArray(valuePoints);
|
||||
|
||||
for (int i = 0; i < valuePoints.length; i += 2) {
|
||||
|
||||
if(mDrawUnitInChart) {
|
||||
|
||||
mDrawCanvas.drawText(
|
||||
mFormatValue.format(mYVals.get(i / 2).getVal()) + mUnit,
|
||||
valuePoints[i], valuePoints[i + 1] - 12, mValuePaint);
|
||||
} else {
|
||||
|
||||
|
||||
mDrawCanvas.drawText(
|
||||
mFormatValue.format(mYVals.get(i / 2).getVal()),
|
||||
valuePoints[i], valuePoints[i + 1] - 12, mValuePaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the skew (default 0.3f), the skew indicates how much the 3D effect
|
||||
* of the chart is turned to the right
|
||||
*
|
||||
* @param skew
|
||||
*/
|
||||
public void setSkew(float skew) {
|
||||
this.mSkew = skew;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the skew value that indicates how much the 3D effect is turned to
|
||||
* the right
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getSkew() {
|
||||
return mSkew;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the depth of the chart (default 0.3f), the depth indicates how much
|
||||
* the 3D effect of the chart goes back
|
||||
*
|
||||
* @param depth
|
||||
*/
|
||||
public void setDepth(float depth) {
|
||||
this.mDepth = depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* returhs the depth, which indicates how much the 3D effect goes back
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getDepth() {
|
||||
return mDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the space between bars in percent of the whole width of one value
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getBarSpace() {
|
||||
return mBarSpace * 100f;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the space between the bars in percent of the total bar width
|
||||
*
|
||||
* @param percent
|
||||
*/
|
||||
public void setBarSpace(float percent) {
|
||||
mBarSpace = percent / 100f;
|
||||
}
|
||||
|
||||
/**
|
||||
* if enabled, chart will be drawn in 3d
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void set3DEnabled(boolean enabled) {
|
||||
this.m3DEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if 3d bars is enabled, false if not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean is3DEnabled() {
|
||||
return m3DEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the top colors that define the color of the top 3D effect path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int[] getTopColors() {
|
||||
return mTopColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the side colors that define the color of the side 3D effect path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int[] getSideColors() {
|
||||
return mSideColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* set this to true to draw the highlightning arrow
|
||||
* @param enabled
|
||||
*/
|
||||
public void setDrawHighlightArrow(boolean enabled) {
|
||||
mDrawHighlightArrow = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if drawing the highlighting arrow is enabled, false if not
|
||||
* @return
|
||||
*/
|
||||
public boolean isDrawHighlightArrowEnabled() {
|
||||
return mDrawHighlightArrow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaint(Paint p, int which) {
|
||||
super.setPaint(p, which);
|
||||
|
||||
switch (which) {
|
||||
case PAINT_HIGHLIGHT_BAR:
|
||||
mHighlightPaint = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawAdditional() {
|
||||
}
|
||||
// get color again
|
||||
c = mDrawPaints[i].getColor();
|
||||
|
||||
// convert
|
||||
Color.colorToHSV(c, hsv);
|
||||
|
||||
// make darker
|
||||
hsv[1] = hsv[1] + 0.1f; // more saturation
|
||||
hsv[2] = hsv[2] - 0.1f; // less brightness
|
||||
|
||||
// reassing
|
||||
c = Color.HSVToColor(hsv);
|
||||
|
||||
mSideColors[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void calcMinMax() {
|
||||
super.calcMinMax();
|
||||
|
||||
// increase deltax by 1 because the bars have a width of 1
|
||||
mDeltaX++;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawHighlights() {
|
||||
|
||||
// if there are values to highlight and highlighnting is enabled, do it
|
||||
if (mHighlightEnabled && valuesToHighlight()) {
|
||||
|
||||
// distance between highlight arrow and bar
|
||||
float offsetY = mDeltaY * 0.04f;
|
||||
|
||||
for (int i = 0; i < mIndicesToHightlight.length; i++) {
|
||||
|
||||
int index = mIndicesToHightlight[i];
|
||||
|
||||
// check outofbounds
|
||||
if (index < mData.getYValSize() && index >= 0) {
|
||||
|
||||
mHighlightPaint.setAlpha(120);
|
||||
|
||||
float y = mData.getYVals().get(index).getVal();
|
||||
float left = index + mBarSpace / 2f;
|
||||
float right = index + 1f - mBarSpace / 2f;
|
||||
float top = y >= 0 ? y : 0;
|
||||
float bottom = y <= 0 ? y : 0;
|
||||
|
||||
RectF highlight = new RectF(left, top, right, bottom);
|
||||
transformRect(highlight);
|
||||
|
||||
mDrawCanvas.drawRect(highlight, mHighlightPaint);
|
||||
|
||||
if (mDrawHighlightArrow) {
|
||||
|
||||
mHighlightPaint.setAlpha(200);
|
||||
|
||||
Path arrow = new Path();
|
||||
arrow.moveTo(index + 0.5f, y + offsetY * 0.3f);
|
||||
arrow.lineTo(index + 0.2f, y + offsetY);
|
||||
arrow.lineTo(index + 0.8f, y + offsetY);
|
||||
|
||||
transformPath(arrow);
|
||||
mDrawCanvas.drawPath(arrow, mHighlightPaint);
|
||||
}
|
||||
|
||||
// float[] pts = new float[] {
|
||||
// index + 0.5f, mYChartMax, index + 0.5f, mYChartMin,
|
||||
// 0, mYVals.get(index), mDeltaX, mYVals.get(index)
|
||||
// };
|
||||
//
|
||||
// transformPointArray(pts);
|
||||
// // draw the highlight lines
|
||||
// mDrawCanvas.drawLines(pts, mHighlightPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RectF mBarRect = new RectF();
|
||||
|
||||
@Override
|
||||
protected void drawData() {
|
||||
|
||||
ArrayList<Path> topPaths = new ArrayList<Path>();
|
||||
ArrayList<Path> sidePaths = new ArrayList<Path>();
|
||||
|
||||
if (m3DEnabled) {
|
||||
|
||||
float[] pts = new float[] { 0f, 0f, 1f, 0f };
|
||||
|
||||
// calculate the depth depending on scale
|
||||
|
||||
transformPointArray(pts);
|
||||
|
||||
pts[3] = pts[2] - pts[0];
|
||||
pts[2] = 0f;
|
||||
pts[1] = 0f;
|
||||
pts[0] = 0f;
|
||||
|
||||
Matrix invert = new Matrix();
|
||||
|
||||
mMatrixOffset.invert(invert);
|
||||
invert.mapPoints(pts);
|
||||
|
||||
mMatrixTouch.invert(invert);
|
||||
invert.mapPoints(pts);
|
||||
|
||||
mMatrixValueToPx.invert(invert);
|
||||
invert.mapPoints(pts);
|
||||
|
||||
float depth = Math.abs(pts[3] - pts[1]) * mDepth;
|
||||
|
||||
for (int i = 0; i < mData.getYValSize(); i++) {
|
||||
|
||||
float y = mData.getYVals().get(i).getVal();
|
||||
float left = i + mBarSpace / 2f;
|
||||
float right = i + 1f - mBarSpace / 2f;
|
||||
float top = y >= 0 ? y : 0;
|
||||
|
||||
// create the 3D effect paths for the top and side
|
||||
Path topPath = new Path();
|
||||
topPath.moveTo(left, top);
|
||||
topPath.lineTo(left + mSkew, top + depth);
|
||||
topPath.lineTo(right + mSkew, top + depth);
|
||||
topPath.lineTo(right, top);
|
||||
|
||||
topPaths.add(topPath);
|
||||
|
||||
Path sidePath = new Path();
|
||||
sidePath.moveTo(right, top);
|
||||
sidePath.lineTo(right + mSkew, top + depth);
|
||||
sidePath.lineTo(right + mSkew, depth);
|
||||
sidePath.lineTo(right, 0);
|
||||
|
||||
sidePaths.add(sidePath);
|
||||
}
|
||||
|
||||
transformPaths(topPaths);
|
||||
transformPaths(sidePaths);
|
||||
}
|
||||
|
||||
// do the drawing
|
||||
for (int i = 0; i < mData.getYValSize(); i++) {
|
||||
|
||||
Paint paint = mDrawPaints[i % mDrawPaints.length];
|
||||
|
||||
float y = mData.getYVals().get(i).getVal();
|
||||
float left = i + mBarSpace / 2f;
|
||||
float right = i + 1f - mBarSpace / 2f;
|
||||
float top = y >= 0 ? y : 0;
|
||||
float bottom = y <= 0 ? y : 0;
|
||||
|
||||
mBarRect.set(left, top, right, bottom);
|
||||
|
||||
transformRect(mBarRect);
|
||||
|
||||
mDrawCanvas.drawRect(mBarRect, paint);
|
||||
|
||||
if (m3DEnabled) {
|
||||
|
||||
int c = paint.getColor();
|
||||
|
||||
paint.setColor(mTopColors[i % mTopColors.length]);
|
||||
mDrawCanvas.drawPath(topPaths.get(i), paint);
|
||||
|
||||
paint.setColor(mSideColors[i % mSideColors.length]);
|
||||
mDrawCanvas.drawPath(sidePaths.get(i), paint);
|
||||
|
||||
paint.setColor(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawValues() {
|
||||
|
||||
// if values are drawn
|
||||
if (mDrawYValues && mData.getYValSize() < mMaxVisibleCount * mScaleX) {
|
||||
|
||||
float[] valuePoints = new float[mData.getYValSize() * 2];
|
||||
|
||||
for (int i = 0; i < valuePoints.length; i += 2) {
|
||||
valuePoints[i] = i / 2 + 0.5f; // add 0.5f too keep the values
|
||||
// centered on top of the bars
|
||||
valuePoints[i + 1] = mData.getYVals().get(i / 2).getVal();
|
||||
}
|
||||
|
||||
transformPointArray(valuePoints);
|
||||
|
||||
for (int i = 0; i < valuePoints.length; i += 2) {
|
||||
|
||||
if (mDrawUnitInChart) {
|
||||
|
||||
mDrawCanvas.drawText(mFormatValue.format(mData.getYVals().get(i / 2).getVal()) + mUnit,
|
||||
valuePoints[i], valuePoints[i + 1] - 12, mValuePaint);
|
||||
} else {
|
||||
|
||||
mDrawCanvas.drawText(mFormatValue.format(mData.getYVals().get(i / 2).getVal()), valuePoints[i],
|
||||
valuePoints[i + 1] - 12, mValuePaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the skew (default 0.3f), the skew indicates how much the 3D effect of the chart is turned to the right
|
||||
*
|
||||
* @param skew
|
||||
*/
|
||||
public void setSkew(float skew) {
|
||||
this.mSkew = skew;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the skew value that indicates how much the 3D effect is turned to the right
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getSkew() {
|
||||
return mSkew;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the depth of the chart (default 0.3f), the depth indicates how much the 3D effect of the chart goes back
|
||||
*
|
||||
* @param depth
|
||||
*/
|
||||
public void setDepth(float depth) {
|
||||
this.mDepth = depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* returhs the depth, which indicates how much the 3D effect goes back
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getDepth() {
|
||||
return mDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the space between bars in percent of the whole width of one value
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getBarSpace() {
|
||||
return mBarSpace * 100f;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the space between the bars in percent of the total bar width
|
||||
*
|
||||
* @param percent
|
||||
*/
|
||||
public void setBarSpace(float percent) {
|
||||
mBarSpace = percent / 100f;
|
||||
}
|
||||
|
||||
/**
|
||||
* if enabled, chart will be drawn in 3d
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void set3DEnabled(boolean enabled) {
|
||||
this.m3DEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if 3d bars is enabled, false if not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean is3DEnabled() {
|
||||
return m3DEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the top colors that define the color of the top 3D effect path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int[] getTopColors() {
|
||||
return mTopColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the side colors that define the color of the side 3D effect path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int[] getSideColors() {
|
||||
return mSideColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* set this to true to draw the highlightning arrow
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void setDrawHighlightArrow(boolean enabled) {
|
||||
mDrawHighlightArrow = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if drawing the highlighting arrow is enabled, false if not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isDrawHighlightArrowEnabled() {
|
||||
return mDrawHighlightArrow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaint(Paint p, int which) {
|
||||
super.setPaint(p, which);
|
||||
|
||||
switch (which) {
|
||||
case PAINT_HIGHLIGHT_BAR:
|
||||
mHighlightPaint = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawAdditional() {
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,10 +0,0 @@
|
|||
package com.github.mikephil.charting;
|
||||
|
||||
public class BarSeries extends Series {
|
||||
|
||||
public BarSeries(float val) {
|
||||
super(val);
|
||||
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
177
MPChartLib/src/com/github/mikephil/charting/ChartData.java
Normal file
177
MPChartLib/src/com/github/mikephil/charting/ChartData.java
Normal file
|
@ -0,0 +1,177 @@
|
|||
package com.github.mikephil.charting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Class that holds all relevant data that represents the chart
|
||||
*
|
||||
* @author Philipp
|
||||
*
|
||||
*/
|
||||
public class ChartData {
|
||||
|
||||
/** maximum y-value in the y-value array */
|
||||
private float mYMax = 0.0f;
|
||||
|
||||
/** the minimum y-value in the y-value array */
|
||||
private float mYMin = 0.0f;
|
||||
|
||||
/** the total sum of all y-values */
|
||||
private float mYValueSum = 0f;
|
||||
|
||||
private ArrayList<String> mXVals;
|
||||
private ArrayList<Series> mYVals;
|
||||
|
||||
/** array that holds all the different type ids that are in the series array */
|
||||
private ArrayList<Integer> mDiffTypes;
|
||||
|
||||
/** field that holds all the series split into their different types */
|
||||
private ArrayList<ArrayList<Series>> typeSeries;
|
||||
|
||||
/**
|
||||
* constructor for chart data
|
||||
*
|
||||
* @param xVals
|
||||
* must be at least as long as the longest series array of one type
|
||||
* @param yVals
|
||||
* all y series values
|
||||
*/
|
||||
public ChartData(ArrayList<String> xVals, ArrayList<Series> yVals) {
|
||||
this.mXVals = xVals;
|
||||
this.mYVals = yVals;
|
||||
|
||||
calcTypes();
|
||||
calcMinMax();
|
||||
calcYValueSum();
|
||||
calcTypeSeries();
|
||||
|
||||
for (int i = 0; i < typeSeries.size(); i++) {
|
||||
if (typeSeries.get(i).size() > xVals.size()) {
|
||||
throw new IllegalArgumentException("x values are smaller than the largest y series array of one type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates all different types that occur in the series and stores them for fast access
|
||||
*/
|
||||
private void calcTypes() {
|
||||
mDiffTypes = new ArrayList<Integer>();
|
||||
|
||||
for (int i = 0; i < mYVals.size(); i++) {
|
||||
|
||||
int type = mYVals.get(i).getType();
|
||||
|
||||
if (!alreadyCounted(mDiffTypes, type)) {
|
||||
mDiffTypes.add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* calc minimum and maximum y value
|
||||
*/
|
||||
private void calcMinMax() {
|
||||
|
||||
mYMin = mYVals.get(0).getVal();
|
||||
mYMax = mYVals.get(0).getVal();
|
||||
|
||||
for (int i = 0; i < mYVals.size(); i++) {
|
||||
if (mYVals.get(i).getVal() < mYMin)
|
||||
mYMin = mYVals.get(i).getVal();
|
||||
|
||||
if (mYVals.get(i).getVal() > mYMax)
|
||||
mYMax = mYVals.get(i).getVal();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the sum of all y-values
|
||||
*/
|
||||
private void calcYValueSum() {
|
||||
|
||||
mYValueSum = 0;
|
||||
|
||||
for (int i = 0; i < getYValSize(); i++) {
|
||||
mYValueSum += Math.abs(getYVals().get(i).getVal());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* extract all different types of series and store them in seperate arrays
|
||||
*/
|
||||
private void calcTypeSeries() {
|
||||
typeSeries = new ArrayList<ArrayList<Series>>();
|
||||
|
||||
for (int i = 0; i < getTypeCount(); i++) {
|
||||
ArrayList<Series> series = new ArrayList<Series>();
|
||||
|
||||
for (int j = 0; j < mYVals.size(); j++) {
|
||||
Series s = mYVals.get(j);
|
||||
if (s.getType() == mDiffTypes.get(i)) {
|
||||
series.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
typeSeries.add(series);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean alreadyCounted(ArrayList<Integer> countedTypes, int type) {
|
||||
for (int i = 0; i < countedTypes.size(); i++) {
|
||||
if (countedTypes.get(i) == type)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getTypeCount() {
|
||||
return mDiffTypes.size();
|
||||
}
|
||||
|
||||
public float getYMin() {
|
||||
return mYMin;
|
||||
}
|
||||
|
||||
public float getYMax() {
|
||||
return mYMax;
|
||||
}
|
||||
|
||||
public float getYValueSum() {
|
||||
return mYValueSum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the ChartData object contains valid data
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isValid() {
|
||||
|
||||
if (mXVals == null || mXVals.size() <= 1 || mYVals == null || mYVals.size() <= 1)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public ArrayList<String> getXVals() {
|
||||
return mXVals;
|
||||
}
|
||||
|
||||
public ArrayList<Series> getYVals() {
|
||||
return mYVals;
|
||||
}
|
||||
|
||||
public ArrayList<ArrayList<Series>> getTypeSeries() {
|
||||
return typeSeries;
|
||||
}
|
||||
|
||||
public int getXValSize() {
|
||||
return mXVals.size();
|
||||
}
|
||||
|
||||
public int getYValSize() {
|
||||
return mYVals.size();
|
||||
}
|
||||
}
|
|
@ -1,391 +1,385 @@
|
|||
|
||||
package com.github.mikephil.charting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Path;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class LineChart extends BarLineChartBase {
|
||||
|
||||
/** the radius of the circle-shaped value indicators */
|
||||
protected float mCircleSize = 4f;
|
||||
/** the radius of the circle-shaped value indicators */
|
||||
protected float mCircleSize = 4f;
|
||||
|
||||
/** the width of the drawn data lines */
|
||||
protected float mLineWidth = 1f;
|
||||
/** the width of the drawn data lines */
|
||||
protected float mLineWidth = 1f;
|
||||
|
||||
/** the width of the highlighning line */
|
||||
protected float mHighlightWidth = 3f;
|
||||
/** the width of the highlighning line */
|
||||
protected float mHighlightWidth = 3f;
|
||||
|
||||
/** if true, the data will also be drawn filled */
|
||||
protected boolean mDrawFilled = false;
|
||||
/** if true, the data will also be drawn filled */
|
||||
protected boolean mDrawFilled = false;
|
||||
|
||||
/** if true, drawing circles is enabled */
|
||||
protected boolean mDrawCircles = true;
|
||||
/** if true, drawing circles is enabled */
|
||||
protected boolean mDrawCircles = true;
|
||||
|
||||
/** paint for the lines of the chart */
|
||||
protected Paint mLinePaint;
|
||||
/** paint for the filled are (if enabled) below the chart line */
|
||||
protected Paint mFilledPaint;
|
||||
|
||||
/** paint for the filled are (if enabled) below the chart line */
|
||||
protected Paint mFilledPaint;
|
||||
/** paint for the outer circle of the value indicators */
|
||||
protected Paint mCirclePaintOuter;
|
||||
|
||||
/** paint for the outer circle of the value indicators */
|
||||
protected Paint mCirclePaintOuter;
|
||||
/** paint for the inner circle of the value indicators */
|
||||
protected Paint mCirclePaintInner;
|
||||
|
||||
/** paint for the inner circle of the value indicators */
|
||||
protected Paint mCirclePaintInner;
|
||||
public LineChart(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public LineChart(Context context) {
|
||||
super(context);
|
||||
}
|
||||
public LineChart(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public LineChart(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public LineChart(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
public LineChart(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
mCircleSize = Utils.convertDpToPixel(mCircleSize);
|
||||
|
||||
mCircleSize = Utils.convertDpToPixel(mCircleSize);
|
||||
mFilledPaint = new Paint();
|
||||
mFilledPaint.setStyle(Paint.Style.FILL);
|
||||
mFilledPaint.setColor(mColorDarkBlue);
|
||||
mFilledPaint.setAlpha(130); // alpha ~55%
|
||||
|
||||
mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mLinePaint.setStrokeWidth(mLineWidth);
|
||||
mLinePaint.setStyle(Paint.Style.STROKE);
|
||||
mLinePaint.setColor(mColorDarkBlue);
|
||||
// mLinePaint.setColor(mDrawColor);
|
||||
mCirclePaintOuter = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
// mCirclePaint.setStrokeWidth(5f);
|
||||
mCirclePaintOuter.setStyle(Paint.Style.FILL);
|
||||
mCirclePaintOuter.setColor(mColorDarkBlue);
|
||||
|
||||
mFilledPaint = new Paint();
|
||||
mFilledPaint.setStyle(Paint.Style.FILL);
|
||||
mFilledPaint.setColor(mColorDarkBlue);
|
||||
mFilledPaint.setAlpha(130); // alpha ~55%
|
||||
mCirclePaintInner = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mCirclePaintInner.setStyle(Paint.Style.FILL);
|
||||
mCirclePaintInner.setColor(Color.WHITE);
|
||||
|
||||
mCirclePaintOuter = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
// mCirclePaint.setStrokeWidth(5f);
|
||||
mCirclePaintOuter.setStyle(Paint.Style.FILL);
|
||||
mCirclePaintOuter.setColor(mColorDarkBlue);
|
||||
mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mHighlightPaint.setStyle(Paint.Style.STROKE);
|
||||
mHighlightPaint.setStrokeWidth(2f);
|
||||
mHighlightPaint.setColor(Color.rgb(255, 187, 115));
|
||||
}
|
||||
|
||||
mCirclePaintInner = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mCirclePaintInner.setStyle(Paint.Style.FILL);
|
||||
mCirclePaintInner.setColor(Color.WHITE);
|
||||
@Override
|
||||
protected void prepareDataPaints(ColorTemplate ct) {
|
||||
|
||||
mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mHighlightPaint.setStyle(Paint.Style.STROKE);
|
||||
mHighlightPaint.setStrokeWidth(2f);
|
||||
mHighlightPaint.setColor(Color.rgb(255, 187, 115));
|
||||
}
|
||||
if (ct == null)
|
||||
return;
|
||||
|
||||
@Override
|
||||
protected void prepareDataPaints(ColorTemplate ct) {
|
||||
mDrawPaints = new Paint[ct.getColors().size()];
|
||||
|
||||
if (ct == null)
|
||||
return;
|
||||
for (int i = 0; i < ct.getColors().size(); i++) {
|
||||
mDrawPaints[i] = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mDrawPaints[i].setStrokeWidth(mLineWidth);
|
||||
mDrawPaints[i].setStyle(Style.STROKE);
|
||||
mDrawPaints[i].setColor(ct.getColors().get(i));
|
||||
}
|
||||
}
|
||||
|
||||
mDrawPaints = new Paint[ct.getColors().size()];
|
||||
@Override
|
||||
protected void drawHighlights() {
|
||||
|
||||
for (int i = 0; i < ct.getColors().size(); i++) {
|
||||
mDrawPaints[i] = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mDrawPaints[i].setStrokeWidth(mLineWidth);
|
||||
mDrawPaints[i].setStyle(Style.STROKE);
|
||||
mDrawPaints[i].setColor(ct.getColors().get(i));
|
||||
}
|
||||
}
|
||||
// if there are values to highlight and highlighnting is enabled, do it
|
||||
if (mHighlightEnabled && valuesToHighlight()) {
|
||||
|
||||
@Override
|
||||
protected void drawHighlights() {
|
||||
for (int i = 0; i < mIndicesToHightlight.length; i++) {
|
||||
|
||||
// if there are values to highlight and highlighnting is enabled, do it
|
||||
if (mHighlightEnabled && valuesToHighlight()) {
|
||||
// RectF highlight = new RectF(mIndicesToHightlight[i] -
|
||||
// mHighlightWidth / 2,
|
||||
// mYChartMax, mIndicesToHightlight[i] + mHighlightWidth / 2,
|
||||
// mYChartMin);
|
||||
// transformRect(highlight);
|
||||
// mDrawCanvas.drawRect(highlight, mHighlightPaint);
|
||||
|
||||
for (int i = 0; i < mIndicesToHightlight.length; i++) {
|
||||
int index = mIndicesToHightlight[i];
|
||||
|
||||
// RectF highlight = new RectF(mIndicesToHightlight[i] -
|
||||
// mHighlightWidth / 2,
|
||||
// mYChartMax, mIndicesToHightlight[i] + mHighlightWidth / 2,
|
||||
// mYChartMin);
|
||||
// transformRect(highlight);
|
||||
// mDrawCanvas.drawRect(highlight, mHighlightPaint);
|
||||
// check outofbounds
|
||||
if (index < mData.getYValSize() && index >= 0) {
|
||||
|
||||
int index = mIndicesToHightlight[i];
|
||||
float[] pts = new float[] { index, mYChartMax, index, mYChartMin, 0,
|
||||
mData.getYVals().get(index).getVal(), mDeltaX, mData.getYVals().get(index).getVal() };
|
||||
|
||||
// check outofbounds
|
||||
if (index < mYVals.size() && index >= 0) {
|
||||
transformPointArray(pts);
|
||||
// draw the highlight lines
|
||||
mDrawCanvas.drawLines(pts, mHighlightPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float[] pts = new float[] {
|
||||
index, mYChartMax, index, mYChartMin,
|
||||
0, mYVals.get(index).getVal(), mDeltaX, mYVals.get(index).getVal()
|
||||
};
|
||||
/**
|
||||
* draws the given y values to the screen
|
||||
*/
|
||||
@Override
|
||||
protected void drawData() {
|
||||
|
||||
transformPointArray(pts);
|
||||
// draw the highlight lines
|
||||
mDrawCanvas.drawLines(pts, mHighlightPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ArrayList<ArrayList<Series>> typeSeries = mData.getTypeSeries();
|
||||
|
||||
/**
|
||||
* draws the given y values to the screen
|
||||
*/
|
||||
@Override
|
||||
protected void drawData() {
|
||||
for (int i = 0; i < mData.getTypeCount(); i++) {
|
||||
|
||||
Path p = new Path();
|
||||
p.moveTo(0, mYVals.get(0).getVal());
|
||||
ArrayList<Series> series = typeSeries.get(i);
|
||||
|
||||
for (int x = 1; x < mYVals.size(); x++) {
|
||||
float[] valuePoints = new float[series.size() * 2];
|
||||
|
||||
p.lineTo(x, mYVals.get(x).getVal());
|
||||
}
|
||||
for (int j = 0; j < valuePoints.length; j += 2) {
|
||||
valuePoints[j] = series.get(j / 2).getXIndex();
|
||||
valuePoints[j + 1] = series.get(j / 2).getVal();
|
||||
}
|
||||
|
||||
transformPath(p);
|
||||
transformPointArray(valuePoints);
|
||||
|
||||
mDrawCanvas.drawPath(p, mLinePaint);
|
||||
for (int j = 0; j < valuePoints.length - 2; j += 2) {
|
||||
|
||||
// if data is drawn filled
|
||||
if (mDrawFilled) {
|
||||
if (valuePoints[j] > mContentRect.right)
|
||||
break;
|
||||
|
||||
Path filled = new Path();
|
||||
filled.moveTo(0, mYVals.get(0).getVal());
|
||||
// make sure the lines don't do shitty things outside bounds
|
||||
if (j != 0 && valuePoints[j - 1] < mContentRect.left)
|
||||
continue;
|
||||
|
||||
// create a new path
|
||||
for (int x = 1; x < mYVals.size(); x++) {
|
||||
|
||||
filled.lineTo(x, mYVals.get(x).getVal());
|
||||
}
|
||||
|
||||
// close up
|
||||
filled.lineTo(mXVals.size() - 1, mYChartMin);
|
||||
filled.lineTo(0f, mYChartMin);
|
||||
filled.close();
|
||||
|
||||
transformPath(filled);
|
||||
|
||||
mDrawCanvas.drawPath(filled, mFilledPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawValues() {
|
||||
|
||||
// if values are drawn
|
||||
if (mDrawYValues && mYVals.size() < mMaxVisibleCount * mScaleX) {
|
||||
|
||||
float[] valuePoints = new float[mYVals.size() * 2];
|
||||
|
||||
for (int i = 0; i < valuePoints.length; i += 2) {
|
||||
valuePoints[i] = i / 2;
|
||||
valuePoints[i + 1] = mYVals.get(i / 2).getVal();
|
||||
}
|
||||
|
||||
transformPointArray(valuePoints);
|
||||
|
||||
for (int i = 0; i < valuePoints.length; i += 2) {
|
||||
|
||||
if (mDrawUnitInChart) {
|
||||
|
||||
mDrawCanvas.drawText(
|
||||
mFormatValue.format(mYVals.get(i / 2).getVal()) + mUnit,
|
||||
valuePoints[i], valuePoints[i + 1] - 12, mValuePaint);
|
||||
} else {
|
||||
|
||||
mDrawCanvas.drawText(
|
||||
mFormatValue.format(mYVals.get(i / 2).getVal()),
|
||||
valuePoints[i], valuePoints[i + 1] - 12, mValuePaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* draws the circle value indicators
|
||||
*/
|
||||
@Override
|
||||
protected void drawAdditional() {
|
||||
|
||||
// if drawing circles is enabled
|
||||
if (mDrawCircles) {
|
||||
|
||||
float[] positions = new float[mYVals.size() * 2];
|
||||
|
||||
for (int i = 0; i < positions.length; i += 2) {
|
||||
positions[i] = i / 2;
|
||||
positions[i + 1] = mYVals.get(i / 2).getVal();
|
||||
}
|
||||
|
||||
transformPointArray(positions);
|
||||
|
||||
for (int i = 0; i < positions.length; i += 2) {
|
||||
|
||||
// make sure the circles don't do shitty things outside bounds
|
||||
if (positions[i] < mContentRect.left || positions[i] > mContentRect.right)
|
||||
continue;
|
||||
|
||||
mDrawCanvas.drawCircle(positions[i], positions[i + 1], mCircleSize,
|
||||
mCirclePaintOuter);
|
||||
mDrawCanvas.drawCircle(positions[i], positions[i + 1], mCircleSize / 2,
|
||||
mCirclePaintInner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set this to true to enable the drawing of circle indicators
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void setDrawCircles(boolean enabled) {
|
||||
this.mDrawCircles = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if drawing circles is enabled, false if not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isDrawCirclesEnabled() {
|
||||
return mDrawCircles;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the size (radius) of the circle shpaed value indicators, default
|
||||
* size = 4f
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
public void setCircleSize(float size) {
|
||||
mCircleSize = Utils.convertDpToPixel(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the circlesize
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
public float getCircleSize(float size) {
|
||||
return Utils.convertPixelsToDp(mCircleSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* set if the chartdata should be drawn as a line or filled default = line /
|
||||
* default = false, disabling this will give up to 20% performance boost on
|
||||
* large datasets
|
||||
*
|
||||
* @param filled
|
||||
*/
|
||||
public void setDrawFilled(boolean filled) {
|
||||
mDrawFilled = filled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if filled drawing is enabled, false if not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isDrawFilledEnabled() {
|
||||
return mDrawFilled;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the line width of the chart (min = 0.5f, max = 10f); default 1f NOTE:
|
||||
* thinner line == better performance, thicker line == worse performance
|
||||
*
|
||||
* @param width
|
||||
*/
|
||||
public void setLineWidth(float width) {
|
||||
|
||||
if (width < 0.5f)
|
||||
width = 0.5f;
|
||||
if (width > 10.0f)
|
||||
width = 10.0f;
|
||||
mLineWidth = width;
|
||||
|
||||
mLinePaint.setStrokeWidth(mLineWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the width of the drawn chart line
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getLineWidth() {
|
||||
return mLineWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the color for the line paint
|
||||
*
|
||||
* @param color
|
||||
*/
|
||||
public void setLineColor(int color) {
|
||||
mLinePaint.setColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the color for the outer circle paint
|
||||
*
|
||||
* @param color
|
||||
*/
|
||||
public void setCircleColor(int color) {
|
||||
mCirclePaintOuter.setColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the color for the fill-paint
|
||||
*
|
||||
* @param color
|
||||
*/
|
||||
public void setFillColor(int color) {
|
||||
mFilledPaint.setColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* set the width of the highlightning lines, default 3f
|
||||
*
|
||||
* @param width
|
||||
*/
|
||||
public void setHighlightLineWidth(float width) {
|
||||
mHighlightWidth = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the width of the highlightning line, default 3f
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getHighlightLineWidth() {
|
||||
return mHighlightWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaint(Paint p, int which) {
|
||||
super.setPaint(p, which);
|
||||
|
||||
switch (which) {
|
||||
case PAINT_FILLED:
|
||||
mFilledPaint = p;
|
||||
break;
|
||||
case PAINT_LINE:
|
||||
mLinePaint = p;
|
||||
break;
|
||||
case PAINT_CIRCLES_INNER:
|
||||
mCirclePaintInner = p;
|
||||
break;
|
||||
case PAINT_CIRCLES_OUTER:
|
||||
mCirclePaintOuter = p;
|
||||
break;
|
||||
case PAINT_HIGHLIGHT_LINE:
|
||||
mHighlightPaint = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mDrawCanvas.drawLine(valuePoints[j], valuePoints[j + 1], valuePoints[j + 2], valuePoints[j + 3],
|
||||
mDrawPaints[i % mDrawPaints.length]);
|
||||
}
|
||||
}
|
||||
|
||||
// if data is drawn filled
|
||||
if (mDrawFilled) {
|
||||
|
||||
Path filled = new Path();
|
||||
filled.moveTo(0, mData.getYVals().get(0).getVal());
|
||||
|
||||
// create a new path
|
||||
for (int x = 1; x < mData.getYValSize(); x++) {
|
||||
|
||||
filled.lineTo(x, mData.getYVals().get(x).getVal());
|
||||
}
|
||||
|
||||
// close up
|
||||
filled.lineTo(mData.getXValSize() - 1, mYChartMin);
|
||||
filled.lineTo(0f, mYChartMin);
|
||||
filled.close();
|
||||
|
||||
transformPath(filled);
|
||||
|
||||
mDrawCanvas.drawPath(filled, mFilledPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawValues() {
|
||||
|
||||
// if values are drawn
|
||||
if (mDrawYValues && mData.getYValSize() < mMaxVisibleCount * mScaleX) {
|
||||
|
||||
float[] valuePoints = new float[mData.getYValSize() * 2];
|
||||
|
||||
for (int i = 0; i < valuePoints.length; i += 2) {
|
||||
valuePoints[i] = i / 2;
|
||||
valuePoints[i + 1] = mData.getYVals().get(i / 2).getVal();
|
||||
}
|
||||
|
||||
transformPointArray(valuePoints);
|
||||
|
||||
for (int i = 0; i < valuePoints.length; i += 2) {
|
||||
|
||||
if (mDrawUnitInChart) {
|
||||
|
||||
mDrawCanvas.drawText(mFormatValue.format(mData.getYVals().get(i / 2).getVal()) + mUnit,
|
||||
valuePoints[i], valuePoints[i + 1] - 12, mValuePaint);
|
||||
} else {
|
||||
|
||||
mDrawCanvas.drawText(mFormatValue.format(mData.getYVals().get(i / 2).getVal()), valuePoints[i],
|
||||
valuePoints[i + 1] - 12, mValuePaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* draws the circle value indicators
|
||||
*/
|
||||
@Override
|
||||
protected void drawAdditional() {
|
||||
// if drawing circles is enabled
|
||||
if (mDrawCircles) {
|
||||
|
||||
ArrayList<ArrayList<Series>> typeSeries = mData.getTypeSeries();
|
||||
|
||||
for (int i = 0; i < mData.getTypeCount(); i++) {
|
||||
|
||||
ArrayList<Series> series = typeSeries.get(i);
|
||||
|
||||
float[] positions = new float[mData.getYValSize() * 2];
|
||||
|
||||
for (int j = 0; j < positions.length; j += 2) {
|
||||
positions[j] = series.get(j / 2).getXIndex();
|
||||
positions[j + 1] = series.get(j / 2).getVal();
|
||||
}
|
||||
|
||||
transformPointArray(positions);
|
||||
|
||||
for (int j = 0; j < positions.length; j += 2) {
|
||||
|
||||
// make sure the circles don't do shitty things outside bounds
|
||||
if (positions[j] < mContentRect.left || positions[j] > mContentRect.right)
|
||||
continue;
|
||||
|
||||
mDrawCanvas.drawCircle(positions[j], positions[j + 1], mCircleSize, mCirclePaintOuter);
|
||||
mDrawCanvas.drawCircle(positions[j], positions[j + 1], mCircleSize / 2, mCirclePaintInner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set this to true to enable the drawing of circle indicators
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void setDrawCircles(boolean enabled) {
|
||||
this.mDrawCircles = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if drawing circles is enabled, false if not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isDrawCirclesEnabled() {
|
||||
return mDrawCircles;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the size (radius) of the circle shpaed value indicators, default size = 4f
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
public void setCircleSize(float size) {
|
||||
mCircleSize = Utils.convertDpToPixel(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the circlesize
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
public float getCircleSize(float size) {
|
||||
return Utils.convertPixelsToDp(mCircleSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* set if the chartdata should be drawn as a line or filled default = line / default = false, disabling this will
|
||||
* give up to 20% performance boost on large datasets
|
||||
*
|
||||
* @param filled
|
||||
*/
|
||||
public void setDrawFilled(boolean filled) {
|
||||
mDrawFilled = filled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if filled drawing is enabled, false if not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isDrawFilledEnabled() {
|
||||
return mDrawFilled;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the line width of the chart (min = 0.5f, max = 10f); default 1f NOTE: thinner line == better performance,
|
||||
* thicker line == worse performance
|
||||
*
|
||||
* @param width
|
||||
*/
|
||||
public void setLineWidth(float width) {
|
||||
|
||||
if (width < 0.5f)
|
||||
width = 0.5f;
|
||||
if (width > 10.0f)
|
||||
width = 10.0f;
|
||||
mLineWidth = width;
|
||||
|
||||
for (int i = 0; i < mDrawPaints.length; i++) {
|
||||
mDrawPaints[i].setStrokeWidth(mLineWidth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the width of the drawn chart line
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getLineWidth() {
|
||||
return mLineWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the color for the outer circle paint
|
||||
*
|
||||
* @param color
|
||||
*/
|
||||
public void setCircleColor(int color) {
|
||||
mCirclePaintOuter.setColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the color for the fill-paint
|
||||
*
|
||||
* @param color
|
||||
*/
|
||||
public void setFillColor(int color) {
|
||||
mFilledPaint.setColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* set the width of the highlightning lines, default 3f
|
||||
*
|
||||
* @param width
|
||||
*/
|
||||
public void setHighlightLineWidth(float width) {
|
||||
mHighlightWidth = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the width of the highlightning line, default 3f
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getHighlightLineWidth() {
|
||||
return mHighlightWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaint(Paint p, int which) {
|
||||
super.setPaint(p, which);
|
||||
|
||||
switch (which) {
|
||||
case PAINT_FILLED:
|
||||
mFilledPaint = p;
|
||||
break;
|
||||
case PAINT_CIRCLES_INNER:
|
||||
mCirclePaintInner = p;
|
||||
break;
|
||||
case PAINT_CIRCLES_OUTER:
|
||||
mCirclePaintOuter = p;
|
||||
break;
|
||||
case PAINT_HIGHLIGHT_LINE:
|
||||
mHighlightPaint = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
package com.github.mikephil.charting;
|
||||
|
||||
public class LineSeries extends Series {
|
||||
|
||||
private int mLineIndex = 0;
|
||||
private int mXIndex = 0;
|
||||
|
||||
public LineSeries(float val, int lineIndex, int xIndex) {
|
||||
super(val);
|
||||
mLineIndex = lineIndex;
|
||||
mXIndex = xIndex;
|
||||
}
|
||||
|
||||
public int getLineIndex() {
|
||||
return mLineIndex;
|
||||
}
|
||||
|
||||
public int getXIndex() {
|
||||
return mXIndex;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,9 +0,0 @@
|
|||
package com.github.mikephil.charting;
|
||||
|
||||
public class PieSeries extends Series {
|
||||
|
||||
public PieSeries(float val) {
|
||||
super(val);
|
||||
|
||||
}
|
||||
}
|
13
MPChartLib/src/com/github/mikephil/charting/Point.java
Normal file
13
MPChartLib/src/com/github/mikephil/charting/Point.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package com.github.mikephil.charting;
|
||||
|
||||
public class Point {
|
||||
|
||||
public double x;
|
||||
public double y;
|
||||
|
||||
public Point(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,14 +1,96 @@
|
|||
package com.github.mikephil.charting;
|
||||
|
||||
public abstract class Series {
|
||||
import java.util.ArrayList;
|
||||
|
||||
private float mVal = 0f;
|
||||
|
||||
public Series(float val) {
|
||||
mVal = val;
|
||||
}
|
||||
|
||||
public float getVal() {
|
||||
return mVal;
|
||||
}
|
||||
public class Series {
|
||||
|
||||
private float mVal = 0f;
|
||||
private int mType = 0;
|
||||
private int mXIndex = 0;
|
||||
|
||||
/**
|
||||
* A series represents one single entry in the chart
|
||||
*
|
||||
* @param val
|
||||
* the y value
|
||||
* @param type
|
||||
* the type (e.g. different lines in the line chart are of different types). The type can be seen as an
|
||||
* id and can be chosen freely.
|
||||
* @param xIndex
|
||||
* the corresponding index in the x value array
|
||||
*/
|
||||
public Series(float val, int type, int xIndex) {
|
||||
mVal = val;
|
||||
mType = type;
|
||||
mXIndex = xIndex;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.mType = type;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
public int getXIndex() {
|
||||
return mXIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to create a series of double values
|
||||
*
|
||||
* @param yValues
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<Series> makeSeries(double[] yValues) {
|
||||
ArrayList<Series> series = new ArrayList<Series>();
|
||||
for (int i = 0; i < yValues.length; i++) {
|
||||
series.add(new Series((float) yValues[i], 0, i));
|
||||
}
|
||||
return series;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to create multiple series of different types of various double value arrays. Each double array
|
||||
* represents one type starting at 0.
|
||||
*
|
||||
* @param yValues
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<Series> makeMultipleSeries(ArrayList<Double[]> yValues) {
|
||||
ArrayList<Series> series = new ArrayList<Series>();
|
||||
|
||||
int sizeOfFirst = yValues.get(0).length;
|
||||
|
||||
for (int i = 0; i < yValues.size(); i++) {
|
||||
Double[] curValues = yValues.get(i);
|
||||
if (curValues.length != sizeOfFirst) {
|
||||
throw new IllegalArgumentException("Array sizes do not match");
|
||||
}
|
||||
for (int j = 0; j < curValues.length; j++) {
|
||||
series.add(new Series(curValues[j].floatValue(), i, j));
|
||||
}
|
||||
}
|
||||
|
||||
return series;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to add a series. The new series has to be the same size as the old. If you want to create a
|
||||
* different sized series, please add manually.
|
||||
*
|
||||
* @param series
|
||||
* @param yValues
|
||||
* @param type
|
||||
*/
|
||||
public static void addSeries(ArrayList<Series> series, double[] yValues, int type) {
|
||||
for (int i = 0; i < yValues.length; i++) {
|
||||
series.add(new Series((float) yValues[i], type, i));
|
||||
}
|
||||
}
|
||||
|
||||
public float getVal() {
|
||||
return mVal;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue