import io.data2viz.charts.*
import io.data2viz.charts.dimension.*
import io.data2viz.charts.chart.*
import io.data2viz.charts.chart.mark.*
import io.data2viz.charts.viz.*
import io.data2viz.charts.layout.*
import io.data2viz.charts.core.*
import io.data2viz.charts.core.Padding
import io.data2viz.geom.*
import io.data2viz.color.*
import io.data2viz.random.RandomDistribution
import kotlinx.datetime.Instant
import kotlinx.browser.document
import org.w3c.dom.*
val width = 900.0
val height = 480.0
fun main() {
    
    // setting up the different accessors
    val accessors: List<Datum<Sample>.() -> Double> = listOf(
        { domain.temperature },
        { domain.pressure },
        { domain.random }
    )
    
    // set a style for placing the CANVAS
    val style = document.createElement("style")
    style.innerHTML = "canvas{display:inline !important;}"
    document.head!!.appendChild(style)
    
    // creating the DIVs, then placing VizContainer inside
    val charts = (0 until 3).map { xi ->
        val div = document.createElement("div")
        document.body!!.appendChild(div)
        
        val chartrow = (0 until 3).map { yi ->
            val vc = (div as HTMLDivElement).newVizContainer()
            vc.apply {
                size = Size(width / 3.0, height / 3.0)
            }
            vc.createChart(samples, accessors[yi], accessors[xi])
        }
        div.setAttribute("style", "height: ${height / 3.0}px;width: ${width}px")
        chartrow
    }
    
    var current = 0
    charts.forEachIndexed { xi, chartrow ->
        chartrow.forEachIndexed { yi, chart ->
            // "unlight" all
            chart.onHighlight { _ -> 
            	charts[0][0].highlight(listOf<Sample>())
            	charts[1][0].highlight(listOf<Sample>())
            	charts[2][0].highlight(listOf<Sample>())
            	charts[0][1].highlight(listOf<Sample>())
            	charts[1][1].highlight(listOf<Sample>())
            	charts[2][1].highlight(listOf<Sample>())
            	charts[0][2].highlight(listOf<Sample>())
            	charts[1][2].highlight(listOf<Sample>())
            	charts[2][2].highlight(listOf<Sample>())
            }
            // then highlight the expected one 
            (0 until 3).forEach { index ->
                chart.onHighlight { evt -> charts[xi][index].highlight(evt.data) }
                chart.onHighlight { evt -> charts[index][yi].highlight(evt.data) }
            }
            // also synchronize all "panning"
            (0 until 9).forEach { index ->
                if (index != current) {
					chart.onPan { evt -> charts[index%3][index/3].pan(evt.panX, evt.panY) }
                }
            }
            current++
        }
    }
}
private fun VizContainer.createChart(dataset:List<Sample>, xAcc: Datum<Sample>.() -> Double, yAcc: Datum<Sample>.() -> Double): Chart<Sample> {
    return chart(dataset) {
        config {
            padding = Padding(2.0, 2.0, 2.0, 2.0)
            events {
                zoomMode = ZoomMode.None
                panMode = PanMode.XY
            }
            
            cursor {
                show = true
            }
        }
        
        series = discrete( { domain.batchCode } )
        
        val ts = quantitative( xAcc )
        val tp = quantitative( yAcc )
        
        plot(ts, tp) {
            x {
                enableTicksLabels = false
                enableTicks = false
            }
            y {
                enableTicksLabels = false
                enableTicks = false
            }
        }
    }
}
val randomGenerator = RandomDistribution(42).normal(100.0, 18.0)
data class Sample(
    val sampleIndex: Int,
    val batchCode: String,
    val timestamp: Instant,
    val temperature: Double,
    val pressure: Double,
    val random: Double,
)
val samples = generateSamples(200)
fun generateSamples(numSamples: Int) = (0 until numSamples).map {
    val batchIndex = 1 + (it % 4)
    val pressure: Double = randomGenerator() * 1000
    val temp: Double = randomGenerator() * batchIndex * pressure / 100000
    val ts = Instant.fromEpochMilliseconds(1611150127144L + (it * 8632L))
    val random = randomGenerator() / temp
    Sample(it, "Batch #$batchIndex", ts, temp, pressure, random)
}
         
      
comments