Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multiline label support #289

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions mobile/src/main/java/com/db/williamchartdemo/DemoFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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.*

Expand Down Expand Up @@ -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)

/**
Expand Down Expand Up @@ -83,12 +88,12 @@ class DemoFragment : Fragment() {
)

private val barSet = listOf(
"JAN" to 4F,
"FEB" to 7F,
"MAR" to 2F,
"MAY" to 2.3F,
"APR" to 5F,
"JUN" to 4F
"JAN\n2020" to 5F,
"FEB\n2020" to 10F,
"MAR\n2020" to -2F,
"MAY\n2020" to 3F,
"APR\n2020" to -5F,
"JUN\n2020" to 4F
)

private val horizontalBarSet = listOf(
Expand Down
5 changes: 4 additions & 1 deletion mobile/src/main/res/layout/demo_fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@
android:layout_height="150dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
app:chart_axis="x"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingVertical="10dp"
app:chart_axis="xy"
app:chart_barsColor="#fff"
app:chart_barsRadius="4dp"
app:chart_labelsColor="#FF70977F"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,24 @@ import com.db.williamchart.data.Label
class AxisLabels : Labels {
override fun draw(canvas: Canvas, paint: Paint, xLabels: List<Label>) {
xLabels.forEach {
canvas.drawText(
it.label,
it.screenPositionX,
it.screenPositionY,
paint
)
if (it.label.contains("\n")) {
val labelLines = it.label.split("\n")
labelLines.forEachIndexed { index, labelLine ->
canvas.drawText(
labelLine,
it.screenPositionX,
it.screenPositionY + index * paint.textSize,
paint
)
}
} else {
canvas.drawText(
it.label,
it.screenPositionX,
it.screenPositionY,
paint
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -126,6 +128,7 @@ class BarChartRenderer(
view.drawBars(
GetVerticalBarFrames()(
innerFrame,
chartConfiguration.scale,
chartConfiguration.barsSpacing,
data
)
Expand All @@ -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) }
)
)
}
}
Expand Down Expand Up @@ -186,9 +189,7 @@ class BarChartRenderer(
val labelsRightPosition = innerFrame.right - halfBarWidth
val widthBetweenLabels = (labelsRightPosition - labelsLeftPosition) / (xLabels.size - 1)
val xLabelsVerticalPosition =
innerFrame.bottom -
painter.measureLabelAscent(chartConfiguration.labelsSize) +
RendererConstants.labelsPaddingToInnerChart
innerFrame.bottom + RendererConstants.labelsPaddingToInnerChart / 2

xLabels.forEachIndexed { index, label ->
label.screenPositionX = labelsLeftPosition + (widthBetweenLabels * index)
Expand All @@ -198,17 +199,15 @@ 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

yLabels.forEachIndexed { index, label ->
yLabels.reversed().forEachIndexed { index, label ->
label.screenPositionX =
innerFrame.left -
RendererConstants.labelsPaddingToInnerChart -
painter.measureLabelWidth(label.label, chartConfiguration.labelsSize) / 2
label.screenPositionY = labelsBottomPosition - heightBetweenLabels * index
innerFrame.left - RendererConstants.labelsPaddingToInnerChart -
painter.measureLabelWidth(label.label, chartConfiguration.labelsSize) / 2
label.screenPositionY = halfLabelHeight + heightBetweenLabels * index
}
}

Expand All @@ -224,12 +223,13 @@ 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)
(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)*/
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ class RendererConstants {
internal const val defaultScaleNumberOfSteps = 3
internal const val notInitialized = -1f
internal const val inDebug = false
internal const val labelsPaddingToInnerChart = 15f
internal const val labelsPaddingToInnerChart = 60f
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<DataPoint>
): List<Frame> {
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)
)
}
}
Expand Down