import io.data2viz.color.*
import io.data2viz.scale.*
import io.data2viz.math.*
import io.data2viz.geom.*
import io.data2viz.viz.*
import io.data2viz.format.*
data class ShowFormat(val name:String, val spec:FormatSpec)
fun main() {
val startNumbers = listOf(0.0, 0.00001, 100000.0)
val steps = listOf(1.0, 0.00005, 10000.0)
val formats = listOf(
ShowFormat("No formatting", FormatSpec()),
ShowFormat("Decimal rounded to 2 significant digits", FormatSpec(type = Type.DECIMAL, precision = 2)),
ShowFormat("Decimal rounded to integer", FormatSpec(type = Type.DECIMAL_ROUNDED, precision = 2, groupSeparation = true)),
ShowFormat("Decimal with SI prefix", FormatSpec(type = Type.DECIMAL_WITH_SI, precision = 2)),
ShowFormat("Exponent notation", FormatSpec(type = Type.EXPONENT, precision = 2, align = Align.LEFT, width = 8)),
ShowFormat("Either decimal or exponent", FormatSpec(type = Type.DECIMAL_OR_EXPONENT, precision = 2, align = Align.RIGHT_WITHOUT_SIGN, width = 8)),
ShowFormat("Fixed point", FormatSpec(type = Type.FIXED_POINT, precision = 2)),
ShowFormat("Percent", FormatSpec(type = Type.PERCENT, precision = 2)),
ShowFormat("Percent rounded to significant digits", FormatSpec(type = Type.PERCENT_ROUNDED, precision = 2)),
ShowFormat("Binary", FormatSpec(type = Type.BINARY, precision = 2)),
ShowFormat("Hexadecimal", FormatSpec(type = Type.HEX_UPPERCASE, precision = 2))
)
val cellWidth = 140.0
val cellHeight = 50.0
var secondsCounter = 0
// this scale map names of the days (as String) to colors
val scale = ScalesChromatic.Discrete.category10<Double> { domain = startNumbers }
val startXOffset = cellWidth / 2
val startYOffset = 25.0
val tableRows = formats.size + 1
val tableColumns = startNumbers.size + 1
val vizWidth = (startNumbers.size + 1) * cellWidth
val vizHeight = (formats.size + 1) * cellHeight
viz {
size = size(vizWidth, vizHeight)
text {
x = startXOffset
y = startYOffset
textAlign = textAlign(TextHAlign.MIDDLE, TextVAlign.MIDDLE)
textContent = "Formatting"
}
for (i in 0..tableRows) {
line {
x1 = 0.0
x2 = vizWidth
y1 = i * cellHeight - 1
y2 = i * cellHeight - 1
}
}
for (i in 0..tableColumns) {
line {
x1 = i * cellWidth - 1
x2 = i * cellWidth - 1
y1 = 0.0
y2 = vizHeight
}
}
line {
x1 = vizWidth - 1
x2 = vizWidth - 1
y1 = 0.0
y2 = vizHeight
}
startNumbers.forEachIndexed { numberIndex, startNumber ->
text {
x = startXOffset + (numberIndex + 1) * cellWidth
y = startYOffset
textColor = scale(startNumber)
textAlign = textAlign(TextHAlign.MIDDLE, TextVAlign.MIDDLE)
textContent = "Number"
}
}
val columns =
startNumbers.mapIndexed { numberIndex, number ->
formats.mapIndexed { formatIndex, format ->
text {
x = startXOffset
y = startYOffset + (formatIndex + 1) * cellHeight
textAlign = textAlign(TextHAlign.MIDDLE, TextVAlign.MIDDLE)
textContent = "${format.name}"
}
text {
x = startXOffset + (numberIndex + 1) * cellWidth
y = startYOffset + (formatIndex + 1) * cellHeight
textColor = scale(number)
textAlign = textAlign(TextHAlign.MIDDLE, TextVAlign.MIDDLE)
textContent = formatter(format.spec.toString())(number)
}
}
}
animation { timerInMs: Double ->
// update one time per second
if (timerInMs / 1000 > secondsCounter) {
secondsCounter++
startNumbers.forEachIndexed { index, startNumber ->
columns[index].forEachIndexed { rowIndex, text ->
text.textContent = formatter(formats[rowIndex].spec.toString())(startNumber + steps[index] * secondsCounter)
}
}
}
}
}.bindRendererOnNewCanvas()
}