Compare commits
66 commits
v3.1.0-alp
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
a6c3808fd5 | ||
|
941579e10f | ||
|
21c811ff9a | ||
|
f3a2ec21c9 | ||
|
9347dd1af7 | ||
|
90e523042c | ||
|
33240f9225 | ||
|
4b67673da9 | ||
|
cef967fd71 | ||
|
eae977306e | ||
|
c0e7f56b5d | ||
|
351e341ee7 | ||
|
f05337768d | ||
|
f8d068d377 | ||
|
5e4a32eb41 | ||
|
1de836ac65 | ||
|
0668d30a6b | ||
|
34fefd28e1 | ||
|
45240c3723 | ||
|
14456f475f | ||
|
e02e9be2fa | ||
|
fcc5af71ce | ||
|
13aee592b1 | ||
|
c97c8d247f | ||
|
ae59e7a19e | ||
|
7752efef7e | ||
|
58545bbbfa | ||
|
4ce14e6cc9 | ||
|
8df9eda7af | ||
|
34c3ceaa05 | ||
|
ea816e8d6d | ||
|
bafb0fbbe4 | ||
|
4549ae17b7 | ||
|
912427e543 | ||
|
3f5475077e | ||
|
2e725e49d3 | ||
|
a4ca1f3fba | ||
|
634a690d6a | ||
|
1987d7eb64 | ||
|
6ebf3fa57a | ||
|
95027fa6a7 | ||
|
d86f39cc91 | ||
|
cb26ed4ef4 | ||
|
dc59171524 | ||
|
726616d079 | ||
|
fffe9a297e | ||
|
2340e12800 | ||
|
c5667d4f14 | ||
|
0563fb48b0 | ||
|
ed8876cef2 | ||
|
12b4351d0c | ||
|
adb56e75bd | ||
|
e95c1eb26a | ||
|
0c2ac2d9cc | ||
|
2058f7bf5d | ||
|
971640b29d | ||
|
7df8a4cedc | ||
|
59028d3bf3 | ||
|
c886bb342a | ||
|
aea2ff3417 | ||
|
42cdba535f | ||
|
29f4cc5c2c | ||
|
fc0e234298 | ||
|
e5b66192e7 | ||
|
608d9e29f5 | ||
|
9148f37f9e |
101 changed files with 2473 additions and 1403 deletions
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: mpandroidchart
|
||||
open_collective: philippjahoda
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
4
.github/ISSUE_TEMPLATE.md
vendored
4
.github/ISSUE_TEMPLATE.md
vendored
|
@ -28,10 +28,10 @@ cannot answer support questions here. We will close your issue without a respons
|
|||
**Device (please complete the following information):**
|
||||
- Device: [e.g. Google Pixel]
|
||||
- Android Version [e.g. 7.0]
|
||||
- Library Version (e.g. 3.0.3)
|
||||
- Library Version (e.g. 3.1.0-alpha)
|
||||
|
||||
**Additional Context**
|
||||
<!-- Add any other context about the problem here.
|
||||
If you have source code demonstrating this bug, create a Gist:
|
||||
If you have source code demonstrating this bug, create a Gist:
|
||||
https://help.github.com/articles/creating-gists/
|
||||
and link to it here. -->
|
||||
|
|
6
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
6
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
|
@ -33,10 +33,12 @@ support questions here. We will close your issue without a response.
|
|||
**Device (please complete the following information):**
|
||||
- Device: [e.g. Google Pixel]
|
||||
- Android Version [e.g. 7.0]
|
||||
- Library Version (e.g. 3.0.3)
|
||||
- Library Version (e.g. 3.1.0-alpha)
|
||||
|
||||
**Additional Context**
|
||||
<!-- Add any other context about the problem here.
|
||||
If you have source code demonstrating this bug, create a Gist:
|
||||
If you have source code demonstrating this bug, create a Gist:
|
||||
https://help.github.com/articles/creating-gists/
|
||||
and link to it here. -->
|
||||
|
||||
ADD A REWARD using [Speed](speedoss.com) to SOLVE this issue QUICKLY and SUPPORT this project.
|
||||
|
|
1
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
1
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
|
@ -31,3 +31,4 @@ support questions here. We will close your issue without a response.
|
|||
|
||||
**Additional context**
|
||||
<!-- Add any other context or screenshots about the feature request here. -->
|
||||
ADD A REWARD using [Speed](speedoss.com) to SOLVE this issue QUICKLY and SUPPORT this project.
|
||||
|
|
5
.github/ISSUE_TEMPLATE/Support_help.md
vendored
5
.github/ISSUE_TEMPLATE/Support_help.md
vendored
|
@ -14,7 +14,7 @@ Instead, do the following:
|
|||
|
||||
1. Download the [Example App](https://play.google.com/store/apps/details?id=com.xxmassdeveloper.mpchartexample) and check out the [source code](https://github.com/PhilJay/MPAndroidChart/tree/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample). 90% of the time there is an example that does exactly what you are trying to do.
|
||||
|
||||
1. Look at the [Wiki](https://github.com/PhilJay/MPAndroidChart/wiki) for the official documentation for MPAndroidChart. You can also browse the [javadoc](https://jitpack.io/com/github/PhilJay/MPAndroidChart/v3.0.3/javadoc/) for a more detailed tutorial of the API.
|
||||
1. Look at the [Wiki](https://github.com/PhilJay/MPAndroidChart/wiki) for the official documentation for MPAndroidChart. You can also browse the [javadoc](https://jitpack.io/com/github/philjay/mpandroidchart/v3.1.0-alpha/javadoc/) for a more detailed tutorial of the API.
|
||||
|
||||
1. Go to [StackOverflow](https://stackoverflow.com/questions/tagged/mpandroidchart) and ask your questions there. The community will be much more helpful and willing to offer guidance.
|
||||
|
||||
|
@ -22,3 +22,6 @@ Instead, do the following:
|
|||
### You have been warned!
|
||||
|
||||
From now on, any issues asking for help will get closed with a link to this file.
|
||||
|
||||
### Additional Context
|
||||
ADD A REWARD using [Speed](speedoss.com) to SOLVE this issue QUICKLY and SUPPORT this project.
|
||||
|
|
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -12,8 +12,8 @@
|
|||
bin/
|
||||
gen/
|
||||
generated/
|
||||
docs/
|
||||
finalOutput/
|
||||
projectFilesBackup/
|
||||
|
||||
build.xml
|
||||
|
||||
|
@ -23,6 +23,8 @@ local.properties
|
|||
# Eclipse project files
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
.vscode/
|
||||
|
||||
# Proguard folder generated by Eclipse
|
||||
proguard/
|
||||
|
@ -31,7 +33,8 @@ proguard/
|
|||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
/.idea/*
|
||||
!/.idea/runConfigurations
|
||||
|
||||
.directory
|
||||
|
||||
|
|
52
.idea/runConfigurations/MPChartExample.xml
generated
Normal file
52
.idea/runConfigurations/MPChartExample.xml
generated
Normal file
|
@ -0,0 +1,52 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="MPChartExample" type="AndroidRunConfigurationType" factoryName="Android App" activateToolWindowBeforeRun="false">
|
||||
<module name="MPChartExample" />
|
||||
<option name="DEPLOY" value="true" />
|
||||
<option name="DEPLOY_APK_FROM_BUNDLE" value="false" />
|
||||
<option name="ARTIFACT_NAME" value="" />
|
||||
<option name="PM_INSTALL_OPTIONS" value="" />
|
||||
<option name="DYNAMIC_FEATURES_DISABLED_LIST" value="" />
|
||||
<option name="ACTIVITY_EXTRA_FLAGS" value="" />
|
||||
<option name="MODE" value="default_activity" />
|
||||
<option name="CLEAR_LOGCAT" value="false" />
|
||||
<option name="SHOW_LOGCAT_AUTOMATICALLY" value="false" />
|
||||
<option name="SKIP_NOOP_APK_INSTALLATIONS" value="true" />
|
||||
<option name="FORCE_STOP_RUNNING_APP" value="true" />
|
||||
<option name="TARGET_SELECTION_MODE" value="SHOW_DIALOG" />
|
||||
<option name="USE_LAST_SELECTED_DEVICE" value="false" />
|
||||
<option name="PREFERRED_AVD" value="" />
|
||||
<option name="SELECTED_CLOUD_MATRIX_CONFIGURATION_ID" value="-1" />
|
||||
<option name="SELECTED_CLOUD_MATRIX_PROJECT_ID" value="" />
|
||||
<option name="DEBUGGER_TYPE" value="Auto" />
|
||||
<Auto>
|
||||
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
|
||||
<option name="SHOW_STATIC_VARS" value="true" />
|
||||
<option name="WORKING_DIR" value="" />
|
||||
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
|
||||
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
|
||||
</Auto>
|
||||
<Hybrid>
|
||||
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
|
||||
<option name="SHOW_STATIC_VARS" value="true" />
|
||||
<option name="WORKING_DIR" value="" />
|
||||
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
|
||||
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
|
||||
</Hybrid>
|
||||
<Java />
|
||||
<Native>
|
||||
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
|
||||
<option name="SHOW_STATIC_VARS" value="true" />
|
||||
<option name="WORKING_DIR" value="" />
|
||||
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
|
||||
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
|
||||
</Native>
|
||||
<Profilers>
|
||||
<option name="ADVANCED_PROFILING_ENABLED" value="false" />
|
||||
<option name="STARTUP_CPU_PROFILING_ENABLED" value="false" />
|
||||
<option name="STARTUP_CPU_PROFILING_CONFIGURATION_NAME" value="Sampled (Java)" />
|
||||
</Profilers>
|
||||
<option name="DEEP_LINK" value="" />
|
||||
<option name="ACTIVITY_CLASS" value="" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
|
@ -6,8 +6,8 @@ android {
|
|||
applicationId "com.xxmassdeveloper.mpchartexample"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 28
|
||||
versionCode 56
|
||||
versionName '3.0.3'
|
||||
versionCode 57
|
||||
versionName '3.1.0'
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation "androidx.appcompat:appcompat:1.0.0"
|
||||
implementation "androidx.appcompat:appcompat:1.0.2"
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
implementation project(':MPChartLib')
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<activity android:name="LineChartTime" />
|
||||
<activity android:name="BarChartActivity" />
|
||||
<activity android:name="HorizontalBarChartActivity" />
|
||||
<activity android:name="HorizontalBarNegativeChartActivity" />
|
||||
<activity android:name="PieChartActivity" />
|
||||
<activity android:name="PiePolylineChartActivity" />
|
||||
<activity android:name="MultiLineChartActivity" />
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
|
@ -28,15 +27,15 @@ 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.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.model.GradientColor;
|
||||
import com.github.mikephil.charting.utils.Fill;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.DayAxisValueFormatter;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.MyAxisValueFormatter;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.MyValueFormatter;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.XYMarkerView;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
|
@ -86,7 +85,7 @@ public class BarChartActivity extends DemoBase implements OnSeekBarChangeListene
|
|||
chart.setDrawGridBackground(false);
|
||||
// chart.setDrawYLabels(false);
|
||||
|
||||
IAxisValueFormatter xAxisFormatter = new DayAxisValueFormatter(chart);
|
||||
ValueFormatter xAxisFormatter = new DayAxisValueFormatter(chart);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setPosition(XAxisPosition.BOTTOM);
|
||||
|
@ -96,7 +95,7 @@ public class BarChartActivity extends DemoBase implements OnSeekBarChangeListene
|
|||
xAxis.setLabelCount(7);
|
||||
xAxis.setValueFormatter(xAxisFormatter);
|
||||
|
||||
IAxisValueFormatter custom = new MyAxisValueFormatter();
|
||||
ValueFormatter custom = new MyValueFormatter("$");
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setTypeface(tfLight);
|
||||
|
@ -165,12 +164,6 @@ public class BarChartActivity extends DemoBase implements OnSeekBarChangeListene
|
|||
|
||||
set1.setDrawIcons(false);
|
||||
|
||||
// set1.setColors(ColorTemplate.MATERIAL_COLORS);
|
||||
|
||||
/*int startColor = ContextCompat.getColor(this, android.R.color.holo_blue_dark);
|
||||
int endColor = ContextCompat.getColor(this, android.R.color.holo_blue_bright);
|
||||
set1.setGradientColor(startColor, endColor);*/
|
||||
|
||||
int startColor1 = ContextCompat.getColor(this, android.R.color.holo_orange_light);
|
||||
int startColor2 = ContextCompat.getColor(this, android.R.color.holo_blue_light);
|
||||
int startColor3 = ContextCompat.getColor(this, android.R.color.holo_orange_light);
|
||||
|
@ -182,14 +175,14 @@ public class BarChartActivity extends DemoBase implements OnSeekBarChangeListene
|
|||
int endColor4 = ContextCompat.getColor(this, android.R.color.holo_red_dark);
|
||||
int endColor5 = ContextCompat.getColor(this, android.R.color.holo_orange_dark);
|
||||
|
||||
List<GradientColor> gradientColors = new ArrayList<>();
|
||||
gradientColors.add(new GradientColor(startColor1, endColor1));
|
||||
gradientColors.add(new GradientColor(startColor2, endColor2));
|
||||
gradientColors.add(new GradientColor(startColor3, endColor3));
|
||||
gradientColors.add(new GradientColor(startColor4, endColor4));
|
||||
gradientColors.add(new GradientColor(startColor5, endColor5));
|
||||
List<Fill> gradientFills = new ArrayList<>();
|
||||
gradientFills.add(new Fill(startColor1, endColor1));
|
||||
gradientFills.add(new Fill(startColor2, endColor2));
|
||||
gradientFills.add(new Fill(startColor3, endColor3));
|
||||
gradientFills.add(new Fill(startColor4, endColor4));
|
||||
gradientFills.add(new Fill(startColor5, endColor5));
|
||||
|
||||
set1.setGradientColors(gradientColors);
|
||||
set1.setFills(gradientFills);
|
||||
|
||||
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(set1);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
|
@ -17,7 +16,6 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
|
@ -25,8 +23,8 @@ 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.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.LargeValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
|
@ -100,9 +98,9 @@ public class BarChartActivityMultiDataset extends DemoBase implements OnSeekBarC
|
|||
xAxis.setTypeface(tfLight);
|
||||
xAxis.setGranularity(1f);
|
||||
xAxis.setCenterAxisLabels(true);
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.content.Intent;
|
||||
|
@ -10,17 +9,13 @@ import android.view.MenuItem;
|
|||
import android.view.WindowManager;
|
||||
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
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.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
@ -88,9 +83,9 @@ public class BarChartPositiveNegative extends DemoBase {
|
|||
data.add(new Data(3f, -442.3f, "01-01"));
|
||||
data.add(new Data(4f, -2280.1f, "01-02"));
|
||||
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getFormattedValue(float value) {
|
||||
return data.get(Math.min(Math.max((int) value, 0), data.size()-1)).xAxisValue;
|
||||
}
|
||||
});
|
||||
|
@ -135,7 +130,7 @@ public class BarChartPositiveNegative extends DemoBase {
|
|||
BarData data = new BarData(set);
|
||||
data.setValueTextSize(13f);
|
||||
data.setValueTypeface(tfRegular);
|
||||
data.setValueFormatter(new ValueFormatter());
|
||||
data.setValueFormatter(new Formatter());
|
||||
data.setBarWidth(0.8f);
|
||||
|
||||
chart.setData(data);
|
||||
|
@ -159,17 +154,17 @@ public class BarChartPositiveNegative extends DemoBase {
|
|||
}
|
||||
}
|
||||
|
||||
private class ValueFormatter implements IValueFormatter
|
||||
private class Formatter extends ValueFormatter
|
||||
{
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
|
||||
ValueFormatter() {
|
||||
Formatter() {
|
||||
mFormat = new DecimalFormat("######.0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
|
||||
public String getFormattedValue(float value) {
|
||||
return mFormat.format(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.content.Intent;
|
||||
|
@ -11,7 +10,6 @@ import android.view.WindowManager;
|
|||
|
||||
import com.github.mikephil.charting.charts.CombinedChart;
|
||||
import com.github.mikephil.charting.charts.CombinedChart.DrawOrder;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
|
@ -31,7 +29,7 @@ import com.github.mikephil.charting.data.LineData;
|
|||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.data.ScatterData;
|
||||
import com.github.mikephil.charting.data.ScatterDataSet;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
@ -83,9 +81,9 @@ public class CombinedChartActivity extends DemoBase {
|
|||
xAxis.setPosition(XAxisPosition.BOTH_SIDED);
|
||||
xAxis.setAxisMinimum(0f);
|
||||
xAxis.setGranularity(1f);
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getFormattedValue(float value) {
|
||||
return months[(int) value % months.length];
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.RectF;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
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 androidx.core.content.ContextCompat;
|
||||
|
||||
import com.github.mikephil.charting.charts.HorizontalBarChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
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.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class HorizontalBarNegativeChartActivity extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private HorizontalBarChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
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_horizontalbarchart);
|
||||
|
||||
setTitle("HorizontalBarChartActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
// chart.setHighlightEnabled(false);
|
||||
|
||||
chart.setDrawBarShadow(false);
|
||||
|
||||
chart.setDrawValueAboveBar(true);
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// if more than 60 entries are displayed in the chart, no values will be
|
||||
// drawn
|
||||
chart.setMaxVisibleValueCount(60);
|
||||
|
||||
// scaling can now only be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
// draw shadows for each bar that show the maximum value
|
||||
// chart.setDrawBarShadow(true);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
XAxis xl = chart.getXAxis();
|
||||
xl.setPosition(XAxisPosition.BOTTOM);
|
||||
xl.setTypeface(tfLight);
|
||||
xl.setDrawAxisLine(true);
|
||||
xl.setDrawGridLines(false);
|
||||
xl.setGranularity(10f);
|
||||
|
||||
YAxis yl = chart.getAxisLeft();
|
||||
yl.setTypeface(tfLight);
|
||||
yl.setDrawAxisLine(true);
|
||||
yl.setDrawGridLines(true);
|
||||
// yl.setInverted(true);
|
||||
|
||||
YAxis yr = chart.getAxisRight();
|
||||
yr.setTypeface(tfLight);
|
||||
yr.setDrawAxisLine(true);
|
||||
yr.setDrawGridLines(false);
|
||||
// yr.setInverted(true);
|
||||
|
||||
chart.setFitBars(true);
|
||||
chart.animateY(2500);
|
||||
|
||||
// setting data
|
||||
seekBarY.setProgress(50);
|
||||
seekBarX.setProgress(12);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
|
||||
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
|
||||
l.setDrawInside(false);
|
||||
l.setFormSize(8f);
|
||||
l.setXEntrySpace(4f);
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
float barWidth = 9f;
|
||||
float spaceForBar = 10f;
|
||||
ArrayList<BarEntry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float val = (float) (Math.random() * range - range / 2);
|
||||
values.add(new BarEntry(i * spaceForBar, val,
|
||||
getResources().getDrawable(R.drawable.star)));
|
||||
}
|
||||
|
||||
BarDataSet set1;
|
||||
|
||||
if (chart.getData() != null &&
|
||||
chart.getData().getDataSetCount() > 0) {
|
||||
set1 = (BarDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set1.setValues(values);
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
} else {
|
||||
set1 = new BarDataSet(values, "DataSet 1");
|
||||
|
||||
set1.setDrawIcons(false);
|
||||
|
||||
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(set1);
|
||||
|
||||
BarData data = new BarData(dataSets);
|
||||
data.setValueTextSize(10f);
|
||||
data.setValueTypeface(tfLight);
|
||||
data.setBarWidth(barWidth);
|
||||
chart.setData(data);
|
||||
}
|
||||
}
|
||||
|
||||
@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.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/HorizontalBarChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
List<IBarDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (IBarDataSet iSet : sets) {
|
||||
iSet.setDrawValues(!iSet.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleIcons: {
|
||||
List<IBarDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (IBarDataSet iSet : sets) {
|
||||
iSet.setDrawIcons(!iSet.isDrawIconsEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleBarBorders: {
|
||||
for (IBarDataSet set : chart.getData().getDataSets())
|
||||
((BarDataSet)set).setBarBorderWidth(set.getBarBorderWidth() == 1.f ? 0.f : 1.f);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
setData(seekBarX.getProgress(), seekBarY.getProgress());
|
||||
chart.setFitBars(true);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "HorizontalBarChartActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
private final RectF mOnValueSelectedRectF = new RectF();
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
|
||||
if (e == null)
|
||||
return;
|
||||
|
||||
RectF bounds = mOnValueSelectedRectF;
|
||||
chart.getBarBounds((BarEntry) e, bounds);
|
||||
|
||||
MPPointF position = chart.getPosition(e, chart.getData().getDataSetByIndex(h.getDataSetIndex())
|
||||
.getAxisDependency());
|
||||
|
||||
Log.i("bounds", bounds.toString());
|
||||
Log.i("position", position.toString());
|
||||
|
||||
MPPointF.recycleInstance(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {}
|
||||
}
|
|
@ -45,7 +45,7 @@ import java.util.List;
|
|||
* Example of a heavily customized {@link LineChart} with limit lines, custom line shapes, etc.
|
||||
*
|
||||
* @since 1.7.4
|
||||
* @version 3.0.3
|
||||
* @version 3.1.0
|
||||
*/
|
||||
public class LineChartActivity1 extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
|
|
@ -38,7 +38,7 @@ import java.util.List;
|
|||
* Example of a dual axis {@link LineChart} with multiple data sets.
|
||||
*
|
||||
* @since 1.7.4
|
||||
* @version 3.0.3
|
||||
* @version 3.1.0
|
||||
*/
|
||||
public class LineChartActivity2 extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
|
@ -16,7 +15,6 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
|
@ -24,7 +22,7 @@ import com.github.mikephil.charting.components.YAxis.AxisDependency;
|
|||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
@ -92,12 +90,12 @@ public class LineChartTime extends DemoBase implements OnSeekBarChangeListener {
|
|||
xAxis.setTextColor(Color.rgb(255, 192, 56));
|
||||
xAxis.setCenterAxisLabels(true);
|
||||
xAxis.setGranularity(1f); // one hour
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
|
||||
private final SimpleDateFormat mFormat = new SimpleDateFormat("dd MMM HH:mm", Locale.ENGLISH);
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getFormattedValue(float value) {
|
||||
|
||||
long millis = TimeUnit.HOURS.toMillis((long) value);
|
||||
return mFormat.format(new Date(millis));
|
||||
|
|
|
@ -160,7 +160,7 @@ public class PieChartActivity extends DemoBase implements OnSeekBarChangeListene
|
|||
//dataSet.setSelectionShift(0f);
|
||||
|
||||
PieData data = new PieData(dataSet);
|
||||
data.setValueFormatter(new PercentFormatter());
|
||||
data.setValueFormatter(new PercentFormatter(chart));
|
||||
data.setValueTextSize(11f);
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
data.setValueTypeface(tfLight);
|
||||
|
@ -210,6 +210,27 @@ public class PieChartActivity extends DemoBase implements OnSeekBarChangeListene
|
|||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleMinAngles: {
|
||||
if (chart.getMinAngleForSlices() == 0f)
|
||||
chart.setMinAngleForSlices(36f);
|
||||
else
|
||||
chart.setMinAngleForSlices(0f);
|
||||
chart.notifyDataSetChanged();
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCurvedSlices: {
|
||||
boolean toSet = !chart.isDrawRoundedSlicesEnabled() || !chart.isDrawHoleEnabled();
|
||||
chart.setDrawRoundedSlices(toSet);
|
||||
if (toSet && !chart.isDrawHoleEnabled()) {
|
||||
chart.setDrawHoleEnabled(true);
|
||||
}
|
||||
if (toSet && chart.isDrawSlicesUnderHoleEnabled()) {
|
||||
chart.setDrawSlicesUnderHole(false);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionDrawCenter: {
|
||||
if (chart.isDrawCenterTextEnabled())
|
||||
chart.setDrawCenterText(false);
|
||||
|
|
|
@ -156,7 +156,6 @@ public class PiePolylineChartActivity extends DemoBase implements OnSeekBarChang
|
|||
dataSet.setValueLinePart1OffsetPercentage(80.f);
|
||||
dataSet.setValueLinePart1Length(0.2f);
|
||||
dataSet.setValueLinePart2Length(0.4f);
|
||||
//dataSet.setUsingSliceColorAsValueLineColor(true);
|
||||
|
||||
//dataSet.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
|
||||
dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
|
||||
|
@ -205,6 +204,27 @@ public class PiePolylineChartActivity extends DemoBase implements OnSeekBarChang
|
|||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleMinAngles: {
|
||||
if (chart.getMinAngleForSlices() == 0f)
|
||||
chart.setMinAngleForSlices(36f);
|
||||
else
|
||||
chart.setMinAngleForSlices(0f);
|
||||
chart.notifyDataSetChanged();
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCurvedSlices: {
|
||||
boolean toSet = !chart.isDrawRoundedSlicesEnabled() || !chart.isDrawHoleEnabled();
|
||||
chart.setDrawRoundedSlices(toSet);
|
||||
if (toSet && !chart.isDrawHoleEnabled()) {
|
||||
chart.setDrawHoleEnabled(true);
|
||||
}
|
||||
if (toSet && chart.isDrawSlicesUnderHoleEnabled()) {
|
||||
chart.setDrawSlicesUnderHole(false);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionDrawCenter: {
|
||||
if (chart.isDrawCenterTextEnabled())
|
||||
chart.setDrawCenterText(false);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
|
@ -14,7 +13,6 @@ import android.view.WindowManager;
|
|||
|
||||
import com.github.mikephil.charting.animation.Easing;
|
||||
import com.github.mikephil.charting.charts.RadarChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.MarkerView;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
|
@ -22,7 +20,7 @@ import com.github.mikephil.charting.components.YAxis;
|
|||
import com.github.mikephil.charting.data.RadarData;
|
||||
import com.github.mikephil.charting.data.RadarDataSet;
|
||||
import com.github.mikephil.charting.data.RadarEntry;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IRadarDataSet;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.RadarMarkerView;
|
||||
|
@ -69,12 +67,12 @@ public class RadarChartActivity extends DemoBase {
|
|||
xAxis.setTextSize(9f);
|
||||
xAxis.setYOffset(0f);
|
||||
xAxis.setXOffset(0f);
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
|
||||
private final String[] mActivities = new String[]{"Burger", "Steak", "Salad", "Pasta", "Pizza"};
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getFormattedValue(float value) {
|
||||
return mActivities[(int) value % mActivities.length];
|
||||
}
|
||||
});
|
||||
|
|
|
@ -24,11 +24,11 @@ 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.formatter.StackedValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.MyAxisValueFormatter;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.MyValueFormatter;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
|
@ -78,7 +78,7 @@ public class StackedBarActivity extends DemoBase implements OnSeekBarChangeListe
|
|||
|
||||
// change the position of the y-labels
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setValueFormatter(new MyAxisValueFormatter());
|
||||
leftAxis.setValueFormatter(new MyValueFormatter("K"));
|
||||
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
|
||||
|
@ -142,7 +142,7 @@ public class StackedBarActivity extends DemoBase implements OnSeekBarChangeListe
|
|||
dataSets.add(set1);
|
||||
|
||||
BarData data = new BarData(dataSets);
|
||||
data.setValueFormatter(new MyValueFormatter());
|
||||
data.setValueFormatter(new StackedValueFormatter(false, "", 1));
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
|
||||
chart.setData(data);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
|
@ -14,7 +13,6 @@ import android.view.MenuItem;
|
|||
import android.view.WindowManager;
|
||||
|
||||
import com.github.mikephil.charting.charts.HorizontalBarChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
|
@ -23,12 +21,10 @@ 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.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
@ -80,12 +76,12 @@ public class StackedBarActivityNegative extends DemoBase implements
|
|||
xAxis.setCenterAxisLabels(true);
|
||||
xAxis.setLabelCount(12);
|
||||
xAxis.setGranularity(10f);
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
|
||||
private final DecimalFormat format = new DecimalFormat("###");
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getFormattedValue(float value) {
|
||||
return format.format(value) + "-" + format.format(value + 10);
|
||||
}
|
||||
});
|
||||
|
@ -242,7 +238,7 @@ public class StackedBarActivityNegative extends DemoBase implements
|
|||
Log.i("NOTING SELECTED", "");
|
||||
}
|
||||
|
||||
private class CustomFormatter implements IValueFormatter, IAxisValueFormatter {
|
||||
private class CustomFormatter extends ValueFormatter {
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
|
||||
|
@ -250,15 +246,8 @@ public class StackedBarActivityNegative extends DemoBase implements
|
|||
mFormat = new DecimalFormat("###");
|
||||
}
|
||||
|
||||
// data
|
||||
@Override
|
||||
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
|
||||
return mFormat.format(Math.abs(value)) + "m";
|
||||
}
|
||||
|
||||
// YAxis
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getFormattedValue(float value) {
|
||||
return mFormat.format(Math.abs(value)) + "m";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.charts.BarLineChartBase;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
|
||||
/**
|
||||
* Created by philipp on 02/06/16.
|
||||
*/
|
||||
public class DayAxisValueFormatter implements IAxisValueFormatter
|
||||
public class DayAxisValueFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
private final String[] mMonths = new String[]{
|
||||
|
@ -21,7 +20,7 @@ public class DayAxisValueFormatter implements IAxisValueFormatter
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getFormattedValue(float value) {
|
||||
|
||||
int days = (int) value;
|
||||
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class MyAxisValueFormatter implements IAxisValueFormatter
|
||||
{
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
|
||||
public MyAxisValueFormatter() {
|
||||
mFormat = new DecimalFormat("###,###,###,##0.0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
return mFormat.format(value) + " $";
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
@ -12,7 +11,7 @@ import java.text.DecimalFormat;
|
|||
* @deprecated The {@link MyAxisValueFormatter} does exactly the same thing and is more functional.
|
||||
*/
|
||||
@Deprecated
|
||||
public class MyCustomXAxisValueFormatter implements IAxisValueFormatter
|
||||
public class MyCustomXAxisValueFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
|
@ -25,7 +24,7 @@ public class MyCustomXAxisValueFormatter implements IAxisValueFormatter
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getFormattedValue(float value) {
|
||||
|
||||
//Log.i("TRANS", "x: " + viewPortHandler.getTransX() + ", y: " + viewPortHandler.getTransY());
|
||||
|
||||
|
|
|
@ -1,22 +1,35 @@
|
|||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class MyValueFormatter implements IValueFormatter
|
||||
public class MyValueFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
private String suffix;
|
||||
|
||||
public MyValueFormatter() {
|
||||
public MyValueFormatter(String suffix) {
|
||||
mFormat = new DecimalFormat("###,###,###,##0.0");
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
|
||||
return mFormat.format(value) + " $";
|
||||
public String getFormattedValue(float value) {
|
||||
return mFormat.format(value) + suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAxisLabel(float value, AxisBase axis) {
|
||||
if (axis instanceof XAxis) {
|
||||
return mFormat.format(value);
|
||||
} else if (value > 0) {
|
||||
return mFormat.format(value) + suffix;
|
||||
} else {
|
||||
return mFormat.format(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
@ -7,7 +6,7 @@ import android.widget.TextView;
|
|||
|
||||
import com.github.mikephil.charting.components.MarkerView;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
|
@ -23,11 +22,11 @@ import java.text.DecimalFormat;
|
|||
public class XYMarkerView extends MarkerView {
|
||||
|
||||
private final TextView tvContent;
|
||||
private final IAxisValueFormatter xAxisValueFormatter;
|
||||
private final ValueFormatter xAxisValueFormatter;
|
||||
|
||||
private final DecimalFormat format;
|
||||
|
||||
public XYMarkerView(Context context, IAxisValueFormatter xAxisValueFormatter) {
|
||||
public XYMarkerView(Context context, ValueFormatter xAxisValueFormatter) {
|
||||
super(context, R.layout.custom_marker_view);
|
||||
|
||||
this.xAxisValueFormatter = xAxisValueFormatter;
|
||||
|
@ -40,7 +39,7 @@ public class XYMarkerView extends MarkerView {
|
|||
@Override
|
||||
public void refreshContent(Entry e, Highlight highlight) {
|
||||
|
||||
tvContent.setText(String.format("x: %s, y: %s", xAxisValueFormatter.getFormattedValue(e.getX(), null), format.format(e.getY())));
|
||||
tvContent.setText(String.format("x: %s, y: %s", xAxisValueFormatter.getFormattedValue(e.getX()), format.format(e.getY())));
|
||||
|
||||
super.refreshContent(e, highlight);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
|
||||
/**
|
||||
* Created by Philipp Jahoda on 14/09/15.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class YearXAxisFormatter implements IAxisValueFormatter
|
||||
public class YearXAxisFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
private final String[] mMonths = new String[]{
|
||||
|
@ -19,7 +19,7 @@ public class YearXAxisFormatter implements IAxisValueFormatter
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getAxisLabel(float value, AxisBase axis) {
|
||||
|
||||
float percent = value / axis.mAxisRange;
|
||||
return mMonths[(int) (mMonths.length * percent)];
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.xxmassdeveloper.mpchartexample.DynamicalAddingActivity;
|
|||
import com.xxmassdeveloper.mpchartexample.FilledLineActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.HalfPieChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.HorizontalBarChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.HorizontalBarNegativeChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.InvertedLineChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.LineChartActivity1;
|
||||
import com.xxmassdeveloper.mpchartexample.LineChartActivity2;
|
||||
|
@ -87,40 +88,41 @@ public class MainActivity extends AppCompatActivity implements OnItemClickListen
|
|||
objects.add(13, new ContentItem("Horizontal", "Render bar chart horizontally."));
|
||||
objects.add(14, new ContentItem("Stacked", "Stacked bar chart."));
|
||||
objects.add(15, new ContentItem("Negative", "Positive and negative values with unique colors."));
|
||||
objects.add(16, new ContentItem("Stacked 2", "Stacked bar chart with negative values."));
|
||||
objects.add(17, new ContentItem("Sine", "Sine function in bar chart format."));
|
||||
objects.add(16, new ContentItem("Negative Horizontal", "demonstrates how to create a HorizontalBarChart with positive and negative values."));
|
||||
objects.add(17, new ContentItem("Stacked 2", "Stacked bar chart with negative values."));
|
||||
objects.add(18, new ContentItem("Sine", "Sine function in bar chart format."));
|
||||
|
||||
////
|
||||
objects.add(18, new ContentItem("Pie Charts"));
|
||||
objects.add(19, new ContentItem("Pie Charts"));
|
||||
|
||||
objects.add(19, new ContentItem("Basic", "Simple pie chart."));
|
||||
objects.add(20, new ContentItem("Value Lines", "Stylish lines drawn outward from slices."));
|
||||
objects.add(21, new ContentItem("Half Pie", "180° (half) pie chart."));
|
||||
objects.add(20, new ContentItem("Basic", "Simple pie chart."));
|
||||
objects.add(21, new ContentItem("Value Lines", "Stylish lines drawn outward from slices."));
|
||||
objects.add(22, new ContentItem("Half Pie", "180° (half) pie chart."));
|
||||
|
||||
////
|
||||
objects.add(22, new ContentItem("Other Charts"));
|
||||
objects.add(23, new ContentItem("Other Charts"));
|
||||
|
||||
objects.add(23, new ContentItem("Combined Chart", "Bar and line chart together."));
|
||||
objects.add(24, new ContentItem("Scatter Plot", "Simple scatter plot."));
|
||||
objects.add(25, new ContentItem("Bubble Chart", "Simple bubble chart."));
|
||||
objects.add(26, new ContentItem("Candlestick", "Simple financial chart."));
|
||||
objects.add(27, new ContentItem("Radar Chart", "Simple web chart."));
|
||||
objects.add(24, new ContentItem("Combined Chart", "Bar and line chart together."));
|
||||
objects.add(25, new ContentItem("Scatter Plot", "Simple scatter plot."));
|
||||
objects.add(26, new ContentItem("Bubble Chart", "Simple bubble chart."));
|
||||
objects.add(27, new ContentItem("Candlestick", "Simple financial chart."));
|
||||
objects.add(28, new ContentItem("Radar Chart", "Simple web chart."));
|
||||
|
||||
////
|
||||
objects.add(28, new ContentItem("Scrolling Charts"));
|
||||
objects.add(29, new ContentItem("Scrolling Charts"));
|
||||
|
||||
objects.add(29, new ContentItem("Multiple", "Various types of charts as fragments."));
|
||||
objects.add(30, new ContentItem("View Pager", "Swipe through different charts."));
|
||||
objects.add(31, new ContentItem("Tall Bar Chart", "Bars bigger than your screen!"));
|
||||
objects.add(32, new ContentItem("Many Bar Charts", "More bars than your screen can handle!"));
|
||||
objects.add(30, new ContentItem("Multiple", "Various types of charts as fragments."));
|
||||
objects.add(31, new ContentItem("View Pager", "Swipe through different charts."));
|
||||
objects.add(32, new ContentItem("Tall Bar Chart", "Bars bigger than your screen!"));
|
||||
objects.add(33, new ContentItem("Many Bar Charts", "More bars than your screen can handle!"));
|
||||
|
||||
////
|
||||
objects.add(33, new ContentItem("Even More Line Charts"));
|
||||
objects.add(34, new ContentItem("Even More Line Charts"));
|
||||
|
||||
objects.add(34, new ContentItem("Dynamic", "Build a line chart by adding points and sets."));
|
||||
objects.add(35, new ContentItem("Realtime", "Add data points in realtime."));
|
||||
objects.add(36, new ContentItem("Hourly", "Uses the current time to add a data point for each hour."));
|
||||
//objects.add(37, new ContentItem("Realm.io Examples", "See more examples that use Realm.io mobile database."));
|
||||
objects.add(35, new ContentItem("Dynamic", "Build a line chart by adding points and sets."));
|
||||
objects.add(36, new ContentItem("Realtime", "Add data points in realtime."));
|
||||
objects.add(37, new ContentItem("Hourly", "Uses the current time to add a data point for each hour."));
|
||||
//objects.add(38, new ContentItem("Realm.io Examples", "See more examples that use Realm.io mobile database."));
|
||||
|
||||
MyAdapter adapter = new MyAdapter(this, objects);
|
||||
|
||||
|
@ -179,57 +181,60 @@ public class MainActivity extends AppCompatActivity implements OnItemClickListen
|
|||
i = new Intent(this, BarChartPositiveNegative.class);
|
||||
break;
|
||||
case 16:
|
||||
i = new Intent(this, StackedBarActivityNegative.class);
|
||||
i = new Intent(this, HorizontalBarNegativeChartActivity.class);
|
||||
break;
|
||||
case 17:
|
||||
i = new Intent(this, StackedBarActivityNegative.class);
|
||||
break;
|
||||
case 18:
|
||||
i = new Intent(this, BarChartActivitySinus.class);
|
||||
break;
|
||||
case 19:
|
||||
case 20:
|
||||
i = new Intent(this, PieChartActivity.class);
|
||||
break;
|
||||
case 20:
|
||||
case 21:
|
||||
i = new Intent(this, PiePolylineChartActivity.class);
|
||||
break;
|
||||
case 21:
|
||||
case 22:
|
||||
i = new Intent(this, HalfPieChartActivity.class);
|
||||
break;
|
||||
case 23:
|
||||
case 24:
|
||||
i = new Intent(this, CombinedChartActivity.class);
|
||||
break;
|
||||
case 24:
|
||||
case 25:
|
||||
i = new Intent(this, ScatterChartActivity.class);
|
||||
break;
|
||||
case 25:
|
||||
case 26:
|
||||
i = new Intent(this, BubbleChartActivity.class);
|
||||
break;
|
||||
case 26:
|
||||
case 27:
|
||||
i = new Intent(this, CandleStickChartActivity.class);
|
||||
break;
|
||||
case 27:
|
||||
case 28:
|
||||
i = new Intent(this, RadarChartActivity.class);
|
||||
break;
|
||||
case 29:
|
||||
case 30:
|
||||
i = new Intent(this, ListViewMultiChartActivity.class);
|
||||
break;
|
||||
case 30:
|
||||
case 31:
|
||||
i = new Intent(this, SimpleChartDemo.class);
|
||||
break;
|
||||
case 31:
|
||||
case 32:
|
||||
i = new Intent(this, ScrollViewActivity.class);
|
||||
break;
|
||||
case 32:
|
||||
case 33:
|
||||
i = new Intent(this, ListViewBarChartActivity.class);
|
||||
break;
|
||||
case 34:
|
||||
case 35:
|
||||
i = new Intent(this, DynamicalAddingActivity.class);
|
||||
break;
|
||||
case 35:
|
||||
case 36:
|
||||
i = new Intent(this, RealtimeLineChartActivity.class);
|
||||
break;
|
||||
case 36:
|
||||
case 37:
|
||||
i = new Intent(this, LineChartTime.class);
|
||||
break;
|
||||
/*case 37:
|
||||
/*case 38:
|
||||
i = new Intent(this, RealmMainActivity.class);
|
||||
break;*/
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:text="Medium Text"
|
||||
android:textColor="@android:color/black"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -21,10 +21,18 @@
|
|||
android:id="@+id/actionTogglePercent"
|
||||
android:title="@string/actionTogglePercent">
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/actionToggleMinAngles"
|
||||
android:title="@string/actionToggleMinAngles">
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/actionToggleHole"
|
||||
android:title="@string/actionToggleHole">
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/actionToggleCurvedSlices"
|
||||
android:title="@string/actionToggleCurvedSlices">
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/actionDrawCenter"
|
||||
android:title="@string/actionDrawCenterText">
|
||||
|
|
|
@ -40,7 +40,9 @@
|
|||
<string name="actionClearChart">Clear chart</string>
|
||||
|
||||
<string name="actionTogglePercent">Toggle Percent</string>
|
||||
<string name="actionToggleMinAngles">Toggle Minimum Angles</string>
|
||||
<string name="actionToggleHole">Toggle Hole</string>
|
||||
<string name="actionToggleCurvedSlices">Toggle Curved Slices</string>
|
||||
<string name="actionDrawCenterText">Draw Center Text</string>
|
||||
<string name="actionToggleHighlightCircle">Toggle Highlight Circle</string>
|
||||
<string name="actionToggleRotation">Toggle Rotation</string>
|
||||
|
|
|
@ -10,7 +10,7 @@ android {
|
|||
minSdkVersion 14
|
||||
targetSdkVersion 28
|
||||
versionCode 3
|
||||
versionName '3.0.3'
|
||||
versionName '3.1.0'
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.animation;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
|
@ -160,98 +159,6 @@ public class ChartAnimator {
|
|||
animatorY.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the drawing / rendering of the chart on both x- and y-axis with
|
||||
* the specified animation time. If animate(...) is called, no further
|
||||
* calling of invalidate() is necessary to refresh the chart.
|
||||
*
|
||||
* @param durationMillisX animation duration along the X axis
|
||||
* @param durationMillisY animation duration along the Y axis
|
||||
* @param easingX EasingFunction for the X axis
|
||||
* @param easingY EasingFunction for the Y axis
|
||||
*
|
||||
* @deprecated Use {@link #animateXY(int, int, EasingFunction, EasingFunction)}
|
||||
* @see #animateXY(int, int, EasingFunction, EasingFunction)
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public void animateXY(int durationMillisX, int durationMillisY, Easing.EasingOption easingX,
|
||||
Easing.EasingOption easingY) {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < 11)
|
||||
return;
|
||||
|
||||
ObjectAnimator animatorY = ObjectAnimator.ofFloat(this, "phaseY", 0f, 1f);
|
||||
animatorY.setInterpolator(Easing.getEasingFunctionFromOption(easingY));
|
||||
animatorY.setDuration(
|
||||
durationMillisY);
|
||||
ObjectAnimator animatorX = ObjectAnimator.ofFloat(this, "phaseX", 0f, 1f);
|
||||
animatorX.setInterpolator(Easing.getEasingFunctionFromOption(easingX));
|
||||
animatorX.setDuration(
|
||||
durationMillisX);
|
||||
|
||||
// make sure only one animator produces update-callbacks (which then
|
||||
// call invalidate())
|
||||
if (durationMillisX > durationMillisY) {
|
||||
animatorX.addUpdateListener(mListener);
|
||||
} else {
|
||||
animatorY.addUpdateListener(mListener);
|
||||
}
|
||||
|
||||
animatorX.start();
|
||||
animatorY.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the rendering of the chart on the x-axis with the specified
|
||||
* animation time. If animate(...) is called, no further calling of
|
||||
* invalidate() is necessary to refresh the chart.
|
||||
*
|
||||
* @param durationMillis animation duration
|
||||
* @param easing EasingFunction
|
||||
*
|
||||
* @deprecated Use {@link #animateX(int, EasingFunction)}
|
||||
* @see #animateX(int, EasingFunction)
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public void animateX(int durationMillis, Easing.EasingOption easing) {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < 11)
|
||||
return;
|
||||
|
||||
ObjectAnimator animatorX = ObjectAnimator.ofFloat(this, "phaseX", 0f, 1f);
|
||||
animatorX.setInterpolator(Easing.getEasingFunctionFromOption(easing));
|
||||
animatorX.setDuration(durationMillis);
|
||||
animatorX.addUpdateListener(mListener);
|
||||
animatorX.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the rendering of the chart on the y-axis with the specified
|
||||
* animation time. If animate(...) is called, no further calling of
|
||||
* invalidate() is necessary to refresh the chart.
|
||||
*
|
||||
* @param durationMillis animation duration
|
||||
* @param easing EasingFunction
|
||||
*
|
||||
* @deprecated Use {@link #animateY(int, EasingFunction)}
|
||||
* @see #animateY(int, EasingFunction)
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public void animateY(int durationMillis, Easing.EasingOption easing) {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < 11)
|
||||
return;
|
||||
|
||||
ObjectAnimator animatorY = ObjectAnimator.ofFloat(this, "phaseY", 0f, 1f);
|
||||
animatorY.setInterpolator(Easing.getEasingFunctionFromOption(easing));
|
||||
animatorY.setDuration(durationMillis);
|
||||
animatorY.addUpdateListener(mListener);
|
||||
animatorY.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Y axis phase of the animation.
|
||||
*
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.animation;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
|
@ -19,112 +18,6 @@ public class Easing {
|
|||
float getInterpolation(float input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum holding EasingOption constants
|
||||
*
|
||||
* @deprecated Use Easing.Linear instead of Easing.EasingOption.Linear
|
||||
*/
|
||||
@Deprecated
|
||||
public enum EasingOption {
|
||||
Linear,
|
||||
EaseInQuad,
|
||||
EaseOutQuad,
|
||||
EaseInOutQuad,
|
||||
EaseInCubic,
|
||||
EaseOutCubic,
|
||||
EaseInOutCubic,
|
||||
EaseInQuart,
|
||||
EaseOutQuart,
|
||||
EaseInOutQuart,
|
||||
EaseInSine,
|
||||
EaseOutSine,
|
||||
EaseInOutSine,
|
||||
EaseInExpo,
|
||||
EaseOutExpo,
|
||||
EaseInOutExpo,
|
||||
EaseInCirc,
|
||||
EaseOutCirc,
|
||||
EaseInOutCirc,
|
||||
EaseInElastic,
|
||||
EaseOutElastic,
|
||||
EaseInOutElastic,
|
||||
EaseInBack,
|
||||
EaseOutBack,
|
||||
EaseInOutBack,
|
||||
EaseInBounce,
|
||||
EaseOutBounce,
|
||||
EaseInOutBounce,
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the EasingFunction of the given EasingOption
|
||||
*
|
||||
* @param easing EasingOption to get
|
||||
* @return EasingFunction
|
||||
*/
|
||||
@Deprecated
|
||||
public static EasingFunction getEasingFunctionFromOption(EasingOption easing) {
|
||||
switch (easing) {
|
||||
default:
|
||||
case Linear:
|
||||
return Easing.Linear;
|
||||
case EaseInQuad:
|
||||
return Easing.EaseInQuad;
|
||||
case EaseOutQuad:
|
||||
return Easing.EaseOutQuad;
|
||||
case EaseInOutQuad:
|
||||
return Easing.EaseInOutQuad;
|
||||
case EaseInCubic:
|
||||
return Easing.EaseInCubic;
|
||||
case EaseOutCubic:
|
||||
return Easing.EaseOutCubic;
|
||||
case EaseInOutCubic:
|
||||
return Easing.EaseInOutCubic;
|
||||
case EaseInQuart:
|
||||
return Easing.EaseInQuart;
|
||||
case EaseOutQuart:
|
||||
return Easing.EaseOutQuart;
|
||||
case EaseInOutQuart:
|
||||
return Easing.EaseInOutQuart;
|
||||
case EaseInSine:
|
||||
return Easing.EaseInSine;
|
||||
case EaseOutSine:
|
||||
return Easing.EaseOutSine;
|
||||
case EaseInOutSine:
|
||||
return Easing.EaseInOutSine;
|
||||
case EaseInExpo:
|
||||
return Easing.EaseInExpo;
|
||||
case EaseOutExpo:
|
||||
return Easing.EaseOutExpo;
|
||||
case EaseInOutExpo:
|
||||
return Easing.EaseInOutExpo;
|
||||
case EaseInCirc:
|
||||
return Easing.EaseInCirc;
|
||||
case EaseOutCirc:
|
||||
return Easing.EaseOutCirc;
|
||||
case EaseInOutCirc:
|
||||
return Easing.EaseInOutCirc;
|
||||
case EaseInElastic:
|
||||
return Easing.EaseInElastic;
|
||||
case EaseOutElastic:
|
||||
return Easing.EaseOutElastic;
|
||||
case EaseInOutElastic:
|
||||
return Easing.EaseInOutElastic;
|
||||
case EaseInBack:
|
||||
return Easing.EaseInBack;
|
||||
case EaseOutBack:
|
||||
return Easing.EaseOutBack;
|
||||
case EaseInOutBack:
|
||||
return Easing.EaseInOutBack;
|
||||
case EaseInBounce:
|
||||
return Easing.EaseInBounce;
|
||||
case EaseOutBounce:
|
||||
return Easing.EaseOutBounce;
|
||||
case EaseInOutBounce:
|
||||
return Easing.EaseInOutBounce;
|
||||
}
|
||||
}
|
||||
|
||||
private static final float DOUBLE_PI = 2f * (float) Math.PI;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
|
|
@ -100,6 +100,8 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
|
|||
|
||||
protected boolean mClipValuesToContent = false;
|
||||
|
||||
protected boolean mClipDataToContent = true;
|
||||
|
||||
/**
|
||||
* Sets the minimum offset (padding) around the chart, defaults to 15
|
||||
*/
|
||||
|
@ -230,9 +232,12 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
|
|||
if (mAxisRight.isEnabled() && mAxisRight.isDrawLimitLinesBehindDataEnabled())
|
||||
mAxisRendererRight.renderLimitLines(canvas);
|
||||
|
||||
// make sure the data cannot be drawn outside the content-rect
|
||||
int clipRestoreCount = canvas.save();
|
||||
canvas.clipRect(mViewPortHandler.getContentRect());
|
||||
|
||||
if (isClipDataToContentEnabled()) {
|
||||
// make sure the data cannot be drawn outside the content-rect
|
||||
canvas.clipRect(mViewPortHandler.getContentRect());
|
||||
}
|
||||
|
||||
mRenderer.drawData(canvas);
|
||||
|
||||
|
@ -394,66 +399,70 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
|
|||
offsets.top = 0.f;
|
||||
offsets.bottom = 0.f;
|
||||
|
||||
// setup offsets for legend
|
||||
if (mLegend != null && mLegend.isEnabled() && !mLegend.isDrawInsideEnabled()) {
|
||||
switch (mLegend.getOrientation()) {
|
||||
case VERTICAL:
|
||||
if (mLegend == null || !mLegend.isEnabled() || mLegend.isDrawInsideEnabled())
|
||||
return;
|
||||
|
||||
switch (mLegend.getHorizontalAlignment()) {
|
||||
case LEFT:
|
||||
offsets.left += Math.min(mLegend.mNeededWidth,
|
||||
mViewPortHandler.getChartWidth() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getXOffset();
|
||||
break;
|
||||
switch (mLegend.getOrientation()) {
|
||||
case VERTICAL:
|
||||
|
||||
case RIGHT:
|
||||
offsets.right += Math.min(mLegend.mNeededWidth,
|
||||
mViewPortHandler.getChartWidth() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getXOffset();
|
||||
break;
|
||||
switch (mLegend.getHorizontalAlignment()) {
|
||||
case LEFT:
|
||||
offsets.left += Math.min(mLegend.mNeededWidth,
|
||||
mViewPortHandler.getChartWidth() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getXOffset();
|
||||
break;
|
||||
|
||||
case CENTER:
|
||||
case RIGHT:
|
||||
offsets.right += Math.min(mLegend.mNeededWidth,
|
||||
mViewPortHandler.getChartWidth() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getXOffset();
|
||||
break;
|
||||
|
||||
switch (mLegend.getVerticalAlignment()) {
|
||||
case TOP:
|
||||
offsets.top += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
break;
|
||||
case CENTER:
|
||||
|
||||
case BOTTOM:
|
||||
offsets.bottom += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
break;
|
||||
switch (mLegend.getVerticalAlignment()) {
|
||||
case TOP:
|
||||
offsets.top += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
case BOTTOM:
|
||||
offsets.bottom += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
break;
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case HORIZONTAL:
|
||||
break;
|
||||
|
||||
switch (mLegend.getVerticalAlignment()) {
|
||||
case TOP:
|
||||
offsets.top += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
break;
|
||||
case HORIZONTAL:
|
||||
|
||||
case BOTTOM:
|
||||
offsets.bottom += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
break;
|
||||
switch (mLegend.getVerticalAlignment()) {
|
||||
case TOP:
|
||||
offsets.top += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BOTTOM:
|
||||
offsets.bottom += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -708,20 +717,14 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
|
|||
public void zoomAndCenterAnimated(float scaleX, float scaleY, float xValue, float yValue, AxisDependency axis,
|
||||
long duration) {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
MPPointD origin = getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop(), axis);
|
||||
|
||||
MPPointD origin = getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop(), axis);
|
||||
Runnable job = AnimatedZoomJob.getInstance(mViewPortHandler, this, getTransformer(axis), getAxis(axis), mXAxis
|
||||
.mAxisRange, scaleX, scaleY, mViewPortHandler.getScaleX(), mViewPortHandler.getScaleY(),
|
||||
xValue, yValue, (float) origin.x, (float) origin.y, duration);
|
||||
addViewportJob(job);
|
||||
|
||||
Runnable job = AnimatedZoomJob.getInstance(mViewPortHandler, this, getTransformer(axis), getAxis(axis), mXAxis
|
||||
.mAxisRange, scaleX, scaleY, mViewPortHandler.getScaleX(), mViewPortHandler.getScaleY(),
|
||||
xValue, yValue, (float) origin.x, (float) origin.y, duration);
|
||||
addViewportJob(job);
|
||||
|
||||
MPPointD.recycleInstance(origin);
|
||||
|
||||
} else {
|
||||
Log.e(LOG_TAG, "Unable to execute zoomAndCenterAnimated(...) on API level < 11");
|
||||
}
|
||||
MPPointD.recycleInstance(origin);
|
||||
}
|
||||
|
||||
protected Matrix mFitScreenMatrixBuffer = new Matrix();
|
||||
|
@ -874,21 +877,16 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
|
|||
@TargetApi(11)
|
||||
public void moveViewToAnimated(float xValue, float yValue, AxisDependency axis, long duration) {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
MPPointD bounds = getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop(), axis);
|
||||
|
||||
MPPointD bounds = getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop(), axis);
|
||||
float yInView = getAxisRange(axis) / mViewPortHandler.getScaleY();
|
||||
|
||||
float yInView = getAxisRange(axis) / mViewPortHandler.getScaleY();
|
||||
Runnable job = AnimatedMoveViewJob.getInstance(mViewPortHandler, xValue, yValue + yInView / 2f,
|
||||
getTransformer(axis), this, (float) bounds.x, (float) bounds.y, duration);
|
||||
|
||||
Runnable job = AnimatedMoveViewJob.getInstance(mViewPortHandler, xValue, yValue + yInView / 2f,
|
||||
getTransformer(axis), this, (float) bounds.x, (float) bounds.y, duration);
|
||||
addViewportJob(job);
|
||||
|
||||
addViewportJob(job);
|
||||
|
||||
MPPointD.recycleInstance(bounds);
|
||||
} else {
|
||||
Log.e(LOG_TAG, "Unable to execute moveViewToAnimated(...) on API level < 11");
|
||||
}
|
||||
MPPointD.recycleInstance(bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -941,23 +939,18 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
|
|||
@TargetApi(11)
|
||||
public void centerViewToAnimated(float xValue, float yValue, AxisDependency axis, long duration) {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
MPPointD bounds = getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop(), axis);
|
||||
|
||||
MPPointD bounds = getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop(), axis);
|
||||
float yInView = getAxisRange(axis) / mViewPortHandler.getScaleY();
|
||||
float xInView = getXAxis().mAxisRange / mViewPortHandler.getScaleX();
|
||||
|
||||
float yInView = getAxisRange(axis) / mViewPortHandler.getScaleY();
|
||||
float xInView = getXAxis().mAxisRange / mViewPortHandler.getScaleX();
|
||||
Runnable job = AnimatedMoveViewJob.getInstance(mViewPortHandler,
|
||||
xValue - xInView / 2f, yValue + yInView / 2f,
|
||||
getTransformer(axis), this, (float) bounds.x, (float) bounds.y, duration);
|
||||
|
||||
Runnable job = AnimatedMoveViewJob.getInstance(mViewPortHandler,
|
||||
xValue - xInView / 2f, yValue + yInView / 2f,
|
||||
getTransformer(axis), this, (float) bounds.x, (float) bounds.y, duration);
|
||||
addViewportJob(job);
|
||||
|
||||
addViewportJob(job);
|
||||
|
||||
MPPointD.recycleInstance(bounds);
|
||||
} else {
|
||||
Log.e(LOG_TAG, "Unable to execute centerViewToAnimated(...) on API level < 11");
|
||||
}
|
||||
MPPointD.recycleInstance(bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1240,6 +1233,17 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
|
|||
mClipValuesToContent = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* When disabled, the data and/or highlights will not be clipped to contentRect. Disabling this option can
|
||||
* be useful, when the data lies fully within the content rect, but is drawn in such a way (such as thick lines)
|
||||
* that there is unwanted clipping.
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void setClipDataToContent(boolean enabled) {
|
||||
mClipDataToContent = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* When enabled, the values will be clipped to contentRect,
|
||||
* otherwise they can bleed outside the content rect.
|
||||
|
@ -1250,6 +1254,17 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
|
|||
return mClipValuesToContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* When disabled, the data and/or highlights will not be clipped to contentRect. Disabling this option can
|
||||
* be useful, when the data lies fully within the content rect, but is drawn in such a way (such as thick lines)
|
||||
* that there is unwanted clipping.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isClipDataToContentEnabled() {
|
||||
return mClipDataToContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the width of the border lines in dp.
|
||||
*
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.charts;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
|
@ -14,7 +13,6 @@ import android.graphics.Paint.Align;
|
|||
import android.graphics.RectF;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore.Images;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
@ -26,7 +24,6 @@ import android.view.ViewGroup;
|
|||
import android.view.ViewParent;
|
||||
|
||||
import com.github.mikephil.charting.animation.ChartAnimator;
|
||||
import com.github.mikephil.charting.animation.Easing;
|
||||
import com.github.mikephil.charting.animation.Easing.EasingFunction;
|
||||
import com.github.mikephil.charting.components.Description;
|
||||
import com.github.mikephil.charting.components.IMarker;
|
||||
|
@ -35,7 +32,7 @@ import com.github.mikephil.charting.components.XAxis;
|
|||
import com.github.mikephil.charting.data.ChartData;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.DefaultValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.ChartHighlighter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.highlight.IHighlighter;
|
||||
|
@ -55,6 +52,8 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Baseclass of all Chart-Views.
|
||||
|
@ -209,18 +208,14 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
setWillNotDraw(false);
|
||||
// setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
mAnimator = new ChartAnimator();
|
||||
} else {
|
||||
mAnimator = new ChartAnimator(new AnimatorUpdateListener() {
|
||||
mAnimator = new ChartAnimator(new AnimatorUpdateListener() {
|
||||
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
// ViewCompat.postInvalidateOnAnimation(Chart.this);
|
||||
postInvalidate();
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
// ViewCompat.postInvalidateOnAnimation(Chart.this);
|
||||
postInvalidate();
|
||||
}
|
||||
});
|
||||
|
||||
// initialize the utils
|
||||
Utils.init(getContext());
|
||||
|
@ -403,8 +398,23 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
boolean hasText = !TextUtils.isEmpty(mNoDataText);
|
||||
|
||||
if (hasText) {
|
||||
MPPointF c = getCenter();
|
||||
canvas.drawText(mNoDataText, c.x, c.y, mInfoPaint);
|
||||
MPPointF pt = getCenter();
|
||||
|
||||
switch (mInfoPaint.getTextAlign()) {
|
||||
case LEFT:
|
||||
pt.x = 0;
|
||||
canvas.drawText(mNoDataText, pt.x, pt.y, mInfoPaint);
|
||||
break;
|
||||
|
||||
case RIGHT:
|
||||
pt.x *= 2.0;
|
||||
canvas.drawText(mNoDataText, pt.x, pt.y, mInfoPaint);
|
||||
break;
|
||||
|
||||
default:
|
||||
canvas.drawText(mNoDataText, pt.x, pt.y, mInfoPaint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -553,6 +563,24 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
invalidate();
|
||||
}
|
||||
|
||||
public void highlightValues(List<Highlight> highs, List<IMarker> markers) {
|
||||
if (highs.size() != markers.size()) throw new IllegalArgumentException("Markers and highs must be mutually corresponding. High size = " + highs.size() + " Markers size = " + markers.size());
|
||||
setMarkers(markers);
|
||||
highlightValues(highs.toArray(new Highlight[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights any y-value at the given x-value in the given DataSet.
|
||||
* Provide -1 as the dataSetIndex to undo all highlighting.
|
||||
* This method will call the listener.
|
||||
* @param x The x-value to highlight
|
||||
* @param dataSetIndex The dataset index to search in
|
||||
* @param dataIndex The data index to search in (only used in CombinedChartView currently)
|
||||
*/
|
||||
public void highlightValue(float x, int dataSetIndex, int dataIndex) {
|
||||
highlightValue(x, dataSetIndex, dataIndex, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights any y-value at the given x-value in the given DataSet.
|
||||
* Provide -1 as the dataSetIndex to undo all highlighting.
|
||||
|
@ -561,7 +589,20 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
* @param dataSetIndex The dataset index to search in
|
||||
*/
|
||||
public void highlightValue(float x, int dataSetIndex) {
|
||||
highlightValue(x, dataSetIndex, true);
|
||||
highlightValue(x, dataSetIndex, -1, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights the value at the given x-value and y-value in the given DataSet.
|
||||
* Provide -1 as the dataSetIndex to undo all highlighting.
|
||||
* This method will call the listener.
|
||||
* @param x The x-value to highlight
|
||||
* @param y The y-value to highlight. Supply `NaN` for "any"
|
||||
* @param dataSetIndex The dataset index to search in
|
||||
* @param dataIndex The data index to search in (only used in CombinedChartView currently)
|
||||
*/
|
||||
public void highlightValue(float x, float y, int dataSetIndex, int dataIndex) {
|
||||
highlightValue(x, y, dataSetIndex, dataIndex, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -573,7 +614,19 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
* @param dataSetIndex The dataset index to search in
|
||||
*/
|
||||
public void highlightValue(float x, float y, int dataSetIndex) {
|
||||
highlightValue(x, y, dataSetIndex, true);
|
||||
highlightValue(x, y, dataSetIndex, -1, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights any y-value at the given x-value in the given DataSet.
|
||||
* Provide -1 as the dataSetIndex to undo all highlighting.
|
||||
* @param x The x-value to highlight
|
||||
* @param dataSetIndex The dataset index to search in
|
||||
* @param dataIndex The data index to search in (only used in CombinedChartView currently)
|
||||
* @param callListener Should the listener be called for this change
|
||||
*/
|
||||
public void highlightValue(float x, int dataSetIndex, int dataIndex, boolean callListener) {
|
||||
highlightValue(x, Float.NaN, dataSetIndex, dataIndex, callListener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -584,7 +637,25 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
* @param callListener Should the listener be called for this change
|
||||
*/
|
||||
public void highlightValue(float x, int dataSetIndex, boolean callListener) {
|
||||
highlightValue(x, Float.NaN, dataSetIndex, callListener);
|
||||
highlightValue(x, Float.NaN, dataSetIndex, -1, callListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights any y-value at the given x-value in the given DataSet.
|
||||
* Provide -1 as the dataSetIndex to undo all highlighting.
|
||||
* @param x The x-value to highlight
|
||||
* @param y The y-value to highlight. Supply `NaN` for "any"
|
||||
* @param dataSetIndex The dataset index to search in
|
||||
* @param dataIndex The data index to search in (only used in CombinedChartView currently)
|
||||
* @param callListener Should the listener be called for this change
|
||||
*/
|
||||
public void highlightValue(float x, float y, int dataSetIndex, int dataIndex, boolean callListener) {
|
||||
|
||||
if (dataSetIndex < 0 || dataSetIndex >= mData.getDataSetCount()) {
|
||||
highlightValue(null, callListener);
|
||||
} else {
|
||||
highlightValue(new Highlight(x, y, dataSetIndex, dataIndex), callListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -596,12 +667,7 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
* @param callListener Should the listener be called for this change
|
||||
*/
|
||||
public void highlightValue(float x, float y, int dataSetIndex, boolean callListener) {
|
||||
|
||||
if (dataSetIndex < 0 || dataSetIndex >= mData.getDataSetCount()) {
|
||||
highlightValue(null, callListener);
|
||||
} else {
|
||||
highlightValue(new Highlight(x, y, dataSetIndex), callListener);
|
||||
}
|
||||
highlightValue(x, y, dataSetIndex, -1, callListener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -712,7 +778,7 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
/**
|
||||
* the view that represents the marker
|
||||
*/
|
||||
protected IMarker mMarker;
|
||||
protected List<IMarker> mMarkers;
|
||||
|
||||
/**
|
||||
* draws all MarkerViews on the highlighted positions
|
||||
|
@ -720,7 +786,7 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
protected void drawMarkers(Canvas canvas) {
|
||||
|
||||
// if there is no marker view or drawing marker is disabled
|
||||
if (mMarker == null || !isDrawMarkersEnabled() || !valuesToHighlight())
|
||||
if (mMarkers == null || !isDrawMarkersEnabled() || !valuesToHighlight())
|
||||
return;
|
||||
|
||||
for (int i = 0; i < mIndicesToHighlight.length; i++) {
|
||||
|
@ -743,10 +809,12 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
continue;
|
||||
|
||||
// callbacks to update the content
|
||||
mMarker.refreshContent(e, highlight);
|
||||
int markerIndex = i % mMarkers.size();
|
||||
IMarker markerItem = mMarkers.get(markerIndex);
|
||||
markerItem.refreshContent(e, highlight);
|
||||
|
||||
// draw the marker
|
||||
mMarker.draw(canvas, pos[0], pos[1]);
|
||||
markerItem.draw(canvas, pos[0], pos[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -892,60 +960,6 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
*/
|
||||
/** CODE BELOW FOR PREDEFINED EASING OPTIONS */
|
||||
|
||||
/**
|
||||
* Animates the drawing / rendering of the chart on both x- and y-axis with
|
||||
* the specified animation time. If animate(...) is called, no further
|
||||
* calling of invalidate() is necessary to refresh the chart. ANIMATIONS
|
||||
* ONLY WORK FOR API LEVEL 11 (Android 3.0.x) AND HIGHER.
|
||||
*
|
||||
* @param durationMillisX
|
||||
* @param durationMillisY
|
||||
* @param easingX a predefined easing option
|
||||
* @param easingY a predefined easing option
|
||||
*
|
||||
* @deprecated Use {@link #animateXY(int, int, EasingFunction, EasingFunction)}
|
||||
* @see #animateXY(int, int, EasingFunction, EasingFunction)
|
||||
*/
|
||||
@Deprecated
|
||||
public void animateXY(int durationMillisX, int durationMillisY, Easing.EasingOption easingX,
|
||||
Easing.EasingOption easingY) {
|
||||
mAnimator.animateXY(durationMillisX, durationMillisY, easingX, easingY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the rendering of the chart on the x-axis with the specified
|
||||
* animation time. If animate(...) is called, no further calling of
|
||||
* invalidate() is necessary to refresh the chart. ANIMATIONS ONLY WORK FOR
|
||||
* API LEVEL 11 (Android 3.0.x) AND HIGHER.
|
||||
*
|
||||
* @param durationMillis
|
||||
* @param easing a predefined easing option
|
||||
*
|
||||
* @deprecated Use {@link #animateX(int, EasingFunction)}
|
||||
* @see #animateX(int, EasingFunction)
|
||||
*/
|
||||
@Deprecated
|
||||
public void animateX(int durationMillis, Easing.EasingOption easing) {
|
||||
mAnimator.animateX(durationMillis, easing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the rendering of the chart on the y-axis with the specified
|
||||
* animation time. If animate(...) is called, no further calling of
|
||||
* invalidate() is necessary to refresh the chart. ANIMATIONS ONLY WORK FOR
|
||||
* API LEVEL 11 (Android 3.0.x) AND HIGHER.
|
||||
*
|
||||
* @param durationMillis
|
||||
* @param easing a predefined easing option
|
||||
*
|
||||
* @deprecated Use {@link #animateY(int, EasingFunction)}
|
||||
* @see #animateY(int, EasingFunction)
|
||||
*/
|
||||
@Deprecated
|
||||
public void animateY(int durationMillis, Easing.EasingOption easing) {
|
||||
mAnimator.animateY(durationMillis, easing);
|
||||
}
|
||||
|
||||
/**
|
||||
* ################ ################ ################ ################
|
||||
* ANIMATIONS ONLY WORK FOR API LEVEL 11 (Android 3.0.x) AND HIGHER.
|
||||
|
@ -1015,7 +1029,7 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
public IValueFormatter getDefaultValueFormatter() {
|
||||
public ValueFormatter getDefaultValueFormatter() {
|
||||
return mDefaultValueFormatter;
|
||||
}
|
||||
|
||||
|
@ -1221,6 +1235,15 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
mInfoPaint.setTypeface(tf);
|
||||
}
|
||||
|
||||
/**
|
||||
* alignment of the no data text
|
||||
*
|
||||
* @param align
|
||||
*/
|
||||
public void setNoDataTextAlignment(Align align) {
|
||||
mInfoPaint.setTextAlign(align);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this to false to disable all gestures and touches on the chart,
|
||||
* default: true
|
||||
|
@ -1231,22 +1254,25 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
this.mTouchEnabled = enabled;
|
||||
}
|
||||
|
||||
public void setMarkers(List<IMarker> marker) {
|
||||
mMarkers = marker;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the marker that is displayed when a value is clicked on the chart
|
||||
*
|
||||
* @param marker
|
||||
*/
|
||||
public void setMarker(IMarker marker) {
|
||||
mMarker = marker;
|
||||
setMarkers(Collections.unmodifiableList(Collections.singletonList(marker)));
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the marker that is set as a marker view for the chart
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IMarker getMarker() {
|
||||
return mMarker;
|
||||
public List<IMarker> getMarker() {
|
||||
return mMarkers;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
@ -1255,7 +1281,7 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
}
|
||||
|
||||
@Deprecated
|
||||
public IMarker getMarkerView() {
|
||||
public List<IMarker> getMarkerView() {
|
||||
return getMarker();
|
||||
}
|
||||
|
||||
|
@ -1752,16 +1778,10 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
*/
|
||||
public void setHardwareAccelerationEnabled(boolean enabled) {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
|
||||
if (enabled)
|
||||
setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
else
|
||||
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
} else {
|
||||
Log.e(LOG_TAG,
|
||||
"Cannot enable/disable hardware acceleration for devices below API level 11.");
|
||||
}
|
||||
if (enabled)
|
||||
setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
else
|
||||
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.graphics.Canvas;
|
|||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import com.github.mikephil.charting.components.IMarker;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BubbleData;
|
||||
import com.github.mikephil.charting.data.CandleData;
|
||||
|
@ -236,7 +237,7 @@ public class CombinedChart extends BarLineChartBase<CombinedData> implements Com
|
|||
protected void drawMarkers(Canvas canvas) {
|
||||
|
||||
// if there is no marker view or drawing marker is disabled
|
||||
if (mMarker == null || !isDrawMarkersEnabled() || !valuesToHighlight())
|
||||
if (mMarkers == null || !isDrawMarkersEnabled() || !valuesToHighlight())
|
||||
return;
|
||||
|
||||
for (int i = 0; i < mIndicesToHighlight.length; i++) {
|
||||
|
@ -262,10 +263,11 @@ public class CombinedChart extends BarLineChartBase<CombinedData> implements Com
|
|||
continue;
|
||||
|
||||
// callbacks to update the content
|
||||
mMarker.refreshContent(e, highlight);
|
||||
IMarker markerItem = mMarkers.get(i % mMarkers.size());
|
||||
markerItem.refreshContent(e, highlight);
|
||||
|
||||
// draw the marker
|
||||
mMarker.draw(canvas, pos[0], pos[1]);
|
||||
markerItem.draw(canvas, pos[0], pos[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,84 @@ public class HorizontalBarChart extends BarChart {
|
|||
|
||||
private RectF mOffsetsBuffer = new RectF();
|
||||
|
||||
protected void calculateLegendOffsets(RectF offsets) {
|
||||
|
||||
offsets.left = 0.f;
|
||||
offsets.right = 0.f;
|
||||
offsets.top = 0.f;
|
||||
offsets.bottom = 0.f;
|
||||
|
||||
if (mLegend == null || !mLegend.isEnabled() || mLegend.isDrawInsideEnabled())
|
||||
return;
|
||||
|
||||
switch (mLegend.getOrientation()) {
|
||||
case VERTICAL:
|
||||
|
||||
switch (mLegend.getHorizontalAlignment()) {
|
||||
case LEFT:
|
||||
offsets.left += Math.min(mLegend.mNeededWidth,
|
||||
mViewPortHandler.getChartWidth() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getXOffset();
|
||||
break;
|
||||
|
||||
case RIGHT:
|
||||
offsets.right += Math.min(mLegend.mNeededWidth,
|
||||
mViewPortHandler.getChartWidth() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getXOffset();
|
||||
break;
|
||||
|
||||
case CENTER:
|
||||
|
||||
switch (mLegend.getVerticalAlignment()) {
|
||||
case TOP:
|
||||
offsets.top += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
break;
|
||||
|
||||
case BOTTOM:
|
||||
offsets.bottom += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case HORIZONTAL:
|
||||
|
||||
switch (mLegend.getVerticalAlignment()) {
|
||||
case TOP:
|
||||
offsets.top += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
|
||||
if (mAxisLeft.isEnabled() && mAxisLeft.isDrawLabelsEnabled())
|
||||
offsets.top += mAxisLeft.getRequiredHeightSpace(
|
||||
mAxisRendererLeft.getPaintAxisLabels());
|
||||
break;
|
||||
|
||||
case BOTTOM:
|
||||
offsets.bottom += Math.min(mLegend.mNeededHeight,
|
||||
mViewPortHandler.getChartHeight() * mLegend.getMaxSizePercent())
|
||||
+ mLegend.getYOffset();
|
||||
|
||||
if (mAxisRight.isEnabled() && mAxisRight.isDrawLabelsEnabled())
|
||||
offsets.bottom += mAxisRight.getRequiredHeightSpace(
|
||||
mAxisRendererRight.getPaintAxisLabels());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculateOffsets() {
|
||||
|
||||
|
|
|
@ -94,6 +94,12 @@ public class PieChart extends PieRadarChartBase<PieData> {
|
|||
|
||||
protected float mMaxAngle = 360f;
|
||||
|
||||
/**
|
||||
* Minimum angle to draw slices, this only works if there is enough room for all slices to have
|
||||
* the minimum angle, default 0f.
|
||||
*/
|
||||
private float mMinAngleForSlices = 0f;
|
||||
|
||||
public PieChart(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
@ -228,7 +234,12 @@ public class PieChart extends PieRadarChartBase<PieData> {
|
|||
|
||||
List<IPieDataSet> dataSets = mData.getDataSets();
|
||||
|
||||
boolean hasMinAngle = mMinAngleForSlices != 0f && entryCount * mMinAngleForSlices <= mMaxAngle;
|
||||
float[] minAngles = new float[entryCount];
|
||||
|
||||
int cnt = 0;
|
||||
float offset = 0f;
|
||||
float diff = 0f;
|
||||
|
||||
for (int i = 0; i < mData.getDataSetCount(); i++) {
|
||||
|
||||
|
@ -236,7 +247,20 @@ public class PieChart extends PieRadarChartBase<PieData> {
|
|||
|
||||
for (int j = 0; j < set.getEntryCount(); j++) {
|
||||
|
||||
mDrawAngles[cnt] = calcAngle(Math.abs(set.getEntryForIndex(j).getY()), yValueSum);
|
||||
float drawAngle = calcAngle(Math.abs(set.getEntryForIndex(j).getY()), yValueSum);
|
||||
|
||||
if (hasMinAngle) {
|
||||
float temp = drawAngle - mMinAngleForSlices;
|
||||
if (temp <= 0) {
|
||||
minAngles[cnt] = mMinAngleForSlices;
|
||||
offset += -temp;
|
||||
} else {
|
||||
minAngles[cnt] = drawAngle;
|
||||
diff += temp;
|
||||
}
|
||||
}
|
||||
|
||||
mDrawAngles[cnt] = drawAngle;
|
||||
|
||||
if (cnt == 0) {
|
||||
mAbsoluteAngles[cnt] = mDrawAngles[cnt];
|
||||
|
@ -248,6 +272,20 @@ public class PieChart extends PieRadarChartBase<PieData> {
|
|||
}
|
||||
}
|
||||
|
||||
if (hasMinAngle) {
|
||||
// Correct bigger slices by relatively reducing their angles based on the total angle needed to subtract
|
||||
// This requires that `entryCount * mMinAngleForSlices <= mMaxAngle` be true to properly work!
|
||||
for (int i = 0; i < entryCount; i++) {
|
||||
minAngles[i] -= (minAngles[i] - mMinAngleForSlices) / diff * offset;
|
||||
if (i == 0) {
|
||||
mAbsoluteAngles[0] = minAngles[0];
|
||||
} else {
|
||||
mAbsoluteAngles[i] = mAbsoluteAngles[i - 1] + minAngles[i];
|
||||
}
|
||||
}
|
||||
|
||||
mDrawAngles = minAngles;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -650,6 +688,16 @@ public class PieChart extends PieRadarChartBase<PieData> {
|
|||
((PieChartRenderer) mRenderer).getPaintEntryLabels().setTextSize(Utils.convertDpToPixel(size));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to draw slices in a curved fashion, only works if drawing the hole is enabled
|
||||
* and if the slices are not drawn under the hole.
|
||||
*
|
||||
* @param enabled draw curved ends of slices
|
||||
*/
|
||||
public void setDrawRoundedSlices(boolean enabled) {
|
||||
mDrawRoundedSlices = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the chart is set to draw each end of a pie-slice
|
||||
* "rounded".
|
||||
|
@ -719,6 +767,32 @@ public class PieChart extends PieRadarChartBase<PieData> {
|
|||
this.mMaxAngle = maxangle;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum angle slices on the chart are rendered with, default is 0f.
|
||||
*
|
||||
* @return minimum angle for slices
|
||||
*/
|
||||
public float getMinAngleForSlices() {
|
||||
return mMinAngleForSlices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the angle to set minimum size for slices, you must call {@link #notifyDataSetChanged()}
|
||||
* and {@link #invalidate()} when changing this, only works if there is enough room for all
|
||||
* slices to have the minimum angle.
|
||||
*
|
||||
* @param minAngle minimum 0, maximum is half of {@link #setMaxAngle(float)}
|
||||
*/
|
||||
public void setMinAngleForSlices(float minAngle) {
|
||||
|
||||
if (minAngle > (mMaxAngle / 2f))
|
||||
minAngle = mMaxAngle / 2f;
|
||||
else if (minAngle < 0)
|
||||
minAngle = 0f;
|
||||
|
||||
this.mMinAngleForSlices = minAngle;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
// releases the bitmap in the renderer to avoid oom error
|
||||
|
|
|
@ -480,9 +480,6 @@ public abstract class PieRadarChartBase<T extends ChartData<? extends IDataSet<?
|
|||
@SuppressLint("NewApi")
|
||||
public void spin(int durationmillis, float fromangle, float toangle, EasingFunction easing) {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < 11)
|
||||
return;
|
||||
|
||||
setRotationAngle(fromangle);
|
||||
|
||||
ObjectAnimator spinAnimator = ObjectAnimator.ofFloat(this, "rotationAngle", fromangle,
|
||||
|
|
|
@ -84,6 +84,7 @@ public class RadarChart extends PieRadarChartBase<RadarData> {
|
|||
super.init();
|
||||
|
||||
mYAxis = new YAxis(AxisDependency.LEFT);
|
||||
mYAxis.setLabelXOffset(10f);
|
||||
|
||||
mWebLineWidth = Utils.convertDpToPixel(1.5f);
|
||||
mInnerWebLineWidth = Utils.convertDpToPixel(0.75f);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.components;
|
||||
|
||||
import android.graphics.Color;
|
||||
|
@ -6,7 +5,7 @@ import android.graphics.DashPathEffect;
|
|||
import android.util.Log;
|
||||
|
||||
import com.github.mikephil.charting.formatter.DefaultAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -22,7 +21,7 @@ public abstract class AxisBase extends ComponentBase {
|
|||
/**
|
||||
* custom formatter that is used instead of the auto-formatter if set
|
||||
*/
|
||||
protected IAxisValueFormatter mAxisValueFormatter;
|
||||
protected ValueFormatter mAxisValueFormatter;
|
||||
|
||||
private int mGridColor = Color.GRAY;
|
||||
|
||||
|
@ -152,6 +151,39 @@ public abstract class AxisBase extends ComponentBase {
|
|||
*/
|
||||
public float mAxisRange = 0f;
|
||||
|
||||
private int mAxisMinLabels = 2;
|
||||
private int mAxisMaxLabels = 25;
|
||||
|
||||
/**
|
||||
* The minumum number of labels on the axis
|
||||
*/
|
||||
public int getAxisMinLabels() {
|
||||
return mAxisMinLabels;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minumum number of labels on the axis
|
||||
*/
|
||||
public void setAxisMinLabels(int labels) {
|
||||
if (labels > 0)
|
||||
mAxisMinLabels = labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of labels on the axis
|
||||
*/
|
||||
public int getAxisMaxLabels() {
|
||||
return mAxisMaxLabels;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of labels on the axis
|
||||
*/
|
||||
public void setAxisMaxLabels(int labels) {
|
||||
if (labels > 0)
|
||||
mAxisMaxLabels = labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
|
@ -315,10 +347,10 @@ public abstract class AxisBase extends ComponentBase {
|
|||
*/
|
||||
public void setLabelCount(int count) {
|
||||
|
||||
if (count > 25)
|
||||
count = 25;
|
||||
if (count < 2)
|
||||
count = 2;
|
||||
if (count > getAxisMaxLabels())
|
||||
count = getAxisMaxLabels();
|
||||
if (count < getAxisMinLabels())
|
||||
count = getAxisMinLabels();
|
||||
|
||||
mLabelCount = count;
|
||||
mForceLabels = false;
|
||||
|
@ -486,7 +518,7 @@ public abstract class AxisBase extends ComponentBase {
|
|||
if (index < 0 || index >= mEntries.length)
|
||||
return "";
|
||||
else
|
||||
return getValueFormatter().getFormattedValue(mEntries[index], this);
|
||||
return getValueFormatter().getAxisLabel(mEntries[index], this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -498,7 +530,7 @@ public abstract class AxisBase extends ComponentBase {
|
|||
*
|
||||
* @param f
|
||||
*/
|
||||
public void setValueFormatter(IAxisValueFormatter f) {
|
||||
public void setValueFormatter(ValueFormatter f) {
|
||||
|
||||
if (f == null)
|
||||
mAxisValueFormatter = new DefaultAxisValueFormatter(mDecimals);
|
||||
|
@ -511,7 +543,7 @@ public abstract class AxisBase extends ComponentBase {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
public IAxisValueFormatter getValueFormatter() {
|
||||
public ValueFormatter getValueFormatter() {
|
||||
|
||||
if (mAxisValueFormatter == null ||
|
||||
(mAxisValueFormatter instanceof DefaultAxisValueFormatter &&
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
|
||||
package com.github.mikephil.charting.components;
|
||||
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.Paint;
|
||||
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
import com.github.mikephil.charting.utils.FSize;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
@ -22,19 +20,6 @@ import java.util.List;
|
|||
*/
|
||||
public class Legend extends ComponentBase {
|
||||
|
||||
/**
|
||||
* This property is deprecated - Use `horizontalAlignment`, `verticalAlignment`, `orientation`, `drawInside`,
|
||||
* `direction`.
|
||||
*/
|
||||
@Deprecated
|
||||
public enum LegendPosition {
|
||||
RIGHT_OF_CHART, RIGHT_OF_CHART_CENTER, RIGHT_OF_CHART_INSIDE,
|
||||
LEFT_OF_CHART, LEFT_OF_CHART_CENTER, LEFT_OF_CHART_INSIDE,
|
||||
BELOW_CHART_LEFT, BELOW_CHART_RIGHT, BELOW_CHART_CENTER,
|
||||
ABOVE_CHART_LEFT, ABOVE_CHART_RIGHT, ABOVE_CHART_CENTER,
|
||||
PIECHART_CENTER
|
||||
}
|
||||
|
||||
public enum LegendForm {
|
||||
/**
|
||||
* Avoid drawing a form
|
||||
|
@ -182,43 +167,6 @@ public class Legend extends ComponentBase {
|
|||
this.mEntries = entries;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Legend(int[] colors, String[] labels) {
|
||||
this();
|
||||
|
||||
if (colors == null || labels == null) {
|
||||
throw new IllegalArgumentException("colors array or labels array is NULL");
|
||||
}
|
||||
|
||||
if (colors.length != labels.length) {
|
||||
throw new IllegalArgumentException(
|
||||
"colors array and labels array need to be of same size");
|
||||
}
|
||||
|
||||
List<LegendEntry> entries = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < Math.min(colors.length, labels.length); i++) {
|
||||
final LegendEntry entry = new LegendEntry();
|
||||
entry.formColor = colors[i];
|
||||
entry.label = labels[i];
|
||||
|
||||
if (entry.formColor == ColorTemplate.COLOR_SKIP)
|
||||
entry.form = LegendForm.NONE;
|
||||
else if (entry.formColor == ColorTemplate.COLOR_NONE ||
|
||||
entry.formColor == 0)
|
||||
entry.form = LegendForm.EMPTY;
|
||||
|
||||
entries.add(entry);
|
||||
}
|
||||
|
||||
mEntries = entries.toArray(new LegendEntry[entries.size()]);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Legend(List<Integer> colors, List<String> labels) {
|
||||
this(Utils.convertIntegers(colors), Utils.convertStrings(labels));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the automatically computed colors for the legend. Use setCustom(...) to set custom colors.
|
||||
*
|
||||
|
@ -287,50 +235,6 @@ public class Legend extends ComponentBase {
|
|||
return max;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int[] getColors() {
|
||||
|
||||
int[] old = new int[mEntries.length];
|
||||
for (int i = 0; i < mEntries.length; i++) {
|
||||
old[i] = mEntries[i].form == LegendForm.NONE ? ColorTemplate.COLOR_SKIP :
|
||||
(mEntries[i].form == LegendForm.EMPTY ? ColorTemplate.COLOR_NONE :
|
||||
mEntries[i].formColor);
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String[] getLabels() {
|
||||
|
||||
String[] old = new String[mEntries.length];
|
||||
for (int i = 0; i < mEntries.length; i++) {
|
||||
old[i] = mEntries[i].label;
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int[] getExtraColors() {
|
||||
|
||||
int[] old = new int[mExtraEntries.length];
|
||||
for (int i = 0; i < mExtraEntries.length; i++) {
|
||||
old[i] = mExtraEntries[i].form == LegendForm.NONE ? ColorTemplate.COLOR_SKIP :
|
||||
(mExtraEntries[i].form == LegendForm.EMPTY ? ColorTemplate.COLOR_NONE :
|
||||
mExtraEntries[i].formColor);
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String[] getExtraLabels() {
|
||||
|
||||
String[] old = new String[mExtraEntries.length];
|
||||
for (int i = 0; i < mExtraEntries.length; i++) {
|
||||
old[i] = mExtraEntries[i].label;
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
public LegendEntry[] getExtraEntries() {
|
||||
|
||||
return mExtraEntries;
|
||||
|
@ -346,11 +250,6 @@ public class Legend extends ComponentBase {
|
|||
mExtraEntries = entries;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setExtra(List<Integer> colors, List<String> labels) {
|
||||
setExtra(Utils.convertIntegers(colors), Utils.convertStrings(labels));
|
||||
}
|
||||
|
||||
/**
|
||||
* Entries that will be appended to the end of the auto calculated
|
||||
* entries after calculating the legend.
|
||||
|
@ -423,109 +322,6 @@ public class Legend extends ComponentBase {
|
|||
return mIsLegendCustom;
|
||||
}
|
||||
|
||||
/**
|
||||
* This property is deprecated - Use `horizontalAlignment`, `verticalAlignment`, `orientation`, `drawInside`,
|
||||
* `direction`.
|
||||
*/
|
||||
@Deprecated
|
||||
public LegendPosition getPosition() {
|
||||
|
||||
if (mOrientation == LegendOrientation.VERTICAL
|
||||
&& mHorizontalAlignment == LegendHorizontalAlignment.CENTER
|
||||
&& mVerticalAlignment == LegendVerticalAlignment.CENTER) {
|
||||
return LegendPosition.PIECHART_CENTER;
|
||||
} else if (mOrientation == LegendOrientation.HORIZONTAL) {
|
||||
if (mVerticalAlignment == LegendVerticalAlignment.TOP)
|
||||
return mHorizontalAlignment == LegendHorizontalAlignment.LEFT
|
||||
? LegendPosition.ABOVE_CHART_LEFT
|
||||
: (mHorizontalAlignment == LegendHorizontalAlignment.RIGHT
|
||||
? LegendPosition.ABOVE_CHART_RIGHT
|
||||
: LegendPosition.ABOVE_CHART_CENTER);
|
||||
else
|
||||
return mHorizontalAlignment == LegendHorizontalAlignment.LEFT
|
||||
? LegendPosition.BELOW_CHART_LEFT
|
||||
: (mHorizontalAlignment == LegendHorizontalAlignment.RIGHT
|
||||
? LegendPosition.BELOW_CHART_RIGHT
|
||||
: LegendPosition.BELOW_CHART_CENTER);
|
||||
} else {
|
||||
if (mHorizontalAlignment == LegendHorizontalAlignment.LEFT)
|
||||
return mVerticalAlignment == LegendVerticalAlignment.TOP && mDrawInside
|
||||
? LegendPosition.LEFT_OF_CHART_INSIDE
|
||||
: (mVerticalAlignment == LegendVerticalAlignment.CENTER
|
||||
? LegendPosition.LEFT_OF_CHART_CENTER
|
||||
: LegendPosition.LEFT_OF_CHART);
|
||||
else
|
||||
return mVerticalAlignment == LegendVerticalAlignment.TOP && mDrawInside
|
||||
? LegendPosition.RIGHT_OF_CHART_INSIDE
|
||||
: (mVerticalAlignment == LegendVerticalAlignment.CENTER
|
||||
? LegendPosition.RIGHT_OF_CHART_CENTER
|
||||
: LegendPosition.RIGHT_OF_CHART);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This property is deprecated - Use `horizontalAlignment`, `verticalAlignment`, `orientation`, `drawInside`,
|
||||
* `direction`.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setPosition(LegendPosition newValue) {
|
||||
|
||||
switch (newValue) {
|
||||
case LEFT_OF_CHART:
|
||||
case LEFT_OF_CHART_INSIDE:
|
||||
case LEFT_OF_CHART_CENTER:
|
||||
mHorizontalAlignment = LegendHorizontalAlignment.LEFT;
|
||||
mVerticalAlignment = newValue == LegendPosition.LEFT_OF_CHART_CENTER
|
||||
? LegendVerticalAlignment.CENTER
|
||||
: LegendVerticalAlignment.TOP;
|
||||
mOrientation = LegendOrientation.VERTICAL;
|
||||
break;
|
||||
|
||||
case RIGHT_OF_CHART:
|
||||
case RIGHT_OF_CHART_INSIDE:
|
||||
case RIGHT_OF_CHART_CENTER:
|
||||
mHorizontalAlignment = LegendHorizontalAlignment.RIGHT;
|
||||
mVerticalAlignment = newValue == LegendPosition.RIGHT_OF_CHART_CENTER
|
||||
? LegendVerticalAlignment.CENTER
|
||||
: LegendVerticalAlignment.TOP;
|
||||
mOrientation = LegendOrientation.VERTICAL;
|
||||
break;
|
||||
|
||||
case ABOVE_CHART_LEFT:
|
||||
case ABOVE_CHART_CENTER:
|
||||
case ABOVE_CHART_RIGHT:
|
||||
mHorizontalAlignment = newValue == LegendPosition.ABOVE_CHART_LEFT
|
||||
? LegendHorizontalAlignment.LEFT
|
||||
: (newValue == LegendPosition.ABOVE_CHART_RIGHT
|
||||
? LegendHorizontalAlignment.RIGHT
|
||||
: LegendHorizontalAlignment.CENTER);
|
||||
mVerticalAlignment = LegendVerticalAlignment.TOP;
|
||||
mOrientation = LegendOrientation.HORIZONTAL;
|
||||
break;
|
||||
|
||||
case BELOW_CHART_LEFT:
|
||||
case BELOW_CHART_CENTER:
|
||||
case BELOW_CHART_RIGHT:
|
||||
mHorizontalAlignment = newValue == LegendPosition.BELOW_CHART_LEFT
|
||||
? LegendHorizontalAlignment.LEFT
|
||||
: (newValue == LegendPosition.BELOW_CHART_RIGHT
|
||||
? LegendHorizontalAlignment.RIGHT
|
||||
: LegendHorizontalAlignment.CENTER);
|
||||
mVerticalAlignment = LegendVerticalAlignment.BOTTOM;
|
||||
mOrientation = LegendOrientation.HORIZONTAL;
|
||||
break;
|
||||
|
||||
case PIECHART_CENTER:
|
||||
mHorizontalAlignment = LegendHorizontalAlignment.CENTER;
|
||||
mVerticalAlignment = LegendVerticalAlignment.CENTER;
|
||||
mOrientation = LegendOrientation.VERTICAL;
|
||||
break;
|
||||
}
|
||||
|
||||
mDrawInside = newValue == LegendPosition.LEFT_OF_CHART_INSIDE
|
||||
|| newValue == LegendPosition.RIGHT_OF_CHART_INSIDE;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the horizontal alignment of the legend
|
||||
*
|
||||
|
@ -907,8 +703,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
width += Utils.calcTextWidth(labelpaint, label);
|
||||
|
||||
if (i < entryCount - 1)
|
||||
maxHeight += labelLineHeight + yEntrySpace;
|
||||
maxHeight += labelLineHeight + yEntrySpace;
|
||||
} else {
|
||||
wasStacked = true;
|
||||
width += formSize;
|
||||
|
|
|
@ -73,6 +73,11 @@ public class YAxis extends AxisBase {
|
|||
*/
|
||||
private YAxisLabelPosition mPosition = YAxisLabelPosition.OUTSIDE_CHART;
|
||||
|
||||
/**
|
||||
* the horizontal offset of the y-label
|
||||
*/
|
||||
private float mXLabelOffset = 0.0f;
|
||||
|
||||
/**
|
||||
* enum for the position of the y-labels relative to the chart
|
||||
*/
|
||||
|
@ -174,6 +179,22 @@ public class YAxis extends AxisBase {
|
|||
mPosition = pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the horizontal offset of the y-label
|
||||
*/
|
||||
public float getLabelXOffset() {
|
||||
return mXLabelOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the horizontal offset of the y-label
|
||||
*
|
||||
* @param xOffset
|
||||
*/
|
||||
public void setLabelXOffset(float xOffset) {
|
||||
mXLabelOffset = xOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if drawing the top y-axis label entry is enabled
|
||||
*
|
||||
|
@ -406,6 +427,26 @@ public class YAxis extends AxisBase {
|
|||
float min = dataMin;
|
||||
float max = dataMax;
|
||||
|
||||
// Make sure max is greater than min
|
||||
// Discussion: https://github.com/danielgindi/Charts/pull/3650#discussion_r221409991
|
||||
if (min > max)
|
||||
{
|
||||
if (mCustomAxisMax && mCustomAxisMin)
|
||||
{
|
||||
float t = min;
|
||||
min = max;
|
||||
max = t;
|
||||
}
|
||||
else if (mCustomAxisMax)
|
||||
{
|
||||
min = max < 0f ? max * 1.5f : max * 0.5f;
|
||||
}
|
||||
else if (mCustomAxisMin)
|
||||
{
|
||||
max = min < 0f ? min * 0.5f : min * 1.5f;
|
||||
}
|
||||
}
|
||||
|
||||
float range = Math.abs(max - min);
|
||||
|
||||
// in case all values are equal
|
||||
|
|
|
@ -4,6 +4,7 @@ package com.github.mikephil.charting.data;
|
|||
import android.graphics.Color;
|
||||
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.utils.Fill;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -38,9 +39,9 @@ public class BarDataSet extends BarLineScatterCandleBubbleDataSet<BarEntry> impl
|
|||
/**
|
||||
* array of labels used to describe the different values of the stacked bars
|
||||
*/
|
||||
private String[] mStackLabels = new String[]{
|
||||
"Stack"
|
||||
};
|
||||
private String[] mStackLabels = new String[]{};
|
||||
|
||||
protected List<Fill> mFills = null;
|
||||
|
||||
public BarDataSet(List<BarEntry> yVals, String label) {
|
||||
super(yVals, label);
|
||||
|
@ -54,8 +55,8 @@ public class BarDataSet extends BarLineScatterCandleBubbleDataSet<BarEntry> impl
|
|||
@Override
|
||||
public DataSet<BarEntry> copy() {
|
||||
List<BarEntry> entries = new ArrayList<BarEntry>();
|
||||
for (int i = 0; i < mValues.size(); i++) {
|
||||
entries.add(mValues.get(i).copy());
|
||||
for (int i = 0; i < mEntries.size(); i++) {
|
||||
entries.add(mEntries.get(i).copy());
|
||||
}
|
||||
BarDataSet copied = new BarDataSet(entries, getLabel());
|
||||
copy(copied);
|
||||
|
@ -71,6 +72,67 @@ public class BarDataSet extends BarLineScatterCandleBubbleDataSet<BarEntry> impl
|
|||
barDataSet.mHighLightAlpha = mHighLightAlpha;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Fill> getFills() {
|
||||
return mFills;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fill getFill(int index) {
|
||||
return mFills.get(index % mFills.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated.
|
||||
* Use getFills() instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public List<Fill> getGradients() {
|
||||
return mFills;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated.
|
||||
* Use getFill(...) instead.
|
||||
*
|
||||
* @param index
|
||||
*/
|
||||
@Deprecated
|
||||
public Fill getGradient(int index) {
|
||||
return getFill(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the start and end color for gradient color, ONLY color that should be used for this DataSet.
|
||||
*
|
||||
* @param startColor
|
||||
* @param endColor
|
||||
*/
|
||||
public void setGradientColor(int startColor, int endColor) {
|
||||
mFills.clear();
|
||||
mFills.add(new Fill(startColor, endColor));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated.
|
||||
* Use setFills(...) instead.
|
||||
*
|
||||
* @param gradientColors
|
||||
*/
|
||||
@Deprecated
|
||||
public void setGradientColors(List<Fill> gradientColors) {
|
||||
this.mFills = gradientColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fills for the bars in this dataset.
|
||||
*
|
||||
* @param fills
|
||||
*/
|
||||
public void setFills(List<Fill> fills) {
|
||||
this.mFills = fills;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total number of entries this DataSet represents, including
|
||||
* stacks. All values belonging to a stack are calculated separately.
|
||||
|
|
|
@ -7,9 +7,8 @@ import android.graphics.Typeface;
|
|||
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.model.GradientColor;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
@ -29,10 +28,6 @@ public abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
|
|||
*/
|
||||
protected List<Integer> mColors = null;
|
||||
|
||||
protected GradientColor mGradientColor = null;
|
||||
|
||||
protected List<GradientColor> mGradientColors = null;
|
||||
|
||||
/**
|
||||
* List representing all colors that are used for drawing the actual values for this DataSet
|
||||
*/
|
||||
|
@ -56,7 +51,7 @@ public abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
|
|||
/**
|
||||
* custom formatter that is used instead of the auto-formatter if set
|
||||
*/
|
||||
protected transient IValueFormatter mValueFormatter;
|
||||
protected transient ValueFormatter mValueFormatter;
|
||||
|
||||
/**
|
||||
* the typeface used for the value text
|
||||
|
@ -146,21 +141,6 @@ public abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
|
|||
return mColors.get(index % mColors.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public GradientColor getGradientColor() {
|
||||
return mGradientColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GradientColor> getGradientColors() {
|
||||
return mGradientColors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GradientColor getGradientColor(int index) {
|
||||
return mGradientColors.get(index % mGradientColors.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* ###### ###### COLOR SETTING RELATED METHODS ##### ######
|
||||
*/
|
||||
|
@ -236,25 +216,6 @@ public abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
|
|||
mColors.add(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the start and end color for gradient color, ONLY color that should be used for this DataSet.
|
||||
*
|
||||
* @param startColor
|
||||
* @param endColor
|
||||
*/
|
||||
public void setGradientColor(int startColor, int endColor) {
|
||||
mGradientColor = new GradientColor(startColor, endColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the start and end color for gradient colors, ONLY color that should be used for this DataSet.
|
||||
*
|
||||
* @param gradientColors
|
||||
*/
|
||||
public void setGradientColors(List<GradientColor> gradientColors) {
|
||||
this.mGradientColors = gradientColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a color with a specific alpha value.
|
||||
*
|
||||
|
@ -313,7 +274,7 @@ public abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setValueFormatter(IValueFormatter f) {
|
||||
public void setValueFormatter(ValueFormatter f) {
|
||||
|
||||
if (f == null)
|
||||
return;
|
||||
|
@ -322,7 +283,7 @@ public abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IValueFormatter getValueFormatter() {
|
||||
public ValueFormatter getValueFormatter() {
|
||||
if (needsFormatter())
|
||||
return Utils.getDefaultValueFormatter();
|
||||
return mValueFormatter;
|
||||
|
@ -534,8 +495,6 @@ public abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
|
|||
baseDataSet.mFormLineDashEffect = mFormLineDashEffect;
|
||||
baseDataSet.mFormLineWidth = mFormLineWidth;
|
||||
baseDataSet.mFormSize = mFormSize;
|
||||
baseDataSet.mGradientColor = mGradientColor;
|
||||
baseDataSet.mGradientColors = mGradientColors;
|
||||
baseDataSet.mHighlightEnabled = mHighlightEnabled;
|
||||
baseDataSet.mIconsOffset = mIconsOffset;
|
||||
baseDataSet.mValueColors = mValueColors;
|
||||
|
|
|
@ -42,8 +42,8 @@ public class BubbleDataSet extends BarLineScatterCandleBubbleDataSet<BubbleEntry
|
|||
@Override
|
||||
public DataSet<BubbleEntry> copy() {
|
||||
List<BubbleEntry> entries = new ArrayList<BubbleEntry>();
|
||||
for (int i = 0; i < mValues.size(); i++) {
|
||||
entries.add(mValues.get(i).copy());
|
||||
for (int i = 0; i < mEntries.size(); i++) {
|
||||
entries.add(mEntries.get(i).copy());
|
||||
}
|
||||
BubbleDataSet copied = new BubbleDataSet(entries, getLabel());
|
||||
copy(copied);
|
||||
|
|
|
@ -80,8 +80,8 @@ public class CandleDataSet extends LineScatterCandleRadarDataSet<CandleEntry> im
|
|||
@Override
|
||||
public DataSet<CandleEntry> copy() {
|
||||
List<CandleEntry> entries = new ArrayList<CandleEntry>();
|
||||
for (int i = 0; i < mValues.size(); i++) {
|
||||
entries.add(mValues.get(i).copy());
|
||||
for (int i = 0; i < mEntries.size(); i++) {
|
||||
entries.add(mEntries.get(i).copy());
|
||||
}
|
||||
CandleDataSet copied = new CandleDataSet(entries, getLabel());
|
||||
copy(copied);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
|
||||
package com.github.mikephil.charting.data;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.util.Log;
|
||||
|
||||
import com.github.mikephil.charting.components.YAxis.AxisDependency;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
|
||||
|
@ -400,7 +399,7 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
|
|||
|
||||
// if a DataSet was removed
|
||||
if (removed) {
|
||||
calcMinMax();
|
||||
notifyDataChanged();
|
||||
}
|
||||
|
||||
return removed;
|
||||
|
@ -527,7 +526,7 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
|
|||
boolean removed = set.removeEntry(e);
|
||||
|
||||
if (removed) {
|
||||
calcMinMax();
|
||||
notifyDataChanged();
|
||||
}
|
||||
|
||||
return removed;
|
||||
|
@ -659,7 +658,7 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
|
|||
*
|
||||
* @param f
|
||||
*/
|
||||
public void setValueFormatter(IValueFormatter f) {
|
||||
public void setValueFormatter(ValueFormatter f) {
|
||||
if (f == null)
|
||||
return;
|
||||
else {
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.github.mikephil.charting.data;
|
|||
|
||||
import android.util.Log;
|
||||
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataSet;
|
||||
|
||||
|
@ -91,18 +92,26 @@ public class CombinedData extends BarLineScatterCandleBubbleData<IBarLineScatter
|
|||
if (data.getXMin() < mXMin)
|
||||
mXMin = data.getXMin();
|
||||
|
||||
if (data.mLeftAxisMax > mLeftAxisMax)
|
||||
mLeftAxisMax = data.mLeftAxisMax;
|
||||
for (IBarLineScatterCandleBubbleDataSet<? extends Entry> dataset : sets) {
|
||||
if (dataset.getAxisDependency() == YAxis.AxisDependency.LEFT) {
|
||||
if (dataset.getYMax() > mLeftAxisMax) {
|
||||
mLeftAxisMax = dataset.getYMax();
|
||||
}
|
||||
|
||||
if (data.mLeftAxisMin < mLeftAxisMin)
|
||||
mLeftAxisMin = data.mLeftAxisMin;
|
||||
|
||||
if (data.mRightAxisMax > mRightAxisMax)
|
||||
mRightAxisMax = data.mRightAxisMax;
|
||||
|
||||
if (data.mRightAxisMin < mRightAxisMin)
|
||||
mRightAxisMin = data.mRightAxisMin;
|
||||
if (dataset.getYMin() < mLeftAxisMin) {
|
||||
mLeftAxisMin = dataset.getYMin();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (dataset.getYMax() > mRightAxisMax) {
|
||||
mRightAxisMax = dataset.getYMax();
|
||||
}
|
||||
|
||||
if (dataset.getYMin() < mRightAxisMin) {
|
||||
mRightAxisMin = dataset.getYMin();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
/**
|
||||
* the entries that this DataSet represents / holds together
|
||||
*/
|
||||
protected List<T> mValues = null;
|
||||
protected List<T> mEntries;
|
||||
|
||||
/**
|
||||
* maximum y-value in the value array
|
||||
|
@ -45,15 +45,15 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
* label that describes the DataSet can be specified. The label can also be
|
||||
* used to retrieve the DataSet from a ChartData object.
|
||||
*
|
||||
* @param values
|
||||
* @param entries
|
||||
* @param label
|
||||
*/
|
||||
public DataSet(List<T> values, String label) {
|
||||
public DataSet(List<T> entries, String label) {
|
||||
super(label);
|
||||
this.mValues = values;
|
||||
this.mEntries = entries;
|
||||
|
||||
if (mValues == null)
|
||||
mValues = new ArrayList<T>();
|
||||
if (mEntries == null)
|
||||
mEntries = new ArrayList<T>();
|
||||
|
||||
calcMinMax();
|
||||
}
|
||||
|
@ -61,35 +61,36 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
@Override
|
||||
public void calcMinMax() {
|
||||
|
||||
if (mValues == null || mValues.isEmpty())
|
||||
return;
|
||||
|
||||
mYMax = -Float.MAX_VALUE;
|
||||
mYMin = Float.MAX_VALUE;
|
||||
mXMax = -Float.MAX_VALUE;
|
||||
mXMin = Float.MAX_VALUE;
|
||||
|
||||
for (T e : mValues) {
|
||||
if (mEntries == null || mEntries.isEmpty())
|
||||
return;
|
||||
|
||||
for (T e : mEntries) {
|
||||
calcMinMax(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calcMinMaxY(float fromX, float toX) {
|
||||
|
||||
if (mValues == null || mValues.isEmpty())
|
||||
return;
|
||||
|
||||
mYMax = -Float.MAX_VALUE;
|
||||
mYMin = Float.MAX_VALUE;
|
||||
|
||||
if (mEntries == null || mEntries.isEmpty())
|
||||
return;
|
||||
|
||||
int indexFrom = getEntryIndex(fromX, Float.NaN, Rounding.DOWN);
|
||||
int indexTo = getEntryIndex(toX, Float.NaN, Rounding.UP);
|
||||
|
||||
if (indexTo < indexFrom) return;
|
||||
|
||||
for (int i = indexFrom; i <= indexTo; i++) {
|
||||
|
||||
// only recalculate y
|
||||
calcMinMaxY(mValues.get(i));
|
||||
calcMinMaxY(mEntries.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,7 +129,18 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
|
||||
@Override
|
||||
public int getEntryCount() {
|
||||
return mValues.size();
|
||||
return mEntries.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated.
|
||||
* Use getEntries() instead.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public List<T> getValues() {
|
||||
return mEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,8 +148,19 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
public List<T> getValues() {
|
||||
return mValues;
|
||||
public List<T> getEntries() {
|
||||
return mEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated.
|
||||
* Use setEntries(...) instead.
|
||||
*
|
||||
* @param values
|
||||
*/
|
||||
@Deprecated
|
||||
public void setValues(List<T> values) {
|
||||
setEntries(values);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,8 +168,8 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
public void setValues(List<T> values) {
|
||||
mValues = values;
|
||||
public void setEntries(List<T> entries) {
|
||||
mEntries = entries;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
@ -169,8 +192,8 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append(toSimpleString());
|
||||
for (int i = 0; i < mValues.size(); i++) {
|
||||
buffer.append(mValues.get(i).toString() + " ");
|
||||
for (int i = 0; i < mEntries.size(); i++) {
|
||||
buffer.append(mEntries.get(i).toString() + " ");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
@ -183,7 +206,7 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
*/
|
||||
public String toSimpleString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("DataSet, label: " + (getLabel() == null ? "" : getLabel()) + ", entries: " + mValues.size() +
|
||||
buffer.append("DataSet, label: " + (getLabel() == null ? "" : getLabel()) + ", entries: " + mEntries.size() +
|
||||
"\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
@ -214,23 +237,23 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
if (e == null)
|
||||
return;
|
||||
|
||||
if (mValues == null) {
|
||||
mValues = new ArrayList<T>();
|
||||
if (mEntries == null) {
|
||||
mEntries = new ArrayList<T>();
|
||||
}
|
||||
|
||||
calcMinMax(e);
|
||||
|
||||
if (mValues.size() > 0 && mValues.get(mValues.size() - 1).getX() > e.getX()) {
|
||||
if (mEntries.size() > 0 && mEntries.get(mEntries.size() - 1).getX() > e.getX()) {
|
||||
int closestIndex = getEntryIndex(e.getX(), e.getY(), Rounding.UP);
|
||||
mValues.add(closestIndex, e);
|
||||
mEntries.add(closestIndex, e);
|
||||
} else {
|
||||
mValues.add(e);
|
||||
mEntries.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
mValues.clear();
|
||||
mEntries.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
@ -240,9 +263,9 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
if (e == null)
|
||||
return false;
|
||||
|
||||
List<T> values = getValues();
|
||||
List<T> values = getEntries();
|
||||
if (values == null) {
|
||||
values = new ArrayList<T>();
|
||||
values = new ArrayList<>();
|
||||
}
|
||||
|
||||
calcMinMax(e);
|
||||
|
@ -257,11 +280,11 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
if (e == null)
|
||||
return false;
|
||||
|
||||
if (mValues == null)
|
||||
if (mEntries == null)
|
||||
return false;
|
||||
|
||||
// remove the entry
|
||||
boolean removed = mValues.remove(e);
|
||||
boolean removed = mEntries.remove(e);
|
||||
|
||||
if (removed) {
|
||||
calcMinMax();
|
||||
|
@ -272,7 +295,7 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
|
||||
@Override
|
||||
public int getEntryIndex(Entry e) {
|
||||
return mValues.indexOf(e);
|
||||
return mEntries.indexOf(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -280,7 +303,7 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
|
||||
int index = getEntryIndex(xValue, closestToY, rounding);
|
||||
if (index > -1)
|
||||
return mValues.get(index);
|
||||
return mEntries.get(index);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -291,24 +314,24 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
|
||||
@Override
|
||||
public T getEntryForIndex(int index) {
|
||||
return mValues.get(index);
|
||||
return mEntries.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEntryIndex(float xValue, float closestToY, Rounding rounding) {
|
||||
|
||||
if (mValues == null || mValues.isEmpty())
|
||||
if (mEntries == null || mEntries.isEmpty())
|
||||
return -1;
|
||||
|
||||
int low = 0;
|
||||
int high = mValues.size() - 1;
|
||||
int high = mEntries.size() - 1;
|
||||
int closest = high;
|
||||
|
||||
while (low < high) {
|
||||
int m = (low + high) / 2;
|
||||
|
||||
final float d1 = mValues.get(m).getX() - xValue,
|
||||
d2 = mValues.get(m + 1).getX() - xValue,
|
||||
final float d1 = mEntries.get(m).getX() - xValue,
|
||||
d2 = mEntries.get(m + 1).getX() - xValue,
|
||||
ad1 = Math.abs(d1), ad2 = Math.abs(d2);
|
||||
|
||||
if (ad2 < ad1) {
|
||||
|
@ -335,10 +358,10 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
}
|
||||
|
||||
if (closest != -1) {
|
||||
float closestXValue = mValues.get(closest).getX();
|
||||
float closestXValue = mEntries.get(closest).getX();
|
||||
if (rounding == Rounding.UP) {
|
||||
// If rounding up, and found x-value is lower than specified x, and we can go upper...
|
||||
if (closestXValue < xValue && closest < mValues.size() - 1) {
|
||||
if (closestXValue < xValue && closest < mEntries.size() - 1) {
|
||||
++closest;
|
||||
}
|
||||
} else if (rounding == Rounding.DOWN) {
|
||||
|
@ -350,23 +373,23 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
|
||||
// Search by closest to y-value
|
||||
if (!Float.isNaN(closestToY)) {
|
||||
while (closest > 0 && mValues.get(closest - 1).getX() == closestXValue)
|
||||
while (closest > 0 && mEntries.get(closest - 1).getX() == closestXValue)
|
||||
closest -= 1;
|
||||
|
||||
float closestYValue = mValues.get(closest).getY();
|
||||
float closestYValue = mEntries.get(closest).getY();
|
||||
int closestYIndex = closest;
|
||||
|
||||
while (true) {
|
||||
closest += 1;
|
||||
if (closest >= mValues.size())
|
||||
if (closest >= mEntries.size())
|
||||
break;
|
||||
|
||||
final Entry value = mValues.get(closest);
|
||||
final Entry value = mEntries.get(closest);
|
||||
|
||||
if (value.getX() != closestXValue)
|
||||
break;
|
||||
|
||||
if (Math.abs(value.getY() - closestToY) < Math.abs(closestYValue - closestToY)) {
|
||||
if (Math.abs(value.getY() - closestToY) <= Math.abs(closestYValue - closestToY)) {
|
||||
closestYValue = closestToY;
|
||||
closestYIndex = closest;
|
||||
}
|
||||
|
@ -385,22 +408,22 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
List<T> entries = new ArrayList<T>();
|
||||
|
||||
int low = 0;
|
||||
int high = mValues.size() - 1;
|
||||
int high = mEntries.size() - 1;
|
||||
|
||||
while (low <= high) {
|
||||
int m = (high + low) / 2;
|
||||
T entry = mValues.get(m);
|
||||
T entry = mEntries.get(m);
|
||||
|
||||
// if we have a match
|
||||
if (xValue == entry.getX()) {
|
||||
while (m > 0 && mValues.get(m - 1).getX() == xValue)
|
||||
while (m > 0 && mEntries.get(m - 1).getX() == xValue)
|
||||
m--;
|
||||
|
||||
high = mValues.size();
|
||||
high = mEntries.size();
|
||||
|
||||
// loop over all "equal" entries
|
||||
for (; m < high; m++) {
|
||||
entry = mValues.get(m);
|
||||
entry = mEntries.get(m);
|
||||
if (entry.getX() == xValue) {
|
||||
entries.add(entry);
|
||||
} else {
|
||||
|
|
|
@ -85,8 +85,8 @@ public class LineDataSet extends LineRadarDataSet<Entry> implements ILineDataSet
|
|||
@Override
|
||||
public DataSet<Entry> copy() {
|
||||
List<Entry> entries = new ArrayList<Entry>();
|
||||
for (int i = 0; i < mValues.size(); i++) {
|
||||
entries.add(mValues.get(i).copy());
|
||||
for (int i = 0; i < mEntries.size(); i++) {
|
||||
entries.add(mEntries.get(i).copy());
|
||||
}
|
||||
LineDataSet copied = new LineDataSet(entries, getLabel());
|
||||
copy(copied);
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.List;
|
|||
*/
|
||||
public abstract class LineRadarDataSet<T extends Entry> extends LineScatterCandleRadarDataSet<T> implements ILineRadarDataSet<T> {
|
||||
|
||||
// TODO: Move to using `Fill` class
|
||||
/**
|
||||
* the color that is used for filling the line surface
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
package com.github.mikephil.charting.data;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IPieDataSet;
|
||||
|
||||
|
@ -46,6 +48,18 @@ public class PieData extends ChartData<IPieDataSet> {
|
|||
return mDataSets.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IPieDataSet> getDataSets() {
|
||||
List<IPieDataSet> dataSets = super.getDataSets();
|
||||
|
||||
if (dataSets.size() < 1) {
|
||||
Log.e("MPAndroidChart",
|
||||
"Found multiple data sets while pie chart only allows one");
|
||||
}
|
||||
|
||||
return dataSets;
|
||||
}
|
||||
|
||||
/**
|
||||
* The PieData object can only have one DataSet. Use getDataSet() method instead.
|
||||
*
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.github.mikephil.charting.data;
|
|||
|
||||
import com.github.mikephil.charting.interfaces.datasets.IPieDataSet;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -22,13 +23,14 @@ public class PieDataSet extends DataSet<PieEntry> implements IPieDataSet {
|
|||
|
||||
private ValuePosition mXValuePosition = ValuePosition.INSIDE_SLICE;
|
||||
private ValuePosition mYValuePosition = ValuePosition.INSIDE_SLICE;
|
||||
private boolean mUsingSliceColorAsValueLineColor = false;
|
||||
private int mValueLineColor = 0xff000000;
|
||||
private boolean mUseValueColorForLine = false;
|
||||
private float mValueLineWidth = 1.0f;
|
||||
private float mValueLinePart1OffsetPercentage = 75.f;
|
||||
private float mValueLinePart1Length = 0.3f;
|
||||
private float mValueLinePart2Length = 0.4f;
|
||||
private boolean mValueLineVariableLength = true;
|
||||
private Integer mHighlightColor = null;
|
||||
|
||||
public PieDataSet(List<PieEntry> yVals, String label) {
|
||||
super(yVals, label);
|
||||
|
@ -38,8 +40,8 @@ public class PieDataSet extends DataSet<PieEntry> implements IPieDataSet {
|
|||
@Override
|
||||
public DataSet<PieEntry> copy() {
|
||||
List<PieEntry> entries = new ArrayList<>();
|
||||
for (int i = 0; i < mValues.size(); i++) {
|
||||
entries.add(mValues.get(i).copy());
|
||||
for (int i = 0; i < mEntries.size(); i++) {
|
||||
entries.add(mEntries.get(i).copy());
|
||||
}
|
||||
PieDataSet copied = new PieDataSet(entries, getLabel());
|
||||
copy(copied);
|
||||
|
@ -135,15 +137,23 @@ public class PieDataSet extends DataSet<PieEntry> implements IPieDataSet {
|
|||
}
|
||||
|
||||
/**
|
||||
* When valuePosition is OutsideSlice, use slice colors as line color if true
|
||||
* This method is deprecated.
|
||||
* Use isUseValueColorForLineEnabled() instead.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean isUsingSliceColorAsValueLineColor() {
|
||||
return mUsingSliceColorAsValueLineColor;
|
||||
return isUseValueColorForLineEnabled();
|
||||
}
|
||||
|
||||
public void setUsingSliceColorAsValueLineColor(boolean usingSliceColorAsValueLineColor) {
|
||||
this.mUsingSliceColorAsValueLineColor = usingSliceColorAsValueLineColor;
|
||||
/**
|
||||
* This method is deprecated.
|
||||
* Use setUseValueColorForLine(...) instead.
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
@Deprecated
|
||||
public void setUsingSliceColorAsValueLineColor(boolean enabled) {
|
||||
setUseValueColorForLine(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,6 +168,17 @@ public class PieDataSet extends DataSet<PieEntry> implements IPieDataSet {
|
|||
this.mValueLineColor = valueLineColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseValueColorForLineEnabled()
|
||||
{
|
||||
return mUseValueColorForLine;
|
||||
}
|
||||
|
||||
public void setUseValueColorForLine(boolean enabled)
|
||||
{
|
||||
mUseValueColorForLine = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* When valuePosition is OutsideSlice, indicates line width
|
||||
*/
|
||||
|
@ -218,6 +239,21 @@ public class PieDataSet extends DataSet<PieEntry> implements IPieDataSet {
|
|||
this.mValueLineVariableLength = valueLineVariableLength;
|
||||
}
|
||||
|
||||
/** Gets the color for the highlighted sector */
|
||||
@Override
|
||||
@Nullable
|
||||
public Integer getHighlightColor()
|
||||
{
|
||||
return mHighlightColor;
|
||||
}
|
||||
|
||||
/** Sets the color for the highlighted sector (null for using entry color) */
|
||||
public void setHighlightColor(@Nullable Integer color)
|
||||
{
|
||||
this.mHighlightColor = color;
|
||||
}
|
||||
|
||||
|
||||
public enum ValuePosition {
|
||||
INSIDE_SLICE,
|
||||
OUTSIDE_SLICE
|
||||
|
|
|
@ -102,8 +102,8 @@ public class RadarDataSet extends LineRadarDataSet<RadarEntry> implements IRadar
|
|||
@Override
|
||||
public DataSet<RadarEntry> copy() {
|
||||
List<RadarEntry> entries = new ArrayList<RadarEntry>();
|
||||
for (int i = 0; i < mValues.size(); i++) {
|
||||
entries.add(mValues.get(i).copy());
|
||||
for (int i = 0; i < mEntries.size(); i++) {
|
||||
entries.add(mEntries.get(i).copy());
|
||||
}
|
||||
RadarDataSet copied = new RadarDataSet(entries, getLabel());
|
||||
copy(copied);
|
||||
|
|
|
@ -48,8 +48,8 @@ public class ScatterDataSet extends LineScatterCandleRadarDataSet<Entry> impleme
|
|||
@Override
|
||||
public DataSet<Entry> copy() {
|
||||
List<Entry> entries = new ArrayList<Entry>();
|
||||
for (int i = 0; i < mValues.size(); i++) {
|
||||
entries.add(mValues.get(i).copy());
|
||||
for (int i = 0; i < mEntries.size(); i++) {
|
||||
entries.add(mEntries.get(i).copy());
|
||||
}
|
||||
ScatterDataSet copied = new ScatterDataSet(entries, getLabel());
|
||||
copy(copied);
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
|
||||
package com.github.mikephil.charting.data.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Implemented according to modified Douglas Peucker {@link}
|
||||
* http://psimpl.sourceforge.net/douglas-peucker.html
|
||||
*/
|
||||
public class ApproximatorN
|
||||
{
|
||||
public float[] reduceWithDouglasPeucker(float[] points, float resultCount) {
|
||||
|
||||
int pointCount = points.length / 2;
|
||||
|
||||
// if a shape has 2 or less points it cannot be reduced
|
||||
if (resultCount <= 2 || resultCount >= pointCount)
|
||||
return points;
|
||||
|
||||
boolean[] keep = new boolean[pointCount];
|
||||
|
||||
// first and last always stay
|
||||
keep[0] = true;
|
||||
keep[pointCount - 1] = true;
|
||||
|
||||
int currentStoredPoints = 2;
|
||||
|
||||
ArrayList<Line> queue = new ArrayList<>();
|
||||
Line line = new Line(0, pointCount - 1, points);
|
||||
queue.add(line);
|
||||
|
||||
do {
|
||||
line = queue.remove(queue.size() - 1);
|
||||
|
||||
// store the key
|
||||
keep[line.index] = true;
|
||||
|
||||
// check point count tolerance
|
||||
currentStoredPoints += 1;
|
||||
|
||||
if (currentStoredPoints == resultCount)
|
||||
break;
|
||||
|
||||
// split the polyline at the key and recurse
|
||||
Line left = new Line(line.start, line.index, points);
|
||||
if (left.index > 0) {
|
||||
int insertionIndex = insertionIndex(left, queue);
|
||||
queue.add(insertionIndex, left);
|
||||
}
|
||||
|
||||
Line right = new Line(line.index, line.end, points);
|
||||
if (right.index > 0) {
|
||||
int insertionIndex = insertionIndex(right, queue);
|
||||
queue.add(insertionIndex, right);
|
||||
}
|
||||
} while (queue.isEmpty());
|
||||
|
||||
float[] reducedEntries = new float[currentStoredPoints * 2];
|
||||
|
||||
for (int i = 0, i2 = 0, r2 = 0; i < currentStoredPoints; i++, r2 += 2) {
|
||||
if (keep[i]) {
|
||||
reducedEntries[i2++] = points[r2];
|
||||
reducedEntries[i2++] = points[r2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
return reducedEntries;
|
||||
}
|
||||
|
||||
private static float distanceToLine(
|
||||
float ptX, float ptY, float[]
|
||||
fromLinePoint1, float[] fromLinePoint2) {
|
||||
float dx = fromLinePoint2[0] - fromLinePoint1[0];
|
||||
float dy = fromLinePoint2[1] - fromLinePoint1[1];
|
||||
|
||||
float dividend = Math.abs(
|
||||
dy * ptX -
|
||||
dx * ptY -
|
||||
fromLinePoint1[0] * fromLinePoint2[1] +
|
||||
fromLinePoint2[0] * fromLinePoint1[1]);
|
||||
double divisor = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
return (float)(dividend / divisor);
|
||||
}
|
||||
|
||||
private static class Line {
|
||||
int start;
|
||||
int end;
|
||||
|
||||
float distance = 0;
|
||||
int index = 0;
|
||||
|
||||
Line(int start, int end, float[] points) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
|
||||
float[] startPoint = new float[]{points[start * 2], points[start * 2 + 1]};
|
||||
float[] endPoint = new float[]{points[end * 2], points[end * 2 + 1]};
|
||||
|
||||
if (end <= start + 1) return;
|
||||
|
||||
for (int i = start + 1, i2 = i * 2; i < end; i++, i2 += 2) {
|
||||
float distance = distanceToLine(
|
||||
points[i2], points[i2 + 1],
|
||||
startPoint, endPoint);
|
||||
|
||||
if (distance > this.distance) {
|
||||
this.index = i;
|
||||
this.distance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean equals(final Line rhs) {
|
||||
return (start == rhs.start) && (end == rhs.end) && index == rhs.index;
|
||||
}
|
||||
|
||||
boolean lessThan(final Line rhs) {
|
||||
return distance < rhs.distance;
|
||||
}
|
||||
}
|
||||
|
||||
private static int insertionIndex(Line line, ArrayList<Line> queue) {
|
||||
int min = 0;
|
||||
int max = queue.size();
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
int midIndex = min + (max - min) / 2;
|
||||
Line midLine = queue.get(midIndex);
|
||||
|
||||
if (midLine.equals(line)) {
|
||||
return midIndex;
|
||||
}
|
||||
else if (line.lessThan(midLine)) {
|
||||
// perform search in left half
|
||||
max = midIndex;
|
||||
}
|
||||
else {
|
||||
// perform search in right half
|
||||
min = midIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
package com.github.mikephil.charting.formatter;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
* Created by philipp on 02/06/16.
|
||||
*/
|
||||
public class DefaultAxisValueFormatter implements IAxisValueFormatter
|
||||
public class DefaultAxisValueFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -18,7 +16,7 @@ public class DefaultAxisValueFormatter implements IAxisValueFormatter
|
|||
/**
|
||||
* the number of decimal digits this formatter uses
|
||||
*/
|
||||
protected int digits = 0;
|
||||
protected int digits;
|
||||
|
||||
/**
|
||||
* Constructor that specifies to how many digits the value should be
|
||||
|
@ -40,7 +38,7 @@ public class DefaultAxisValueFormatter implements IAxisValueFormatter
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getFormattedValue(float value) {
|
||||
// avoid memory allocations here (for performance)
|
||||
return mFormat.format(value);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
|
||||
package com.github.mikephil.charting.formatter;
|
||||
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
|
@ -12,7 +8,7 @@ import java.text.DecimalFormat;
|
|||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
public class DefaultValueFormatter implements IValueFormatter
|
||||
public class DefaultValueFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -52,7 +48,7 @@ public class DefaultValueFormatter implements IValueFormatter
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
|
||||
public String getFormattedValue(float value) {
|
||||
|
||||
// put more logic here ...
|
||||
// avoid memory allocations here (for performance reasons)
|
||||
|
|
|
@ -6,7 +6,10 @@ import com.github.mikephil.charting.components.AxisBase;
|
|||
* Created by Philipp Jahoda on 20/09/15.
|
||||
* Custom formatter interface that allows formatting of
|
||||
* axis labels before they are being drawn.
|
||||
*
|
||||
* @deprecated Extend {@link ValueFormatter} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public interface IAxisValueFormatter
|
||||
{
|
||||
|
||||
|
@ -18,6 +21,9 @@ public interface IAxisValueFormatter
|
|||
* @param value the value to be formatted
|
||||
* @param axis the axis the value belongs to
|
||||
* @return
|
||||
*
|
||||
* @deprecated Extend {@link ValueFormatter} and use {@link ValueFormatter#getAxisLabel(float, AxisBase)}
|
||||
*/
|
||||
@Deprecated
|
||||
String getFormattedValue(float value, AxisBase axis);
|
||||
}
|
||||
|
|
|
@ -4,13 +4,12 @@ import com.github.mikephil.charting.data.Entry;
|
|||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
/**
|
||||
* Interface that allows custom formatting of all values inside the chart before they are
|
||||
* being drawn to the screen. Simply create your own formatting class and let
|
||||
* it implement IValueFormatter. Then override the getFormattedValue(...) method
|
||||
* and return whatever you want.
|
||||
* Interface to format all values before they are drawn as labels.
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
* @deprecated Extend {@link ValueFormatter} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public interface IValueFormatter
|
||||
{
|
||||
|
||||
|
@ -24,6 +23,9 @@ public interface IValueFormatter
|
|||
* @param dataSetIndex the index of the DataSet the entry in focus belongs to
|
||||
* @param viewPortHandler provides information about the current chart state (scale, translation, ...)
|
||||
* @return the formatted label ready for being drawn
|
||||
*
|
||||
* @deprecated Extend {@link ValueFormatter} and override an appropriate method
|
||||
*/
|
||||
@Deprecated
|
||||
String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler);
|
||||
}
|
||||
|
|
|
@ -1,18 +1,11 @@
|
|||
|
||||
package com.github.mikephil.charting.formatter;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* This formatter is used for passing an array of x-axis labels, on whole x steps.
|
||||
*/
|
||||
public class IndexAxisValueFormatter implements IAxisValueFormatter
|
||||
public class IndexAxisValueFormatter extends ValueFormatter
|
||||
{
|
||||
private String[] mValues = new String[] {};
|
||||
private int mValueCount = 0;
|
||||
|
@ -44,7 +37,8 @@ public class IndexAxisValueFormatter implements IAxisValueFormatter
|
|||
setValues(values.toArray(new String[values.size()]));
|
||||
}
|
||||
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
int index = Math.round(value);
|
||||
|
||||
if (index < 0 || index >= mValueCount || index != (int)value)
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
|
||||
package com.github.mikephil.charting.formatter;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
|
@ -17,7 +12,7 @@ import java.text.DecimalFormat;
|
|||
* @author Philipp Jahoda
|
||||
* @author Oleksandr Tyshkovets <olexandr.tyshkovets@gmail.com>
|
||||
*/
|
||||
public class LargeValueFormatter implements IValueFormatter, IAxisValueFormatter
|
||||
public class LargeValueFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
private String[] mSuffix = new String[]{
|
||||
|
@ -41,15 +36,8 @@ public class LargeValueFormatter implements IValueFormatter, IAxisValueFormatter
|
|||
mText = appendix;
|
||||
}
|
||||
|
||||
// IValueFormatter
|
||||
@Override
|
||||
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
|
||||
return makePretty(value) + mText;
|
||||
}
|
||||
|
||||
// IAxisValueFormatter
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
public String getFormattedValue(float value) {
|
||||
return makePretty(value) + mText;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,49 +1,54 @@
|
|||
|
||||
package com.github.mikephil.charting.formatter;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
import com.github.mikephil.charting.charts.PieChart;
|
||||
import com.github.mikephil.charting.data.PieEntry;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
* This IValueFormatter is just for convenience and simply puts a "%" sign after
|
||||
* each value. (Recommeded for PieChart)
|
||||
* each value. (Recommended for PieChart)
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
public class PercentFormatter implements IValueFormatter, IAxisValueFormatter
|
||||
public class PercentFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
protected DecimalFormat mFormat;
|
||||
public DecimalFormat mFormat;
|
||||
private PieChart pieChart;
|
||||
private boolean percentSignSeparated;
|
||||
|
||||
public PercentFormatter() {
|
||||
mFormat = new DecimalFormat("###,###,##0.0");
|
||||
percentSignSeparated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow a custom decimalformat
|
||||
*
|
||||
* @param format
|
||||
*/
|
||||
public PercentFormatter(DecimalFormat format) {
|
||||
this.mFormat = format;
|
||||
// Can be used to remove percent signs if the chart isn't in percent mode
|
||||
public PercentFormatter(PieChart pieChart) {
|
||||
this();
|
||||
this.pieChart = pieChart;
|
||||
}
|
||||
|
||||
// Can be used to remove percent signs if the chart isn't in percent mode
|
||||
public PercentFormatter(PieChart pieChart, boolean percentSignSeparated) {
|
||||
this(pieChart);
|
||||
this.percentSignSeparated = percentSignSeparated;
|
||||
}
|
||||
|
||||
// IValueFormatter
|
||||
@Override
|
||||
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
|
||||
return mFormat.format(value) + " %";
|
||||
public String getFormattedValue(float value) {
|
||||
return mFormat.format(value) + (percentSignSeparated ? " %" : "%");
|
||||
}
|
||||
|
||||
// IAxisValueFormatter
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
return mFormat.format(value) + " %";
|
||||
public String getPieLabel(float value, PieEntry pieEntry) {
|
||||
if (pieChart != null && pieChart.isUsePercentValuesEnabled()) {
|
||||
// Converted to percent
|
||||
return getFormattedValue(value);
|
||||
} else {
|
||||
// raw value, skip percent sign
|
||||
return mFormat.format(value);
|
||||
}
|
||||
}
|
||||
|
||||
public int getDecimalDigits() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package com.github.mikephil.charting.formatter;
|
||||
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
|
@ -12,7 +10,7 @@ import java.text.DecimalFormat;
|
|||
* A formatter specifically for stacked BarChart that allows to specify whether the all stack values
|
||||
* or just the top value should be drawn.
|
||||
*/
|
||||
public class StackedValueFormatter implements IValueFormatter
|
||||
public class StackedValueFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -23,7 +21,7 @@ public class StackedValueFormatter implements IValueFormatter
|
|||
/**
|
||||
* a string that should be appended behind the value
|
||||
*/
|
||||
private String mAppendix;
|
||||
private String mSuffix;
|
||||
|
||||
private DecimalFormat mFormat;
|
||||
|
||||
|
@ -31,12 +29,12 @@ public class StackedValueFormatter implements IValueFormatter
|
|||
* Constructor.
|
||||
*
|
||||
* @param drawWholeStack if true, all stack values of the stacked bar entry are drawn, else only top
|
||||
* @param appendix a string that should be appended behind the value
|
||||
* @param suffix a string that should be appended behind the value
|
||||
* @param decimals the number of decimal digits to use
|
||||
*/
|
||||
public StackedValueFormatter(boolean drawWholeStack, String appendix, int decimals) {
|
||||
public StackedValueFormatter(boolean drawWholeStack, String suffix, int decimals) {
|
||||
this.mDrawWholeStack = drawWholeStack;
|
||||
this.mAppendix = appendix;
|
||||
this.mSuffix = suffix;
|
||||
|
||||
StringBuffer b = new StringBuffer();
|
||||
for (int i = 0; i < decimals; i++) {
|
||||
|
@ -49,12 +47,10 @@ public class StackedValueFormatter implements IValueFormatter
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
|
||||
public String getBarStackedLabel(float value, BarEntry entry) {
|
||||
if (!mDrawWholeStack) {
|
||||
|
||||
if (!mDrawWholeStack && entry instanceof BarEntry) {
|
||||
|
||||
BarEntry barEntry = (BarEntry) entry;
|
||||
float[] vals = barEntry.getYVals();
|
||||
float[] vals = entry.getYVals();
|
||||
|
||||
if (vals != null) {
|
||||
|
||||
|
@ -62,7 +58,7 @@ public class StackedValueFormatter implements IValueFormatter
|
|||
if (vals[vals.length - 1] == value) {
|
||||
|
||||
// return the "sum" across all stack values
|
||||
return mFormat.format(barEntry.getY()) + mAppendix;
|
||||
return mFormat.format(entry.getY()) + mSuffix;
|
||||
} else {
|
||||
return ""; // return empty
|
||||
}
|
||||
|
@ -70,6 +66,6 @@ public class StackedValueFormatter implements IValueFormatter
|
|||
}
|
||||
|
||||
// return the "proposed" value
|
||||
return mFormat.format(value) + mAppendix;
|
||||
return mFormat.format(value) + mSuffix;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
package com.github.mikephil.charting.formatter;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.BubbleEntry;
|
||||
import com.github.mikephil.charting.data.CandleEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.PieEntry;
|
||||
import com.github.mikephil.charting.data.RadarEntry;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
/**
|
||||
* Class to format all values before they are drawn as labels.
|
||||
*/
|
||||
public abstract class ValueFormatter implements IAxisValueFormatter, IValueFormatter{
|
||||
|
||||
/**
|
||||
* <b>DO NOT USE</b>, only for backwards compatibility and will be removed in future versions.
|
||||
*
|
||||
* @param value the value to be formatted
|
||||
* @param axis the axis the value belongs to
|
||||
* @return formatted string label
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
return getFormattedValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>DO NOT USE</b>, only for backwards compatibility and will be removed in future versions.
|
||||
* @param value the value to be formatted
|
||||
* @param entry the entry the value belongs to - in e.g. BarChart, this is of class BarEntry
|
||||
* @param dataSetIndex the index of the DataSet the entry in focus belongs to
|
||||
* @param viewPortHandler provides information about the current chart state (scale, translation, ...)
|
||||
* @return formatted string label
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
|
||||
return getFormattedValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when drawing any label, used to change numbers into formatted strings.
|
||||
*
|
||||
* @param value float to be formatted
|
||||
* @return formatted string label
|
||||
*/
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to draw axis labels, calls {@link #getFormattedValue(float)} by default.
|
||||
*
|
||||
* @param value float to be formatted
|
||||
* @param axis axis being labeled
|
||||
* @return formatted string label
|
||||
*/
|
||||
public String getAxisLabel(float value, AxisBase axis) {
|
||||
return getFormattedValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to draw bar labels, calls {@link #getFormattedValue(float)} by default.
|
||||
*
|
||||
* @param barEntry bar being labeled
|
||||
* @return formatted string label
|
||||
*/
|
||||
public String getBarLabel(BarEntry barEntry) {
|
||||
return getFormattedValue(barEntry.getY());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to draw stacked bar labels, calls {@link #getFormattedValue(float)} by default.
|
||||
*
|
||||
* @param value current value to be formatted
|
||||
* @param stackedEntry stacked entry being labeled, contains all Y values
|
||||
* @return formatted string label
|
||||
*/
|
||||
public String getBarStackedLabel(float value, BarEntry stackedEntry) {
|
||||
return getFormattedValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to draw line and scatter labels, calls {@link #getFormattedValue(float)} by default.
|
||||
*
|
||||
* @param entry point being labeled, contains X value
|
||||
* @return formatted string label
|
||||
*/
|
||||
public String getPointLabel(Entry entry) {
|
||||
return getFormattedValue(entry.getY());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to draw pie value labels, calls {@link #getFormattedValue(float)} by default.
|
||||
*
|
||||
* @param value float to be formatted, may have been converted to percentage
|
||||
* @param pieEntry slice being labeled, contains original, non-percentage Y value
|
||||
* @return formatted string label
|
||||
*/
|
||||
public String getPieLabel(float value, PieEntry pieEntry) {
|
||||
return getFormattedValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to draw radar value labels, calls {@link #getFormattedValue(float)} by default.
|
||||
*
|
||||
* @param radarEntry entry being labeled
|
||||
* @return formatted string label
|
||||
*/
|
||||
public String getRadarLabel(RadarEntry radarEntry) {
|
||||
return getFormattedValue(radarEntry.getY());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to draw bubble size labels, calls {@link #getFormattedValue(float)} by default.
|
||||
*
|
||||
* @param bubbleEntry bubble being labeled, also contains X and Y values
|
||||
* @return formatted string label
|
||||
*/
|
||||
public String getBubbleLabel(BubbleEntry bubbleEntry) {
|
||||
return getFormattedValue(bubbleEntry.getSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to draw high labels, calls {@link #getFormattedValue(float)} by default.
|
||||
*
|
||||
* @param candleEntry candlestick being labeled
|
||||
* @return formatted string label
|
||||
*/
|
||||
public String getCandleLabel(CandleEntry candleEntry) {
|
||||
return getFormattedValue(candleEntry.getHigh());
|
||||
}
|
||||
|
||||
}
|
|
@ -60,10 +60,18 @@ public class Highlight {
|
|||
*/
|
||||
private float mDrawY;
|
||||
|
||||
public Highlight(float x, float y, int dataSetIndex, int dataIndex) {
|
||||
this.mX = x;
|
||||
this.mY = y;
|
||||
this.mDataSetIndex = dataSetIndex;
|
||||
this.mDataIndex = dataIndex;
|
||||
}
|
||||
|
||||
public Highlight(float x, float y, int dataSetIndex) {
|
||||
this.mX = x;
|
||||
this.mY = y;
|
||||
this.mDataSetIndex = dataSetIndex;
|
||||
this.mDataIndex = -1;
|
||||
}
|
||||
|
||||
public Highlight(float x, int dataSetIndex, int stackIndex) {
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.github.mikephil.charting.interfaces.dataprovider;
|
|||
import android.graphics.RectF;
|
||||
|
||||
import com.github.mikephil.charting.data.ChartData;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
|
||||
/**
|
||||
|
@ -61,7 +61,7 @@ public interface ChartInterface {
|
|||
|
||||
RectF getContentRect();
|
||||
|
||||
IValueFormatter getDefaultValueFormatter();
|
||||
ValueFormatter getDefaultValueFormatter();
|
||||
|
||||
ChartData getData();
|
||||
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
package com.github.mikephil.charting.interfaces.datasets;
|
||||
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.utils.Fill;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by philipp on 21/10/15.
|
||||
*/
|
||||
public interface IBarDataSet extends IBarLineScatterCandleBubbleDataSet<BarEntry> {
|
||||
|
||||
List<Fill> getFills();
|
||||
|
||||
Fill getFill(int index);
|
||||
|
||||
/**
|
||||
* Returns true if this DataSet is stacked (stacksize > 1) or not.
|
||||
*
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
package com.github.mikephil.charting.interfaces.datasets;
|
||||
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Typeface;
|
||||
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.DataSet;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.github.mikephil.charting.model.GradientColor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -286,28 +284,6 @@ public interface IDataSet<T extends Entry> {
|
|||
*/
|
||||
int getColor();
|
||||
|
||||
/**
|
||||
* Returns the Gradient color model
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
GradientColor getGradientColor();
|
||||
|
||||
/**
|
||||
* Returns the Gradient colors
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<GradientColor> getGradientColors();
|
||||
|
||||
/**
|
||||
* Returns the Gradient colors
|
||||
*
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
GradientColor getGradientColor(int index);
|
||||
|
||||
/**
|
||||
* Returns the color at the given index of the DataSet's color array.
|
||||
* Performs a IndexOutOfBounds check by modulus.
|
||||
|
@ -341,14 +317,14 @@ public interface IDataSet<T extends Entry> {
|
|||
*
|
||||
* @param f
|
||||
*/
|
||||
void setValueFormatter(IValueFormatter f);
|
||||
void setValueFormatter(ValueFormatter f);
|
||||
|
||||
/**
|
||||
* Returns the formatter used for drawing the values inside the chart.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
IValueFormatter getValueFormatter();
|
||||
ValueFormatter getValueFormatter();
|
||||
|
||||
/**
|
||||
* Returns true if the valueFormatter object of this DataSet is null.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.github.mikephil.charting.interfaces.datasets;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.github.mikephil.charting.data.PieDataSet;
|
||||
import com.github.mikephil.charting.data.PieEntry;
|
||||
|
||||
|
@ -35,16 +37,16 @@ public interface IPieDataSet extends IDataSet<PieEntry> {
|
|||
PieDataSet.ValuePosition getXValuePosition();
|
||||
PieDataSet.ValuePosition getYValuePosition();
|
||||
|
||||
/**
|
||||
* When valuePosition is OutsideSlice, use slice colors as line color if true
|
||||
* */
|
||||
boolean isUsingSliceColorAsValueLineColor();
|
||||
|
||||
/**
|
||||
* When valuePosition is OutsideSlice, indicates line color
|
||||
* */
|
||||
int getValueLineColor();
|
||||
|
||||
/**
|
||||
* When valuePosition is OutsideSlice and enabled, line will have the same color as the slice
|
||||
* */
|
||||
boolean isUseValueColorForLineEnabled();
|
||||
|
||||
/**
|
||||
* When valuePosition is OutsideSlice, indicates line width
|
||||
* */
|
||||
|
@ -70,5 +72,11 @@ public interface IPieDataSet extends IDataSet<PieEntry> {
|
|||
* */
|
||||
boolean isValueLineVariableLength();
|
||||
|
||||
/**
|
||||
* Gets the color for the highlighted sector
|
||||
* */
|
||||
@Nullable
|
||||
Integer getHighlightColor();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -580,12 +580,19 @@ public class BarLineChartTouchListener extends ChartTouchListener<BarLineChartBa
|
|||
|
||||
MPPointF trans = getTrans(e.getX(), e.getY());
|
||||
|
||||
mChart.zoom(mChart.isScaleXEnabled() ? 1.4f : 1f, mChart.isScaleYEnabled() ? 1.4f : 1f, trans.x, trans.y);
|
||||
float scaleX = mChart.isScaleXEnabled() ? 1.4f : 1f;
|
||||
float scaleY = mChart.isScaleYEnabled() ? 1.4f : 1f;
|
||||
|
||||
mChart.zoom(scaleX, scaleY, trans.x, trans.y);
|
||||
|
||||
if (mChart.isLogEnabled())
|
||||
Log.i("BarlineChartTouch", "Double-Tap, Zooming In, x: " + trans.x + ", y: "
|
||||
+ trans.y);
|
||||
|
||||
if (l != null) {
|
||||
l.onChartScale(e, scaleX, scaleY);
|
||||
}
|
||||
|
||||
MPPointF.recycleInstance(trans);
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ public interface OnChartGestureListener {
|
|||
void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY);
|
||||
|
||||
/**
|
||||
* Callbacks when the chart is scaled / zoomed via pinch zoom gesture.
|
||||
* Callbacks when the chart is scaled / zoomed via pinch zoom / double-tap gesture.
|
||||
*
|
||||
* @param me
|
||||
* @param scaleX scalefactor on the x-axis
|
||||
|
|
|
@ -1,28 +1,69 @@
|
|||
package com.github.mikephil.charting.model;
|
||||
|
||||
public class GradientColor {
|
||||
import com.github.mikephil.charting.utils.Fill;
|
||||
|
||||
private int startColor;
|
||||
private int endColor;
|
||||
|
||||
public GradientColor(int startColor, int endColor) {
|
||||
this.startColor = startColor;
|
||||
this.endColor = endColor;
|
||||
/**
|
||||
* Deprecated. Use `Fill`
|
||||
*/
|
||||
@Deprecated
|
||||
public class GradientColor extends Fill
|
||||
{
|
||||
/**
|
||||
* Deprecated. Use `Fill.getGradientColors()`
|
||||
*/
|
||||
@Deprecated
|
||||
public int getStartColor()
|
||||
{
|
||||
return getGradientColors()[0];
|
||||
}
|
||||
|
||||
public int getStartColor() {
|
||||
return startColor;
|
||||
/**
|
||||
* Deprecated. Use `Fill.setGradientColors(...)`
|
||||
*/
|
||||
@Deprecated
|
||||
public void setStartColor(int startColor)
|
||||
{
|
||||
if (getGradientColors() == null || getGradientColors().length != 2)
|
||||
{
|
||||
setGradientColors(new int[]{
|
||||
startColor,
|
||||
getGradientColors() != null && getGradientColors().length > 1
|
||||
? getGradientColors()[1]
|
||||
: 0
|
||||
});
|
||||
} else
|
||||
{
|
||||
getGradientColors()[0] = startColor;
|
||||
}
|
||||
}
|
||||
|
||||
public void setStartColor(int startColor) {
|
||||
this.startColor = startColor;
|
||||
/**
|
||||
* Deprecated. Use `Fill.getGradientColors()`
|
||||
*/
|
||||
@Deprecated
|
||||
public int getEndColor()
|
||||
{
|
||||
return getGradientColors()[1];
|
||||
}
|
||||
|
||||
public int getEndColor() {
|
||||
return endColor;
|
||||
/**
|
||||
* Deprecated. Use `Fill.setGradientColors(...)`
|
||||
*/
|
||||
@Deprecated
|
||||
public void setEndColor(int endColor)
|
||||
{
|
||||
if (getGradientColors() == null || getGradientColors().length != 2)
|
||||
{
|
||||
setGradientColors(new int[]{
|
||||
getGradientColors() != null && getGradientColors().length > 0
|
||||
? getGradientColors()[0]
|
||||
: 0,
|
||||
endColor
|
||||
});
|
||||
} else
|
||||
{
|
||||
getGradientColors()[1] = endColor;
|
||||
}
|
||||
}
|
||||
|
||||
public void setEndColor(int endColor) {
|
||||
this.endColor = endColor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,9 +174,12 @@ public abstract class AxisRenderer extends Renderer {
|
|||
double intervalMagnitude = Utils.roundToNextSignificant(Math.pow(10, (int) Math.log10(interval)));
|
||||
int intervalSigDigit = (int) (interval / intervalMagnitude);
|
||||
if (intervalSigDigit > 5) {
|
||||
// Use one order of magnitude higher, to avoid intervals like 0.9 or
|
||||
// 90
|
||||
interval = Math.floor(10 * intervalMagnitude);
|
||||
// Use one order of magnitude higher, to avoid intervals like 0.9 or 90
|
||||
// if it's 0.0 after floor(), we use the old value
|
||||
interval = Math.floor(10.0 * intervalMagnitude) == 0.0
|
||||
? interval
|
||||
: Math.floor(10.0 * intervalMagnitude);
|
||||
|
||||
}
|
||||
|
||||
int n = mAxis.isCenterAxisLabelsEnabled() ? 1 : 0;
|
||||
|
@ -214,11 +217,14 @@ public abstract class AxisRenderer extends Renderer {
|
|||
double f;
|
||||
int i;
|
||||
|
||||
if (interval != 0.0) {
|
||||
if (interval != 0.0 && last != first) {
|
||||
for (f = first; f <= last; f += interval) {
|
||||
++n;
|
||||
}
|
||||
}
|
||||
else if (last == first && n == 0) {
|
||||
n = 1;
|
||||
}
|
||||
|
||||
mAxis.mEntryCount = n;
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
@ -11,16 +10,16 @@ import com.github.mikephil.charting.animation.ChartAnimator;
|
|||
import com.github.mikephil.charting.buffer.BarBuffer;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.highlight.Range;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.utils.Fill;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.github.mikephil.charting.utils.Transformer;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
import android.graphics.LinearGradient;
|
||||
import com.github.mikephil.charting.model.GradientColor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -145,13 +144,15 @@ public class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
|
||||
trans.pointValuesToPixel(buffer.buffer);
|
||||
|
||||
final boolean isCustomFill = dataSet.getFills() != null && !dataSet.getFills().isEmpty();
|
||||
final boolean isSingleColor = dataSet.getColors().size() == 1;
|
||||
final boolean isInverted = mChart.isInverted(dataSet.getAxisDependency());
|
||||
|
||||
if (isSingleColor) {
|
||||
mRenderPaint.setColor(dataSet.getColor());
|
||||
}
|
||||
|
||||
for (int j = 0; j < buffer.size(); j += 4) {
|
||||
for (int j = 0, pos = 0; j < buffer.size(); j += 4, pos++) {
|
||||
|
||||
if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2]))
|
||||
continue;
|
||||
|
@ -162,38 +163,24 @@ public class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
if (!isSingleColor) {
|
||||
// Set the color for the currently drawn value. If the index
|
||||
// is out of bounds, reuse colors.
|
||||
mRenderPaint.setColor(dataSet.getColor(j / 4));
|
||||
mRenderPaint.setColor(dataSet.getColor(pos));
|
||||
}
|
||||
|
||||
if (dataSet.getGradientColor() != null) {
|
||||
GradientColor gradientColor = dataSet.getGradientColor();
|
||||
mRenderPaint.setShader(
|
||||
new LinearGradient(
|
||||
buffer.buffer[j],
|
||||
buffer.buffer[j + 3],
|
||||
buffer.buffer[j],
|
||||
buffer.buffer[j + 1],
|
||||
gradientColor.getStartColor(),
|
||||
gradientColor.getEndColor(),
|
||||
android.graphics.Shader.TileMode.MIRROR));
|
||||
if (isCustomFill) {
|
||||
dataSet.getFill(pos)
|
||||
.fillRect(
|
||||
c, mRenderPaint,
|
||||
buffer.buffer[j],
|
||||
buffer.buffer[j + 1],
|
||||
buffer.buffer[j + 2],
|
||||
buffer.buffer[j + 3],
|
||||
isInverted ? Fill.Direction.DOWN : Fill.Direction.UP);
|
||||
}
|
||||
|
||||
if (dataSet.getGradientColors() != null) {
|
||||
mRenderPaint.setShader(
|
||||
new LinearGradient(
|
||||
buffer.buffer[j],
|
||||
buffer.buffer[j + 3],
|
||||
buffer.buffer[j],
|
||||
buffer.buffer[j + 1],
|
||||
dataSet.getGradientColor(j / 4).getStartColor(),
|
||||
dataSet.getGradientColor(j / 4).getEndColor(),
|
||||
android.graphics.Shader.TileMode.MIRROR));
|
||||
else {
|
||||
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
|
||||
buffer.buffer[j + 3], mRenderPaint);
|
||||
}
|
||||
|
||||
|
||||
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
|
||||
buffer.buffer[j + 3], mRenderPaint);
|
||||
|
||||
if (drawBorder) {
|
||||
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
|
||||
buffer.buffer[j + 3], mBarBorderPaint);
|
||||
|
@ -254,6 +241,8 @@ public class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
|
||||
final float phaseY = mAnimator.getPhaseY();
|
||||
|
||||
ValueFormatter formatter = dataSet.getValueFormatter();
|
||||
|
||||
MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
|
||||
iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
|
||||
iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
|
||||
|
@ -276,8 +265,7 @@ public class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
float val = entry.getY();
|
||||
|
||||
if (dataSet.isDrawValuesEnabled()) {
|
||||
drawValue(c, dataSet.getValueFormatter(), val, entry, i, x,
|
||||
val >= 0 ?
|
||||
drawValue(c, formatter.getBarLabel(entry), x, val >= 0 ?
|
||||
(buffer.buffer[j + 1] + posOffset) :
|
||||
(buffer.buffer[j + 3] + negOffset),
|
||||
dataSet.getValueTextColor(j / 4));
|
||||
|
@ -335,8 +323,7 @@ public class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
continue;
|
||||
|
||||
if (dataSet.isDrawValuesEnabled()) {
|
||||
drawValue(c, dataSet.getValueFormatter(), entry.getY(), entry, i, x,
|
||||
buffer.buffer[bufferIndex + 1] +
|
||||
drawValue(c, formatter.getBarLabel(entry), x, buffer.buffer[bufferIndex + 1] +
|
||||
(entry.getY() >= 0 ? posOffset : negOffset),
|
||||
color);
|
||||
}
|
||||
|
@ -407,14 +394,7 @@ public class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
continue;
|
||||
|
||||
if (dataSet.isDrawValuesEnabled()) {
|
||||
drawValue(c,
|
||||
dataSet.getValueFormatter(),
|
||||
vals[k / 2],
|
||||
entry,
|
||||
i,
|
||||
x,
|
||||
y,
|
||||
color);
|
||||
drawValue(c, formatter.getBarStackedLabel(val, entry), x, y, color);
|
||||
}
|
||||
|
||||
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
|
||||
|
@ -442,6 +422,12 @@ public class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawValue(Canvas c, String valueText, float x, float y, int color) {
|
||||
mValuePaint.setColor(color);
|
||||
c.drawText(valueText, x, y, mValuePaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawHighlighted(Canvas c, Highlight[] indices) {
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
@ -9,6 +8,7 @@ import android.graphics.drawable.Drawable;
|
|||
import com.github.mikephil.charting.animation.ChartAnimator;
|
||||
import com.github.mikephil.charting.data.BubbleData;
|
||||
import com.github.mikephil.charting.data.BubbleEntry;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.BubbleDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBubbleDataSet;
|
||||
|
@ -108,7 +108,7 @@ public class BubbleChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
if (!mViewPortHandler.isInBoundsRight(pointBuffer[0] - shapeHalf))
|
||||
break;
|
||||
|
||||
final int color = dataSet.getColor((int) entry.getX());
|
||||
final int color = dataSet.getColor(j);
|
||||
|
||||
mRenderPaint.setColor(color);
|
||||
c.drawCircle(pointBuffer[0], pointBuffer[1], shapeHalf, mRenderPaint);
|
||||
|
@ -150,6 +150,8 @@ public class BubbleChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
|
||||
final float alpha = phaseX == 1 ? phaseY : phaseX;
|
||||
|
||||
ValueFormatter formatter = dataSet.getValueFormatter();
|
||||
|
||||
MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
|
||||
iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
|
||||
iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
|
||||
|
@ -172,8 +174,7 @@ public class BubbleChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
BubbleEntry entry = dataSet.getEntryForIndex(j / 2 + mXBounds.min);
|
||||
|
||||
if (dataSet.isDrawValuesEnabled()) {
|
||||
drawValue(c, dataSet.getValueFormatter(), entry.getSize(), entry, i, x,
|
||||
y + (0.5f * lineHeight), valueTextColor);
|
||||
drawValue(c, formatter.getBubbleLabel(entry), x, y + (0.5f * lineHeight), valueTextColor);
|
||||
}
|
||||
|
||||
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
|
||||
|
@ -195,6 +196,12 @@ public class BubbleChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawValue(Canvas c, String valueText, float x, float y, int color) {
|
||||
mValuePaint.setColor(color);
|
||||
c.drawText(valueText, x, y, mValuePaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawExtras(Canvas c) {
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
@ -8,6 +7,7 @@ import android.graphics.drawable.Drawable;
|
|||
import com.github.mikephil.charting.animation.ChartAnimator;
|
||||
import com.github.mikephil.charting.data.CandleData;
|
||||
import com.github.mikephil.charting.data.CandleEntry;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.CandleDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ICandleDataSet;
|
||||
|
@ -279,6 +279,8 @@ public class CandleStickChartRenderer extends LineScatterCandleRadarRenderer {
|
|||
|
||||
float yOffset = Utils.convertDpToPixel(5f);
|
||||
|
||||
ValueFormatter formatter = dataSet.getValueFormatter();
|
||||
|
||||
MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
|
||||
iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
|
||||
iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
|
||||
|
@ -297,15 +299,7 @@ public class CandleStickChartRenderer extends LineScatterCandleRadarRenderer {
|
|||
CandleEntry entry = dataSet.getEntryForIndex(j / 2 + mXBounds.min);
|
||||
|
||||
if (dataSet.isDrawValuesEnabled()) {
|
||||
drawValue(c,
|
||||
dataSet.getValueFormatter(),
|
||||
entry.getHigh(),
|
||||
entry,
|
||||
i,
|
||||
x,
|
||||
y - yOffset,
|
||||
dataSet
|
||||
.getValueTextColor(j / 2));
|
||||
drawValue(c, formatter.getCandleLabel(entry), x, y - yOffset, dataSet.getValueTextColor(j / 2));
|
||||
}
|
||||
|
||||
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
|
||||
|
@ -327,6 +321,12 @@ public class CandleStickChartRenderer extends LineScatterCandleRadarRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawValue(Canvas c, String valueText, float x, float y, int color) {
|
||||
mValuePaint.setColor(color);
|
||||
c.drawText(valueText, x, y, mValuePaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawExtras(Canvas c) {
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.util.Log;
|
||||
|
||||
import com.github.mikephil.charting.animation.ChartAnimator;
|
||||
import com.github.mikephil.charting.charts.Chart;
|
||||
|
@ -9,7 +10,6 @@ import com.github.mikephil.charting.charts.CombinedChart.DrawOrder;
|
|||
import com.github.mikephil.charting.data.ChartData;
|
||||
import com.github.mikephil.charting.data.CombinedData;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.BarLineScatterCandleBubbleDataProvider;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
@ -89,6 +89,11 @@ public class CombinedChartRenderer extends DataRenderer {
|
|||
renderer.drawData(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawValue(Canvas c, String valueText, float x, float y, int color) {
|
||||
Log.e("MPAndroidChart", "Erroneous call to drawValue() in CombinedChartRenderer!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawValues(Canvas c) {
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
@ -6,15 +5,11 @@ import android.graphics.Color;
|
|||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.github.mikephil.charting.animation.ChartAnimator;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.ChartInterface;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
|
@ -138,19 +133,13 @@ public abstract class DataRenderer extends Renderer {
|
|||
/**
|
||||
* Draws the value of the given entry by using the provided IValueFormatter.
|
||||
*
|
||||
* @param c canvas
|
||||
* @param formatter formatter for custom value-formatting
|
||||
* @param value the value to be drawn
|
||||
* @param entry the entry the value belongs to
|
||||
* @param dataSetIndex the index of the DataSet the drawn Entry belongs to
|
||||
* @param x position
|
||||
* @param y position
|
||||
* @param c canvas
|
||||
* @param valueText label to draw
|
||||
* @param x position
|
||||
* @param y position
|
||||
* @param color
|
||||
*/
|
||||
public void drawValue(Canvas c, IValueFormatter formatter, float value, Entry entry, int dataSetIndex, float x, float y, int color) {
|
||||
mValuePaint.setColor(color);
|
||||
c.drawText(formatter.getFormattedValue(value, entry, dataSetIndex, mViewPortHandler), x, y, mValuePaint);
|
||||
}
|
||||
public abstract void drawValue(Canvas c, String valueText, float x, float y, int color);
|
||||
|
||||
/**
|
||||
* Draws any kind of additional information (e.g. line-circles).
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
@ -11,11 +10,12 @@ import com.github.mikephil.charting.buffer.BarBuffer;
|
|||
import com.github.mikephil.charting.buffer.HorizontalBarBuffer;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.ChartInterface;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.utils.Fill;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.github.mikephil.charting.utils.Transformer;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
@ -112,13 +112,15 @@ public class HorizontalBarChartRenderer extends BarChartRenderer {
|
|||
|
||||
trans.pointValuesToPixel(buffer.buffer);
|
||||
|
||||
final boolean isCustomFill = dataSet.getFills() != null && !dataSet.getFills().isEmpty();
|
||||
final boolean isSingleColor = dataSet.getColors().size() == 1;
|
||||
final boolean isInverted = mChart.isInverted(dataSet.getAxisDependency());
|
||||
|
||||
if (isSingleColor) {
|
||||
mRenderPaint.setColor(dataSet.getColor());
|
||||
}
|
||||
|
||||
for (int j = 0; j < buffer.size(); j += 4) {
|
||||
for (int j = 0, pos = 0; j < buffer.size(); j += 4, pos++) {
|
||||
|
||||
if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 3]))
|
||||
break;
|
||||
|
@ -132,8 +134,20 @@ public class HorizontalBarChartRenderer extends BarChartRenderer {
|
|||
mRenderPaint.setColor(dataSet.getColor(j / 4));
|
||||
}
|
||||
|
||||
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
|
||||
buffer.buffer[j + 3], mRenderPaint);
|
||||
if (isCustomFill) {
|
||||
dataSet.getFill(pos)
|
||||
.fillRect(
|
||||
c, mRenderPaint,
|
||||
buffer.buffer[j],
|
||||
buffer.buffer[j + 1],
|
||||
buffer.buffer[j + 2],
|
||||
buffer.buffer[j + 3],
|
||||
isInverted ? Fill.Direction.LEFT : Fill.Direction.RIGHT);
|
||||
}
|
||||
else {
|
||||
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
|
||||
buffer.buffer[j + 3], mRenderPaint);
|
||||
}
|
||||
|
||||
if (drawBorder) {
|
||||
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
|
||||
|
@ -167,7 +181,7 @@ public class HorizontalBarChartRenderer extends BarChartRenderer {
|
|||
applyValueTextStyle(dataSet);
|
||||
final float halfTextHeight = Utils.calcTextHeight(mValuePaint, "10") / 2f;
|
||||
|
||||
IValueFormatter formatter = dataSet.getValueFormatter();
|
||||
ValueFormatter formatter = dataSet.getValueFormatter();
|
||||
|
||||
// get the buffer
|
||||
BarBuffer buffer = mBarBuffers[i];
|
||||
|
@ -196,12 +210,13 @@ public class HorizontalBarChartRenderer extends BarChartRenderer {
|
|||
|
||||
BarEntry entry = dataSet.getEntryForIndex(j / 4);
|
||||
float val = entry.getY();
|
||||
String formattedValue = formatter.getFormattedValue(val, entry, i, mViewPortHandler);
|
||||
String formattedValue = formatter.getBarLabel(entry);
|
||||
|
||||
// calculate the correct offset depending on the draw position of the value
|
||||
float valueTextWidth = Utils.calcTextWidth(mValuePaint, formattedValue);
|
||||
posOffset = (drawValueAboveBar ? valueOffsetPlus : -(valueTextWidth + valueOffsetPlus));
|
||||
negOffset = (drawValueAboveBar ? -(valueTextWidth + valueOffsetPlus) : valueOffsetPlus);
|
||||
negOffset = (drawValueAboveBar ? -(valueTextWidth + valueOffsetPlus) : valueOffsetPlus)
|
||||
- (buffer.buffer[j + 2] - buffer.buffer[j]);
|
||||
|
||||
if (isInverted) {
|
||||
posOffset = -posOffset - valueTextWidth;
|
||||
|
@ -265,9 +280,7 @@ public class HorizontalBarChartRenderer extends BarChartRenderer {
|
|||
if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[bufferIndex + 1]))
|
||||
continue;
|
||||
|
||||
float val = entry.getY();
|
||||
String formattedValue = formatter.getFormattedValue(val,
|
||||
entry, i, mViewPortHandler);
|
||||
String formattedValue = formatter.getBarLabel(entry);
|
||||
|
||||
// calculate the correct offset depending on the draw position of the value
|
||||
float valueTextWidth = Utils.calcTextWidth(mValuePaint, formattedValue);
|
||||
|
@ -337,8 +350,7 @@ public class HorizontalBarChartRenderer extends BarChartRenderer {
|
|||
for (int k = 0; k < transformed.length; k += 2) {
|
||||
|
||||
final float val = vals[k / 2];
|
||||
String formattedValue = formatter.getFormattedValue(val,
|
||||
entry, i, mViewPortHandler);
|
||||
String formattedValue = formatter.getBarStackedLabel(val, entry);
|
||||
|
||||
// calculate the correct offset depending on the draw position of the value
|
||||
float valueTextWidth = Utils.calcTextWidth(mValuePaint, formattedValue);
|
||||
|
@ -396,7 +408,8 @@ public class HorizontalBarChartRenderer extends BarChartRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
protected void drawValue(Canvas c, String valueText, float x, float y, int color) {
|
||||
@Override
|
||||
public void drawValue(Canvas c, String valueText, float x, float y, int color) {
|
||||
mValuePaint.setColor(color);
|
||||
c.drawText(valueText, x, y, mValuePaint);
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@ public class LegendRenderer extends Renderer {
|
|||
for (int i = 0; i < data.getDataSetCount(); i++) {
|
||||
|
||||
IDataSet dataSet = data.getDataSetByIndex(i);
|
||||
if (dataSet == null) continue;
|
||||
|
||||
List<Integer> clrs = dataSet.getColors();
|
||||
int entryCount = dataSet.getEntryCount();
|
||||
|
@ -100,10 +101,19 @@ public class LegendRenderer extends Renderer {
|
|||
IBarDataSet bds = (IBarDataSet) dataSet;
|
||||
String[] sLabels = bds.getStackLabels();
|
||||
|
||||
for (int j = 0; j < clrs.size() && j < bds.getStackSize(); j++) {
|
||||
int minEntries = Math.min(clrs.size(), bds.getStackSize());
|
||||
|
||||
for (int j = 0; j < minEntries; j++) {
|
||||
String label;
|
||||
if (sLabels.length > 0) {
|
||||
int labelIndex = j % minEntries;
|
||||
label = labelIndex < sLabels.length ? sLabels[labelIndex] : null;
|
||||
} else {
|
||||
label = null;
|
||||
}
|
||||
|
||||
computedEntries.add(new LegendEntry(
|
||||
sLabels[j % sLabels.length],
|
||||
label,
|
||||
dataSet.getForm(),
|
||||
dataSet.getFormSize(),
|
||||
dataSet.getFormLineWidth(),
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.github.mikephil.charting.charts.LineChart;
|
|||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
|
@ -294,7 +295,7 @@ public class LineChartRenderer extends LineRadarRenderer {
|
|||
|
||||
int entryCount = dataSet.getEntryCount();
|
||||
|
||||
final boolean isDrawSteppedEnabled = dataSet.isDrawSteppedEnabled();
|
||||
final boolean isDrawSteppedEnabled = dataSet.getMode() == LineDataSet.Mode.STEPPED;
|
||||
final int pointsPerEntryPair = isDrawSteppedEnabled ? 4 : 2;
|
||||
|
||||
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
|
||||
|
@ -322,10 +323,14 @@ public class LineChartRenderer extends LineRadarRenderer {
|
|||
// more than 1 color
|
||||
if (dataSet.getColors().size() > 1) {
|
||||
|
||||
if (mLineBuffer.length <= pointsPerEntryPair * 2)
|
||||
mLineBuffer = new float[pointsPerEntryPair * 4];
|
||||
int numberOfFloats = pointsPerEntryPair * 2;
|
||||
|
||||
for (int j = mXBounds.min; j <= mXBounds.range + mXBounds.min; j++) {
|
||||
if (mLineBuffer.length <= numberOfFloats)
|
||||
mLineBuffer = new float[numberOfFloats * 2];
|
||||
|
||||
int max = mXBounds.min + mXBounds.range;
|
||||
|
||||
for (int j = mXBounds.min; j < max; j++) {
|
||||
|
||||
Entry e = dataSet.getEntryForIndex(j);
|
||||
if (e == null) continue;
|
||||
|
@ -356,16 +361,26 @@ public class LineChartRenderer extends LineRadarRenderer {
|
|||
mLineBuffer[3] = mLineBuffer[1];
|
||||
}
|
||||
|
||||
// Determine the start and end coordinates of the line, and make sure they differ.
|
||||
float firstCoordinateX = mLineBuffer[0];
|
||||
float firstCoordinateY = mLineBuffer[1];
|
||||
float lastCoordinateX = mLineBuffer[numberOfFloats - 2];
|
||||
float lastCoordinateY = mLineBuffer[numberOfFloats - 1];
|
||||
|
||||
if (firstCoordinateX == lastCoordinateX &&
|
||||
firstCoordinateY == lastCoordinateY)
|
||||
continue;
|
||||
|
||||
trans.pointValuesToPixel(mLineBuffer);
|
||||
|
||||
if (!mViewPortHandler.isInBoundsRight(mLineBuffer[0]))
|
||||
if (!mViewPortHandler.isInBoundsRight(firstCoordinateX))
|
||||
break;
|
||||
|
||||
// make sure the lines don't do shitty things outside
|
||||
// bounds
|
||||
if (!mViewPortHandler.isInBoundsLeft(mLineBuffer[2])
|
||||
|| (!mViewPortHandler.isInBoundsTop(mLineBuffer[1]) && !mViewPortHandler
|
||||
.isInBoundsBottom(mLineBuffer[3])))
|
||||
if (!mViewPortHandler.isInBoundsLeft(lastCoordinateX) ||
|
||||
!mViewPortHandler.isInBoundsTop(Math.max(firstCoordinateY, lastCoordinateY)) ||
|
||||
!mViewPortHandler.isInBoundsBottom(Math.min(firstCoordinateY, lastCoordinateY)))
|
||||
continue;
|
||||
|
||||
// get the color that is set for this line-segment
|
||||
|
@ -547,6 +562,7 @@ public class LineChartRenderer extends LineRadarRenderer {
|
|||
|
||||
float[] positions = trans.generateTransformedValuesLine(dataSet, mAnimator.getPhaseX(), mAnimator
|
||||
.getPhaseY(), mXBounds.min, mXBounds.max);
|
||||
ValueFormatter formatter = dataSet.getValueFormatter();
|
||||
|
||||
MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
|
||||
iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
|
||||
|
@ -566,8 +582,7 @@ public class LineChartRenderer extends LineRadarRenderer {
|
|||
Entry entry = dataSet.getEntryForIndex(j / 2 + mXBounds.min);
|
||||
|
||||
if (dataSet.isDrawValuesEnabled()) {
|
||||
drawValue(c, dataSet.getValueFormatter(), entry.getY(), entry, i, x,
|
||||
y - valOffset, dataSet.getValueTextColor(j / 2));
|
||||
drawValue(c, formatter.getPointLabel(entry), x, y - valOffset, dataSet.getValueTextColor(j / 2));
|
||||
}
|
||||
|
||||
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
|
||||
|
@ -589,6 +604,12 @@ public class LineChartRenderer extends LineRadarRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawValue(Canvas c, String valueText, float x, float y, int color) {
|
||||
mValuePaint.setColor(color);
|
||||
c.drawText(valueText, x, y, mValuePaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawExtras(Canvas c) {
|
||||
drawCircles(c);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
@ -22,7 +21,7 @@ import com.github.mikephil.charting.data.Entry;
|
|||
import com.github.mikephil.charting.data.PieData;
|
||||
import com.github.mikephil.charting.data.PieDataSet;
|
||||
import com.github.mikephil.charting.data.PieEntry;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IPieDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
@ -231,6 +230,9 @@ public class PieChartRenderer extends DataRenderer {
|
|||
final float userInnerRadius = drawInnerArc
|
||||
? radius * (mChart.getHoleRadius() / 100.f)
|
||||
: 0.f;
|
||||
final float roundedRadius = (radius - (radius * mChart.getHoleRadius() / 100f)) / 2f;
|
||||
final RectF roundedCircleBox = new RectF();
|
||||
final boolean drawRoundedSlices = drawInnerArc && mChart.isDrawRoundedSlicesEnabled();
|
||||
|
||||
int visibleAngleCount = 0;
|
||||
for (int j = 0; j < entryCount; j++) {
|
||||
|
@ -250,133 +252,151 @@ public class PieChartRenderer extends DataRenderer {
|
|||
Entry e = dataSet.getEntryForIndex(j);
|
||||
|
||||
// draw only if the value is greater than zero
|
||||
if ((Math.abs(e.getY()) > Utils.FLOAT_EPSILON)) {
|
||||
|
||||
if (!mChart.needsHighlight(j)) {
|
||||
|
||||
final boolean accountForSliceSpacing = sliceSpace > 0.f && sliceAngle <= 180.f;
|
||||
|
||||
mRenderPaint.setColor(dataSet.getColor(j));
|
||||
|
||||
final float sliceSpaceAngleOuter = visibleAngleCount == 1 ?
|
||||
0.f :
|
||||
sliceSpace / (Utils.FDEG2RAD * radius);
|
||||
final float startAngleOuter = rotationAngle + (angle + sliceSpaceAngleOuter / 2.f) * phaseY;
|
||||
float sweepAngleOuter = (sliceAngle - sliceSpaceAngleOuter) * phaseY;
|
||||
if (sweepAngleOuter < 0.f) {
|
||||
sweepAngleOuter = 0.f;
|
||||
}
|
||||
|
||||
mPathBuffer.reset();
|
||||
|
||||
float arcStartPointX = center.x + radius * (float) Math.cos(startAngleOuter * Utils.FDEG2RAD);
|
||||
float arcStartPointY = center.y + radius * (float) Math.sin(startAngleOuter * Utils.FDEG2RAD);
|
||||
|
||||
if (sweepAngleOuter >= 360.f && sweepAngleOuter % 360f <= Utils.FLOAT_EPSILON) {
|
||||
// Android is doing "mod 360"
|
||||
mPathBuffer.addCircle(center.x, center.y, radius, Path.Direction.CW);
|
||||
} else {
|
||||
|
||||
mPathBuffer.moveTo(arcStartPointX, arcStartPointY);
|
||||
|
||||
mPathBuffer.arcTo(
|
||||
circleBox,
|
||||
startAngleOuter,
|
||||
sweepAngleOuter
|
||||
);
|
||||
}
|
||||
|
||||
// API < 21 does not receive floats in addArc, but a RectF
|
||||
mInnerRectBuffer.set(
|
||||
center.x - innerRadius,
|
||||
center.y - innerRadius,
|
||||
center.x + innerRadius,
|
||||
center.y + innerRadius);
|
||||
|
||||
if (drawInnerArc &&
|
||||
(innerRadius > 0.f || accountForSliceSpacing)) {
|
||||
|
||||
if (accountForSliceSpacing) {
|
||||
float minSpacedRadius =
|
||||
calculateMinimumRadiusForSpacedSlice(
|
||||
center, radius,
|
||||
sliceAngle * phaseY,
|
||||
arcStartPointX, arcStartPointY,
|
||||
startAngleOuter,
|
||||
sweepAngleOuter);
|
||||
|
||||
if (minSpacedRadius < 0.f)
|
||||
minSpacedRadius = -minSpacedRadius;
|
||||
|
||||
innerRadius = Math.max(innerRadius, minSpacedRadius);
|
||||
}
|
||||
|
||||
final float sliceSpaceAngleInner = visibleAngleCount == 1 || innerRadius == 0.f ?
|
||||
0.f :
|
||||
sliceSpace / (Utils.FDEG2RAD * innerRadius);
|
||||
final float startAngleInner = rotationAngle + (angle + sliceSpaceAngleInner / 2.f) * phaseY;
|
||||
float sweepAngleInner = (sliceAngle - sliceSpaceAngleInner) * phaseY;
|
||||
if (sweepAngleInner < 0.f) {
|
||||
sweepAngleInner = 0.f;
|
||||
}
|
||||
final float endAngleInner = startAngleInner + sweepAngleInner;
|
||||
|
||||
if (sweepAngleOuter >= 360.f && sweepAngleOuter % 360f <= Utils.FLOAT_EPSILON) {
|
||||
// Android is doing "mod 360"
|
||||
mPathBuffer.addCircle(center.x, center.y, innerRadius, Path.Direction.CCW);
|
||||
} else {
|
||||
|
||||
mPathBuffer.lineTo(
|
||||
center.x + innerRadius * (float) Math.cos(endAngleInner * Utils.FDEG2RAD),
|
||||
center.y + innerRadius * (float) Math.sin(endAngleInner * Utils.FDEG2RAD));
|
||||
|
||||
mPathBuffer.arcTo(
|
||||
mInnerRectBuffer,
|
||||
endAngleInner,
|
||||
-sweepAngleInner
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
if (sweepAngleOuter % 360f > Utils.FLOAT_EPSILON) {
|
||||
if (accountForSliceSpacing) {
|
||||
|
||||
float angleMiddle = startAngleOuter + sweepAngleOuter / 2.f;
|
||||
|
||||
float sliceSpaceOffset =
|
||||
calculateMinimumRadiusForSpacedSlice(
|
||||
center,
|
||||
radius,
|
||||
sliceAngle * phaseY,
|
||||
arcStartPointX,
|
||||
arcStartPointY,
|
||||
startAngleOuter,
|
||||
sweepAngleOuter);
|
||||
|
||||
float arcEndPointX = center.x +
|
||||
sliceSpaceOffset * (float) Math.cos(angleMiddle * Utils.FDEG2RAD);
|
||||
float arcEndPointY = center.y +
|
||||
sliceSpaceOffset * (float) Math.sin(angleMiddle * Utils.FDEG2RAD);
|
||||
|
||||
mPathBuffer.lineTo(
|
||||
arcEndPointX,
|
||||
arcEndPointY);
|
||||
|
||||
} else {
|
||||
mPathBuffer.lineTo(
|
||||
center.x,
|
||||
center.y);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mPathBuffer.close();
|
||||
|
||||
mBitmapCanvas.drawPath(mPathBuffer, mRenderPaint);
|
||||
}
|
||||
if (!(Math.abs(e.getY()) > Utils.FLOAT_EPSILON)) {
|
||||
angle += sliceAngle * phaseX;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't draw if it's highlighted, unless the chart uses rounded slices
|
||||
if (dataSet.isHighlightEnabled() && mChart.needsHighlight(j) && !drawRoundedSlices) {
|
||||
angle += sliceAngle * phaseX;
|
||||
continue;
|
||||
}
|
||||
|
||||
final boolean accountForSliceSpacing = sliceSpace > 0.f && sliceAngle <= 180.f;
|
||||
|
||||
mRenderPaint.setColor(dataSet.getColor(j));
|
||||
|
||||
final float sliceSpaceAngleOuter = visibleAngleCount == 1 ?
|
||||
0.f :
|
||||
sliceSpace / (Utils.FDEG2RAD * radius);
|
||||
final float startAngleOuter = rotationAngle + (angle + sliceSpaceAngleOuter / 2.f) * phaseY;
|
||||
float sweepAngleOuter = (sliceAngle - sliceSpaceAngleOuter) * phaseY;
|
||||
if (sweepAngleOuter < 0.f) {
|
||||
sweepAngleOuter = 0.f;
|
||||
}
|
||||
|
||||
mPathBuffer.reset();
|
||||
|
||||
if (drawRoundedSlices) {
|
||||
float x = center.x + (radius - roundedRadius) * (float) Math.cos(startAngleOuter * Utils.FDEG2RAD);
|
||||
float y = center.y + (radius - roundedRadius) * (float) Math.sin(startAngleOuter * Utils.FDEG2RAD);
|
||||
roundedCircleBox.set(x - roundedRadius, y - roundedRadius, x + roundedRadius, y + roundedRadius);
|
||||
}
|
||||
|
||||
float arcStartPointX = center.x + radius * (float) Math.cos(startAngleOuter * Utils.FDEG2RAD);
|
||||
float arcStartPointY = center.y + radius * (float) Math.sin(startAngleOuter * Utils.FDEG2RAD);
|
||||
|
||||
if (sweepAngleOuter >= 360.f && sweepAngleOuter % 360f <= Utils.FLOAT_EPSILON) {
|
||||
// Android is doing "mod 360"
|
||||
mPathBuffer.addCircle(center.x, center.y, radius, Path.Direction.CW);
|
||||
} else {
|
||||
|
||||
if (drawRoundedSlices) {
|
||||
mPathBuffer.arcTo(roundedCircleBox, startAngleOuter + 180, -180);
|
||||
}
|
||||
|
||||
mPathBuffer.arcTo(
|
||||
circleBox,
|
||||
startAngleOuter,
|
||||
sweepAngleOuter
|
||||
);
|
||||
}
|
||||
|
||||
// API < 21 does not receive floats in addArc, but a RectF
|
||||
mInnerRectBuffer.set(
|
||||
center.x - innerRadius,
|
||||
center.y - innerRadius,
|
||||
center.x + innerRadius,
|
||||
center.y + innerRadius);
|
||||
|
||||
if (drawInnerArc && (innerRadius > 0.f || accountForSliceSpacing)) {
|
||||
|
||||
if (accountForSliceSpacing) {
|
||||
float minSpacedRadius =
|
||||
calculateMinimumRadiusForSpacedSlice(
|
||||
center, radius,
|
||||
sliceAngle * phaseY,
|
||||
arcStartPointX, arcStartPointY,
|
||||
startAngleOuter,
|
||||
sweepAngleOuter);
|
||||
|
||||
if (minSpacedRadius < 0.f)
|
||||
minSpacedRadius = -minSpacedRadius;
|
||||
|
||||
innerRadius = Math.max(innerRadius, minSpacedRadius);
|
||||
}
|
||||
|
||||
final float sliceSpaceAngleInner = visibleAngleCount == 1 || innerRadius == 0.f ?
|
||||
0.f :
|
||||
sliceSpace / (Utils.FDEG2RAD * innerRadius);
|
||||
final float startAngleInner = rotationAngle + (angle + sliceSpaceAngleInner / 2.f) * phaseY;
|
||||
float sweepAngleInner = (sliceAngle - sliceSpaceAngleInner) * phaseY;
|
||||
if (sweepAngleInner < 0.f) {
|
||||
sweepAngleInner = 0.f;
|
||||
}
|
||||
final float endAngleInner = startAngleInner + sweepAngleInner;
|
||||
|
||||
if (sweepAngleOuter >= 360.f && sweepAngleOuter % 360f <= Utils.FLOAT_EPSILON) {
|
||||
// Android is doing "mod 360"
|
||||
mPathBuffer.addCircle(center.x, center.y, innerRadius, Path.Direction.CCW);
|
||||
} else {
|
||||
|
||||
if (drawRoundedSlices) {
|
||||
float x = center.x + (radius - roundedRadius) * (float) Math.cos(endAngleInner * Utils.FDEG2RAD);
|
||||
float y = center.y + (radius - roundedRadius) * (float) Math.sin(endAngleInner * Utils.FDEG2RAD);
|
||||
roundedCircleBox.set(x - roundedRadius, y - roundedRadius, x + roundedRadius, y + roundedRadius);
|
||||
mPathBuffer.arcTo(roundedCircleBox, endAngleInner, 180);
|
||||
} else
|
||||
mPathBuffer.lineTo(
|
||||
center.x + innerRadius * (float) Math.cos(endAngleInner * Utils.FDEG2RAD),
|
||||
center.y + innerRadius * (float) Math.sin(endAngleInner * Utils.FDEG2RAD));
|
||||
|
||||
mPathBuffer.arcTo(
|
||||
mInnerRectBuffer,
|
||||
endAngleInner,
|
||||
-sweepAngleInner
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
if (sweepAngleOuter % 360f > Utils.FLOAT_EPSILON) {
|
||||
if (accountForSliceSpacing) {
|
||||
|
||||
float angleMiddle = startAngleOuter + sweepAngleOuter / 2.f;
|
||||
|
||||
float sliceSpaceOffset =
|
||||
calculateMinimumRadiusForSpacedSlice(
|
||||
center,
|
||||
radius,
|
||||
sliceAngle * phaseY,
|
||||
arcStartPointX,
|
||||
arcStartPointY,
|
||||
startAngleOuter,
|
||||
sweepAngleOuter);
|
||||
|
||||
float arcEndPointX = center.x +
|
||||
sliceSpaceOffset * (float) Math.cos(angleMiddle * Utils.FDEG2RAD);
|
||||
float arcEndPointY = center.y +
|
||||
sliceSpaceOffset * (float) Math.sin(angleMiddle * Utils.FDEG2RAD);
|
||||
|
||||
mPathBuffer.lineTo(
|
||||
arcEndPointX,
|
||||
arcEndPointY);
|
||||
|
||||
} else {
|
||||
mPathBuffer.lineTo(
|
||||
center.x,
|
||||
center.y);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mPathBuffer.close();
|
||||
|
||||
mBitmapCanvas.drawPath(mPathBuffer, mRenderPaint);
|
||||
|
||||
angle += sliceAngle * phaseX;
|
||||
}
|
||||
|
||||
|
@ -397,11 +417,17 @@ public class PieChartRenderer extends DataRenderer {
|
|||
float phaseX = mAnimator.getPhaseX();
|
||||
float phaseY = mAnimator.getPhaseY();
|
||||
|
||||
final float roundedRadius = (radius - (radius * mChart.getHoleRadius() / 100f)) / 2f;
|
||||
final float holeRadiusPercent = mChart.getHoleRadius() / 100.f;
|
||||
float labelRadiusOffset = radius / 10f * 3.6f;
|
||||
|
||||
if (mChart.isDrawHoleEnabled()) {
|
||||
labelRadiusOffset = (radius - (radius * holeRadiusPercent)) / 2f;
|
||||
|
||||
if (!mChart.isDrawSlicesUnderHoleEnabled() && mChart.isDrawRoundedSlicesEnabled()) {
|
||||
// Add curved circle slice and spacing to rotation angle, so that it sits nicely inside
|
||||
rotationAngle += roundedRadius * 360 / (Math.PI * 2 * radius);
|
||||
}
|
||||
}
|
||||
|
||||
final float labelRadius = radius - labelRadiusOffset;
|
||||
|
@ -438,11 +464,13 @@ public class PieChartRenderer extends DataRenderer {
|
|||
float lineHeight = Utils.calcTextHeight(mValuePaint, "Q")
|
||||
+ Utils.convertDpToPixel(4f);
|
||||
|
||||
IValueFormatter formatter = dataSet.getValueFormatter();
|
||||
ValueFormatter formatter = dataSet.getValueFormatter();
|
||||
|
||||
int entryCount = dataSet.getEntryCount();
|
||||
|
||||
mValueLinePaint.setColor(dataSet.getValueLineColor());
|
||||
boolean isUseValueColorForLineEnabled = dataSet.isUseValueColorForLineEnabled();
|
||||
int valueLineColor = dataSet.getValueLineColor();
|
||||
|
||||
mValueLinePaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getValueLineWidth()));
|
||||
|
||||
final float sliceSpace = getSliceSpace(dataSet);
|
||||
|
@ -472,6 +500,8 @@ public class PieChartRenderer extends DataRenderer {
|
|||
|
||||
float value = mChart.isUsePercentValuesEnabled() ? entry.getY()
|
||||
/ yValueSum * 100f : entry.getY();
|
||||
String formattedValue = formatter.getPieLabel(value, entry);
|
||||
String entryLabel = entry.getLabel();
|
||||
|
||||
final float sliceXBase = (float) Math.cos(transformedAngle * Utils.FDEG2RAD);
|
||||
final float sliceYBase = (float) Math.sin(transformedAngle * Utils.FDEG2RAD);
|
||||
|
@ -537,12 +567,15 @@ public class PieChartRenderer extends DataRenderer {
|
|||
labelPty = pt2y;
|
||||
}
|
||||
|
||||
if (dataSet.getValueLineColor() != ColorTemplate.COLOR_NONE) {
|
||||
int lineColor = ColorTemplate.COLOR_NONE;
|
||||
|
||||
if (dataSet.isUsingSliceColorAsValueLineColor()) {
|
||||
mValueLinePaint.setColor(dataSet.getColor(j));
|
||||
}
|
||||
if (isUseValueColorForLineEnabled)
|
||||
lineColor = dataSet.getColor(j);
|
||||
else if (valueLineColor != ColorTemplate.COLOR_NONE)
|
||||
lineColor = valueLineColor;
|
||||
|
||||
if (lineColor != ColorTemplate.COLOR_NONE) {
|
||||
mValueLinePaint.setColor(lineColor);
|
||||
c.drawLine(pt0x, pt0y, pt1x, pt1y, mValueLinePaint);
|
||||
c.drawLine(pt1x, pt1y, pt2x, pt2y, mValueLinePaint);
|
||||
}
|
||||
|
@ -550,27 +583,19 @@ public class PieChartRenderer extends DataRenderer {
|
|||
// draw everything, depending on settings
|
||||
if (drawXOutside && drawYOutside) {
|
||||
|
||||
drawValue(c,
|
||||
formatter,
|
||||
value,
|
||||
entry,
|
||||
0,
|
||||
labelPtx,
|
||||
labelPty,
|
||||
dataSet.getValueTextColor(j));
|
||||
drawValue(c, formattedValue, labelPtx, labelPty, dataSet.getValueTextColor(j));
|
||||
|
||||
if (j < data.getEntryCount() && entry.getLabel() != null) {
|
||||
drawEntryLabel(c, entry.getLabel(), labelPtx, labelPty + lineHeight);
|
||||
if (j < data.getEntryCount() && entryLabel != null) {
|
||||
drawEntryLabel(c, entryLabel, labelPtx, labelPty + lineHeight);
|
||||
}
|
||||
|
||||
} else if (drawXOutside) {
|
||||
if (j < data.getEntryCount() && entry.getLabel() != null) {
|
||||
drawEntryLabel(c, entry.getLabel(), labelPtx, labelPty + lineHeight / 2.f);
|
||||
if (j < data.getEntryCount() && entryLabel != null) {
|
||||
drawEntryLabel(c, entryLabel, labelPtx, labelPty + lineHeight / 2.f);
|
||||
}
|
||||
} else if (drawYOutside) {
|
||||
|
||||
drawValue(c, formatter, value, entry, 0, labelPtx, labelPty + lineHeight / 2.f, dataSet
|
||||
.getValueTextColor(j));
|
||||
drawValue(c, formattedValue, labelPtx, labelPty + lineHeight / 2.f, dataSet.getValueTextColor(j));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -584,19 +609,18 @@ public class PieChartRenderer extends DataRenderer {
|
|||
// draw everything, depending on settings
|
||||
if (drawXInside && drawYInside) {
|
||||
|
||||
drawValue(c, formatter, value, entry, 0, x, y, dataSet.getValueTextColor(j));
|
||||
drawValue(c, formattedValue, x, y, dataSet.getValueTextColor(j));
|
||||
|
||||
if (j < data.getEntryCount() && entry.getLabel() != null) {
|
||||
drawEntryLabel(c, entry.getLabel(), x, y + lineHeight);
|
||||
if (j < data.getEntryCount() && entryLabel != null) {
|
||||
drawEntryLabel(c, entryLabel, x, y + lineHeight);
|
||||
}
|
||||
|
||||
} else if (drawXInside) {
|
||||
if (j < data.getEntryCount() && entry.getLabel() != null) {
|
||||
drawEntryLabel(c, entry.getLabel(), x, y + lineHeight / 2f);
|
||||
if (j < data.getEntryCount() && entryLabel != null) {
|
||||
drawEntryLabel(c, entryLabel, x, y + lineHeight / 2f);
|
||||
}
|
||||
} else if (drawYInside) {
|
||||
|
||||
drawValue(c, formatter, value, entry, 0, x, y + lineHeight / 2f, dataSet.getValueTextColor(j));
|
||||
drawValue(c, formattedValue, x, y + lineHeight / 2f, dataSet.getValueTextColor(j));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -626,6 +650,12 @@ public class PieChartRenderer extends DataRenderer {
|
|||
c.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawValue(Canvas c, String valueText, float x, float y, int color) {
|
||||
mValuePaint.setColor(color);
|
||||
c.drawText(valueText, x, y, mValuePaint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an entry label at the specified position.
|
||||
*
|
||||
|
@ -640,7 +670,6 @@ public class PieChartRenderer extends DataRenderer {
|
|||
|
||||
@Override
|
||||
public void drawExtras(Canvas c) {
|
||||
// drawCircles(c);
|
||||
drawHole(c);
|
||||
c.drawBitmap(mDrawBitmap.get(), 0, 0, null);
|
||||
drawCenterText(c);
|
||||
|
@ -766,6 +795,15 @@ public class PieChartRenderer extends DataRenderer {
|
|||
@Override
|
||||
public void drawHighlighted(Canvas c, Highlight[] indices) {
|
||||
|
||||
/* Skip entirely if using rounded circle slices, because it doesn't make sense to highlight
|
||||
* in this way.
|
||||
* TODO: add support for changing slice color with highlighting rather than only shifting the slice
|
||||
*/
|
||||
|
||||
final boolean drawInnerArc = mChart.isDrawHoleEnabled() && !mChart.isDrawSlicesUnderHoleEnabled();
|
||||
if (drawInnerArc && mChart.isDrawRoundedSlicesEnabled())
|
||||
return;
|
||||
|
||||
float phaseX = mAnimator.getPhaseX();
|
||||
float phaseY = mAnimator.getPhaseY();
|
||||
|
||||
|
@ -776,7 +814,6 @@ public class PieChartRenderer extends DataRenderer {
|
|||
float[] absoluteAngles = mChart.getAbsoluteAngles();
|
||||
final MPPointF center = mChart.getCenterCircleBox();
|
||||
final float radius = mChart.getRadius();
|
||||
final boolean drawInnerArc = mChart.isDrawHoleEnabled() && !mChart.isDrawSlicesUnderHoleEnabled();
|
||||
final float userInnerRadius = drawInnerArc
|
||||
? radius * (mChart.getHoleRadius() / 100.f)
|
||||
: 0.f;
|
||||
|
@ -793,8 +830,7 @@ public class PieChartRenderer extends DataRenderer {
|
|||
continue;
|
||||
|
||||
IPieDataSet set = mChart.getData()
|
||||
.getDataSetByIndex(indices[i]
|
||||
.getDataSetIndex());
|
||||
.getDataSetByIndex(indices[i].getDataSetIndex());
|
||||
|
||||
if (set == null || !set.isHighlightEnabled())
|
||||
continue;
|
||||
|
@ -825,7 +861,10 @@ public class PieChartRenderer extends DataRenderer {
|
|||
|
||||
final boolean accountForSliceSpacing = sliceSpace > 0.f && sliceAngle <= 180.f;
|
||||
|
||||
mRenderPaint.setColor(set.getColor(index));
|
||||
Integer highlightColor = set.getHighlightColor();
|
||||
if (highlightColor == null)
|
||||
highlightColor = set.getColor(index);
|
||||
mRenderPaint.setColor(highlightColor);
|
||||
|
||||
final float sliceSpaceAngleOuter = visibleAngleCount == 1 ?
|
||||
0.f :
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
@ -11,6 +10,7 @@ import com.github.mikephil.charting.animation.ChartAnimator;
|
|||
import com.github.mikephil.charting.charts.RadarChart;
|
||||
import com.github.mikephil.charting.data.RadarData;
|
||||
import com.github.mikephil.charting.data.RadarEntry;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IRadarDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
@ -174,6 +174,8 @@ public class RadarChartRenderer extends LineRadarRenderer {
|
|||
// apply the text-styling defined by the DataSet
|
||||
applyValueTextStyle(dataSet);
|
||||
|
||||
ValueFormatter formatter = dataSet.getValueFormatter();
|
||||
|
||||
MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
|
||||
iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
|
||||
iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
|
||||
|
@ -189,15 +191,7 @@ public class RadarChartRenderer extends LineRadarRenderer {
|
|||
pOut);
|
||||
|
||||
if (dataSet.isDrawValuesEnabled()) {
|
||||
drawValue(c,
|
||||
dataSet.getValueFormatter(),
|
||||
entry.getY(),
|
||||
entry,
|
||||
i,
|
||||
pOut.x,
|
||||
pOut.y - yoffset,
|
||||
dataSet.getValueTextColor
|
||||
(j));
|
||||
drawValue(c, formatter.getRadarLabel(entry), pOut.x, pOut.y - yoffset, dataSet.getValueTextColor(j));
|
||||
}
|
||||
|
||||
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
|
||||
|
@ -231,6 +225,12 @@ public class RadarChartRenderer extends LineRadarRenderer {
|
|||
MPPointF.recycleInstance(pIcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawValue(Canvas c, String valueText, float x, float y, int color) {
|
||||
mValuePaint.setColor(color);
|
||||
c.drawText(valueText, x, y, mValuePaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawExtras(Canvas c) {
|
||||
drawWeb(c);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
@ -8,6 +7,7 @@ import android.util.Log;
|
|||
import com.github.mikephil.charting.animation.ChartAnimator;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.ScatterData;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.ScatterDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet;
|
||||
|
@ -118,6 +118,8 @@ public class ScatterChartRenderer extends LineScatterCandleRadarRenderer {
|
|||
|
||||
float shapeSize = Utils.convertDpToPixel(dataSet.getScatterShapeSize());
|
||||
|
||||
ValueFormatter formatter = dataSet.getValueFormatter();
|
||||
|
||||
MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
|
||||
iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
|
||||
iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
|
||||
|
@ -135,14 +137,7 @@ public class ScatterChartRenderer extends LineScatterCandleRadarRenderer {
|
|||
Entry entry = dataSet.getEntryForIndex(j / 2 + mXBounds.min);
|
||||
|
||||
if (dataSet.isDrawValuesEnabled()) {
|
||||
drawValue(c,
|
||||
dataSet.getValueFormatter(),
|
||||
entry.getY(),
|
||||
entry,
|
||||
i,
|
||||
positions[j],
|
||||
positions[j + 1] - shapeSize,
|
||||
dataSet.getValueTextColor(j / 2 + mXBounds.min));
|
||||
drawValue(c, formatter.getPointLabel(entry), positions[j], positions[j + 1] - shapeSize, dataSet.getValueTextColor(j / 2 + mXBounds.min));
|
||||
}
|
||||
|
||||
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
|
||||
|
@ -164,6 +159,12 @@ public class ScatterChartRenderer extends LineScatterCandleRadarRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawValue(Canvas c, String valueText, float x, float y, int color) {
|
||||
mValuePaint.setColor(color);
|
||||
c.drawText(valueText, x, y, mValuePaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawExtras(Canvas c) {
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
@ -202,7 +201,7 @@ public class XAxisRenderer extends AxisRenderer {
|
|||
|
||||
if (mViewPortHandler.isInBoundsX(x)) {
|
||||
|
||||
String label = mXAxis.getValueFormatter().getFormattedValue(mXAxis.mEntries[i / 2], mXAxis);
|
||||
String label = mXAxis.getValueFormatter().getAxisLabel(mXAxis.mEntries[i / 2], mXAxis);
|
||||
|
||||
if (mXAxis.isAvoidFirstLastClippingEnabled()) {
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
@ -57,10 +56,10 @@ public class XAxisRendererHorizontalBarChart extends XAxisRenderer {
|
|||
|
||||
computeAxisValues(min, max);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void computeSize() {
|
||||
|
||||
|
||||
mAxisLabelPaint.setTypeface(mXAxis.getTypeface());
|
||||
mAxisLabelPaint.setTextSize(mXAxis.getTextSize());
|
||||
|
||||
|
@ -156,7 +155,7 @@ public class XAxisRendererHorizontalBarChart extends XAxisRenderer {
|
|||
|
||||
if (mViewPortHandler.isInBoundsY(y)) {
|
||||
|
||||
String label = mXAxis.getValueFormatter().getFormattedValue(mXAxis.mEntries[i / 2], mXAxis);
|
||||
String label = mXAxis.getValueFormatter().getAxisLabel(mXAxis.mEntries[i / 2], mXAxis);
|
||||
drawLabel(c, label, pos, y, anchor, labelRotationAngleDegrees);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
package com.github.mikephil.charting.renderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.PointF;
|
||||
|
||||
import com.github.mikephil.charting.charts.RadarChart;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
|
@ -43,7 +41,7 @@ public class XAxisRendererRadarChart extends XAxisRenderer {
|
|||
MPPointF pOut = MPPointF.getInstance(0,0);
|
||||
for (int i = 0; i < mChart.getData().getMaxEntryCountSet().getEntryCount(); i++) {
|
||||
|
||||
String label = mXAxis.getValueFormatter().getFormattedValue(i, mXAxis);
|
||||
String label = mXAxis.getValueFormatter().getAxisLabel(i, mXAxis);
|
||||
|
||||
float angle = (sliceangle * i + mChart.getRotationAngle()) % 360f;
|
||||
|
||||
|
|
|
@ -119,12 +119,17 @@ public class YAxisRenderer extends AxisRenderer {
|
|||
? mYAxis.mEntryCount
|
||||
: (mYAxis.mEntryCount - 1);
|
||||
|
||||
float xOffset = mYAxis.getLabelXOffset();
|
||||
|
||||
// draw
|
||||
for (int i = from; i < to; i++) {
|
||||
|
||||
String text = mYAxis.getFormattedLabel(i);
|
||||
|
||||
c.drawText(text, fixedPosition, positions[i * 2 + 1] + offset, mAxisLabelPaint);
|
||||
c.drawText(text,
|
||||
fixedPosition + xOffset,
|
||||
positions[i * 2 + 1] + offset,
|
||||
mAxisLabelPaint);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -142,11 +142,16 @@ public class YAxisRendererHorizontalBarChart extends YAxisRenderer {
|
|||
? mYAxis.mEntryCount
|
||||
: (mYAxis.mEntryCount - 1);
|
||||
|
||||
float xOffset = mYAxis.getLabelXOffset();
|
||||
|
||||
for (int i = from; i < to; i++) {
|
||||
|
||||
String text = mYAxis.getFormattedLabel(i);
|
||||
|
||||
c.drawText(text, positions[i * 2], fixedPosition - offset, mAxisLabelPaint);
|
||||
c.drawText(text,
|
||||
positions[i * 2],
|
||||
fixedPosition - offset + xOffset,
|
||||
mAxisLabelPaint);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,9 +52,11 @@ public class YAxisRendererRadarChart extends YAxisRenderer {
|
|||
double intervalMagnitude = Utils.roundToNextSignificant(Math.pow(10, (int) Math.log10(interval)));
|
||||
int intervalSigDigit = (int) (interval / intervalMagnitude);
|
||||
if (intervalSigDigit > 5) {
|
||||
// Use one order of magnitude higher, to avoid intervals like 0.9 or
|
||||
// 90
|
||||
interval = Math.floor(10 * intervalMagnitude);
|
||||
// Use one order of magnitude higher, to avoid intervals like 0.9 or 90
|
||||
// if it's 0.0 after floor(), we use the old value
|
||||
interval = Math.floor(10.0 * intervalMagnitude) == 0.0
|
||||
? interval
|
||||
: Math.floor(10.0 * intervalMagnitude);
|
||||
}
|
||||
|
||||
boolean centeringEnabled = mAxis.isCenterAxisLabelsEnabled();
|
||||
|
@ -161,6 +163,8 @@ public class YAxisRendererRadarChart extends YAxisRenderer {
|
|||
? mYAxis.mEntryCount
|
||||
: (mYAxis.mEntryCount - 1);
|
||||
|
||||
float xOffset = mYAxis.getLabelXOffset();
|
||||
|
||||
for (int j = from; j < to; j++) {
|
||||
|
||||
float r = (mYAxis.mEntries[j] - mYAxis.mAxisMinimum) * factor;
|
||||
|
@ -169,7 +173,7 @@ public class YAxisRendererRadarChart extends YAxisRenderer {
|
|||
|
||||
String label = mYAxis.getFormattedLabel(j);
|
||||
|
||||
c.drawText(label, pOut.x + 10, pOut.y, mAxisLabelPaint);
|
||||
c.drawText(label, pOut.x + xOffset, pOut.y, mAxisLabelPaint);
|
||||
}
|
||||
MPPointF.recycleInstance(center);
|
||||
MPPointF.recycleInstance(pOut);
|
||||
|
|
|
@ -0,0 +1,342 @@
|
|||
package com.github.mikephil.charting.utils;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class Fill
|
||||
{
|
||||
public enum Type
|
||||
{
|
||||
EMPTY, COLOR, LINEAR_GRADIENT, DRAWABLE
|
||||
}
|
||||
|
||||
public enum Direction
|
||||
{
|
||||
DOWN, UP, RIGHT, LEFT
|
||||
}
|
||||
|
||||
/**
|
||||
* the type of fill
|
||||
*/
|
||||
private Type mType = Type.EMPTY;
|
||||
|
||||
/**
|
||||
* the color that is used for filling
|
||||
*/
|
||||
@Nullable
|
||||
private Integer mColor = null;
|
||||
|
||||
private Integer mFinalColor = null;
|
||||
|
||||
/**
|
||||
* the drawable to be used for filling
|
||||
*/
|
||||
@Nullable
|
||||
protected Drawable mDrawable;
|
||||
|
||||
@Nullable
|
||||
private int[] mGradientColors;
|
||||
|
||||
@Nullable
|
||||
private float[] mGradientPositions;
|
||||
|
||||
/**
|
||||
* transparency used for filling
|
||||
*/
|
||||
private int mAlpha = 255;
|
||||
|
||||
public Fill()
|
||||
{
|
||||
}
|
||||
|
||||
public Fill(int color)
|
||||
{
|
||||
this.mType = Type.COLOR;
|
||||
this.mColor = color;
|
||||
calculateFinalColor();
|
||||
}
|
||||
|
||||
public Fill(int startColor, int endColor)
|
||||
{
|
||||
this.mType = Type.LINEAR_GRADIENT;
|
||||
this.mGradientColors = new int[]{startColor, endColor};
|
||||
}
|
||||
|
||||
public Fill(@NonNull int[] gradientColors)
|
||||
{
|
||||
this.mType = Type.LINEAR_GRADIENT;
|
||||
this.mGradientColors = gradientColors;
|
||||
}
|
||||
|
||||
public Fill(@NonNull int[] gradientColors, @NonNull float[] gradientPositions)
|
||||
{
|
||||
this.mType = Type.LINEAR_GRADIENT;
|
||||
this.mGradientColors = gradientColors;
|
||||
this.mGradientPositions = gradientPositions;
|
||||
}
|
||||
|
||||
public Fill(@NonNull Drawable drawable)
|
||||
{
|
||||
this.mType = Type.DRAWABLE;
|
||||
this.mDrawable = drawable;
|
||||
}
|
||||
|
||||
public Type getType()
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
public void setType(Type type)
|
||||
{
|
||||
this.mType = type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getColor()
|
||||
{
|
||||
return mColor;
|
||||
}
|
||||
|
||||
public void setColor(int color)
|
||||
{
|
||||
this.mColor = color;
|
||||
calculateFinalColor();
|
||||
}
|
||||
|
||||
public int[] getGradientColors()
|
||||
{
|
||||
return mGradientColors;
|
||||
}
|
||||
|
||||
public void setGradientColors(int[] colors)
|
||||
{
|
||||
this.mGradientColors = colors;
|
||||
}
|
||||
|
||||
public float[] getGradientPositions()
|
||||
{
|
||||
return mGradientPositions;
|
||||
}
|
||||
|
||||
public void setGradientPositions(float[] positions)
|
||||
{
|
||||
this.mGradientPositions = positions;
|
||||
}
|
||||
|
||||
public void setGradientColors(int startColor, int endColor)
|
||||
{
|
||||
this.mGradientColors = new int[]{startColor, endColor};
|
||||
}
|
||||
|
||||
public int getAlpha()
|
||||
{
|
||||
return mAlpha;
|
||||
}
|
||||
|
||||
public void setAlpha(int alpha)
|
||||
{
|
||||
this.mAlpha = alpha;
|
||||
calculateFinalColor();
|
||||
}
|
||||
|
||||
private void calculateFinalColor()
|
||||
{
|
||||
if (mColor == null)
|
||||
{
|
||||
mFinalColor = null;
|
||||
} else
|
||||
{
|
||||
int alpha = (int) Math.floor(((mColor >> 24) / 255.0) * (mAlpha / 255.0) * 255.0);
|
||||
mFinalColor = (alpha << 24) | (mColor & 0xffffff);
|
||||
}
|
||||
}
|
||||
|
||||
public void fillRect(Canvas c, Paint paint,
|
||||
float left, float top, float right, float bottom,
|
||||
Direction gradientDirection)
|
||||
{
|
||||
switch (mType)
|
||||
{
|
||||
case EMPTY:
|
||||
return;
|
||||
|
||||
case COLOR:
|
||||
{
|
||||
if (mFinalColor == null) return;
|
||||
|
||||
if (isClipPathSupported())
|
||||
{
|
||||
int save = c.save();
|
||||
|
||||
c.clipRect(left, top, right, bottom);
|
||||
c.drawColor(mFinalColor);
|
||||
|
||||
c.restoreToCount(save);
|
||||
}
|
||||
else
|
||||
{
|
||||
// save
|
||||
Paint.Style previous = paint.getStyle();
|
||||
int previousColor = paint.getColor();
|
||||
|
||||
// set
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
paint.setColor(mFinalColor);
|
||||
|
||||
c.drawRect(left, top, right, bottom, paint);
|
||||
|
||||
// restore
|
||||
paint.setColor(previousColor);
|
||||
paint.setStyle(previous);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LINEAR_GRADIENT:
|
||||
{
|
||||
if (mGradientColors == null) return;
|
||||
|
||||
LinearGradient gradient = new LinearGradient(
|
||||
(int) (gradientDirection == Direction.RIGHT
|
||||
? right
|
||||
: gradientDirection == Direction.LEFT
|
||||
? left
|
||||
: left),
|
||||
(int) (gradientDirection == Direction.UP
|
||||
? bottom
|
||||
: gradientDirection == Direction.DOWN
|
||||
? top
|
||||
: top),
|
||||
(int) (gradientDirection == Direction.RIGHT
|
||||
? left
|
||||
: gradientDirection == Direction.LEFT
|
||||
? right
|
||||
: left),
|
||||
(int) (gradientDirection == Direction.UP
|
||||
? top
|
||||
: gradientDirection == Direction.DOWN
|
||||
? bottom
|
||||
: top),
|
||||
mGradientColors,
|
||||
mGradientPositions,
|
||||
android.graphics.Shader.TileMode.MIRROR);
|
||||
|
||||
paint.setShader(gradient);
|
||||
|
||||
c.drawRect(left, top, right, bottom, paint);
|
||||
}
|
||||
break;
|
||||
|
||||
case DRAWABLE:
|
||||
{
|
||||
if (mDrawable == null) return;
|
||||
|
||||
mDrawable.setBounds((int) left, (int) top, (int) right, (int) bottom);
|
||||
mDrawable.draw(c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void fillPath(Canvas c, Path path, Paint paint,
|
||||
@Nullable RectF clipRect)
|
||||
{
|
||||
switch (mType)
|
||||
{
|
||||
case EMPTY:
|
||||
return;
|
||||
|
||||
case COLOR:
|
||||
{
|
||||
if (mFinalColor == null) return;
|
||||
|
||||
if (clipRect != null && isClipPathSupported())
|
||||
{
|
||||
int save = c.save();
|
||||
|
||||
c.clipPath(path);
|
||||
c.drawColor(mFinalColor);
|
||||
|
||||
c.restoreToCount(save);
|
||||
}
|
||||
else
|
||||
{
|
||||
// save
|
||||
Paint.Style previous = paint.getStyle();
|
||||
int previousColor = paint.getColor();
|
||||
|
||||
// set
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
paint.setColor(mFinalColor);
|
||||
|
||||
c.drawPath(path, paint);
|
||||
|
||||
// restore
|
||||
paint.setColor(previousColor);
|
||||
paint.setStyle(previous);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LINEAR_GRADIENT:
|
||||
{
|
||||
if (mGradientColors == null) return;
|
||||
|
||||
LinearGradient gradient = new LinearGradient(
|
||||
0,
|
||||
0,
|
||||
c.getWidth(),
|
||||
c.getHeight(),
|
||||
mGradientColors,
|
||||
mGradientPositions,
|
||||
android.graphics.Shader.TileMode.MIRROR);
|
||||
|
||||
paint.setShader(gradient);
|
||||
|
||||
c.drawPath(path, paint);
|
||||
}
|
||||
break;
|
||||
|
||||
case DRAWABLE:
|
||||
{
|
||||
if (mDrawable == null) return;
|
||||
|
||||
ensureClipPathSupported();
|
||||
|
||||
int save = c.save();
|
||||
c.clipPath(path);
|
||||
|
||||
mDrawable.setBounds(
|
||||
clipRect == null ? 0 : (int) clipRect.left,
|
||||
clipRect == null ? 0 : (int) clipRect.top,
|
||||
clipRect == null ? c.getWidth() : (int) clipRect.right,
|
||||
clipRect == null ? c.getHeight() : (int) clipRect.bottom);
|
||||
mDrawable.draw(c);
|
||||
|
||||
c.restoreToCount(save);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isClipPathSupported()
|
||||
{
|
||||
return Utils.getSDKInt() >= 18;
|
||||
}
|
||||
|
||||
private void ensureClipPathSupported()
|
||||
{
|
||||
if (Utils.getSDKInt() < 18)
|
||||
{
|
||||
throw new RuntimeException("Fill-drawables not (yet) supported below API level 18, " +
|
||||
"this code was run on API level " + Utils.getSDKInt() + ".");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package com.github.mikephil.charting.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
@ -7,7 +6,6 @@ import android.content.res.Resources;
|
|||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.text.Layout;
|
||||
|
@ -15,14 +13,13 @@ import android.text.StaticLayout;
|
|||
import android.text.TextPaint;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.SizeF;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.github.mikephil.charting.formatter.DefaultValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -229,15 +226,14 @@ public abstract class Utils {
|
|||
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
|
||||
};
|
||||
|
||||
private static IValueFormatter mDefaultValueFormatter = generateDefaultValueFormatter();
|
||||
private static ValueFormatter mDefaultValueFormatter = generateDefaultValueFormatter();
|
||||
|
||||
private static IValueFormatter generateDefaultValueFormatter() {
|
||||
final DefaultValueFormatter formatter = new DefaultValueFormatter(1);
|
||||
return formatter;
|
||||
private static ValueFormatter generateDefaultValueFormatter() {
|
||||
return new DefaultValueFormatter(1);
|
||||
}
|
||||
|
||||
/// - returns: The default value formatter used for all chart components that needs a default
|
||||
public static IValueFormatter getDefaultValueFormatter()
|
||||
public static ValueFormatter getDefaultValueFormatter()
|
||||
{
|
||||
return mDefaultValueFormatter;
|
||||
}
|
||||
|
@ -353,11 +349,11 @@ public abstract class Utils {
|
|||
* @return
|
||||
*/
|
||||
public static float roundToNextSignificant(double number) {
|
||||
if (Double.isInfinite(number) ||
|
||||
Double.isNaN(number) ||
|
||||
if (Double.isInfinite(number) ||
|
||||
Double.isNaN(number) ||
|
||||
number == 0.0)
|
||||
return 0;
|
||||
|
||||
|
||||
final float d = (float) Math.ceil((float) Math.log10(number < 0 ? -number : number));
|
||||
final int pw = 1 - (int) d;
|
||||
final float magnitude = (float) Math.pow(10, pw);
|
||||
|
@ -375,10 +371,10 @@ public abstract class Utils {
|
|||
public static int getDecimals(float number) {
|
||||
|
||||
float i = roundToNextSignificant(number);
|
||||
|
||||
|
||||
if (Float.isInfinite(i))
|
||||
return 0;
|
||||
|
||||
|
||||
return (int) Math.ceil(-Math.log10(i)) + 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,80 +16,80 @@ public class LargeValueFormatterTest {
|
|||
|
||||
LargeValueFormatter formatter = new LargeValueFormatter();
|
||||
|
||||
String result = formatter.getFormattedValue(5f, null);
|
||||
String result = formatter.getFormattedValue(5f);
|
||||
assertEquals("5", result);
|
||||
|
||||
result = formatter.getFormattedValue(5.5f, null);
|
||||
result = formatter.getFormattedValue(5.5f);
|
||||
assertEquals("5.5", result);
|
||||
|
||||
result = formatter.getFormattedValue(50f, null);
|
||||
result = formatter.getFormattedValue(50f);
|
||||
assertEquals("50", result);
|
||||
|
||||
result = formatter.getFormattedValue(50.5f, null);
|
||||
result = formatter.getFormattedValue(50.5f);
|
||||
assertEquals("50.5", result);
|
||||
|
||||
result = formatter.getFormattedValue(500f, null);
|
||||
result = formatter.getFormattedValue(500f);
|
||||
assertEquals("500", result);
|
||||
|
||||
result = formatter.getFormattedValue(1100f, null);
|
||||
result = formatter.getFormattedValue(1100f);
|
||||
assertEquals("1.1k", result);
|
||||
|
||||
result = formatter.getFormattedValue(10000f, null);
|
||||
result = formatter.getFormattedValue(10000f);
|
||||
assertEquals("10k", result);
|
||||
|
||||
result = formatter.getFormattedValue(10500f, null);
|
||||
result = formatter.getFormattedValue(10500f);
|
||||
assertEquals("10.5k", result);
|
||||
|
||||
result = formatter.getFormattedValue(100000f, null);
|
||||
result = formatter.getFormattedValue(100000f);
|
||||
assertEquals("100k", result);
|
||||
|
||||
result = formatter.getFormattedValue(1000000f, null);
|
||||
result = formatter.getFormattedValue(1000000f);
|
||||
assertEquals("1m", result);
|
||||
|
||||
result = formatter.getFormattedValue(1500000f, null);
|
||||
result = formatter.getFormattedValue(1500000f);
|
||||
assertEquals("1.5m", result);
|
||||
|
||||
result = formatter.getFormattedValue(9500000f, null);
|
||||
result = formatter.getFormattedValue(9500000f);
|
||||
assertEquals("9.5m", result);
|
||||
|
||||
result = formatter.getFormattedValue(22200000f, null);
|
||||
result = formatter.getFormattedValue(22200000f);
|
||||
assertEquals("22.2m", result);
|
||||
|
||||
result = formatter.getFormattedValue(222000000f, null);
|
||||
result = formatter.getFormattedValue(222000000f);
|
||||
assertEquals("222m", result);
|
||||
|
||||
result = formatter.getFormattedValue(1000000000f, null);
|
||||
result = formatter.getFormattedValue(1000000000f);
|
||||
assertEquals("1b", result);
|
||||
|
||||
result = formatter.getFormattedValue(9900000000f, null);
|
||||
result = formatter.getFormattedValue(9900000000f);
|
||||
assertEquals("9.9b", result);
|
||||
|
||||
result = formatter.getFormattedValue(99000000000f, null);
|
||||
result = formatter.getFormattedValue(99000000000f);
|
||||
assertEquals("99b", result);
|
||||
|
||||
result = formatter.getFormattedValue(99500000000f, null);
|
||||
result = formatter.getFormattedValue(99500000000f);
|
||||
assertEquals("99.5b", result);
|
||||
|
||||
result = formatter.getFormattedValue(999000000000f, null);
|
||||
result = formatter.getFormattedValue(999000000000f);
|
||||
assertEquals("999b", result);
|
||||
|
||||
result = formatter.getFormattedValue(1000000000000f, null);
|
||||
result = formatter.getFormattedValue(1000000000000f);
|
||||
assertEquals("1t", result);
|
||||
|
||||
formatter.setSuffix(new String[]{"", "k", "m", "b", "t", "q"}); // quadrillion support
|
||||
result = formatter.getFormattedValue(1000000000000000f, null);
|
||||
result = formatter.getFormattedValue(1000000000000000f);
|
||||
assertEquals("1q", result);
|
||||
|
||||
result = formatter.getFormattedValue(1100000000000000f, null);
|
||||
result = formatter.getFormattedValue(1100000000000000f);
|
||||
assertEquals("1.1q", result);
|
||||
|
||||
result = formatter.getFormattedValue(10000000000000000f, null);
|
||||
result = formatter.getFormattedValue(10000000000000000f);
|
||||
assertEquals("10q", result);
|
||||
|
||||
result = formatter.getFormattedValue(13300000000000000f, null);
|
||||
result = formatter.getFormattedValue(13300000000000000f);
|
||||
assertEquals("13.3q", result);
|
||||
|
||||
result = formatter.getFormattedValue(100000000000000000f, null);
|
||||
result = formatter.getFormattedValue(100000000000000000f);
|
||||
assertEquals("100q", result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.github.mikephil.charting.test;
|
|||
|
||||
import com.github.mikephil.charting.utils.ObjectPool;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
|
36
README.md
36
README.md
|
@ -23,23 +23,9 @@
|
|||
1. [License](#licence)
|
||||
1. [Creators](#creators)
|
||||
|
||||
## [Realtime Graphing Solution | SciChart](https://scichart.com/android-chart-features?source=MPAndroidChart)
|
||||
## [Coding Newsletter](https://weeklycoding.com)
|
||||
|
||||
<img align="left" width="190" height="190" style="margin:0px 15px 0px 0px" src="https://raw.github.com/PhilJay/MPChart/master/design/other/left.png">
|
||||
<img align="right" width="90" height="90" style="margin:0px 15px 0px 0px" src="https://raw.github.com/PhilJay/MPChart/master/design/other/right.png">
|
||||
|
||||
MPAndroidChart is free software, as a result **dynamic & realtime data is not officially supported**. If you are looking for an enterprise-grade chart solution with extreme realtime performance and tech support, we recommend
|
||||
<a href="https://scichart.com/android-chart-features?source=MPAndroidChart" target="_blank">SciChart Android</a>.
|
||||
|
||||
<img align="right" width="270" height="60" style="margin:0px 0px 0px 0px" src="https://raw.github.com/PhilJay/MPChart/master/design/other/bottom.png">
|
||||
|
||||
All MPAndroidChart users are entitled to a special **discount of 5%** off the <a href="https://store.scichart.com?productTab=Android&CouponCode=MPANDROIDCHART&source=MPAndroidChart" target="_blank">SciChart store</a>, using the following discount code: **MPANDROIDCHART**
|
||||
|
||||
<br/>
|
||||
|
||||
## [Daily Coding Newsletter](https://philjay.substack.com/subscribe)
|
||||
|
||||
Sign up for my [daily coding newsletter](https://philjay.substack.com/subscribe) to get quick updates on Kotlin and Android development related topics.
|
||||
Sign up for my [coding newsletter](https://weeklycoding.com) to get quick updates on Kotlin and Android development related topics.
|
||||
|
||||
<h2 id="quick-start">Quick Start :chart_with_upwards_trend:</h2>
|
||||
|
||||
|
@ -53,7 +39,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
|
||||
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -70,7 +56,7 @@ dependencies {
|
|||
<dependency>
|
||||
<groupId>com.github.PhilJay</groupId>
|
||||
<artifactId>MPAndroidChart</artifactId>
|
||||
<version>v3.0.3</version>
|
||||
<version>v3.1.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
@ -78,13 +64,14 @@ dependencies {
|
|||
|
||||
<h2 id="documentation">Documentation :notebook_with_decorative_cover:</h2>
|
||||
|
||||
See the [**documentation**](https://github.com/PhilJay/MPAndroidChart/wiki) for examples and general use of MPAndroidChart.
|
||||
See the [**documentation**](https://weeklycoding.com/mpandroidchart/) for examples and general use of MPAndroidChart.
|
||||
|
||||
See the [**javadocs**](https://jitpack.io/com/github/PhilJay/MPAndroidChart/v3.0.3/javadoc/) for more advanced documentation.
|
||||
See the [**javadocs**](https://jitpack.io/com/github/PhilJay/MPAndroidChart/v3.1.0/javadoc/) for more advanced documentation.
|
||||
|
||||
<br/>
|
||||
|
||||
<h2 id="examples">Examples :eyes:</h2>
|
||||
|
||||
Download the [MPAndroidChart Example App](https://play.google.com/store/apps/details?id=com.xxmassdeveloper.mpchartexample) or look at the [source code](https://github.com/PhilJay/MPAndroidChart/tree/master/MPChartExample).
|
||||
|
||||
[](https://www.youtube.com/watch?v=ufaK_Hd6BpI)
|
||||
|
@ -95,7 +82,7 @@ Download the [MPAndroidChart Example App](https://play.google.com/store/apps/det
|
|||
|
||||
This repository's issue tracker is only for bugs and feature requests. The maintainers ask that you refrain from asking questions about how to use MPAndroidChart through the issue tracker.
|
||||
|
||||
Please read the [**documentation**](https://github.com/PhilJay/MPAndroidChart/wiki) first, then ask all your questions on [stackoverflow.com](https://stackoverflow.com/questions/tagged/mpandroidchart) for the fastest answer.
|
||||
Please read the [**documentation**](https://weeklycoding.com/mpandroidchart/) first, then ask all your questions on [stackoverflow.com](https://stackoverflow.com/questions/tagged/mpandroidchart) for the fastest answer.
|
||||
|
||||
<br/>
|
||||
|
||||
|
@ -111,6 +98,9 @@ Please read the [**documentation**](https://github.com/PhilJay/MPAndroidChart/wi
|
|||
|
||||
0x04ef098bf9f91871391363e3caf791afa3adc39b
|
||||
|
||||
[**Lightning Network (tippin.me)**](https://tippin.me/@PhilippJahoda)
|
||||
|
||||
|
||||
**PayPal**
|
||||
|
||||
- [**Donate 5 $**](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=7G52RA87ED8NY): Thank's for creating this project, here's a coffee (or some beer) for you!
|
||||
|
@ -129,7 +119,7 @@ If you like this library, please tell others about it :two_hearts: :two_hearts:
|
|||
[](https://plus.google.com/share?url=https://github.com/PhilJay/MPAndroidChart)
|
||||
[](https://www.facebook.com/sharer/sharer.php?u=https://github.com/PhilJay/MPAndroidChart)
|
||||
|
||||
You can follow me on Twitter [**@PhilippJahoda**](https://twitter.com/PhilippJahoda) or sign up for my [**daily coding newsletter**](https://philjay.substack.com/subscribe).
|
||||
You can follow me on Twitter [**@PhilippJahoda**](https://twitter.com/PhilippJahoda) or sign up for my [**coding newsletter**](https://weeklycoding.com).
|
||||
|
||||
<br/>
|
||||
|
||||
|
@ -205,7 +195,7 @@ You can follow me on Twitter [**@PhilippJahoda**](https://twitter.com/PhilippJah
|
|||
|
||||
<h1 id="license">License :page_facing_up:</h1>
|
||||
|
||||
Copyright 2018 Philipp Jahoda
|
||||
Copyright 2019 Philipp Jahoda
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -2,9 +2,10 @@ buildscript {
|
|||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath 'com.android.tools.build:gradle:3.4.0'
|
||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue