From 373d2ec3761d238b3d7ef3a1f9b944150cd1ea8e Mon Sep 17 00:00:00 2001 From: Ugurcan Yildirim Date: Tue, 24 Nov 2020 11:32:55 +0300 Subject: [PATCH 1/2] Fix barchart drawing for negative values --- .../com/db/williamchartdemo/DemoFragment.kt | 11 ++++-- .../williamchart/renderer/BarChartRenderer.kt | 38 ++++++++++--------- .../renderer/executor/GetVerticalBarFrames.kt | 14 +++++-- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/mobile/src/main/java/com/db/williamchartdemo/DemoFragment.kt b/mobile/src/main/java/com/db/williamchartdemo/DemoFragment.kt index 5907cf0a..c2871509 100644 --- a/mobile/src/main/java/com/db/williamchartdemo/DemoFragment.kt +++ b/mobile/src/main/java/com/db/williamchartdemo/DemoFragment.kt @@ -7,6 +7,7 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import com.db.williamchart.ExperimentalFeature +import com.db.williamchart.data.Scale import com.db.williamchart.slidertooltip.SliderTooltip import kotlinx.android.synthetic.main.demo_fragment.* @@ -46,6 +47,10 @@ class DemoFragment : Fragment() { * Bar Chart */ barChart.animation.duration = animationDuration + barChart.scale = Scale( + barSet.map { it.second }.minOrNull() ?: 0F, + barSet.map { it.second }.maxOrNull() ?: 0F + ) barChart.animate(barSet) /** @@ -84,10 +89,10 @@ class DemoFragment : Fragment() { private val barSet = listOf( "JAN" to 4F, - "FEB" to 7F, - "MAR" to 2F, + "FEB" to 10F, + "MAR" to -2F, "MAY" to 2.3F, - "APR" to 5F, + "APR" to -5F, "JUN" to 4F ) diff --git a/williamchart/src/main/java/com/db/williamchart/renderer/BarChartRenderer.kt b/williamchart/src/main/java/com/db/williamchart/renderer/BarChartRenderer.kt index 88de8410..9e7de23c 100644 --- a/williamchart/src/main/java/com/db/williamchart/renderer/BarChartRenderer.kt +++ b/williamchart/src/main/java/com/db/williamchart/renderer/BarChartRenderer.kt @@ -93,7 +93,9 @@ class BarChartRenderer( placeLabelsY(innerFrame) placeDataPoints(innerFrame) - animation.animateFrom(innerFrame.bottom, data) { view.postInvalidate() } + val chartHeight = innerFrame.bottom - innerFrame.top + val startPoint = chartHeight * configuration.scale.max / configuration.scale.size + animation.animateFrom(startPoint, data) { view.postInvalidate() } return false } @@ -126,6 +128,7 @@ class BarChartRenderer( view.drawBars( GetVerticalBarFrames()( innerFrame, + chartConfiguration.scale, chartConfiguration.barsSpacing, data ) @@ -134,17 +137,17 @@ class BarChartRenderer( if (RendererConstants.inDebug) { view.drawDebugFrame( listOf(outerFrame, innerFrame) + - DebugWithLabelsFrame()( - painter = painter, - axisType = chartConfiguration.axis, - xLabels = xLabels, - yLabels = yLabels, - labelsSize = chartConfiguration.labelsSize - ) + - DefineVerticalBarsClickableFrames()( - innerFrame, - data.map { Pair(it.screenPositionX, it.screenPositionY) } - ) + DebugWithLabelsFrame()( + painter = painter, + axisType = chartConfiguration.axis, + xLabels = xLabels, + yLabels = yLabels, + labelsSize = chartConfiguration.labelsSize + ) + + DefineVerticalBarsClickableFrames()( + innerFrame, + data.map { Pair(it.screenPositionX, it.screenPositionY) } + ) ) } } @@ -187,8 +190,8 @@ class BarChartRenderer( val widthBetweenLabels = (labelsRightPosition - labelsLeftPosition) / (xLabels.size - 1) val xLabelsVerticalPosition = innerFrame.bottom - - painter.measureLabelAscent(chartConfiguration.labelsSize) + - RendererConstants.labelsPaddingToInnerChart + painter.measureLabelAscent(chartConfiguration.labelsSize) + + RendererConstants.labelsPaddingToInnerChart xLabels.forEachIndexed { index, label -> label.screenPositionX = labelsLeftPosition + (widthBetweenLabels * index) @@ -206,8 +209,8 @@ class BarChartRenderer( yLabels.forEachIndexed { index, label -> label.screenPositionX = innerFrame.left - - RendererConstants.labelsPaddingToInnerChart - - painter.measureLabelWidth(label.label, chartConfiguration.labelsSize) / 2 + RendererConstants.labelsPaddingToInnerChart - + painter.measureLabelWidth(label.label, chartConfiguration.labelsSize) / 2 label.screenPositionY = labelsBottomPosition - heightBetweenLabels * index } } @@ -223,8 +226,7 @@ class BarChartRenderer( data.forEachIndexed { index, dataPoint -> dataPoint.screenPositionX = labelsLeftPosition + (widthBetweenLabels * index) - dataPoint.screenPositionY = - innerFrame.bottom - + dataPoint.screenPositionY = innerFrame.bottom - // bar length must be positive, or zero (chartHeight * max( 0f, diff --git a/williamchart/src/main/java/com/db/williamchart/renderer/executor/GetVerticalBarFrames.kt b/williamchart/src/main/java/com/db/williamchart/renderer/executor/GetVerticalBarFrames.kt index 602649e0..dfb08189 100644 --- a/williamchart/src/main/java/com/db/williamchart/renderer/executor/GetVerticalBarFrames.kt +++ b/williamchart/src/main/java/com/db/williamchart/renderer/executor/GetVerticalBarFrames.kt @@ -2,24 +2,32 @@ package com.db.williamchart.renderer.executor import com.db.williamchart.data.DataPoint import com.db.williamchart.data.Frame +import com.db.williamchart.data.Scale +import kotlin.math.max +import kotlin.math.min class GetVerticalBarFrames { operator fun invoke( innerFrame: Frame, + scale: Scale, spacingBetweenBars: Float, data: List ): List { val halfBarWidth = (innerFrame.right - innerFrame.left - (data.size + 1) * spacingBetweenBars) / - data.size / 2 + data.size / 2 + val chartHeight = innerFrame.bottom - innerFrame.top return data.map { + val y1 = it.screenPositionY + val y2 = chartHeight * scale.max / scale.size + Frame( left = it.screenPositionX - halfBarWidth, - top = it.screenPositionY, + top = min(y1, y2), right = it.screenPositionX + halfBarWidth, - bottom = innerFrame.bottom + bottom = max(y1, y2) ) } } From a7ec1773b1a2ae58c420bd381e79647e5dfbeb9c Mon Sep 17 00:00:00 2001 From: Ugurcan Yildirim Date: Tue, 24 Nov 2020 16:07:29 +0300 Subject: [PATCH 2/2] Fix bar y-point calculation --- .../com/db/williamchartdemo/DemoFragment.kt | 4 ++-- mobile/src/main/res/layout/demo_fragment.xml | 2 +- .../williamchart/renderer/BarChartRenderer.kt | 20 ++++++++++--------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/mobile/src/main/java/com/db/williamchartdemo/DemoFragment.kt b/mobile/src/main/java/com/db/williamchartdemo/DemoFragment.kt index c2871509..f18b66b1 100644 --- a/mobile/src/main/java/com/db/williamchartdemo/DemoFragment.kt +++ b/mobile/src/main/java/com/db/williamchartdemo/DemoFragment.kt @@ -88,10 +88,10 @@ class DemoFragment : Fragment() { ) private val barSet = listOf( - "JAN" to 4F, + "JAN" to 5F, "FEB" to 10F, "MAR" to -2F, - "MAY" to 2.3F, + "MAY" to 3F, "APR" to -5F, "JUN" to 4F ) diff --git a/mobile/src/main/res/layout/demo_fragment.xml b/mobile/src/main/res/layout/demo_fragment.xml index 380e5302..d755290d 100644 --- a/mobile/src/main/res/layout/demo_fragment.xml +++ b/mobile/src/main/res/layout/demo_fragment.xml @@ -105,7 +105,7 @@ android:layout_height="150dp" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" - app:chart_axis="x" + app:chart_axis="xy" app:chart_barsColor="#fff" app:chart_barsRadius="4dp" app:chart_labelsColor="#FF70977F" diff --git a/williamchart/src/main/java/com/db/williamchart/renderer/BarChartRenderer.kt b/williamchart/src/main/java/com/db/williamchart/renderer/BarChartRenderer.kt index 9e7de23c..6986013a 100644 --- a/williamchart/src/main/java/com/db/williamchart/renderer/BarChartRenderer.kt +++ b/williamchart/src/main/java/com/db/williamchart/renderer/BarChartRenderer.kt @@ -201,10 +201,10 @@ class BarChartRenderer( private fun placeLabelsY(innerFrame: Frame) { + val halfLabelHeight = painter.measureLabelHeight(chartConfiguration.labelsSize) / 2 val heightBetweenLabels = - (innerFrame.bottom - innerFrame.top) / RendererConstants.defaultScaleNumberOfSteps - val labelsBottomPosition = - innerFrame.bottom + painter.measureLabelHeight(chartConfiguration.labelsSize) / 2 + (innerFrame.bottom - innerFrame.top - halfLabelHeight) / RendererConstants.defaultScaleNumberOfSteps + val labelsBottomPosition = innerFrame.bottom - halfLabelHeight yLabels.forEachIndexed { index, label -> label.screenPositionX = @@ -226,12 +226,14 @@ class BarChartRenderer( data.forEachIndexed { index, dataPoint -> dataPoint.screenPositionX = labelsLeftPosition + (widthBetweenLabels * index) - dataPoint.screenPositionY = innerFrame.bottom - - // bar length must be positive, or zero - (chartHeight * max( - 0f, - dataPoint.value - chartConfiguration.scale.min - ) / scaleSize) + dataPoint.screenPositionY = + (chartConfiguration.scale.max - dataPoint.value) / scaleSize * chartHeight + /*innerFrame.bottom - + // bar length must be positive, or zero + (chartHeight * max( + 0f, + dataPoint.value - chartConfiguration.scale.min + ) / scaleSize)*/ } } }