Made changes to the data model (especially Entry and DataSet class) to support CandleStickChart.

This commit is contained in:
Philipp Jahoda 2014-08-19 15:00:05 +02:00
parent f8d34e24dc
commit f36ba8de48
24 changed files with 662 additions and 229 deletions

View file

@ -37,6 +37,7 @@
<activity android:name="StackedBarActivity"></activity>
<activity android:name="AnotherBarActivity"></activity>
<activity android:name="InvertedLineChartActivity"></activity>
<activity android:name="CandleStickChartActivity"></activity>
</application>
</manifest>

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.github.mikephil.charting.charts.CandleStickChart
android:id="@+id/chart1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/seekBar1" />
<SeekBar
android:id="@+id/seekBar2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_margin="8dp"
android:layout_toLeftOf="@+id/tvYMax"
android:layout_marginRight="5dp"
android:max="200"
android:paddingBottom="12dp" />
<SeekBar
android:id="@+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/seekBar2"
android:layout_margin="8dp"
android:layout_marginBottom="35dp"
android:layout_toLeftOf="@+id/tvXMax"
android:layout_marginRight="5dp"
android:max="500"
android:paddingBottom="12dp" />
<TextView
android:id="@+id/tvXMax"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/seekBar1"
android:layout_alignParentRight="true"
android:text="500"
android:layout_marginBottom="15dp"
android:layout_marginRight="10dp"
android:gravity="right"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/tvYMax"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/seekBar2"
android:layout_alignParentRight="true"
android:text="500"
android:layout_marginBottom="15dp"
android:layout_marginRight="10dp"
android:gravity="right"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>

View file

@ -13,7 +13,7 @@ import android.widget.Toast;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.filter.Approximator;
import com.github.mikephil.charting.data.filter.Approximator.ApproximatorType;
import com.github.mikephil.charting.utils.ColorTemplate;
@ -209,12 +209,12 @@ public class AnotherBarActivity extends DemoBase implements OnSeekBarChangeListe
tvX.setText("" + (mSeekBarX.getProgress() + 1));
tvY.setText("" + (mSeekBarY.getProgress()));
ArrayList<Entry> yVals1 = new ArrayList<Entry>();
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < mSeekBarX.getProgress()+1; i++) {
float mult = (mSeekBarY.getProgress() + 1);
float val1 = (float) (Math.random() * mult) + mult / 3;
yVals1.add(new Entry((int) val1, i));
yVals1.add(new BarEntry((int) val1, i));
}
ArrayList<String> xVals = new ArrayList<String>();

View file

@ -14,7 +14,7 @@ import android.widget.Toast;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.filter.Approximator;
import com.github.mikephil.charting.data.filter.Approximator.ApproximatorType;
import com.github.mikephil.charting.utils.Legend;
@ -239,12 +239,12 @@ public class BarChartActivity extends DemoBase implements OnSeekBarChangeListene
xVals.add(mMonths[i % 12]);
}
ArrayList<Entry> yVals1 = new ArrayList<Entry>();
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < mSeekBarX.getProgress()+1; i++) {
float mult = (mSeekBarY.getProgress() + 1);
float val = (float) (Math.random() * mult) + 3;
yVals1.add(new Entry(val, i));
yVals1.add(new BarEntry(val, i));
}
BarDataSet set1 = new BarDataSet(yVals1, "DataSet");

View file

@ -12,13 +12,11 @@ import android.widget.TextView;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.utils.ColorTemplate;
import com.github.mikephil.charting.utils.Legend;
import com.github.mikephil.charting.utils.Legend.LegendPosition;
import com.github.mikephil.charting.utils.XLabels;
import com.github.mikephil.charting.utils.YLabels;
import com.github.mikephil.charting.utils.YLabels.YLabelPosition;
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
import java.util.ArrayList;
@ -176,23 +174,23 @@ public class BarChartActivityMultiDataset extends DemoBase implements OnSeekBarC
xVals.add((i) + "");
}
ArrayList<Entry> yVals1 = new ArrayList<Entry>();
ArrayList<Entry> yVals2 = new ArrayList<Entry>();
ArrayList<Entry> yVals3 = new ArrayList<Entry>();
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
ArrayList<BarEntry> yVals2 = new ArrayList<BarEntry>();
ArrayList<BarEntry> yVals3 = new ArrayList<BarEntry>();
for (int i = 0; i < mSeekBarX.getProgress() / 3; i++) {
float val = (float) (Math.random() * mSeekBarY.getProgress()) + 3;
yVals1.add(new Entry(val, i));
yVals1.add(new BarEntry(val, i));
}
for (int i = mSeekBarX.getProgress() / 3; i < mSeekBarX.getProgress() / 3 * 2; i++) {
float val = (float) (Math.random() * mSeekBarY.getProgress()) + 3;
yVals2.add(new Entry(val, i));
yVals2.add(new BarEntry(val, i));
}
for (int i = mSeekBarX.getProgress() / 3 * 2; i < mSeekBarX.getProgress(); i++) {
float val = (float) (Math.random() * mSeekBarY.getProgress()) + 3;
yVals3.add(new Entry(val, i));
yVals3.add(new BarEntry(val, i));
}
// create 3 datasets with different types

View file

@ -0,0 +1,220 @@
package com.xxmassdeveloper.mpchartexample;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import com.github.mikephil.charting.charts.CandleStickChart;
import com.github.mikephil.charting.data.CandleData;
import com.github.mikephil.charting.data.CandleDataSet;
import com.github.mikephil.charting.data.CandleEntry;
import com.github.mikephil.charting.data.filter.Approximator;
import com.github.mikephil.charting.data.filter.Approximator.ApproximatorType;
import com.github.mikephil.charting.utils.ColorTemplate;
import com.github.mikephil.charting.utils.XLabels;
import com.github.mikephil.charting.utils.XLabels.XLabelPosition;
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
import java.util.ArrayList;
public class CandleStickChartActivity extends DemoBase implements OnSeekBarChangeListener {
private CandleStickChart 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_candlechart);
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 = (CandleStickChart) findViewById(R.id.chart1);
mChart.setDrawYValues(false);
mChart.setUnit("");
mChart.setDescription("");
// if more than 60 entries are displayed in the chart, no values will be
// drawn
mChart.setMaxVisibleValueCount(60);
// scaling can now only be done on x- and y-axis separately
mChart.setPinchZoom(false);
mChart.setDrawVerticalGrid(false);
mChart.setDrawHorizontalGrid(false);
mChart.setDrawGridBackground(false);
XLabels xLabels = mChart.getXLabels();
xLabels.setPosition(XLabelPosition.BOTTOM);
xLabels.setCenterXLabelText(true);
xLabels.setSpaceBetweenLabels(0);
mChart.setDrawYLabels(false);
mChart.setDrawLegend(false);
// setting data
mSeekBarX.setProgress(10);
mSeekBarY.setProgress(100);
// Legend l = mChart.getLegend();
// l.setPosition(LegendPosition.BELOW_CHART_CENTER);
// l.setFormSize(8f);
// l.setFormToTextSpace(4f);
// l.setXEntrySpace(6f);
// mChart.setDrawLegend(false);
}
@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.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.actionTogglePinch: {
if (mChart.isPinchZoomEnabled())
mChart.setPinchZoom(false);
else
mChart.setPinchZoom(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: {
XLabels xLabels = mChart.getXLabels();
if (xLabels.isAdjustXLabelsEnabled())
xLabels.setAdjustXLabels(false);
else
xLabels.setAdjustXLabels(true);
mChart.invalidate();
break;
}
case R.id.animateX: {
mChart.animateX(3000);
break;
}
case R.id.animateY: {
mChart.animateY(3000);
break;
}
case R.id.animateXY: {
mChart.animateXY(3000, 3000);
break;
}
case R.id.actionToggleFilter: {
Approximator a = new Approximator(ApproximatorType.DOUGLAS_PEUCKER, 25);
if (!mChart.isFilteringEnabled()) {
mChart.enableFiltering(a);
} else {
mChart.disableFiltering();
}
mChart.invalidate();
break;
}
case R.id.actionSave: {
if (mChart.saveToGallery("title" + System.currentTimeMillis(), 50)) {
Toast.makeText(getApplicationContext(), "Saving SUCCESSFUL!",
Toast.LENGTH_SHORT).show();
} else
Toast.makeText(getApplicationContext(), "Saving FAILED!", Toast.LENGTH_SHORT)
.show();
break;
}
}
return true;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
tvX.setText("" + (mSeekBarX.getProgress() + 1));
tvY.setText("" + (mSeekBarY.getProgress()));
ArrayList<CandleEntry> yVals1 = new ArrayList<CandleEntry>();
for (int i = 0; i < mSeekBarX.getProgress()+1; i++) {
float mult = (mSeekBarY.getProgress() + 1);
float val = (float) (Math.random() * mult) + mult / 3;
yVals1.add(new CandleEntry(val, i, val+5, val-5, val+7, val-7));
}
ArrayList<String> xVals = new ArrayList<String>();
for (int i = 0; i < mSeekBarX.getProgress()+1; i++) {
xVals.add((int) yVals1.get(i).getVal() + " " + mChart.getUnit());
}
CandleDataSet set1 = new CandleDataSet(yVals1, "Data Set");
set1.setColors(ColorTemplate.createColors(getApplicationContext(),
ColorTemplate.VORDIPLOM_COLORS));
CandleData data = new CandleData(xVals, set1);
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
}
}

View file

@ -15,8 +15,7 @@ import android.widget.ListView;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.ChartData;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.utils.ColorTemplate;
import com.github.mikephil.charting.utils.XLabels;
import com.github.mikephil.charting.utils.XLabels.XLabelPosition;
@ -124,10 +123,10 @@ public class ListViewBarChartActivity extends DemoBase {
*/
private BarData generateData(int cnt) {
ArrayList<Entry> entries = new ArrayList<Entry>();
ArrayList<BarEntry> entries = new ArrayList<BarEntry>();
for (int i = 0; i < 12; i++) {
entries.add(new Entry((int) (Math.random() * 70) + 30, i));
entries.add(new BarEntry((int) (Math.random() * 70) + 30, i));
}
BarDataSet d = new BarDataSet(entries, "New DataSet " + cnt);

View file

@ -11,6 +11,7 @@ import android.widget.ListView;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.ChartData;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
@ -132,10 +133,10 @@ public class ListViewMultiChartActivity extends DemoBase {
*/
private ChartData generateDataBar(int cnt) {
ArrayList<Entry> entries = new ArrayList<Entry>();
ArrayList<BarEntry> entries = new ArrayList<BarEntry>();
for (int i = 0; i < 12; i++) {
entries.add(new Entry((int) (Math.random() * 70) + 30, i));
entries.add(new BarEntry((int) (Math.random() * 70) + 30, i));
}
BarDataSet d = new BarDataSet(entries, "New DataSet " + cnt);

View file

@ -14,6 +14,7 @@ import android.widget.Toast;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.filter.Approximator;
import com.github.mikephil.charting.data.filter.Approximator.ApproximatorType;
@ -66,7 +67,10 @@ public class StackedBarActivity extends DemoBase implements OnSeekBarChangeListe
mChart.setMaxVisibleValueCount(60);
// sets the number of digits for values inside the chart
mChart.setValueDigits(2);
mChart.setValueDigits(0);
// if false values are only drawn for the stack sum, else each value is drawn
mChart.setDrawValuesForWholeStack(true);
// disable 3D
mChart.set3DEnabled(false);
@ -220,7 +224,7 @@ public class StackedBarActivity extends DemoBase implements OnSeekBarChangeListe
xVals.add(mMonths[i % mMonths.length]);
}
ArrayList<Entry> yVals1 = new ArrayList<Entry>();
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < mSeekBarX.getProgress()+1; i++) {
float mult = (mSeekBarY.getProgress() + 1);
@ -228,7 +232,7 @@ public class StackedBarActivity extends DemoBase implements OnSeekBarChangeListe
float val2 = (float) (Math.random() * mult) + mult / 3;
float val3 = (float) (Math.random() * mult) + mult / 3;
yVals1.add(new Entry(new float[] {
yVals1.add(new BarEntry(new float[] {
(int) val1, (int) val2, (int) val3
}, i));
}

View file

@ -2,11 +2,11 @@ package com.xxmassdeveloper.mpchartexample.fragments;
import android.support.v4.app.Fragment;
import com.github.mikephil.charting.charts.Chart;
import com.github.mikephil.charting.charts.ScatterChart;
import com.github.mikephil.charting.charts.ScatterChart.ScatterShape;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.ChartData;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
@ -29,12 +29,12 @@ public abstract class SimpleFragment extends Fragment {
for(int i = 0; i < dataSets; i++) {
ArrayList<Entry> entries = new ArrayList<Entry>();
ArrayList<BarEntry> entries = new ArrayList<BarEntry>();
// entries = FileUtils.loadEntriesFromAssets(getActivity().getAssets(), "stacked_bars.txt");
for(int j = 0; j < count; j++) {
entries.add(new Entry((float) (Math.random() * range) + range / 4, j));
entries.add(new BarEntry((float) (Math.random() * range) + range / 4, j));
}
BarDataSet ds = new BarDataSet(entries, getLabel(i));

View file

@ -23,6 +23,7 @@ import com.github.mikephil.charting.utils.Utils;
import com.xxmassdeveloper.mpchartexample.AnotherBarActivity;
import com.xxmassdeveloper.mpchartexample.BarChartActivity;
import com.xxmassdeveloper.mpchartexample.BarChartActivityMultiDataset;
import com.xxmassdeveloper.mpchartexample.CandleStickChartActivity;
import com.xxmassdeveloper.mpchartexample.InvertedLineChartActivity;
import com.xxmassdeveloper.mpchartexample.LineChartActivity;
import com.xxmassdeveloper.mpchartexample.ListViewBarChartActivity;
@ -77,6 +78,9 @@ public class MainActivity extends Activity implements OnItemClickListener {
objects.add(new ContentItem(
"Inverted Line Chart",
"Demonstrates the feature of inverting the y-axis."));
objects.add(new ContentItem(
"Candle Stick Chart",
"Demonstrates usage of the CandleStickChart."));
MyAdapter adapter = new MyAdapter(this, objects);
@ -151,6 +155,10 @@ public class MainActivity extends Activity implements OnItemClickListener {
i = new Intent(this, InvertedLineChartActivity.class);
startActivity(i);
break;
case 13:
i = new Intent(this, CandleStickChartActivity.class);
startActivity(i);
break;
}
overridePendingTransition(R.anim.move_right_in_activity, R.anim.move_left_out_activity);

View file

@ -10,6 +10,7 @@ import android.util.Log;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.utils.Highlight;
import com.github.mikephil.charting.utils.Utils;
@ -166,10 +167,10 @@ public class BarChart extends BarLineChartBase {
protected void calcMinMax(boolean fixedValues) {
super.calcMinMax(fixedValues);
// if (!mStartAtZero && getYMin() >= 0f) {
// mYChartMin = getYMin();
// mDeltaY = Math.abs(mYChartMax - mYChartMin);
// }
// if (!mStartAtZero && getYMin() >= 0f) {
// mYChartMin = getYMin();
// mDeltaY = Math.abs(mYChartMax - mYChartMin);
// }
// increase deltax by 1 because the bars have a width of 1
mDeltaX++;
@ -193,29 +194,29 @@ public class BarChart extends BarLineChartBase {
if (index < mCurrentData.getYValCount() && index >= 0 && index < mDeltaX * mPhaseX) {
mHighlightPaint.setAlpha(120);
Entry e = getEntryByDataSetIndex(index, dataSetIndex);
prepareBar(e.getXIndex(), e.getSum(), ds.getBarSpace());
Entry e = getEntryByDataSetIndex(index, dataSetIndex);
prepareBar(e.getXIndex(), e.getVal(), ds.getBarSpace());
mDrawCanvas.drawRect(mBarRect, mHighlightPaint);
// if (mDrawHighlightArrow) {
//
//
// // distance between highlight arrow and bar
// float offsetY = mDeltaY * 0.04f;
//
// 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);
// }
// if (mDrawHighlightArrow) {
//
//
// // distance between highlight arrow and bar
// float offsetY = mDeltaY * 0.04f;
//
// 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);
// }
}
}
}
@ -230,15 +231,17 @@ public class BarChart extends BarLineChartBase {
for (int i = 0; i < mCurrentData.getDataSetCount(); i++) {
BarDataSet dataSet = dataSets.get(i);
ArrayList<Entry> entries = dataSet.getYVals();
boolean noStacks = dataSet.getStackSize() == 1 ? true : false;
ArrayList<BarEntry> entries = (ArrayList<BarEntry>) dataSet.getYVals();
// do the drawing
for (int j = 0; j < dataSet.getEntryCount() * mPhaseX; j++) {
Entry e = entries.get(j);
BarEntry e = entries.get(j);
// no stacks
if (dataSet.getStackSize() == 1) {
if (noStacks) {
prepareBar(e.getXIndex(), e.getVal(), dataSet.getBarSpace());
@ -284,12 +287,12 @@ public class BarChart extends BarLineChartBase {
} else {
float all = e.getSum();
float all = e.getVal();
// if drawing the bar shadow is enabled
if (mDrawBarShadow) {
prepareBar(e.getXIndex(), e.getSum(), dataSet.getBarSpace());
prepareBar(e.getXIndex(), e.getVal(), dataSet.getBarSpace());
mRenderPaint.setColor(dataSet.getBarShadowColor());
mDrawCanvas.drawRect(mBarShadow, mRenderPaint);
}
@ -501,7 +504,7 @@ public class BarChart extends BarLineChartBase {
for (int i = 0; i < mCurrentData.getDataSetCount(); i++) {
BarDataSet dataSet = dataSets.get(i);
ArrayList<Entry> entries = dataSet.getYVals();
ArrayList<BarEntry> entries = (ArrayList<BarEntry>) dataSet.getYVals();
float[] valuePoints = generateTransformedValues(entries, 0.5f);
@ -517,7 +520,7 @@ public class BarChart extends BarLineChartBase {
|| isOffContentBottom(valuePoints[j + 1]))
continue;
float val = entries.get(j / 2).getSum();
float val = entries.get(j / 2).getVal();
drawValue(mFormatValue.format(val), valuePoints[j],
valuePoints[j + 1] + offset);
@ -535,7 +538,7 @@ public class BarChart extends BarLineChartBase {
|| isOffContentBottom(valuePoints[j + 1]))
continue;
Entry e = entries.get(j / 2);
BarEntry e = entries.get(j / 2);
float[] vals = e.getVals();
@ -551,7 +554,7 @@ public class BarChart extends BarLineChartBase {
float[] transformed = new float[vals.length * 2];
int cnt = 0;
float add = e.getSum();
float add = e.getVal();
for (int k = 0; k < transformed.length; k += 2) {
@ -685,7 +688,8 @@ public class BarChart extends BarLineChartBase {
@Override
public Paint getPaint(int which) {
Paint p = super.getPaint(which);
if(p != null) return p;
if (p != null)
return p;
switch (which) {
case PAINT_HIGHLIGHT_BAR:

View file

@ -4,6 +4,8 @@ package com.github.mikephil.charting.charts;
import android.content.Context;
import android.util.AttributeSet;
import com.github.mikephil.charting.data.CandleData;
/**
* Chart that draws candle-sticks.
*
@ -23,12 +25,21 @@ public class CandleStickChart extends BarLineChartBase {
super(context, attrs, defStyle);
}
/**
* Sets a CandleData object for the CandleStickChart.
*
* @param data
*/
public void setData(CandleData data) {
super.setData(data);
}
@Override
protected void drawData() {
// TODO Auto-generated method stub
}
@Override
protected void drawValues() {
// TODO Auto-generated method stub

View file

@ -570,13 +570,13 @@ public abstract class Chart extends View implements AnimatorUpdateListener {
* to center for barchart
* @return
*/
protected float[] generateTransformedValues(ArrayList<Entry> entries, float xOffset) {
protected float[] generateTransformedValues(ArrayList<? extends Entry> entries, float xOffset) {
float[] valuePoints = new float[entries.size() * 2];
for (int j = 0; j < valuePoints.length; j += 2) {
valuePoints[j] = entries.get(j / 2).getXIndex() + xOffset;
valuePoints[j + 1] = entries.get(j / 2).getSum() * mPhaseY;
valuePoints[j + 1] = entries.get(j / 2).getVal() * mPhaseY;
}
transformPointArray(valuePoints);
@ -1157,23 +1157,23 @@ public abstract class Chart extends View implements AnimatorUpdateListener {
*/
/** BELOW THIS FOR DYNAMICALLY ADDING ENTRIES AND DATASETS */
public void addEntry(Entry e, int dataSetIndex) {
mOriginalData.getDataSetByIndex(dataSetIndex).addEntry(e);
prepare();
calcMinMax(false);
prepareMatrix();
calculateOffsets();
}
public void addEntry(Entry e, String label) {
mOriginalData.getDataSetByLabel(label, false).addEntry(e);
prepare();
calcMinMax(false);
prepareMatrix();
calculateOffsets();
}
// public void addEntry(Entry e, int dataSetIndex) {
// mOriginalData.getDataSetByIndex(dataSetIndex).addEntry(e);
//
// prepare();
// calcMinMax(false);
// prepareMatrix();
// calculateOffsets();
// }
//
// public void addEntry(Entry e, String label) {
// mOriginalData.getDataSetByLabel(label, false).addEntry(e);
//
// prepare();
// calcMinMax(false);
// prepareMatrix();
// calculateOffsets();
// }
public void addDataSet(DataSet d) {
mOriginalData.addDataSet(d);

View file

@ -117,7 +117,7 @@ public class LineChart extends BarLineChartBase {
for (int i = 0; i < mCurrentData.getDataSetCount(); i++) {
LineDataSet dataSet = dataSets.get(i);
ArrayList<Entry> entries = dataSet.getYVals();
ArrayList<? extends Entry> entries = dataSet.getYVals();
float[] valuePoints = generateTransformedValues(entries, 0f);
@ -206,7 +206,7 @@ public class LineChart extends BarLineChartBase {
* @param entries
* @return
*/
private Path generateFilledPath(ArrayList<Entry> entries) {
private Path generateFilledPath(ArrayList<? extends Entry> entries) {
Path filled = new Path();
filled.moveTo(entries.get(0).getXIndex(), entries.get(0).getVal() * mPhaseY);
@ -260,7 +260,7 @@ public class LineChart extends BarLineChartBase {
if (!dataSet.isDrawCirclesEnabled())
valOffset = valOffset / 2;
ArrayList<Entry> entries = dataSet.getYVals();
ArrayList<? extends Entry> entries = dataSet.getYVals();
float[] positions = generateTransformedValues(entries, 0f);
@ -308,7 +308,7 @@ public class LineChart extends BarLineChartBase {
// if drawing circles is enabled for this dataset
if (dataSet.isDrawCirclesEnabled()) {
ArrayList<Entry> entries = dataSet.getYVals();
ArrayList<? extends Entry> entries = dataSet.getYVals();
float[] positions = generateTransformedValues(entries, 0f);

View file

@ -358,7 +358,7 @@ public class PieChart extends Chart {
for (int i = 0; i < mCurrentData.getDataSetCount(); i++) {
DataSet set = dataSets.get(i);
ArrayList<Entry> entries = set.getYVals();
ArrayList<? extends Entry> entries = set.getYVals();
for (int j = 0; j < entries.size(); j++) {
@ -436,7 +436,7 @@ public class PieChart extends Chart {
for (int i = 0; i < mCurrentData.getDataSetCount(); i++) {
PieDataSet dataSet = dataSets.get(i);
ArrayList<Entry> entries = dataSet.getYVals();
ArrayList<? extends Entry> entries = dataSet.getYVals();
for (int j = 0; j < entries.size(); j++) {
@ -548,7 +548,7 @@ public class PieChart extends Chart {
for (int i = 0; i < mCurrentData.getDataSetCount(); i++) {
DataSet dataSet = dataSets.get(i);
ArrayList<Entry> entries = dataSet.getYVals();
ArrayList<? extends Entry> entries = dataSet.getYVals();
for (int j = 0; j < entries.size() * mPhaseX; j++) {

View file

@ -54,7 +54,7 @@ public class ScatterChart extends BarLineChartBase {
for (int i = 0; i < mCurrentData.getDataSetCount(); i++) {
ScatterDataSet dataSet = dataSets.get(i);
ArrayList<Entry> entries = dataSet.getYVals();
ArrayList<? extends Entry> entries = dataSet.getYVals();
float shapeHalf = dataSet.getScatterShapeSize() / 2f;
@ -131,7 +131,7 @@ public class ScatterChart extends BarLineChartBase {
for (int i = 0; i < mCurrentData.getDataSetCount(); i++) {
ScatterDataSet dataSet = dataSets.get(i);
ArrayList<Entry> entries = dataSet.getYVals();
ArrayList<? extends Entry> entries = dataSet.getYVals();
float[] positions = generateTransformedValues(entries, 0f);

View file

@ -30,20 +30,20 @@ public class BarDataSet extends DataSet {
private String[] mStackLabels = new String[] { "Stack" };
public BarDataSet(ArrayList<Entry> yVals, String label) {
public BarDataSet(ArrayList<BarEntry> yVals, String label) {
super(yVals, label);
calcStackSize();
calcEntryCountIncludingStacks();
calcStackSize(yVals);
calcEntryCountIncludingStacks(yVals);
}
@Override
public DataSet copy() {
ArrayList<Entry> yVals = new ArrayList<Entry>();
ArrayList<BarEntry> yVals = new ArrayList<BarEntry>();
for (int i = 0; i < mYVals.size(); i++) {
yVals.add(mYVals.get(i).copy());
yVals.add(((BarEntry) mYVals.get(i)).copy());
}
BarDataSet copied = new BarDataSet(yVals, getLabel());
@ -60,13 +60,13 @@ public class BarDataSet extends DataSet {
* Calculates the total number of entries this DataSet represents, including
* stacks. All values belonging to a stack are calculated separately.
*/
private void calcEntryCountIncludingStacks() {
private void calcEntryCountIncludingStacks(ArrayList<BarEntry> yVals) {
mEntryCountStacks = 0;
for (int i = 0; i < mYVals.size(); i++) {
for (int i = 0; i < yVals.size(); i++) {
float[] vals = mYVals.get(i).getVals();
float[] vals = yVals.get(i).getVals();
if (vals == null)
mEntryCountStacks++;
@ -79,11 +79,11 @@ public class BarDataSet extends DataSet {
* calculates the maximum stacksize that occurs in the Entries array of this
* DataSet
*/
private void calcStackSize() {
private void calcStackSize(ArrayList<BarEntry> yVals) {
for (int i = 0; i < mYVals.size(); i++) {
for (int i = 0; i < yVals.size(); i++) {
float[] vals = mYVals.get(i).getVals();
float[] vals = yVals.get(i).getVals();
if (vals != null && vals.length > mStackSize)
mStackSize = vals.length;

View file

@ -0,0 +1,109 @@
package com.github.mikephil.charting.data;
/**
* Entry class for the BarChart. (especially stacked bars)
*
* @author Philipp Jahoda
*/
public class BarEntry extends Entry {
/** the values the stacked barchart holds */
private float[] mVals;
/**
* Constructor for stacked bar entries.
*
* @param vals
* @param xIndex
*/
public BarEntry(float[] vals, int xIndex) {
super(calcSum(vals), xIndex);
this.mVals = vals;
}
/**
* Constructor for normal bars (not stacked).
*
* @param val
* @param xIndex
*/
public BarEntry(float val, int xIndex) {
super(val, xIndex);
}
/**
* Returns an exact copy of the BarEntry.
*/
public BarEntry copy() {
BarEntry copied = new BarEntry(getVal(), getXIndex());
copied.mVals = mVals;
return copied;
}
/**
* Returns the stacked values this BarEntry represents, or null, if only a
* single value is represented (then, use getVal()).
*
* @return
*/
public float[] getVals() {
return mVals;
}
/**
* Set the array of values this BarEntry should represent.
*
* @param vals
*/
public void setVals(float[] vals) {
mVals = vals;
}
/**
* Returns the closest value inside the values array (for stacked barchart)
* to the value given as a parameter. The closest value must be higher
* (above) the provided value.
*
* @param val
* @return
*/
public int getClosestIndexAbove(float val) {
if (mVals == null)
return 0;
float dist = 0f;
int closestIndex = 0;
for (int i = 0; i < mVals.length; i++) {
float newDist = Math.abs((getVal() - mVals[i]) - val);
if (newDist < dist && mVals[i] > val) {
dist = newDist;
closestIndex = i;
}
}
return closestIndex;
}
/**
* Calculates the sum across all values.
*
* @param vals
* @return
*/
public static float calcSum(float[] vals) {
float sum = 0f;
for (float f : vals)
sum += f;
return sum;
}
}

View file

@ -4,17 +4,17 @@ import java.util.ArrayList;
public class CandleDataSet extends DataSet {
public CandleDataSet(ArrayList<Entry> yVals, String label) {
public CandleDataSet(ArrayList<CandleEntry> yVals, String label) {
super(yVals, label);
}
@Override
public DataSet copy() {
ArrayList<Entry> yVals = new ArrayList<Entry>();
ArrayList<CandleEntry> yVals = new ArrayList<CandleEntry>();
for (int i = 0; i < mYVals.size(); i++) {
yVals.add(mYVals.get(i).copy());
yVals.add(((CandleEntry) mYVals.get(i)).copy());
}
CandleDataSet copied = new CandleDataSet(yVals, getLabel());

View file

@ -0,0 +1,67 @@
package com.github.mikephil.charting.data;
/**
* Subclass of Entry that holds all values for one entry in a CandleStickChart.
*
* @author Philipp Jahoda
*/
public class CandleEntry extends Entry {
private float mShadowHigh = 0f;
private float mShadowLow = 0f;
private float mClose = 0f;
private float mOpen = 0f;
public CandleEntry(float val, int xIndex, float shadowH, float shadowL, float open, float close) {
super(val, xIndex);
this.mShadowHigh = shadowH;
this.mShadowLow = shadowL;
this.mOpen = open;
this.mClose = close;
}
public CandleEntry copy() {
CandleEntry c = new CandleEntry(getVal(), getXIndex(), mShadowHigh, mShadowLow, mOpen,
mClose);
return c;
}
public float getShadowHigh() {
return mShadowHigh;
}
public void setShadowHigh(float mShadowHigh) {
this.mShadowHigh = mShadowHigh;
}
public float getShadowLow() {
return mShadowLow;
}
public void setShadowLow(float mShadowLow) {
this.mShadowLow = mShadowLow;
}
public float getClose() {
return mClose;
}
public void setClose(float mClose) {
this.mClose = mClose;
}
public float getOpen() {
return mOpen;
}
public void setOpen(float mOpen) {
this.mOpen = mOpen;
}
}

View file

@ -22,7 +22,7 @@ public abstract class DataSet {
protected ArrayList<Integer> mColors = null;
/** the entries that this dataset represents / holds together */
protected ArrayList<Entry> mYVals = null;
protected ArrayList<? extends Entry> mYVals = null;
/** maximum y-value in the y-value array */
protected float mYMax = 0.0f;
@ -44,7 +44,7 @@ public abstract class DataSet {
* @param yVals
* @param label
*/
public DataSet(ArrayList<Entry> yVals, String label) {
public DataSet(ArrayList<? extends Entry> yVals, String label) {
this.mLabel = label;
this.mYVals = yVals;
@ -80,18 +80,18 @@ public abstract class DataSet {
return;
}
mYMin = mYVals.get(0).getSum();
mYMax = mYVals.get(0).getSum();
mYMin = mYVals.get(0).getVal();
mYMax = mYVals.get(0).getVal();
for (int i = 0; i < mYVals.size(); i++) {
Entry e = mYVals.get(i);
if (e.getSum() < mYMin)
mYMin = e.getSum();
if (e.getVal() < mYMin)
mYMin = e.getVal();
if (e.getSum() > mYMax)
mYMax = e.getSum();
if (e.getVal() > mYMax)
mYMax = e.getVal();
}
}
@ -103,7 +103,7 @@ public abstract class DataSet {
mYValueSum = 0;
for (int i = 0; i < mYVals.size(); i++) {
mYValueSum += Math.abs(mYVals.get(i).getSum());
mYValueSum += Math.abs(mYVals.get(i).getVal());
}
}
@ -130,7 +130,7 @@ public abstract class DataSet {
Entry e = getEntryForXIndex(xIndex);
if (e != null)
return e.getSum();
return e.getVal();
else
return Float.NaN;
}
@ -178,7 +178,7 @@ public abstract class DataSet {
*
* @return
*/
public ArrayList<Entry> getYVals() {
public ArrayList<? extends Entry> getYVals() {
return mYVals;
}
@ -275,30 +275,30 @@ public abstract class DataSet {
return mLabel;
}
/**
* Adds an Entry dynamically.
*
* @param d
*/
public void addEntry(Entry e) {
float sum = e.getSum();
if(mYVals == null || mYVals.size() <= 0) {
mYVals = new ArrayList<Entry>();
mYMax = sum;
mYMin = sum;
} else {
if(mYMax < sum) mYMax = sum;
if(mYMin > sum) mYMin = sum;
}
mYVals.add(e);
mYValueSum += sum;
}
// /**
// * Adds an Entry dynamically.
// *
// * @param d
// */
// public void addEntry(Entry e) {
//
// float sum = e.getSum();
//
// if(mYVals == null || mYVals.size() <= 0) {
//
// mYVals = new ArrayList<Entry>();
// mYMax = sum;
// mYMin = sum;
// } else {
//
// if(mYMax < sum) mYMax = sum;
// if(mYMin > sum) mYMin = sum;
// }
//
// mYVals.add(e);
//
// mYValueSum += sum;
// }
/** BELOW THIS COLOR HANDLING */

View file

@ -15,9 +15,6 @@ public class Entry {
/** the index on the x-axis */
private int mXIndex = 0;
/** array of values, needed for stacked-barchart only */
private float[] mVals;
/**
* A Entry represents one single entry in the chart.
*
@ -31,19 +28,20 @@ public class Entry {
mXIndex = xIndex;
}
/**
* A Entry represents one single entry in the chart.
*
* @param vals the y values (the actual value of the entry) this entry
* should represent. E.g. multiple values for a stacked BarChart.
* @param xIndex the corresponding index in the x value array (index on the
* x-axis of the chart, must NOT be higher than the length of the
* x-values String array)
*/
public Entry(float[] vals, int xIndex) {
mVals = vals;
mXIndex = xIndex;
}
// /**
// * A Entry represents one single entry in the chart.
// *
// * @param vals the y values (the actual value of the entry) this entry
// * should represent. E.g. multiple values for a stacked BarChart.
// * @param xIndex the corresponding index in the x value array (index on
// the
// * x-axis of the chart, must NOT be higher than the length of the
// * x-values String array)
// */
// public Entry(float[] vals, int xIndex) {
// mVals = vals;
// mXIndex = xIndex;
// }
/**
* returns the x-index the value of this object is mapped to
@ -64,7 +62,7 @@ public class Entry {
}
/**
* returns the value the entry represents
* Returns the total value the entry represents.
*
* @return
*/
@ -73,7 +71,7 @@ public class Entry {
}
/**
* sets the value for the entry
* Sets the value for the entry.
*
* @param val
*/
@ -81,44 +79,26 @@ public class Entry {
this.mVal = val;
}
/**
* Returns the values this Entry reprsents, might return null if only a
* single value is represented. Then, user getVal() instead.
*
* @return
*/
public float[] getVals() {
return mVals;
}
/**
* Set the array of values this Entry should represent.
*
* @param vals
*/
public void setVals(float[] vals) {
mVals = vals;
}
/**
* If this Enry represents mulitple values (e.g. Stacked BarChart), it will
* return the sum of them, otherwise just the one value it represents.
*
* @return
*/
public float getSum() {
if (mVals == null)
return mVal;
else {
float sum = 0f;
for (int i = 0; i < mVals.length; i++)
sum += mVals[i];
return sum;
}
}
// /**
// * If this Enry represents mulitple values (e.g. Stacked BarChart), it
// will
// * return the sum of them, otherwise just the one value it represents.
// *
// * @return
// */
// public float getSum() {
// if (mVals == null)
// return mVal;
// else {
//
// float sum = 0f;
//
// for (int i = 0; i < mVals.length; i++)
// sum += mVals[i];
//
// return sum;
// }
// }
/**
* returns an exact copy of the entry
@ -127,7 +107,6 @@ public class Entry {
*/
public Entry copy() {
Entry e = new Entry(mVal, mXIndex);
e.setVals(mVals);
return e;
}
@ -136,35 +115,6 @@ public class Entry {
*/
@Override
public String toString() {
return "Entry, xIndex: " + mXIndex + " val (sum): " + getSum();
}
/**
* Returns the closest value inside the values array (for stacked barchart)
* to the value given as a parameter. The closest value must be higher
* (above) the provided value.
*
* @param val
* @return
*/
public int getClosestIndexAbove(float val) {
if (mVals == null)
return 0;
float dist = 0f;
int closestIndex = 0;
for (int i = 0; i < mVals.length; i++) {
float newDist = Math.abs((getSum() - mVals[i]) - val);
if (newDist < dist && mVals[i] > val) {
dist = newDist;
closestIndex = i;
}
}
return closestIndex;
return "Entry, xIndex: " + mXIndex + " val (sum): " + getVal();
}
}

View file

@ -5,6 +5,7 @@ import android.content.res.AssetManager;
import android.os.Environment;
import android.util.Log;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import java.io.BufferedReader;
@ -59,7 +60,7 @@ public class FileUtils {
vals[i] = Float.parseFloat(split[i]);
}
entries.add(new Entry(vals, Integer.parseInt(split[split.length - 1])));
entries.add(new BarEntry(vals, Integer.parseInt(split[split.length - 1])));
}
}
} catch (IOException e) {
@ -129,7 +130,7 @@ public class FileUtils {
vals[i] = Float.parseFloat(split[i]);
}
entries.add(new Entry(vals, Integer.parseInt(split[split.length - 1])));
entries.add(new BarEntry(vals, Integer.parseInt(split[split.length - 1])));
}
line = reader.readLine();
}