diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/BarChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/BarChart.java index 838ff7f454..2efbd4093c 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/BarChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/BarChart.java @@ -8,12 +8,15 @@ import com.github.mikephil.charting.components.YAxis; import com.github.mikephil.charting.data.BarData; import com.github.mikephil.charting.data.BarEntry; +import com.github.mikephil.charting.formatter.IAxisValueFormatter; import com.github.mikephil.charting.highlight.BarHighlighter; import com.github.mikephil.charting.highlight.Highlight; import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider; import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; import com.github.mikephil.charting.renderer.BarChartRenderer; +import java.util.Locale; + /** * Chart that draws bars. * @@ -275,4 +278,33 @@ public void setRoundedBarRadius(float mRoundedBarRadius) { this.mDrawRoundedBars = true; init(); } + + @Override + public String getAccessibilityDescription() { + + BarData barData = getBarData(); + + int entryCount = barData.getEntryCount(); + + // Find the min and max index + IAxisValueFormatter yAxisValueFormatter = getAxisLeft().getValueFormatter(); + String minVal = yAxisValueFormatter.getFormattedValue(barData.getYMin(), null); + String maxVal = yAxisValueFormatter.getFormattedValue(barData.getYMax(), null); + + // Data range... + IAxisValueFormatter xAxisValueFormatter = getXAxis().getValueFormatter(); + String minRange = xAxisValueFormatter.getFormattedValue(barData.getXMin(), null); + String maxRange = xAxisValueFormatter.getFormattedValue(barData.getXMax(), null); + + String entries = entryCount == 1 ? "entry" : "entries"; + + // Format the values of min and max; to recite them back + + String description = String.format(Locale.getDefault(), "The bar chart has %d %s. " + + "The minimum value is %s and maximum value is %s." + + "Data ranges from %s to %s.", + entryCount, entries, minVal, maxVal, minRange, maxRange); + + return description; + } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/BubbleChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/BubbleChart.java index 23dac5780f..1510d85f01 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/BubbleChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/BubbleChart.java @@ -40,4 +40,9 @@ protected void init() { public BubbleData getBubbleData() { return mData; } + + @Override + public String getAccessibilityDescription() { + return "This is bubble chart"; + } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/CandleStickChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/CandleStickChart.java index fa36e3522f..29ba92d56b 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/CandleStickChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/CandleStickChart.java @@ -41,4 +41,9 @@ protected void init() { public CandleData getCandleData() { return mData; } + + @Override + public String getAccessibilityDescription() { + return "This is a candlestick chart"; + } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/Chart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/Chart.java index 8ea56d6cfd..e3250953e3 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/Chart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/Chart.java @@ -21,6 +21,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; +import android.view.accessibility.AccessibilityEvent; import com.github.mikephil.charting.animation.ChartAnimator; import com.github.mikephil.charting.animation.Easing.EasingFunction; @@ -170,6 +171,16 @@ public abstract class Chart and completed as " + completed); + + event.getText().add(getAccessibilityDescription()); + + // Add the user generated summary after the dynamic summary is complete. + if (!TextUtils.isEmpty(this.getAccessibilitySummaryDescription())) { + event.getText().add(this.getAccessibilitySummaryDescription()); + } + + return true; + } + + // endregion } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/CombinedChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/CombinedChart.java index ab4504abaf..8a1656f5b8 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/CombinedChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/CombinedChart.java @@ -266,4 +266,8 @@ protected void drawMarkers(Canvas canvas) { } } + @Override + public String getAccessibilityDescription() { + return "This is a combined chart"; + } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/LineChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/LineChart.java index aa7afc4c85..db0536db27 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/LineChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/LineChart.java @@ -5,9 +5,12 @@ import android.util.AttributeSet; import com.github.mikephil.charting.data.LineData; +import com.github.mikephil.charting.formatter.IAxisValueFormatter; import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider; import com.github.mikephil.charting.renderer.LineChartRenderer; +import java.util.Locale; + /** * Chart that draws lines, surfaces, circles, ... * @@ -47,4 +50,28 @@ protected void onDetachedFromWindow() { } super.onDetachedFromWindow(); } + + @Override + public String getAccessibilityDescription() { + LineData lineData = getLineData(); + + int numberOfPoints = lineData.getEntryCount(); + + // Min and max values... + IAxisValueFormatter yAxisValueFormmater = getAxisLeft().getValueFormatter(); + String minVal = yAxisValueFormmater.getFormattedValue(lineData.getYMin(), null); + String maxVal = yAxisValueFormmater.getFormattedValue(lineData.getYMax(), null); + + // Data range... + IAxisValueFormatter xAxisValueFormatter = getXAxis().getValueFormatter(); + String minRange = xAxisValueFormatter.getFormattedValue(lineData.getXMin(), null); + String maxRange = xAxisValueFormatter.getFormattedValue(lineData.getXMax(), null); + + String entries = numberOfPoints == 1 ? "entry" : "entries"; + + return String.format(Locale.getDefault(), "The line chart has %d %s. " + + "The minimum value is %s and maximum value is %s." + + "Data ranges from %s to %s.", + numberOfPoints, entries, minVal, maxVal, minRange, maxRange); + } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/PieChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/PieChart.java index de11b3a844..fd0c7a2839 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/PieChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/PieChart.java @@ -6,10 +6,12 @@ import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Typeface; +import android.text.TextUtils; import android.util.AttributeSet; import com.github.mikephil.charting.components.XAxis; import com.github.mikephil.charting.data.PieData; +import com.github.mikephil.charting.data.PieEntry; import com.github.mikephil.charting.highlight.Highlight; import com.github.mikephil.charting.highlight.PieHighlighter; import com.github.mikephil.charting.interfaces.datasets.IPieDataSet; @@ -17,7 +19,9 @@ import com.github.mikephil.charting.utils.MPPointF; import com.github.mikephil.charting.utils.Utils; +import java.util.ArrayList; import java.util.List; +import java.util.Locale; /** * View that represents a pie chart. Draws cake like slices. @@ -801,4 +805,27 @@ protected void onDetachedFromWindow() { } super.onDetachedFromWindow(); } + + @Override + public String getAccessibilityDescription() { + + PieData pieData = getData(); + + int entryCount = pieData.getEntryCount(); + + StringBuilder builder = new StringBuilder(); + + builder.append(String.format(Locale.getDefault(), "The pie chart has %d entries.", + entryCount)); + + for (int i = 0; i < entryCount; i++) { + PieEntry entry = pieData.getDataSet().getEntryForIndex(i); + float percentage = (entry.getValue() / pieData.getYValueSum()) * 100; + builder.append(String.format(Locale.getDefault(), "%s has %.2f percent pie taken", + (TextUtils.isEmpty(entry.getLabel()) ? "No Label" : entry.getLabel()), + percentage)); + } + + return builder.toString(); + } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/RadarChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/RadarChart.java index a1a96507d4..524e222bb6 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/RadarChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/RadarChart.java @@ -382,4 +382,9 @@ public float getYChartMin() { public float getYRange() { return mYAxis.mAxisRange; } + + @Override + public String getAccessibilityDescription() { + return "This is a Radar chart"; + } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/ScatterChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/ScatterChart.java index 37e8395b5e..231ed0288b 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/ScatterChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/ScatterChart.java @@ -74,4 +74,9 @@ public static ScatterShape[] getAllDefaultShapes() { return new ScatterShape[]{SQUARE, CIRCLE, TRIANGLE, CROSS, X, CHEVRON_UP, CHEVRON_DOWN}; } } + + @Override + public String getAccessibilityDescription() { + return "This is scatter chart"; + } }