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

Provide LocalDate interpolator #446

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions interpolate/api/interpolate.api
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public final class com/juul/krayon/interpolate/InterpolatorKt {
public static final fun interpolator (FF)Lcom/juul/krayon/interpolate/BidirectionalInterpolator;
public static final fun interpolator (II)Lcom/juul/krayon/interpolate/BidirectionalInterpolator;
public static final fun interpolator (Lkotlinx/datetime/Instant;Lkotlinx/datetime/Instant;)Lcom/juul/krayon/interpolate/BidirectionalInterpolator;
public static final fun interpolator (Lkotlinx/datetime/LocalDate;Lkotlinx/datetime/LocalDate;)Lcom/juul/krayon/interpolate/BidirectionalInterpolator;
public static final fun interpolator (Lkotlinx/datetime/LocalDateTime;Lkotlinx/datetime/LocalDateTime;)Lcom/juul/krayon/interpolate/BidirectionalInterpolator;
public static final fun interpolator-h4DbW5E (II)Lcom/juul/krayon/interpolate/Interpolator;
}
Expand Down
1 change: 1 addition & 0 deletions interpolate/api/interpolate.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ final fun com.juul.krayon.interpolate/interpolator(kotlin/Double, kotlin/Double)
final fun com.juul.krayon.interpolate/interpolator(kotlin/Float, kotlin/Float): com.juul.krayon.interpolate/BidirectionalInterpolator<kotlin/Float> // com.juul.krayon.interpolate/interpolator|interpolator(kotlin.Float;kotlin.Float){}[0]
final fun com.juul.krayon.interpolate/interpolator(kotlin/Int, kotlin/Int): com.juul.krayon.interpolate/BidirectionalInterpolator<kotlin/Int> // com.juul.krayon.interpolate/interpolator|interpolator(kotlin.Int;kotlin.Int){}[0]
final fun com.juul.krayon.interpolate/interpolator(kotlinx.datetime/Instant, kotlinx.datetime/Instant): com.juul.krayon.interpolate/BidirectionalInterpolator<kotlinx.datetime/Instant> // com.juul.krayon.interpolate/interpolator|interpolator(kotlinx.datetime.Instant;kotlinx.datetime.Instant){}[0]
final fun com.juul.krayon.interpolate/interpolator(kotlinx.datetime/LocalDate, kotlinx.datetime/LocalDate): com.juul.krayon.interpolate/BidirectionalInterpolator<kotlinx.datetime/LocalDate> // com.juul.krayon.interpolate/interpolator|interpolator(kotlinx.datetime.LocalDate;kotlinx.datetime.LocalDate){}[0]
final fun com.juul.krayon.interpolate/interpolator(kotlinx.datetime/LocalDateTime, kotlinx.datetime/LocalDateTime): com.juul.krayon.interpolate/BidirectionalInterpolator<kotlinx.datetime/LocalDateTime> // com.juul.krayon.interpolate/interpolator|interpolator(kotlinx.datetime.LocalDateTime;kotlinx.datetime.LocalDateTime){}[0]
6 changes: 6 additions & 0 deletions interpolate/src/commonMain/kotlin/Interpolator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.juul.krayon.interpolate

import com.juul.krayon.color.Color
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime

public interface Interpolator<T> {
Expand All @@ -28,6 +29,11 @@ public fun interpolator(
stop: Instant,
): BidirectionalInterpolator<Instant> = LinearInstantInterpolator(start, stop)

public fun interpolator(
start: LocalDate,
stop: LocalDate,
): BidirectionalInterpolator<LocalDate> = LinearLocalDateInterpolator(start, stop)

public fun interpolator(
start: LocalDateTime,
stop: LocalDateTime,
Expand Down
18 changes: 18 additions & 0 deletions interpolate/src/commonMain/kotlin/LinearInterpolator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import com.juul.krayon.color.Color
import com.juul.krayon.color.lerp
import com.juul.krayon.time.minus
import com.juul.krayon.time.plus
import kotlinx.datetime.DatePeriod
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.plus
import kotlin.math.roundToInt

internal class LinearIntInterpolator(
private val start: Int,
Expand Down Expand Up @@ -51,6 +55,20 @@ internal class LinearInstantInterpolator(
override fun invert(value: Instant): Float = ((value - start) / range).toFloat()
}

internal class LinearLocalDateInterpolator(
private val start: LocalDate,
stop: LocalDate,
) : BidirectionalInterpolator<LocalDate> {

private val range = stop.toEpochDays() - start.toEpochDays()

override fun interpolate(fraction: Float): LocalDate =
start + DatePeriod(days = (range * fraction).roundToInt())
Copy link
Member Author

@twyatt twyatt Jan 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure if roundToInt (vs. just toInt) is the best approach here.


override fun invert(value: LocalDate): Float =
(value.toEpochDays() - start.toEpochDays()).toFloat() / range
}

internal class LinearLocalDateTimeInterpolator(
private val start: LocalDateTime,
stop: LocalDateTime,
Expand Down
4 changes: 4 additions & 0 deletions scale/api/scale.api
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,26 @@ public final class com/juul/krayon/scale/ContinuousScaleKt {
public static final fun domain (Lcom/juul/krayon/scale/ContinuousScale;[F)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun domain (Lcom/juul/krayon/scale/ContinuousScale;[I)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun domain (Lcom/juul/krayon/scale/ContinuousScale;[Lkotlinx/datetime/Instant;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun domain (Lcom/juul/krayon/scale/ContinuousScale;[Lkotlinx/datetime/LocalDate;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun domain (Lcom/juul/krayon/scale/ContinuousScale;[Lkotlinx/datetime/LocalDateTime;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun domainDouble (Lcom/juul/krayon/scale/ContinuousScale;Ljava/lang/Iterable;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun domainFloat (Lcom/juul/krayon/scale/ContinuousScale;Ljava/lang/Iterable;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun domainInstant (Lcom/juul/krayon/scale/ContinuousScale;Ljava/lang/Iterable;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun domainInt (Lcom/juul/krayon/scale/ContinuousScale;Ljava/lang/Iterable;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun domainLocalDate (Lcom/juul/krayon/scale/ContinuousScale;Ljava/lang/Iterable;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun domainLocalDateTime (Lcom/juul/krayon/scale/ContinuousScale;Ljava/lang/Iterable;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun range (Lcom/juul/krayon/scale/ContinuousScale;[D)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun range (Lcom/juul/krayon/scale/ContinuousScale;[F)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun range (Lcom/juul/krayon/scale/ContinuousScale;[I)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun range (Lcom/juul/krayon/scale/ContinuousScale;[Lkotlinx/datetime/Instant;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun range (Lcom/juul/krayon/scale/ContinuousScale;[Lkotlinx/datetime/LocalDate;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun range (Lcom/juul/krayon/scale/ContinuousScale;[Lkotlinx/datetime/LocalDateTime;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun rangeColor (Lcom/juul/krayon/scale/ContinuousScale;Ljava/util/List;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun rangeDouble (Lcom/juul/krayon/scale/ContinuousScale;Ljava/util/List;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun rangeFloat (Lcom/juul/krayon/scale/ContinuousScale;Ljava/util/List;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun rangeInstant (Lcom/juul/krayon/scale/ContinuousScale;Ljava/util/List;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun rangeInt (Lcom/juul/krayon/scale/ContinuousScale;Ljava/util/List;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun rangeLocalDate (Lcom/juul/krayon/scale/ContinuousScale;Ljava/util/List;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun rangeLocalDateTime (Lcom/juul/krayon/scale/ContinuousScale;Ljava/util/List;)Lcom/juul/krayon/scale/ContinuousScale;
public static final fun scale (Ljava/util/List;Ljava/util/List;)Lcom/juul/krayon/scale/ContinuousScale;
public static synthetic fun scale$default (Ljava/util/List;Ljava/util/List;ILjava/lang/Object;)Lcom/juul/krayon/scale/ContinuousScale;
Expand Down
4 changes: 4 additions & 0 deletions scale/api/scale.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ final fun <#A: kotlin/Any?> (com.juul.krayon.scale/ContinuousScale<*, #A>).com.j
final fun <#A: kotlin/Any?> (com.juul.krayon.scale/ContinuousScale<*, #A>).com.juul.krayon.scale/domain(kotlin.collections/Iterable<kotlin/Float>): com.juul.krayon.scale/ContinuousScale<kotlin/Float, #A> // com.juul.krayon.scale/domain|domain@com.juul.krayon.scale.ContinuousScale<*,0:0>(kotlin.collections.Iterable<kotlin.Float>){0§<kotlin.Any?>}[0]
final fun <#A: kotlin/Any?> (com.juul.krayon.scale/ContinuousScale<*, #A>).com.juul.krayon.scale/domain(kotlin.collections/Iterable<kotlin/Int>): com.juul.krayon.scale/ContinuousScale<kotlin/Int, #A> // com.juul.krayon.scale/domain|domain@com.juul.krayon.scale.ContinuousScale<*,0:0>(kotlin.collections.Iterable<kotlin.Int>){0§<kotlin.Any?>}[0]
final fun <#A: kotlin/Any?> (com.juul.krayon.scale/ContinuousScale<*, #A>).com.juul.krayon.scale/domain(kotlin.collections/Iterable<kotlinx.datetime/Instant>): com.juul.krayon.scale/ContinuousScale<kotlinx.datetime/Instant, #A> // com.juul.krayon.scale/domain|domain@com.juul.krayon.scale.ContinuousScale<*,0:0>(kotlin.collections.Iterable<kotlinx.datetime.Instant>){0§<kotlin.Any?>}[0]
final fun <#A: kotlin/Any?> (com.juul.krayon.scale/ContinuousScale<*, #A>).com.juul.krayon.scale/domain(kotlin.collections/Iterable<kotlinx.datetime/LocalDate>): com.juul.krayon.scale/ContinuousScale<kotlinx.datetime/LocalDate, #A> // com.juul.krayon.scale/domain|domain@com.juul.krayon.scale.ContinuousScale<*,0:0>(kotlin.collections.Iterable<kotlinx.datetime.LocalDate>){0§<kotlin.Any?>}[0]
final fun <#A: kotlin/Any?> (com.juul.krayon.scale/ContinuousScale<*, #A>).com.juul.krayon.scale/domain(kotlin.collections/Iterable<kotlinx.datetime/LocalDateTime>): com.juul.krayon.scale/ContinuousScale<kotlinx.datetime/LocalDateTime, #A> // com.juul.krayon.scale/domain|domain@com.juul.krayon.scale.ContinuousScale<*,0:0>(kotlin.collections.Iterable<kotlinx.datetime.LocalDateTime>){0§<kotlin.Any?>}[0]
final fun <#A: kotlin/Any?> (com.juul.krayon.scale/ContinuousScale<*, #A>).com.juul.krayon.scale/domain(kotlin/Array<out kotlinx.datetime/Instant>...): com.juul.krayon.scale/ContinuousScale<kotlinx.datetime/Instant, #A> // com.juul.krayon.scale/domain|domain@com.juul.krayon.scale.ContinuousScale<*,0:0>(kotlin.Array<out|kotlinx.datetime.Instant>...){0§<kotlin.Any?>}[0]
final fun <#A: kotlin/Any?> (com.juul.krayon.scale/ContinuousScale<*, #A>).com.juul.krayon.scale/domain(kotlin/Array<out kotlinx.datetime/LocalDate>...): com.juul.krayon.scale/ContinuousScale<kotlinx.datetime/LocalDate, #A> // com.juul.krayon.scale/domain|domain@com.juul.krayon.scale.ContinuousScale<*,0:0>(kotlin.Array<out|kotlinx.datetime.LocalDate>...){0§<kotlin.Any?>}[0]
final fun <#A: kotlin/Any?> (com.juul.krayon.scale/ContinuousScale<*, #A>).com.juul.krayon.scale/domain(kotlin/Array<out kotlinx.datetime/LocalDateTime>...): com.juul.krayon.scale/ContinuousScale<kotlinx.datetime/LocalDateTime, #A> // com.juul.krayon.scale/domain|domain@com.juul.krayon.scale.ContinuousScale<*,0:0>(kotlin.Array<out|kotlinx.datetime.LocalDateTime>...){0§<kotlin.Any?>}[0]
final fun <#A: kotlin/Any?> (com.juul.krayon.scale/ContinuousScale<*, #A>).com.juul.krayon.scale/domain(kotlin/DoubleArray...): com.juul.krayon.scale/ContinuousScale<kotlin/Double, #A> // com.juul.krayon.scale/domain|domain@com.juul.krayon.scale.ContinuousScale<*,0:0>(kotlin.DoubleArray...){0§<kotlin.Any?>}[0]
final fun <#A: kotlin/Any?> (com.juul.krayon.scale/ContinuousScale<*, #A>).com.juul.krayon.scale/domain(kotlin/FloatArray...): com.juul.krayon.scale/ContinuousScale<kotlin/Float, #A> // com.juul.krayon.scale/domain|domain@com.juul.krayon.scale.ContinuousScale<*,0:0>(kotlin.FloatArray...){0§<kotlin.Any?>}[0]
Expand All @@ -57,8 +59,10 @@ final fun <#A: kotlin/Comparable<#A>> (com.juul.krayon.scale/ContinuousScale<#A,
final fun <#A: kotlin/Comparable<#A>> (com.juul.krayon.scale/ContinuousScale<#A, *>).com.juul.krayon.scale/range(kotlin.collections/List<kotlin/Float>): com.juul.krayon.scale/ContinuousScale<#A, kotlin/Float> // com.juul.krayon.scale/range|range@com.juul.krayon.scale.ContinuousScale<0:0,*>(kotlin.collections.List<kotlin.Float>){0§<kotlin.Comparable<0:0>>}[0]
final fun <#A: kotlin/Comparable<#A>> (com.juul.krayon.scale/ContinuousScale<#A, *>).com.juul.krayon.scale/range(kotlin.collections/List<kotlin/Int>): com.juul.krayon.scale/ContinuousScale<#A, kotlin/Int> // com.juul.krayon.scale/range|range@com.juul.krayon.scale.ContinuousScale<0:0,*>(kotlin.collections.List<kotlin.Int>){0§<kotlin.Comparable<0:0>>}[0]
final fun <#A: kotlin/Comparable<#A>> (com.juul.krayon.scale/ContinuousScale<#A, *>).com.juul.krayon.scale/range(kotlin.collections/List<kotlinx.datetime/Instant>): com.juul.krayon.scale/ContinuousScale<#A, kotlinx.datetime/Instant> // com.juul.krayon.scale/range|range@com.juul.krayon.scale.ContinuousScale<0:0,*>(kotlin.collections.List<kotlinx.datetime.Instant>){0§<kotlin.Comparable<0:0>>}[0]
final fun <#A: kotlin/Comparable<#A>> (com.juul.krayon.scale/ContinuousScale<#A, *>).com.juul.krayon.scale/range(kotlin.collections/List<kotlinx.datetime/LocalDate>): com.juul.krayon.scale/ContinuousScale<#A, kotlinx.datetime/LocalDate> // com.juul.krayon.scale/range|range@com.juul.krayon.scale.ContinuousScale<0:0,*>(kotlin.collections.List<kotlinx.datetime.LocalDate>){0§<kotlin.Comparable<0:0>>}[0]
final fun <#A: kotlin/Comparable<#A>> (com.juul.krayon.scale/ContinuousScale<#A, *>).com.juul.krayon.scale/range(kotlin.collections/List<kotlinx.datetime/LocalDateTime>): com.juul.krayon.scale/ContinuousScale<#A, kotlinx.datetime/LocalDateTime> // com.juul.krayon.scale/range|range@com.juul.krayon.scale.ContinuousScale<0:0,*>(kotlin.collections.List<kotlinx.datetime.LocalDateTime>){0§<kotlin.Comparable<0:0>>}[0]
final fun <#A: kotlin/Comparable<#A>> (com.juul.krayon.scale/ContinuousScale<#A, *>).com.juul.krayon.scale/range(kotlin/Array<out kotlinx.datetime/Instant>...): com.juul.krayon.scale/ContinuousScale<#A, kotlinx.datetime/Instant> // com.juul.krayon.scale/range|range@com.juul.krayon.scale.ContinuousScale<0:0,*>(kotlin.Array<out|kotlinx.datetime.Instant>...){0§<kotlin.Comparable<0:0>>}[0]
final fun <#A: kotlin/Comparable<#A>> (com.juul.krayon.scale/ContinuousScale<#A, *>).com.juul.krayon.scale/range(kotlin/Array<out kotlinx.datetime/LocalDate>...): com.juul.krayon.scale/ContinuousScale<#A, kotlinx.datetime/LocalDate> // com.juul.krayon.scale/range|range@com.juul.krayon.scale.ContinuousScale<0:0,*>(kotlin.Array<out|kotlinx.datetime.LocalDate>...){0§<kotlin.Comparable<0:0>>}[0]
final fun <#A: kotlin/Comparable<#A>> (com.juul.krayon.scale/ContinuousScale<#A, *>).com.juul.krayon.scale/range(kotlin/Array<out kotlinx.datetime/LocalDateTime>...): com.juul.krayon.scale/ContinuousScale<#A, kotlinx.datetime/LocalDateTime> // com.juul.krayon.scale/range|range@com.juul.krayon.scale.ContinuousScale<0:0,*>(kotlin.Array<out|kotlinx.datetime.LocalDateTime>...){0§<kotlin.Comparable<0:0>>}[0]
final fun <#A: kotlin/Comparable<#A>> (com.juul.krayon.scale/ContinuousScale<#A, *>).com.juul.krayon.scale/range(kotlin/DoubleArray...): com.juul.krayon.scale/ContinuousScale<#A, kotlin/Double> // com.juul.krayon.scale/range|range@com.juul.krayon.scale.ContinuousScale<0:0,*>(kotlin.DoubleArray...){0§<kotlin.Comparable<0:0>>}[0]
final fun <#A: kotlin/Comparable<#A>> (com.juul.krayon.scale/ContinuousScale<#A, *>).com.juul.krayon.scale/range(kotlin/FloatArray...): com.juul.krayon.scale/ContinuousScale<#A, kotlin/Float> // com.juul.krayon.scale/range|range@com.juul.krayon.scale.ContinuousScale<0:0,*>(kotlin.FloatArray...){0§<kotlin.Comparable<0:0>>}[0]
Expand Down
15 changes: 15 additions & 0 deletions scale/src/commonMain/kotlin/ContinuousScale.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.juul.krayon.interpolate.Interpolator
import com.juul.krayon.interpolate.Inverter
import com.juul.krayon.interpolate.interpolator
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
import kotlin.jvm.JvmName

Expand Down Expand Up @@ -34,6 +35,8 @@ public fun <R> ContinuousScale<*, R>.domain(vararg domain: Double): ContinuousSc

public fun <R> ContinuousScale<*, R>.domain(vararg domain: Instant): ContinuousScale<Instant, R> = domain(domain.toList())

public fun <R> ContinuousScale<*, R>.domain(vararg domain: LocalDate): ContinuousScale<LocalDate, R> = domain(domain.toList())

public fun <R> ContinuousScale<*, R>.domain(vararg domain: LocalDateTime): ContinuousScale<LocalDateTime, R> = domain(domain.toList())

// List domains
Expand All @@ -51,6 +54,11 @@ public fun <R> ContinuousScale<*, R>.domain(
domain: Iterable<Instant>,
): ContinuousScale<Instant, R> = domain(domain.toList(), ::interpolator)

@JvmName("domainLocalDate")
public fun <R> ContinuousScale<*, R>.domain(
domain: Iterable<LocalDate>,
): ContinuousScale<LocalDate, R> = domain(domain.toList(), ::interpolator)

@JvmName("domainLocalDateTime")
public fun <R> ContinuousScale<*, R>.domain(
domain: Iterable<LocalDateTime>,
Expand All @@ -65,6 +73,8 @@ public fun <D : Comparable<D>> ContinuousScale<D, *>.range(vararg range: Double)

public fun <D : Comparable<D>> ContinuousScale<D, *>.range(vararg range: Instant): ContinuousScale<D, Instant> = range(range.toList())

public fun <D : Comparable<D>> ContinuousScale<D, *>.range(vararg range: LocalDate): ContinuousScale<D, LocalDate> = range(range.toList())

public fun <D : Comparable<D>> ContinuousScale<D, *>.range(vararg range: LocalDateTime): ContinuousScale<D, LocalDateTime> = range(
range.toList(),
)
Expand All @@ -85,6 +95,11 @@ public fun <D : Comparable<D>> ContinuousScale<D, *>.range(range: List<Double>):
@JvmName("rangeInstant")
public fun <D : Comparable<D>> ContinuousScale<D, *>.range(range: List<Instant>): ContinuousScale<D, Instant> = range(range, ::interpolator)

@JvmName("rangeLocalDate")
public fun <D : Comparable<D>> ContinuousScale<D, *>.range(
range: List<LocalDate>,
): ContinuousScale<D, LocalDate> = range(range, ::interpolator)

@JvmName("rangeLocalDateTime")
public fun <D : Comparable<D>> ContinuousScale<D, *>.range(
range: List<LocalDateTime>,
Expand Down
Loading