io.data2viz.shape.stack.Stack.kt Maven / Gradle / Ivy
/*
* Copyright (c) 2018-2019. data2viz sàrl.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package io.data2viz.shape.stack
import io.data2viz.shape.const
data class StackSpace(
var from: Double,
var to: Double,
val paramIndex: Int,
val data: T
)
data class StackParam(
val stackedValues: MutableList>,
// val data: T,
var index: Int
)
// TODO : use "serieIndex" and "dataIndex" to help understand the algorithm
fun stack(init: StackGenerator.() -> Unit) = StackGenerator().apply(init)
class StackGenerator {
var series: (T) -> Array = const(arrayOf(.0))
var order: StackOrder = StackOrder.NONE
var offset: StackOffset = StackOffset.NONE
fun stack(data: List): Array> {
val ret = mutableListOf>()
// BUILDING : build the StackParam and StackSpace that function will return
val firstValue = series(data[0])
firstValue.forEachIndexed { index, _ ->
val stackedValues = mutableListOf>()
val stack = StackParam(stackedValues, index)
ret.add(stack)
}
data.forEachIndexed { index1, element ->
series(element).forEachIndexed { index2, serie ->
val stack = ret[index2]
stack.stackedValues.add(StackSpace(.0, serie, index1, data[index1]))
}
}
// ORDERING : order series depending on its sum
val indexes = order.sort(ret)
indexes.forEachIndexed { realIndex, oldIndex ->
ret[oldIndex].index = realIndex
}
// OFFSETTING : place values along the baseline and normalize them if needed
offset.offset(ret)
return ret.toTypedArray()
}
}