
commonMain.data.ClusteredDataSet.kt Maven / Gradle / Ivy
package com.juul.krayon.chart.data
import com.juul.krayon.chart.checkRectangular
import kotlin.jvm.JvmName
/** A collection of data which can be grouped into [Cluster]s. */
public interface ClusteredDataSet : DataSet {
/** The clustered data. Guaranteed to have at least one cluster. */
public val clusterData: List>
}
internal class RectangularClusteredDataSet private constructor(
override val seriesData: List>,
override val clusterData: List>,
) : ClusteredDataSet {
init {
// Rectangularity is checked by the constructor functions, no need to do it here.
require(seriesData.isNotEmpty() && clusterData.isNotEmpty()) { "Must have at least one series/cluster." }
}
companion object {
fun fromSeriesData(seriesData: List>) = RectangularClusteredDataSet(
seriesData,
seriesData.transposeOf().map { Cluster(it) }
)
fun fromClusterData(clusterData: List>) = RectangularClusteredDataSet(
clusterData.transposeOf().map { Series(it) },
clusterData
)
@Suppress("UnnecessaryVariable") // I'm gonna make some extra variables in hopes that it makes understanding easier
fun List>.transposeOf(): List> {
if (isEmpty()) return emptyList()
checkRectangular(this)
val newOuterLength = first().size
return (0 until newOuterLength).map { newOuterIndex ->
val oldOuterLength = size
(0 until oldOuterLength).map { oldOuterIndex ->
val oldInnerIndex = newOuterIndex
this[oldOuterIndex][oldInnerIndex]
}
}
}
}
}
/** Creates [ClusteredDataSet] with a single [Series]. */
public fun Series.toClusteredDataSet(): ClusteredDataSet =
RectangularClusteredDataSet.fromSeriesData(listOf(this))
/** Creates a [ClusteredDataSet] from one or more [Series]. Each series must have the same length. */
public fun rectangularDataSetOf(firstSeries: Series, vararg moreSeries: Series): ClusteredDataSet =
RectangularClusteredDataSet.fromSeriesData(listOf(firstSeries, *moreSeries))
/** Creates [ClusteredDataSet] with a list of [Series]s. Each series must have the same length */
@JvmName("seriesToRectangularDataSet")
public fun Iterable>.toRectangularDataSet(): ClusteredDataSet =
RectangularClusteredDataSet.fromSeriesData(this.toList())
/** Creates [ClusteredDataSet] with a single [Cluster]. */
public fun Cluster.toClusteredDataSet(): ClusteredDataSet =
RectangularClusteredDataSet.fromClusterData(listOf(this))
/** Creates a [ClusteredDataSet] from one or more [Cluster]s. Each cluster must have the same length. */
public fun rectangularDataSetOf(firstCluster: Cluster, vararg moreClusters: Cluster): ClusteredDataSet =
RectangularClusteredDataSet.fromClusterData(listOf(firstCluster, *moreClusters))
/** Creates [ClusteredDataSet] with a list of [Cluster]s. Each cluster must have the same length */
@JvmName("clustersToRectangularDataSet")
public fun Iterable>.toRectangularDataSet(): ClusteredDataSet =
RectangularClusteredDataSet.fromClusterData(this.toList())
© 2015 - 2025 Weber Informatics LLC | Privacy Policy