@nativescript-community/ui-chart 2.0.7 → 2.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/animation/ChartAnimator.d.ts +61 -0
- package/animation/ChartAnimator.js +95 -0
- package/animation/ChartAnimator.js.map +1 -0
- package/animation/Tween.d.ts +4 -0
- package/animation/Tween.js +25 -0
- package/animation/Tween.js.map +1 -0
- package/buffer/AbstractBuffer.d.ts +40 -0
- package/buffer/AbstractBuffer.js +49 -0
- package/buffer/AbstractBuffer.js.map +1 -0
- package/buffer/BarBuffer.d.ts +15 -0
- package/buffer/BarBuffer.js +109 -0
- package/buffer/BarBuffer.js.map +1 -0
- package/buffer/HorizontalBarBuffer.d.ts +6 -0
- package/buffer/HorizontalBarBuffer.js +81 -0
- package/buffer/HorizontalBarBuffer.js.map +1 -0
- package/charts/BarChart.d.ts +96 -0
- package/charts/BarChart.js +143 -0
- package/charts/BarChart.js.map +1 -0
- package/charts/BarLineChartBase.d.ts +583 -0
- package/charts/BarLineChartBase.js +1231 -0
- package/charts/BarLineChartBase.js.map +1 -0
- package/charts/BubbleChart.d.ts +27 -0
- package/charts/BubbleChart.js +20 -0
- package/charts/BubbleChart.js.map +1 -0
- package/charts/CandleStickChart.d.ts +29 -0
- package/charts/CandleStickChart.js +19 -0
- package/charts/CandleStickChart.js.map +1 -0
- package/charts/Chart.d.ts +498 -0
- package/charts/Chart.js +799 -0
- package/charts/Chart.js.map +1 -0
- package/charts/CombinedChart.d.ts +78 -0
- package/charts/CombinedChart.js +119 -0
- package/charts/CombinedChart.js.map +1 -0
- package/charts/HorizontalBarChart.d.ts +54 -0
- package/charts/HorizontalBarChart.js +180 -0
- package/charts/HorizontalBarChart.js.map +1 -0
- package/charts/LineChart.d.ts +20 -0
- package/charts/LineChart.js +19 -0
- package/charts/LineChart.js.map +1 -0
- package/charts/PieChart.d.ts +247 -0
- package/charts/PieChart.js +453 -0
- package/charts/PieChart.js.map +1 -0
- package/charts/PieRadarChartBase.d.ts +130 -0
- package/charts/PieRadarChartBase.js +360 -0
- package/charts/PieRadarChartBase.js.map +1 -0
- package/charts/RadarChart.d.ts +101 -0
- package/charts/RadarChart.js +172 -0
- package/charts/RadarChart.js.map +1 -0
- package/charts/ScatterChart.d.ts +36 -0
- package/charts/ScatterChart.js +31 -0
- package/charts/ScatterChart.js.map +1 -0
- package/charts/index.d.ts +9 -0
- package/charts/index.js +10 -0
- package/charts/index.js.map +1 -0
- package/components/AxisBase.d.ts +299 -0
- package/components/AxisBase.js +352 -0
- package/components/AxisBase.js.map +1 -0
- package/components/ComponentBase.d.ts +60 -0
- package/components/ComponentBase.js +77 -0
- package/components/ComponentBase.js.map +1 -0
- package/components/Description.d.ts +22 -0
- package/components/Description.js +21 -0
- package/components/Description.js.map +1 -0
- package/components/IMarker.d.ts +39 -0
- package/components/IMarker.js +2 -0
- package/components/IMarker.js.map +1 -0
- package/components/Legend.d.ts +198 -0
- package/components/Legend.js +386 -0
- package/components/Legend.js.map +1 -0
- package/components/LegendEntry.d.ts +50 -0
- package/components/LegendEntry.js +51 -0
- package/components/LegendEntry.js.map +1 -0
- package/components/LimitLine.d.ts +55 -0
- package/components/LimitLine.js +62 -0
- package/components/LimitLine.js.map +1 -0
- package/components/MarkerImage.d.ts +1 -0
- package/components/MarkerImage.js +97 -0
- package/components/MarkerImage.js.map +1 -0
- package/components/XAxis.d.ts +55 -0
- package/components/XAxis.js +59 -0
- package/components/XAxis.js.map +1 -0
- package/components/YAxis.d.ts +135 -0
- package/components/YAxis.js +205 -0
- package/components/YAxis.js.map +1 -0
- package/data/BarData.d.ts +39 -0
- package/data/BarData.js +126 -0
- package/data/BarData.js.map +1 -0
- package/data/BarDataSet.d.ts +47 -0
- package/data/BarDataSet.js +109 -0
- package/data/BarDataSet.js.map +1 -0
- package/data/BarEntry.d.ts +11 -0
- package/data/BarEntry.js +2 -0
- package/data/BarEntry.js.map +1 -0
- package/data/BarLineScatterCandleBubbleData.d.ts +10 -0
- package/data/BarLineScatterCandleBubbleData.js +9 -0
- package/data/BarLineScatterCandleBubbleData.js.map +1 -0
- package/data/BarLineScatterCandleBubbleDataSet.d.ts +17 -0
- package/data/BarLineScatterCandleBubbleDataSet.js +18 -0
- package/data/BarLineScatterCandleBubbleDataSet.js.map +1 -0
- package/data/BaseDataSet.d.ts +180 -0
- package/data/BaseDataSet.js +220 -0
- package/data/BaseDataSet.js.map +1 -0
- package/data/BaseEntry.d.ts +10 -0
- package/data/BaseEntry.js +2 -0
- package/data/BaseEntry.js.map +1 -0
- package/data/BubbleData.d.ts +12 -0
- package/data/BubbleData.js +15 -0
- package/data/BubbleData.js.map +1 -0
- package/data/BubbleDataSet.d.ts +18 -0
- package/data/BubbleDataSet.js +36 -0
- package/data/BubbleDataSet.js.map +1 -0
- package/data/BubbleEntry.d.ts +5 -0
- package/data/BubbleEntry.js +2 -0
- package/data/BubbleEntry.js.map +1 -0
- package/data/CandleData.d.ts +5 -0
- package/data/CandleData.js +4 -0
- package/data/CandleData.js.map +1 -0
- package/data/CandleDataSet.d.ts +76 -0
- package/data/CandleDataSet.js +116 -0
- package/data/CandleDataSet.js.map +1 -0
- package/data/CandleEntry.d.ts +11 -0
- package/data/CandleEntry.js +2 -0
- package/data/CandleEntry.js.map +1 -0
- package/data/ChartData.d.ts +320 -0
- package/data/ChartData.js +702 -0
- package/data/ChartData.js.map +1 -0
- package/data/CombinedData.d.ts +61 -0
- package/data/CombinedData.js +153 -0
- package/data/CombinedData.js.map +1 -0
- package/data/DataSet.d.ts +98 -0
- package/data/DataSet.js +424 -0
- package/data/DataSet.js.map +1 -0
- package/data/Entry.d.ts +3 -0
- package/data/Entry.js +2 -0
- package/data/Entry.js.map +1 -0
- package/data/LineData.d.ts +10 -0
- package/data/LineData.js +9 -0
- package/data/LineData.js.map +1 -0
- package/data/LineDataSet.d.ts +106 -0
- package/data/LineDataSet.js +148 -0
- package/data/LineDataSet.js.map +1 -0
- package/data/LineRadarDataSet.d.ts +32 -0
- package/data/LineRadarDataSet.js +29 -0
- package/data/LineRadarDataSet.js.map +1 -0
- package/data/LineScatterCandleRadarDataSet.d.ts +36 -0
- package/data/LineScatterCandleRadarDataSet.js +44 -0
- package/data/LineScatterCandleRadarDataSet.js.map +1 -0
- package/data/PieData.d.ts +39 -0
- package/data/PieData.js +55 -0
- package/data/PieData.js.map +1 -0
- package/data/PieDataSet.d.ts +52 -0
- package/data/PieDataSet.js +54 -0
- package/data/PieDataSet.js.map +1 -0
- package/data/PieEntry.d.ts +7 -0
- package/data/PieEntry.js +2 -0
- package/data/PieEntry.js.map +1 -0
- package/data/RadarData.d.ts +17 -0
- package/data/RadarData.js +15 -0
- package/data/RadarData.js.map +1 -0
- package/data/RadarDataSet.d.ts +14 -0
- package/data/RadarDataSet.js +20 -0
- package/data/RadarDataSet.js.map +1 -0
- package/data/RadarEntry.d.ts +3 -0
- package/data/RadarEntry.js +2 -0
- package/data/RadarEntry.js.map +1 -0
- package/data/ScatterData.d.ts +9 -0
- package/data/ScatterData.js +17 -0
- package/data/ScatterData.js.map +1 -0
- package/data/ScatterDataSet.d.ts +40 -0
- package/data/ScatterDataSet.js +61 -0
- package/data/ScatterDataSet.js.map +1 -0
- package/formatter/DefaultAxisValueFormatter.d.ts +23 -0
- package/formatter/DefaultAxisValueFormatter.js +30 -0
- package/formatter/DefaultAxisValueFormatter.js.map +1 -0
- package/formatter/DefaultFillFormatter.d.ts +6 -0
- package/formatter/DefaultFillFormatter.js +29 -0
- package/formatter/DefaultFillFormatter.js.map +1 -0
- package/formatter/DefaultValueFormatter.d.ts +3 -0
- package/formatter/DefaultValueFormatter.js +4 -0
- package/formatter/DefaultValueFormatter.js.map +1 -0
- package/formatter/IAxisValueFormatter.d.ts +23 -0
- package/formatter/IAxisValueFormatter.js +2 -0
- package/formatter/IAxisValueFormatter.js.map +1 -0
- package/formatter/IFillFormatter.d.ts +30 -0
- package/formatter/IFillFormatter.js +2 -0
- package/formatter/IFillFormatter.js.map +1 -0
- package/formatter/IValueFormatter.d.ts +25 -0
- package/formatter/IValueFormatter.js +2 -0
- package/formatter/IValueFormatter.js.map +1 -0
- package/formatter/ValueFormatter.d.ts +81 -0
- package/formatter/ValueFormatter.js +90 -0
- package/formatter/ValueFormatter.js.map +1 -0
- package/highlight/BarHighlighter.d.ts +33 -0
- package/highlight/BarHighlighter.js +89 -0
- package/highlight/BarHighlighter.js.map +1 -0
- package/highlight/ChartHighlighter.d.ts +102 -0
- package/highlight/ChartHighlighter.js +220 -0
- package/highlight/ChartHighlighter.js.map +1 -0
- package/highlight/CombinedHighlighter.d.ts +17 -0
- package/highlight/CombinedHighlighter.js +59 -0
- package/highlight/CombinedHighlighter.js.map +1 -0
- package/highlight/Highlight.d.ts +69 -0
- package/highlight/Highlight.js +8 -0
- package/highlight/Highlight.js.map +1 -0
- package/highlight/HorizontalBarHighlighter.d.ts +10 -0
- package/highlight/HorizontalBarHighlighter.js +54 -0
- package/highlight/HorizontalBarHighlighter.js.map +1 -0
- package/highlight/IHighlighter.d.ts +15 -0
- package/highlight/IHighlighter.js +2 -0
- package/highlight/IHighlighter.js.map +1 -0
- package/highlight/PieHighlighter.d.ts +9 -0
- package/highlight/PieHighlighter.js +21 -0
- package/highlight/PieHighlighter.js.map +1 -0
- package/highlight/PieRadarHighlighter.d.ts +25 -0
- package/highlight/PieRadarHighlighter.js +33 -0
- package/highlight/PieRadarHighlighter.js.map +1 -0
- package/highlight/RadarHighlighter.d.ts +20 -0
- package/highlight/RadarHighlighter.js +59 -0
- package/highlight/RadarHighlighter.js.map +1 -0
- package/index.d.ts +11 -0
- package/index.js +15 -0
- package/index.js.map +1 -0
- package/interfaces/dataprovider/BarDataProvider.d.ts +9 -0
- package/interfaces/dataprovider/BarLineScatterCandleBubbleDataProvider.d.ts +19 -0
- package/interfaces/dataprovider/BubbleDataProvider.d.ts +6 -0
- package/interfaces/dataprovider/CandleDataProvider.d.ts +6 -0
- package/interfaces/dataprovider/ChartInterface.d.ts +60 -0
- package/interfaces/dataprovider/CombinedDataProvider.d.ts +13 -0
- package/interfaces/dataprovider/LineDataProvider.d.ts +9 -0
- package/interfaces/dataprovider/ScatterDataProvider.d.ts +6 -0
- package/interfaces/datasets/IBarDataSet.d.ts +47 -0
- package/interfaces/datasets/IBarLineScatterCandleBubbleDataSet.d.ts +12 -0
- package/interfaces/datasets/IBubbleDataSet.d.ts +19 -0
- package/interfaces/datasets/ICandleDataSet.d.ts +81 -0
- package/interfaces/datasets/IDataSet.d.ts +385 -0
- package/interfaces/datasets/ILineDataSet.d.ts +67 -0
- package/interfaces/datasets/ILineRadarDataSet.d.ts +35 -0
- package/interfaces/datasets/ILineScatterCandleRadarDataSet.d.ts +32 -0
- package/interfaces/datasets/IPieDataSet.d.ts +49 -0
- package/interfaces/datasets/IRadarDataSet.d.ts +21 -0
- package/interfaces/datasets/IScatterDataSet.d.ts +37 -0
- package/jobs/AnimatedMoveViewJob.d.ts +15 -0
- package/jobs/AnimatedMoveViewJob.js +42 -0
- package/jobs/AnimatedMoveViewJob.js.map +1 -0
- package/jobs/AnimatedViewPortJob.d.ts +31 -0
- package/jobs/AnimatedViewPortJob.js +52 -0
- package/jobs/AnimatedViewPortJob.js.map +1 -0
- package/jobs/AnimatedZoomJob.d.ts +23 -0
- package/jobs/AnimatedZoomJob.js +63 -0
- package/jobs/AnimatedZoomJob.js.map +1 -0
- package/jobs/MoveViewJob.d.ts +14 -0
- package/jobs/MoveViewJob.js +36 -0
- package/jobs/MoveViewJob.js.map +1 -0
- package/jobs/ViewPortJob.d.ts +13 -0
- package/jobs/ViewPortJob.js +14 -0
- package/jobs/ViewPortJob.js.map +1 -0
- package/jobs/ZoomJob.d.ts +15 -0
- package/jobs/ZoomJob.js +48 -0
- package/jobs/ZoomJob.js.map +1 -0
- package/listener/BarLineChartTouchListener.d.ts +187 -0
- package/listener/BarLineChartTouchListener.js +544 -0
- package/listener/BarLineChartTouchListener.js.map +1 -0
- package/listener/ChartTouchListener.d.ts +69 -0
- package/listener/ChartTouchListener.js +81 -0
- package/listener/ChartTouchListener.js.map +1 -0
- package/listener/PieRadarChartTouchListener.d.ts +100 -0
- package/listener/PieRadarChartTouchListener.js +282 -0
- package/listener/PieRadarChartTouchListener.js.map +1 -0
- package/model/GradientColor.d.ts +9 -0
- package/model/GradientColor.js +19 -0
- package/model/GradientColor.js.map +1 -0
- package/package.json +9 -2
- package/renderer/AxisRenderer.d.ts +103 -0
- package/renderer/AxisRenderer.js +215 -0
- package/renderer/AxisRenderer.js.map +1 -0
- package/renderer/BarChartRenderer.d.ts +40 -0
- package/renderer/BarChartRenderer.js +362 -0
- package/renderer/BarChartRenderer.js.map +1 -0
- package/renderer/BarLineScatterCandleBubbleRenderer.d.ts +57 -0
- package/renderer/BarLineScatterCandleBubbleRenderer.js +63 -0
- package/renderer/BarLineScatterCandleBubbleRenderer.js.map +1 -0
- package/renderer/BubbleChartRenderer.d.ts +22 -0
- package/renderer/BubbleChartRenderer.js +204 -0
- package/renderer/BubbleChartRenderer.js.map +1 -0
- package/renderer/CandleStickChartRenderer.d.ts +18 -0
- package/renderer/CandleStickChartRenderer.js +268 -0
- package/renderer/CandleStickChartRenderer.js.map +1 -0
- package/renderer/CombinedChartRenderer.d.ts +40 -0
- package/renderer/CombinedChartRenderer.js +133 -0
- package/renderer/CombinedChartRenderer.js.map +1 -0
- package/renderer/DataRenderer.d.ts +103 -0
- package/renderer/DataRenderer.js +110 -0
- package/renderer/DataRenderer.js.map +1 -0
- package/renderer/HorizontalBarChartRenderer.d.ts +20 -0
- package/renderer/HorizontalBarChartRenderer.js +303 -0
- package/renderer/HorizontalBarChartRenderer.js.map +1 -0
- package/renderer/LegendRenderer.d.ts +54 -0
- package/renderer/LegendRenderer.js +336 -0
- package/renderer/LegendRenderer.js.map +1 -0
- package/renderer/LineChartRenderer.d.ts +100 -0
- package/renderer/LineChartRenderer.js +745 -0
- package/renderer/LineChartRenderer.js.map +1 -0
- package/renderer/LineRadarRenderer.d.ts +30 -0
- package/renderer/LineRadarRenderer.js +76 -0
- package/renderer/LineRadarRenderer.js.map +1 -0
- package/renderer/LineScatterCandleRadarRenderer.d.ts +20 -0
- package/renderer/LineScatterCandleRadarRenderer.js +45 -0
- package/renderer/LineScatterCandleRadarRenderer.js.map +1 -0
- package/renderer/PieChartRenderer.d.ts +86 -0
- package/renderer/PieChartRenderer.js +714 -0
- package/renderer/PieChartRenderer.js.map +1 -0
- package/renderer/RadarChartRenderer.d.ts +33 -0
- package/renderer/RadarChartRenderer.js +290 -0
- package/renderer/RadarChartRenderer.js.map +1 -0
- package/renderer/Renderer.d.ts +13 -0
- package/renderer/Renderer.js +11 -0
- package/renderer/Renderer.js.map +1 -0
- package/renderer/ScatterChartRenderer.d.ts +16 -0
- package/renderer/ScatterChartRenderer.js +147 -0
- package/renderer/ScatterChartRenderer.js.map +1 -0
- package/renderer/XAxisRenderer.d.ts +58 -0
- package/renderer/XAxisRenderer.js +458 -0
- package/renderer/XAxisRenderer.js.map +1 -0
- package/renderer/XAxisRendererHorizontalBarChart.d.ts +31 -0
- package/renderer/XAxisRendererHorizontalBarChart.js +264 -0
- package/renderer/XAxisRendererHorizontalBarChart.js.map +1 -0
- package/renderer/XAxisRendererRadarChart.d.ts +17 -0
- package/renderer/XAxisRendererRadarChart.js +51 -0
- package/renderer/XAxisRendererRadarChart.js.map +1 -0
- package/renderer/YAxisRenderer.d.ts +60 -0
- package/renderer/YAxisRenderer.js +379 -0
- package/renderer/YAxisRenderer.js.map +1 -0
- package/renderer/YAxisRendererHorizontalBarChart.d.ts +33 -0
- package/renderer/YAxisRendererHorizontalBarChart.js +258 -0
- package/renderer/YAxisRendererHorizontalBarChart.js.map +1 -0
- package/renderer/YAxisRendererRadarChart.d.ts +14 -0
- package/renderer/YAxisRendererRadarChart.js +180 -0
- package/renderer/YAxisRendererRadarChart.js.map +1 -0
- package/renderer/scatter/ChevronDownShapeRenderer.d.ts +11 -0
- package/renderer/scatter/ChevronDownShapeRenderer.js +15 -0
- package/renderer/scatter/ChevronDownShapeRenderer.js.map +1 -0
- package/renderer/scatter/ChevronUpShapeRenderer.d.ts +11 -0
- package/renderer/scatter/ChevronUpShapeRenderer.js +15 -0
- package/renderer/scatter/ChevronUpShapeRenderer.js.map +1 -0
- package/renderer/scatter/CircleShapeRenderer.d.ts +11 -0
- package/renderer/scatter/CircleShapeRenderer.js +31 -0
- package/renderer/scatter/CircleShapeRenderer.js.map +1 -0
- package/renderer/scatter/CrossShapeRenderer.d.ts +11 -0
- package/renderer/scatter/CrossShapeRenderer.js +15 -0
- package/renderer/scatter/CrossShapeRenderer.js.map +1 -0
- package/renderer/scatter/IShapeRenderer.d.ts +20 -0
- package/renderer/scatter/IShapeRenderer.js +2 -0
- package/renderer/scatter/IShapeRenderer.js.map +1 -0
- package/renderer/scatter/SquareShapeRenderer.d.ts +11 -0
- package/renderer/scatter/SquareShapeRenderer.js +31 -0
- package/renderer/scatter/SquareShapeRenderer.js.map +1 -0
- package/renderer/scatter/TriangleShapeRenderer.d.ts +12 -0
- package/renderer/scatter/TriangleShapeRenderer.js +43 -0
- package/renderer/scatter/TriangleShapeRenderer.js.map +1 -0
- package/renderer/scatter/XShapeRenderer.d.ts +11 -0
- package/renderer/scatter/XShapeRenderer.js +15 -0
- package/renderer/scatter/XShapeRenderer.js.map +1 -0
- package/utils/ColorTemplate.d.ts +34 -0
- package/utils/ColorTemplate.js +51 -0
- package/utils/ColorTemplate.js.map +1 -0
- package/utils/HorizontalViewPortHandler.d.ts +6 -0
- package/utils/HorizontalViewPortHandler.js +7 -0
- package/utils/HorizontalViewPortHandler.js.map +1 -0
- package/utils/MPPointD.d.ts +5 -0
- package/utils/MPPointF.d.ts +7 -0
- package/utils/MPSize.d.ts +7 -0
- package/utils/ObjectPool.d.ts +81 -0
- package/utils/ObjectPool.js +183 -0
- package/utils/ObjectPool.js.map +1 -0
- package/utils/Transformer.d.ts +175 -0
- package/utils/Transformer.js +356 -0
- package/utils/Transformer.js.map +1 -0
- package/utils/TransformerHorizontalBarChart.d.ts +14 -0
- package/utils/TransformerHorizontalBarChart.js +30 -0
- package/utils/TransformerHorizontalBarChart.js.map +1 -0
- package/utils/Utils.d.ts +203 -0
- package/utils/Utils.js +653 -0
- package/utils/Utils.js.map +1 -0
- package/utils/ViewPortHandler.d.ts +299 -0
- package/utils/ViewPortHandler.js +585 -0
- package/utils/ViewPortHandler.js.map +1 -0
- package/utils/colors/colorful.d.ts +1 -0
- package/utils/colors/colorful.js +2 -0
- package/utils/colors/colorful.js.map +1 -0
- package/utils/colors/joyful.d.ts +1 -0
- package/utils/colors/joyful.js +2 -0
- package/utils/colors/joyful.js.map +1 -0
- package/utils/colors/liberty.d.ts +1 -0
- package/utils/colors/liberty.js +2 -0
- package/utils/colors/liberty.js.map +1 -0
- package/utils/colors/material.d.ts +1 -0
- package/utils/colors/material.js +2 -0
- package/utils/colors/material.js.map +1 -0
- package/utils/colors/pastel.d.ts +1 -0
- package/utils/colors/pastel.js +2 -0
- package/utils/colors/pastel.js.map +1 -0
- package/utils/colors/vordiplom.d.ts +1 -0
- package/utils/colors/vordiplom.js +2 -0
- package/utils/colors/vordiplom.js.map +1 -0
|
@@ -0,0 +1,714 @@
|
|
|
1
|
+
import { Align, Canvas, Direction, LayoutAlignment, RectF, StaticLayout, Style, releaseImage } from '@nativescript-community/ui-canvas';
|
|
2
|
+
import { DataRenderer } from './DataRenderer';
|
|
3
|
+
import { ValuePosition } from '../data/PieDataSet';
|
|
4
|
+
import { ColorTemplate } from '../utils/ColorTemplate';
|
|
5
|
+
import { Utils } from '../utils/Utils';
|
|
6
|
+
export class PieChartRenderer extends DataRenderer {
|
|
7
|
+
get centerTextLastBounds() {
|
|
8
|
+
if (!this.mCenterTextLastBounds) {
|
|
9
|
+
this.mCenterTextLastBounds = new RectF(0, 0, 0, 0);
|
|
10
|
+
}
|
|
11
|
+
return this.mCenterTextLastBounds;
|
|
12
|
+
}
|
|
13
|
+
get rectBuffer() {
|
|
14
|
+
if (!this.mRectBuffer) {
|
|
15
|
+
this.mRectBuffer = [new RectF(0, 0, 0, 0), new RectF(0, 0, 0, 0)];
|
|
16
|
+
}
|
|
17
|
+
return this.mRectBuffer;
|
|
18
|
+
}
|
|
19
|
+
constructor(chart, animator, viewPortHandler) {
|
|
20
|
+
super(animator, viewPortHandler);
|
|
21
|
+
this.mChart = chart;
|
|
22
|
+
}
|
|
23
|
+
get centerTextPaint() {
|
|
24
|
+
if (!this.mCenterTextPaint) {
|
|
25
|
+
this.mCenterTextPaint = Utils.getTemplatePaint('black-fill');
|
|
26
|
+
this.mCenterTextPaint.setTextSize(12);
|
|
27
|
+
}
|
|
28
|
+
return this.mCenterTextPaint;
|
|
29
|
+
}
|
|
30
|
+
get entryLabelsPaint() {
|
|
31
|
+
if (!this.mEntryLabelsPaint) {
|
|
32
|
+
this.mEntryLabelsPaint = Utils.getTemplatePaint('white-fill');
|
|
33
|
+
this.mEntryLabelsPaint.setTextAlign(Align.CENTER);
|
|
34
|
+
this.mEntryLabelsPaint.setTextSize(13);
|
|
35
|
+
}
|
|
36
|
+
return this.mEntryLabelsPaint;
|
|
37
|
+
}
|
|
38
|
+
get transparentCirclePaint() {
|
|
39
|
+
if (!this.mTransparentCirclePaint) {
|
|
40
|
+
this.mTransparentCirclePaint = Utils.getTemplatePaint('white-fill');
|
|
41
|
+
this.mTransparentCirclePaint.setAlpha(105);
|
|
42
|
+
}
|
|
43
|
+
return this.mTransparentCirclePaint;
|
|
44
|
+
}
|
|
45
|
+
get holePaint() {
|
|
46
|
+
if (!this.mHolePaint) {
|
|
47
|
+
this.mHolePaint = Utils.getTemplatePaint('white-fill');
|
|
48
|
+
}
|
|
49
|
+
return this.mHolePaint;
|
|
50
|
+
}
|
|
51
|
+
get valuePaint() {
|
|
52
|
+
if (!this.mValuePaint) {
|
|
53
|
+
this.mValuePaint = Utils.getTemplatePaint('value');
|
|
54
|
+
this.mValuePaint.setColor('white');
|
|
55
|
+
this.mValuePaint.setTextSize(13);
|
|
56
|
+
}
|
|
57
|
+
return this.mValuePaint;
|
|
58
|
+
}
|
|
59
|
+
drawData(c) {
|
|
60
|
+
const width = this.mViewPortHandler.chartWidth;
|
|
61
|
+
const height = this.mViewPortHandler.chartHeight;
|
|
62
|
+
let drawBitmap = this.mDrawBitmap?.get();
|
|
63
|
+
if (!drawBitmap || drawBitmap.width !== width || drawBitmap.height !== height) {
|
|
64
|
+
if (width > 0 && height > 0) {
|
|
65
|
+
this.mBitmapCanvas = new Canvas(width, height);
|
|
66
|
+
drawBitmap = this.mBitmapCanvas.getImage();
|
|
67
|
+
this.mDrawBitmap = new WeakRef(drawBitmap);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.mBitmapCanvas.clear();
|
|
75
|
+
}
|
|
76
|
+
let needsBitmapDrawing = false;
|
|
77
|
+
const pieData = this.mChart.data;
|
|
78
|
+
for (const set of pieData.dataSets) {
|
|
79
|
+
needsBitmapDrawing = this.drawDataSet(c, set) || needsBitmapDrawing;
|
|
80
|
+
}
|
|
81
|
+
if (needsBitmapDrawing) {
|
|
82
|
+
const renderPaint = this.renderPaint;
|
|
83
|
+
c.drawBitmap(drawBitmap, 0, 0, renderPaint);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
calculateMinimumRadiusForSpacedSlice(center, radius, angle, arcStartPointX, arcStartPointY, startAngle, sweepAngle) {
|
|
87
|
+
const angleMiddle = startAngle + sweepAngle / 2;
|
|
88
|
+
// Other polet of the arc
|
|
89
|
+
const arcEndPointX = center.x + radius * Math.cos((startAngle + sweepAngle) * Utils.DEG2RAD);
|
|
90
|
+
const arcEndPointY = center.y + radius * Math.sin((startAngle + sweepAngle) * Utils.DEG2RAD);
|
|
91
|
+
// Middle polet on the arc
|
|
92
|
+
const arcMidPointX = center.x + radius * Math.cos(angleMiddle * Utils.DEG2RAD);
|
|
93
|
+
const arcMidPointY = center.y + radius * Math.sin(angleMiddle * Utils.DEG2RAD);
|
|
94
|
+
// This is the base of the contained triangle
|
|
95
|
+
const basePointsDistance = Math.sqrt(Math.pow(arcEndPointX - arcStartPointX, 2) + Math.pow(arcEndPointY - arcStartPointY, 2));
|
|
96
|
+
// After reducing space from both sides of the "slice",
|
|
97
|
+
// the angle of the contained triangle should stay the same.
|
|
98
|
+
// So let's find out the height of that triangle.
|
|
99
|
+
const containedTriangleHeight = (basePointsDistance / 2.0) * Math.tan(((180.0 - angle) / 2.0) * Utils.DEG2RAD);
|
|
100
|
+
// Now we subtract that from the radius
|
|
101
|
+
let spacedRadius = radius - containedTriangleHeight;
|
|
102
|
+
// And now subtract the height of the arc that's between the triangle and the outer circle
|
|
103
|
+
spacedRadius -= Math.sqrt(Math.pow(arcMidPointX - (arcEndPointX + arcStartPointX) / 2, 2) + Math.pow(arcMidPointY - (arcEndPointY + arcStartPointY) / 2, 2));
|
|
104
|
+
return spacedRadius;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Calculates the sliceSpace to use based on visible values and their size compared to the set sliceSpace.
|
|
108
|
+
*
|
|
109
|
+
* @param dataSet
|
|
110
|
+
* @return
|
|
111
|
+
*/
|
|
112
|
+
getSliceSpace(dataSet) {
|
|
113
|
+
if (!dataSet.automaticallyDisableSliceSpacing) {
|
|
114
|
+
return dataSet.sliceSpace;
|
|
115
|
+
}
|
|
116
|
+
const spaceSizeRatio = dataSet.sliceSpace / this.mViewPortHandler.smallestContentExtension;
|
|
117
|
+
const minValueRatio = (dataSet.yMin / this.mChart.data.getYValueSum()) * 2;
|
|
118
|
+
const sliceSpace = spaceSizeRatio > minValueRatio ? 0 : dataSet.sliceSpace;
|
|
119
|
+
return sliceSpace;
|
|
120
|
+
}
|
|
121
|
+
drawDataSet(c, dataSet) {
|
|
122
|
+
const chart = this.mChart;
|
|
123
|
+
const result = false;
|
|
124
|
+
let angle = 0;
|
|
125
|
+
const yKey = dataSet.yProperty;
|
|
126
|
+
const rotationAngle = chart.rotationAngle;
|
|
127
|
+
const phaseX = this.animator.phaseX;
|
|
128
|
+
const phaseY = this.animator.phaseY;
|
|
129
|
+
const circleBox = chart.circleBox;
|
|
130
|
+
const entryCount = dataSet.entryCount;
|
|
131
|
+
const drawAngles = chart.drawAngles;
|
|
132
|
+
const center = chart.centerCircleBox;
|
|
133
|
+
const radius = chart.radius;
|
|
134
|
+
const drawInnerArc = chart.drawHoleEnabled && !chart.drawSlicesUnderHoleEnabled;
|
|
135
|
+
const userInnerRadius = drawInnerArc ? radius * (chart.holeRadius / 100) : 0;
|
|
136
|
+
const roundedRadius = (radius - (radius * chart.holeRadius) / 100) / 2;
|
|
137
|
+
const roundedCircleBox = new RectF(0, 0, 0, 0);
|
|
138
|
+
const drawRoundedSlices = drawInnerArc && chart.drawRoundedSlices;
|
|
139
|
+
let visibleAngleCount = 0;
|
|
140
|
+
for (let j = 0; j < entryCount; j++) {
|
|
141
|
+
// draw only if the value is greater than zero
|
|
142
|
+
if (Math.abs(dataSet.getEntryForIndex(j)[yKey]) > Utils.NUMBER_EPSILON) {
|
|
143
|
+
visibleAngleCount++;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const sliceSpace = visibleAngleCount <= 1 ? 0 : this.getSliceSpace(dataSet);
|
|
147
|
+
const customRender = chart.customRenderer;
|
|
148
|
+
const renderPaint = this.renderPaint;
|
|
149
|
+
const pathBuffer = Utils.getTempPath();
|
|
150
|
+
const previousShader = renderPaint.getShader();
|
|
151
|
+
const shader = dataSet.fillShader;
|
|
152
|
+
if (shader) {
|
|
153
|
+
renderPaint.setShader(shader);
|
|
154
|
+
}
|
|
155
|
+
for (let j = 0; j < entryCount; j++) {
|
|
156
|
+
const sliceAngle = drawAngles[j];
|
|
157
|
+
let innerRadius = userInnerRadius;
|
|
158
|
+
const e = dataSet.getEntryForIndex(j);
|
|
159
|
+
// draw only if the value is greater than zero
|
|
160
|
+
if (!(Math.abs(e[yKey]) > Utils.NUMBER_EPSILON)) {
|
|
161
|
+
angle += sliceAngle * phaseX;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
// Don't draw if it's highlighted, unless the chart uses rounded slices
|
|
165
|
+
if (chart.needsHighlight(j) && !drawRoundedSlices) {
|
|
166
|
+
angle += sliceAngle * phaseX;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
const accountForSliceSpacing = sliceSpace > 0 && sliceAngle <= 180;
|
|
170
|
+
renderPaint.setColor(dataSet.getColor(j));
|
|
171
|
+
const sliceSpaceAngleOuter = visibleAngleCount === 1 ? 0 : sliceSpace / (Utils.DEG2RAD * radius);
|
|
172
|
+
const startAngleOuter = rotationAngle + (angle + sliceSpaceAngleOuter / 2) * phaseY;
|
|
173
|
+
let sweepAngleOuter = (sliceAngle - sliceSpaceAngleOuter) * phaseY;
|
|
174
|
+
if (sweepAngleOuter < 0) {
|
|
175
|
+
sweepAngleOuter = 0;
|
|
176
|
+
}
|
|
177
|
+
pathBuffer.reset();
|
|
178
|
+
if (drawRoundedSlices) {
|
|
179
|
+
const x = center.x + (radius - roundedRadius) * Math.cos(startAngleOuter * Utils.DEG2RAD);
|
|
180
|
+
const y = center.y + (radius - roundedRadius) * Math.sin(startAngleOuter * Utils.DEG2RAD);
|
|
181
|
+
roundedCircleBox.set(x - roundedRadius, y - roundedRadius, x + roundedRadius, y + roundedRadius);
|
|
182
|
+
}
|
|
183
|
+
const arcStartPointX = center.x + radius * Math.cos(startAngleOuter * Utils.DEG2RAD);
|
|
184
|
+
const arcStartPointY = center.y + radius * Math.sin(startAngleOuter * Utils.DEG2RAD);
|
|
185
|
+
if (sweepAngleOuter >= 360 && sweepAngleOuter % 360 <= Utils.NUMBER_EPSILON) {
|
|
186
|
+
// Android is doing "mod 360"
|
|
187
|
+
pathBuffer.addCircle(center.x, center.y, radius, Direction.CW);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
if (drawRoundedSlices) {
|
|
191
|
+
pathBuffer.arcTo(roundedCircleBox, startAngleOuter + 180, -180);
|
|
192
|
+
}
|
|
193
|
+
pathBuffer.arcTo(circleBox, startAngleOuter, sweepAngleOuter);
|
|
194
|
+
}
|
|
195
|
+
// Android API < 21 does not receive floats in addArc, but a RectF
|
|
196
|
+
if (drawInnerArc && (innerRadius > 0 || accountForSliceSpacing)) {
|
|
197
|
+
const innerRectBuffer = Utils.getTempRectF();
|
|
198
|
+
innerRectBuffer.set(center.x - innerRadius, center.y - innerRadius, center.x + innerRadius, center.y + innerRadius);
|
|
199
|
+
if (accountForSliceSpacing) {
|
|
200
|
+
let minSpacedRadius = this.calculateMinimumRadiusForSpacedSlice(center, radius, sliceAngle * phaseY, arcStartPointX, arcStartPointY, startAngleOuter, sweepAngleOuter);
|
|
201
|
+
if (minSpacedRadius < 0) {
|
|
202
|
+
minSpacedRadius = -minSpacedRadius;
|
|
203
|
+
}
|
|
204
|
+
innerRadius = Math.max(innerRadius, minSpacedRadius);
|
|
205
|
+
}
|
|
206
|
+
const sliceSpaceAngleInner = visibleAngleCount === 1 || innerRadius === 0 ? 0 : sliceSpace / (Utils.DEG2RAD * innerRadius);
|
|
207
|
+
const startAngleInner = rotationAngle + (angle + sliceSpaceAngleInner / 2) * phaseY;
|
|
208
|
+
let sweepAngleInner = (sliceAngle - sliceSpaceAngleInner) * phaseY;
|
|
209
|
+
if (sweepAngleInner < 0) {
|
|
210
|
+
sweepAngleInner = 0;
|
|
211
|
+
}
|
|
212
|
+
const endAngleInner = startAngleInner + sweepAngleInner;
|
|
213
|
+
if (sweepAngleOuter >= 360 && sweepAngleOuter % 360 <= Utils.NUMBER_EPSILON) {
|
|
214
|
+
// Android is doing "mod 360"
|
|
215
|
+
pathBuffer.addCircle(center.x, center.y, innerRadius, Direction.CCW);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
if (drawRoundedSlices) {
|
|
219
|
+
const x = center.x + (radius - roundedRadius) * Math.cos(endAngleInner * Utils.DEG2RAD);
|
|
220
|
+
const y = center.y + (radius - roundedRadius) * Math.sin(endAngleInner * Utils.DEG2RAD);
|
|
221
|
+
roundedCircleBox.set(x - roundedRadius, y - roundedRadius, x + roundedRadius, y + roundedRadius);
|
|
222
|
+
pathBuffer.arcTo(roundedCircleBox, endAngleInner, 180);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
pathBuffer.lineTo(center.x + innerRadius * Math.cos(endAngleInner * Utils.DEG2RAD), center.y + innerRadius * Math.sin(endAngleInner * Utils.DEG2RAD));
|
|
226
|
+
}
|
|
227
|
+
pathBuffer.arcTo(innerRectBuffer, endAngleInner, -sweepAngleInner);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
if (sweepAngleOuter % 360 > Utils.NUMBER_EPSILON) {
|
|
232
|
+
if (accountForSliceSpacing) {
|
|
233
|
+
const angleMiddle = startAngleOuter + sweepAngleOuter / 2;
|
|
234
|
+
const sliceSpaceOffset = this.calculateMinimumRadiusForSpacedSlice(center, radius, sliceAngle * phaseY, arcStartPointX, arcStartPointY, startAngleOuter, sweepAngleOuter);
|
|
235
|
+
const arcEndPointX = center.x + sliceSpaceOffset * Math.cos(angleMiddle * Utils.DEG2RAD);
|
|
236
|
+
const arcEndPointY = center.y + sliceSpaceOffset * Math.sin(angleMiddle * Utils.DEG2RAD);
|
|
237
|
+
pathBuffer.lineTo(arcEndPointX, arcEndPointY);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
pathBuffer.lineTo(center.x, center.y);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
pathBuffer.close();
|
|
245
|
+
if (customRender && customRender.drawSlice) {
|
|
246
|
+
customRender.drawSlice(c, e, pathBuffer, renderPaint);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
c.drawPath(pathBuffer, renderPaint);
|
|
250
|
+
}
|
|
251
|
+
angle += sliceAngle * phaseX;
|
|
252
|
+
}
|
|
253
|
+
renderPaint.setShader(previousShader);
|
|
254
|
+
return result;
|
|
255
|
+
}
|
|
256
|
+
drawValues(c) {
|
|
257
|
+
const chart = this.mChart;
|
|
258
|
+
const drawEntryLabels = chart.drawEntryLabels;
|
|
259
|
+
const data = chart.data;
|
|
260
|
+
const dataSets = data.dataSets;
|
|
261
|
+
if (!drawEntryLabels || dataSets.some((d) => d.drawValuesEnabled || d.drawIconsEnabled) === false) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const center = chart.centerCircleBox;
|
|
265
|
+
// Get whole the radius
|
|
266
|
+
const radius = chart.radius;
|
|
267
|
+
let rotationAngle = chart.rotationAngle;
|
|
268
|
+
const drawAngles = chart.drawAngles;
|
|
269
|
+
const absoluteAngles = chart.absoluteAngles;
|
|
270
|
+
const phaseX = this.animator.phaseX;
|
|
271
|
+
const phaseY = this.animator.phaseY;
|
|
272
|
+
const roundedRadius = (radius - (radius * chart.holeRadius) / 100) / 2;
|
|
273
|
+
const holeRadiusPercent = chart.holeRadius / 100;
|
|
274
|
+
let labelRadiusOffset = (radius / 10) * 3.6;
|
|
275
|
+
if (chart.drawHoleEnabled) {
|
|
276
|
+
labelRadiusOffset = (radius - radius * holeRadiusPercent) / 2;
|
|
277
|
+
if (!chart.drawSlicesUnderHoleEnabled && chart.drawRoundedSlices) {
|
|
278
|
+
// Add curved circle slice and spacing to rotation angle, so that it sits nicely inside
|
|
279
|
+
rotationAngle += (roundedRadius * 360) / (Math.PI * 2 * radius);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
const labelRadius = radius - labelRadiusOffset;
|
|
283
|
+
const yValueSum = data.getYValueSum();
|
|
284
|
+
let angle;
|
|
285
|
+
let xIndex = 0;
|
|
286
|
+
c.save();
|
|
287
|
+
const offset = 5;
|
|
288
|
+
const paint = this.valuePaint;
|
|
289
|
+
const entryLabelsPaint = drawEntryLabels ? this.entryLabelsPaint : undefined;
|
|
290
|
+
const customRender = chart.customRenderer;
|
|
291
|
+
const valueLinePaint = Utils.getTempPaint();
|
|
292
|
+
valueLinePaint.setStyle(Style.STROKE);
|
|
293
|
+
for (let i = 0; i < dataSets.length; i++) {
|
|
294
|
+
const dataSet = dataSets[i];
|
|
295
|
+
const drawValues = dataSet.drawValuesEnabled;
|
|
296
|
+
if (!drawValues) {
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
const yKey = dataSet.yProperty;
|
|
300
|
+
const xValuePosition = dataSet.xValuePosition;
|
|
301
|
+
const yValuePosition = dataSet.yValuePosition;
|
|
302
|
+
// Apply the text-styling defined by the DataSet
|
|
303
|
+
this.applyValueTextStyle(dataSet);
|
|
304
|
+
const lineHeight = Utils.calcTextHeight(paint, 'Q') + 4;
|
|
305
|
+
const formatter = dataSet.valueFormatter;
|
|
306
|
+
const entryCount = dataSet.entryCount;
|
|
307
|
+
valueLinePaint.setColor(dataSet.valueLineColor);
|
|
308
|
+
valueLinePaint.setStrokeWidth(dataSet.valueLineWidth);
|
|
309
|
+
const sliceSpace = this.getSliceSpace(dataSet);
|
|
310
|
+
const iconsOffset = dataSet.iconsOffset;
|
|
311
|
+
const valuesOffset = dataSet.valuesOffset;
|
|
312
|
+
const isDrawIconsEnabled = dataSet.drawIconsEnabled;
|
|
313
|
+
for (let j = 0; j < entryCount; j++) {
|
|
314
|
+
const entry = dataSet.getEntryForIndex(j);
|
|
315
|
+
if (xIndex === 0) {
|
|
316
|
+
angle = 0;
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
angle = absoluteAngles[xIndex - 1] * phaseX;
|
|
320
|
+
}
|
|
321
|
+
const sliceAngle = drawAngles[xIndex];
|
|
322
|
+
const sliceSpaceMiddleAngle = sliceSpace / (Utils.DEG2RAD * labelRadius);
|
|
323
|
+
// offset needed to center the drawn text in the slice
|
|
324
|
+
const angleOffset = (sliceAngle - sliceSpaceMiddleAngle / 2) / 2;
|
|
325
|
+
angle = angle + angleOffset;
|
|
326
|
+
const transformedAngle = rotationAngle + angle * phaseY;
|
|
327
|
+
const value = chart.usePercentValues ? (entry[yKey] / yValueSum) * 100 : entry[yKey];
|
|
328
|
+
const formattedValue = (formatter.getPieLabel || formatter.getFormattedValue)(value, entry);
|
|
329
|
+
const entryLabel = entry.label;
|
|
330
|
+
const sliceXBase = Math.cos(transformedAngle * Utils.DEG2RAD);
|
|
331
|
+
const sliceYBase = Math.sin(transformedAngle * Utils.DEG2RAD);
|
|
332
|
+
const drawXOutside = drawEntryLabels && xValuePosition === ValuePosition.OUTSIDE_SLICE;
|
|
333
|
+
const drawYOutside = drawValues && yValuePosition === ValuePosition.OUTSIDE_SLICE;
|
|
334
|
+
const drawXInside = drawEntryLabels && xValuePosition === ValuePosition.INSIDE_SLICE;
|
|
335
|
+
const drawYInside = drawValues && yValuePosition === ValuePosition.INSIDE_SLICE;
|
|
336
|
+
if (drawXOutside || drawYOutside) {
|
|
337
|
+
const valueLineLength1 = dataSet.valueLinePart1Length;
|
|
338
|
+
const valueLineLength2 = dataSet.valueLinePart2Length;
|
|
339
|
+
const valueLinePart1OffsetPercentage = dataSet.valueLinePart1OffsetPercentage / 100;
|
|
340
|
+
let pt2x, pt2y;
|
|
341
|
+
let labelPtx, labelPty;
|
|
342
|
+
let line1Radius;
|
|
343
|
+
if (chart.drawHoleEnabled) {
|
|
344
|
+
line1Radius = (radius - radius * holeRadiusPercent) * valueLinePart1OffsetPercentage + radius * holeRadiusPercent;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
line1Radius = radius * valueLinePart1OffsetPercentage;
|
|
348
|
+
}
|
|
349
|
+
const polyline2Width = dataSet.valueLineVariableLength ? labelRadius * valueLineLength2 * Math.abs(Math.sin(transformedAngle * Utils.DEG2RAD)) : labelRadius * valueLineLength2;
|
|
350
|
+
const pt0x = line1Radius * sliceXBase + center.x;
|
|
351
|
+
const pt0y = line1Radius * sliceYBase + center.y;
|
|
352
|
+
const pt1x = labelRadius * (1 + valueLineLength1) * sliceXBase + center.x;
|
|
353
|
+
const pt1y = labelRadius * (1 + valueLineLength1) * sliceYBase + center.y;
|
|
354
|
+
if (transformedAngle % 360.0 >= 90.0 && transformedAngle % 360.0 <= 270.0) {
|
|
355
|
+
pt2x = pt1x - polyline2Width;
|
|
356
|
+
pt2y = pt1y;
|
|
357
|
+
paint.setTextAlign(Align.RIGHT);
|
|
358
|
+
if (drawXOutside) {
|
|
359
|
+
entryLabelsPaint.setTextAlign(Align.RIGHT);
|
|
360
|
+
}
|
|
361
|
+
labelPtx = pt2x - offset;
|
|
362
|
+
labelPty = pt2y;
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
pt2x = pt1x + polyline2Width;
|
|
366
|
+
pt2y = pt1y;
|
|
367
|
+
paint.setTextAlign(Align.LEFT);
|
|
368
|
+
if (drawXOutside) {
|
|
369
|
+
entryLabelsPaint.setTextAlign(Align.LEFT);
|
|
370
|
+
}
|
|
371
|
+
labelPtx = pt2x + offset;
|
|
372
|
+
labelPty = pt2y;
|
|
373
|
+
}
|
|
374
|
+
if (dataSet.valueLineColor !== ColorTemplate.COLOR_NONE) {
|
|
375
|
+
if (dataSet.usingSliceColorAsValueLineColor) {
|
|
376
|
+
valueLinePaint.setColor(dataSet.getColor(j));
|
|
377
|
+
}
|
|
378
|
+
c.drawLine(pt0x, pt0y, pt1x, pt1y, valueLinePaint);
|
|
379
|
+
c.drawLine(pt1x, pt1y, pt2x, pt2y, valueLinePaint);
|
|
380
|
+
}
|
|
381
|
+
// draw everything, depending on settings
|
|
382
|
+
if (drawXOutside && drawYOutside) {
|
|
383
|
+
this.drawValue(c, chart, dataSet, i, entry, j, formattedValue, labelPtx + valuesOffset.x, labelPty + valuesOffset.y, dataSet.getValueTextColor(j), paint, customRender);
|
|
384
|
+
if (j < data.entryCount && entryLabel) {
|
|
385
|
+
this.drawEntryLabel(c, entryLabel, labelPtx, labelPty + lineHeight, entryLabelsPaint);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
else if (drawXOutside) {
|
|
389
|
+
if (j < data.entryCount && entryLabel) {
|
|
390
|
+
this.drawEntryLabel(c, entryLabel, labelPtx, labelPty + lineHeight / 2, entryLabelsPaint);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
else if (drawYOutside) {
|
|
394
|
+
this.drawValue(c, chart, dataSet, i, entry, j, formattedValue, labelPtx + valuesOffset.x, labelPty + valuesOffset.y + lineHeight / 2, dataSet.getValueTextColor(j), paint, customRender);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
if (drawXInside || drawYInside) {
|
|
398
|
+
// calculate the text position
|
|
399
|
+
const x = labelRadius * sliceXBase + center.x;
|
|
400
|
+
const y = labelRadius * sliceYBase + center.y;
|
|
401
|
+
paint.setTextAlign(Align.CENTER);
|
|
402
|
+
// draw everything, depending on settings
|
|
403
|
+
if (drawXInside && drawYInside) {
|
|
404
|
+
this.drawValue(c, chart, dataSet, i, entry, j, formattedValue, x + valuesOffset.x, y + valuesOffset.y, dataSet.getValueTextColor(j), paint, customRender);
|
|
405
|
+
if (j < data.entryCount && entryLabel) {
|
|
406
|
+
this.drawEntryLabel(c, entryLabel, x, y + lineHeight, entryLabelsPaint);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
else if (drawXInside) {
|
|
410
|
+
if (j < data.entryCount && entryLabel) {
|
|
411
|
+
this.drawEntryLabel(c, entryLabel, x, y + lineHeight / 2, entryLabelsPaint);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
else if (drawYInside) {
|
|
415
|
+
this.drawValue(c, chart, dataSet, i, entry, j, formattedValue, x + valuesOffset.x, y + valuesOffset.y + lineHeight / 2, dataSet.getValueTextColor(j), paint, customRender);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (isDrawIconsEnabled) {
|
|
419
|
+
const x = (labelRadius + iconsOffset.y) * sliceXBase + center.x;
|
|
420
|
+
let y = (labelRadius + iconsOffset.y) * sliceYBase + center.y;
|
|
421
|
+
y += iconsOffset.x;
|
|
422
|
+
this.drawIcon(c, chart, dataSet, i, entry, j, dataSet.getEntryIcon(entry), x, y, customRender);
|
|
423
|
+
}
|
|
424
|
+
xIndex++;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
c.restore();
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Draws an entry label at the specified position.
|
|
431
|
+
*
|
|
432
|
+
* @param c
|
|
433
|
+
* @param label
|
|
434
|
+
* @param x
|
|
435
|
+
* @param y
|
|
436
|
+
*/
|
|
437
|
+
drawEntryLabel(c, label, x, y, paint) {
|
|
438
|
+
c.drawText(label.toString(), x, y, paint);
|
|
439
|
+
}
|
|
440
|
+
drawExtras(c) {
|
|
441
|
+
this.drawHole(c);
|
|
442
|
+
if (this.mDrawBitmap.get()) {
|
|
443
|
+
c.drawBitmap(this.mDrawBitmap.get(), 0, 0, null);
|
|
444
|
+
}
|
|
445
|
+
this.drawCenterText(c);
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Draws the hole in the center of the chart and the transparent circle /
|
|
449
|
+
* hole.
|
|
450
|
+
*/
|
|
451
|
+
drawHole(c) {
|
|
452
|
+
const chart = this.mChart;
|
|
453
|
+
if (chart.drawHoleEnabled) {
|
|
454
|
+
const radius = chart.radius;
|
|
455
|
+
const holeRadius = radius * (chart.holeRadius / 100);
|
|
456
|
+
const center = chart.centerCircleBox;
|
|
457
|
+
const paint = this.holePaint;
|
|
458
|
+
if (ColorTemplate.getColorInstance(paint.getColor()).a > 0) {
|
|
459
|
+
// draw the hole-circle
|
|
460
|
+
c.drawCircle(center.x, center.y, holeRadius, paint);
|
|
461
|
+
}
|
|
462
|
+
const transparentCirclePaint = this.transparentCirclePaint;
|
|
463
|
+
// only draw the circle if it can be seen (not covered by the hole)
|
|
464
|
+
if (ColorTemplate.getColorInstance(transparentCirclePaint.getColor()).a > 0 && chart.transparentCircleRadiusPercent > chart.holeRadius) {
|
|
465
|
+
const alpha = transparentCirclePaint.getAlpha();
|
|
466
|
+
const secondHoleRadius = radius * (chart.transparentCircleRadiusPercent / 100);
|
|
467
|
+
transparentCirclePaint.setAlpha(alpha * this.animator.phaseX * this.animator.phaseY);
|
|
468
|
+
// draw the transparent-circle
|
|
469
|
+
const path = Utils.getTempPath();
|
|
470
|
+
path.reset();
|
|
471
|
+
path.addCircle(center.x, center.y, secondHoleRadius, Direction.CW);
|
|
472
|
+
path.addCircle(center.x, center.y, holeRadius, Direction.CCW);
|
|
473
|
+
c.drawPath(path, transparentCirclePaint);
|
|
474
|
+
// reset alpha
|
|
475
|
+
transparentCirclePaint.setAlpha(alpha);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Draws the description text in the center of the pie chart makes most
|
|
481
|
+
* sense when center-hole is enabled.
|
|
482
|
+
*/
|
|
483
|
+
drawCenterText(c) {
|
|
484
|
+
const chart = this.mChart;
|
|
485
|
+
const centerText = chart.centerText;
|
|
486
|
+
if (centerText && chart.drawCenterText) {
|
|
487
|
+
const center = chart.centerCircleBox;
|
|
488
|
+
const offset = chart.centerTextOffset;
|
|
489
|
+
const x = center.x + offset.x;
|
|
490
|
+
const y = center.y + offset.y;
|
|
491
|
+
const innerRadius = chart.drawHoleEnabled && !chart.drawSlicesUnderHoleEnabled ? chart.radius * (chart.holeRadius / 100) : chart.radius;
|
|
492
|
+
const rectBuffer = this.rectBuffer;
|
|
493
|
+
const holeRect = rectBuffer[0];
|
|
494
|
+
holeRect.left = x - innerRadius;
|
|
495
|
+
holeRect.top = y - innerRadius;
|
|
496
|
+
holeRect.right = x + innerRadius;
|
|
497
|
+
holeRect.bottom = y + innerRadius;
|
|
498
|
+
const boundingRect = rectBuffer[1];
|
|
499
|
+
boundingRect.set(holeRect);
|
|
500
|
+
const radiusPercent = chart.centerTextRadiusPercent / 100;
|
|
501
|
+
if (radiusPercent > 0.0) {
|
|
502
|
+
boundingRect.inset((boundingRect.width() - boundingRect.width() * radiusPercent) / 2, (boundingRect.height() - boundingRect.height() * radiusPercent) / 2);
|
|
503
|
+
}
|
|
504
|
+
const centerTextLastBounds = this.centerTextLastBounds;
|
|
505
|
+
if (!this.mCenterTextLayout || centerText !== this.mCenterTextLastValue || boundingRect !== centerTextLastBounds) {
|
|
506
|
+
// Next time we won't recalculate StaticLayout...
|
|
507
|
+
centerTextLastBounds.set(boundingRect);
|
|
508
|
+
this.mCenterTextLastValue = centerText;
|
|
509
|
+
const width = centerTextLastBounds.width();
|
|
510
|
+
// If width is 0, it will crash. Always have a minimum of 1
|
|
511
|
+
this.mCenterTextLayout = new StaticLayout(centerText, this.centerTextPaint, Math.max(Math.ceil(width), 1), LayoutAlignment.ALIGN_CENTER, 1, 0, false);
|
|
512
|
+
}
|
|
513
|
+
//let layoutWidth = Utils.getStaticLayoutMaxWidth(mCenterTextLayout);
|
|
514
|
+
const layoutHeight = this.mCenterTextLayout.getHeight();
|
|
515
|
+
c.save();
|
|
516
|
+
if (__ANDROID__) {
|
|
517
|
+
if (android.os.Build.VERSION.SDK_INT >= 18) {
|
|
518
|
+
const path = Utils.getTempPath();
|
|
519
|
+
path.reset();
|
|
520
|
+
path.addOval(holeRect, Direction.CW);
|
|
521
|
+
c.clipPath(path);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
c.translate(boundingRect.left, boundingRect.top + (boundingRect.height() - layoutHeight) / 2);
|
|
525
|
+
this.mCenterTextLayout.draw(c);
|
|
526
|
+
c.restore();
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
drawHighlighted(c, indices) {
|
|
530
|
+
/* Skip entirely if using rounded circle slices, because it doesn't make sense to highlight
|
|
531
|
+
* in this way.
|
|
532
|
+
* TODO: add support for changing slice color with highlighting rather than only shifting the slice
|
|
533
|
+
*/
|
|
534
|
+
const chart = this.mChart;
|
|
535
|
+
const drawInnerArc = chart.drawHoleEnabled && !chart.drawSlicesUnderHoleEnabled;
|
|
536
|
+
if (drawInnerArc && chart.drawRoundedSlices) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
const phaseX = this.animator.phaseX;
|
|
540
|
+
const phaseY = this.animator.phaseY;
|
|
541
|
+
let angle;
|
|
542
|
+
const rotationAngle = chart.rotationAngle;
|
|
543
|
+
const drawAngles = chart.drawAngles;
|
|
544
|
+
const absoluteAngles = chart.absoluteAngles;
|
|
545
|
+
const center = chart.centerCircleBox;
|
|
546
|
+
const radius = chart.radius;
|
|
547
|
+
const userInnerRadius = drawInnerArc ? radius * (chart.holeRadius / 100) : 0;
|
|
548
|
+
const highlightedCircleBox = Utils.getTempRectF();
|
|
549
|
+
const customRender = chart.customRenderer;
|
|
550
|
+
const renderPaint = this.renderPaint;
|
|
551
|
+
const pathBuffer = Utils.getTempPath();
|
|
552
|
+
for (let i = 0; i < indices.length; i++) {
|
|
553
|
+
// get the index to highlight
|
|
554
|
+
const high = indices[i];
|
|
555
|
+
const index = high.x;
|
|
556
|
+
if (index >= drawAngles.length) {
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
const set = chart.data.getDataSetByIndex(high.dataSetIndex);
|
|
560
|
+
if (!set || !set.highlightEnabled) {
|
|
561
|
+
continue;
|
|
562
|
+
}
|
|
563
|
+
const yKey = set.yProperty;
|
|
564
|
+
const entryCount = set.entryCount;
|
|
565
|
+
let visibleAngleCount = 0;
|
|
566
|
+
for (let j = 0; j < entryCount; j++) {
|
|
567
|
+
// draw only if the value is greater than zero
|
|
568
|
+
if (Math.abs(set.getEntryForIndex(j)[yKey]) > Utils.NUMBER_EPSILON) {
|
|
569
|
+
visibleAngleCount++;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
if (index === 0) {
|
|
573
|
+
angle = 0;
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
angle = absoluteAngles[index - 1] * phaseX;
|
|
577
|
+
}
|
|
578
|
+
const sliceSpace = visibleAngleCount <= 1 ? 0 : set.sliceSpace;
|
|
579
|
+
const sliceAngle = drawAngles[index];
|
|
580
|
+
let innerRadius = userInnerRadius;
|
|
581
|
+
const shift = set.selectionShift;
|
|
582
|
+
const highlightedRadius = radius + shift;
|
|
583
|
+
highlightedCircleBox.set(chart.circleBox);
|
|
584
|
+
highlightedCircleBox.inset(-shift, -shift);
|
|
585
|
+
const accountForSliceSpacing = sliceSpace > 0 && sliceAngle <= 180;
|
|
586
|
+
renderPaint.setColor(set.getColor(index));
|
|
587
|
+
const sliceSpaceAngleOuter = visibleAngleCount === 1 ? 0 : sliceSpace / (Utils.DEG2RAD * radius);
|
|
588
|
+
const sliceSpaceAngleShifted = visibleAngleCount === 1 ? 0 : sliceSpace / (Utils.DEG2RAD * highlightedRadius);
|
|
589
|
+
const startAngleOuter = rotationAngle + (angle + sliceSpaceAngleOuter / 2) * phaseY;
|
|
590
|
+
let sweepAngleOuter = (sliceAngle - sliceSpaceAngleOuter) * phaseY;
|
|
591
|
+
if (sweepAngleOuter < 0) {
|
|
592
|
+
sweepAngleOuter = 0;
|
|
593
|
+
}
|
|
594
|
+
const startAngleShifted = rotationAngle + (angle + sliceSpaceAngleShifted / 2) * phaseY;
|
|
595
|
+
let sweepAngleShifted = (sliceAngle - sliceSpaceAngleShifted) * phaseY;
|
|
596
|
+
if (sweepAngleShifted < 0) {
|
|
597
|
+
sweepAngleShifted = 0;
|
|
598
|
+
}
|
|
599
|
+
pathBuffer.reset();
|
|
600
|
+
if (sweepAngleOuter >= 360 && sweepAngleOuter % 360 <= Utils.NUMBER_EPSILON) {
|
|
601
|
+
// Android is doing "mod 360"
|
|
602
|
+
pathBuffer.addCircle(center.x, center.y, highlightedRadius, Direction.CW);
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
pathBuffer.moveTo(center.x + highlightedRadius * Math.cos(startAngleShifted * Utils.DEG2RAD), center.y + highlightedRadius * Math.sin(startAngleShifted * Utils.DEG2RAD));
|
|
606
|
+
pathBuffer.arcTo(highlightedCircleBox, startAngleShifted, sweepAngleShifted);
|
|
607
|
+
}
|
|
608
|
+
let sliceSpaceRadius = 0;
|
|
609
|
+
if (accountForSliceSpacing) {
|
|
610
|
+
sliceSpaceRadius = this.calculateMinimumRadiusForSpacedSlice(center, radius, sliceAngle * phaseY, center.x + radius * Math.cos(startAngleOuter * Utils.DEG2RAD), center.y + radius * Math.sin(startAngleOuter * Utils.DEG2RAD), startAngleOuter, sweepAngleOuter);
|
|
611
|
+
}
|
|
612
|
+
if (drawInnerArc && (innerRadius > 0 || accountForSliceSpacing)) {
|
|
613
|
+
// Android API < 21 does not receive floats in addArc, but a RectF
|
|
614
|
+
const innerRectBuffer = Utils.getTempRectF();
|
|
615
|
+
innerRectBuffer.set(center.x - innerRadius, center.y - innerRadius, center.x + innerRadius, center.y + innerRadius);
|
|
616
|
+
if (accountForSliceSpacing) {
|
|
617
|
+
let minSpacedRadius = sliceSpaceRadius;
|
|
618
|
+
if (minSpacedRadius < 0)
|
|
619
|
+
minSpacedRadius = -minSpacedRadius;
|
|
620
|
+
innerRadius = Math.max(innerRadius, minSpacedRadius);
|
|
621
|
+
}
|
|
622
|
+
const sliceSpaceAngleInner = visibleAngleCount === 1 || innerRadius === 0 ? 0 : sliceSpace / (Utils.DEG2RAD * innerRadius);
|
|
623
|
+
const startAngleInner = rotationAngle + (angle + sliceSpaceAngleInner / 2) * phaseY;
|
|
624
|
+
let sweepAngleInner = (sliceAngle - sliceSpaceAngleInner) * phaseY;
|
|
625
|
+
if (sweepAngleInner < 0) {
|
|
626
|
+
sweepAngleInner = 0;
|
|
627
|
+
}
|
|
628
|
+
const endAngleInner = startAngleInner + sweepAngleInner;
|
|
629
|
+
if (sweepAngleOuter >= 360 && sweepAngleOuter % 360 <= Utils.NUMBER_EPSILON) {
|
|
630
|
+
// Android is doing "mod 360"
|
|
631
|
+
pathBuffer.addCircle(center.x, center.y, innerRadius, Direction.CCW);
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
pathBuffer.lineTo(center.x + innerRadius * Math.cos(endAngleInner * Utils.DEG2RAD), center.y + innerRadius * Math.sin(endAngleInner * Utils.DEG2RAD));
|
|
635
|
+
pathBuffer.arcTo(innerRectBuffer, endAngleInner, -sweepAngleInner);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
else {
|
|
639
|
+
if (sweepAngleOuter % 360 > Utils.NUMBER_EPSILON) {
|
|
640
|
+
if (accountForSliceSpacing) {
|
|
641
|
+
const angleMiddle = startAngleOuter + sweepAngleOuter / 2;
|
|
642
|
+
const arcEndPointX = center.x + sliceSpaceRadius * Math.cos(angleMiddle * Utils.DEG2RAD);
|
|
643
|
+
const arcEndPointY = center.y + sliceSpaceRadius * Math.sin(angleMiddle * Utils.DEG2RAD);
|
|
644
|
+
pathBuffer.lineTo(arcEndPointX, arcEndPointY);
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
pathBuffer.lineTo(center.x, center.y);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
pathBuffer.close();
|
|
652
|
+
if (customRender && customRender.drawHighlight) {
|
|
653
|
+
customRender.drawHighlight(c, high, pathBuffer, renderPaint);
|
|
654
|
+
}
|
|
655
|
+
else {
|
|
656
|
+
c.drawPath(pathBuffer, renderPaint);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* This gives all pie-slices a rounded edge.
|
|
662
|
+
*
|
|
663
|
+
* @param c
|
|
664
|
+
*/
|
|
665
|
+
drawRoundedSlices(c) {
|
|
666
|
+
const chart = this.mChart;
|
|
667
|
+
if (!chart.drawRoundedSlices) {
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
const dataSet = chart.data.getDataSet();
|
|
671
|
+
if (!dataSet.visible) {
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
const yKey = dataSet.yProperty;
|
|
675
|
+
const phaseX = this.animator.phaseX;
|
|
676
|
+
const phaseY = this.animator.phaseY;
|
|
677
|
+
const center = chart.centerCircleBox;
|
|
678
|
+
const r = chart.radius;
|
|
679
|
+
// calculate the radius of the "slice-circle"
|
|
680
|
+
const circleRadius = (r - (r * chart.holeRadius) / 100) / 2;
|
|
681
|
+
const drawAngles = chart.drawAngles;
|
|
682
|
+
let angle = chart.rotationAngle;
|
|
683
|
+
const renderPaint = this.renderPaint;
|
|
684
|
+
for (let j = 0; j < dataSet.entryCount; j++) {
|
|
685
|
+
const sliceAngle = drawAngles[j];
|
|
686
|
+
const e = dataSet.getEntryForIndex(j);
|
|
687
|
+
// draw only if the value is greater than zero
|
|
688
|
+
if (Math.abs(e[yKey]) > Utils.NUMBER_EPSILON) {
|
|
689
|
+
const x = (r - circleRadius) * Math.cos((angle + sliceAngle) * phaseY * Utils.DEG2RAD) + center.x;
|
|
690
|
+
const y = (r - circleRadius) * Math.sin((angle + sliceAngle) * phaseY * Utils.DEG2RAD) + center.y;
|
|
691
|
+
renderPaint.setColor(dataSet.getColor(j));
|
|
692
|
+
c.drawCircle(x, y, circleRadius, renderPaint);
|
|
693
|
+
}
|
|
694
|
+
angle += sliceAngle * phaseX;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Releases the drawing bitmap.
|
|
699
|
+
*/
|
|
700
|
+
releaseBitmap() {
|
|
701
|
+
if (this.mBitmapCanvas) {
|
|
702
|
+
this.mBitmapCanvas.setBitmap(null);
|
|
703
|
+
this.mBitmapCanvas = null;
|
|
704
|
+
}
|
|
705
|
+
if (this.mDrawBitmap) {
|
|
706
|
+
const drawBitmap = this.mDrawBitmap.get();
|
|
707
|
+
if (drawBitmap) {
|
|
708
|
+
releaseImage(drawBitmap);
|
|
709
|
+
}
|
|
710
|
+
this.mDrawBitmap = null;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
//# sourceMappingURL=PieChartRenderer.js.map
|