Charts: keyboard sample control

import io.data2viz.charts.* import io.data2viz.charts.core.Padding import io.data2viz.charts.core.* 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.config.configs.* import io.data2viz.math.* import io.data2viz.color.* import io.data2viz.geom.* import io.data2viz.shape.Symbols import io.data2viz.dsv.Dsv import org.w3c.fetch.Response import org.w3c.dom.events.EventListener import org.w3c.dom.events.Event import org.w3c.dom.events.KeyboardEvent import kotlinx.browser.document import kotlinx.browser.window import kotlin.js.Promise import kotlin.math.* import kotlinx.datetime.Instant val width = 600.0 val height = 400.0 // The dataset holds 2016 & 2017 private val year = 2017 // The "Weather" class data class Weather( val city: String, val year: Int, val month: Int, val highTemp: Double, val avgTemp: Double, val lowTemp: Double, val precip: Double ) // This function transform a CSV line to a "Weather" instance private fun parseWeather(row: List<String>) = Weather( row[0], row[1].toInt(), row[2].toInt(), row[3].toDouble(), row[4].toDouble(), row[5].toDouble(), row[6].toDouble() ) // Just use a simple list of months label for the X axis private val months = listOf("Jan.", "Feb.", "Mar.", "Apr.", "May", "Jun.", "Jul.", "Aug.", "Sep.", "Oct.", "Nov.", "Dec.") lateinit var chart: Chart<Weather> lateinit var results: List<Weather> private var selectedIndex: Int = 0 private var selectedSeries: Int = 0 fun main() { // Creating and sizing the VizContainer val vc = newVizContainer().apply { size = Size(width, height) } // source file: https://docs.google.com/spreadsheets/d/1Rwa_frxeBqPad4bqxfm8sTxL8FRDSFODnreSWBhXvwg/edit?usp=sharing // original taken from https://vincentarelbundock.github.io/Rdatasets/ val request: Promise<Response> = window.fetch("https://docs.google.com/spreadsheets/d/e/2PACX-1vTX4QuCNyDvUoAwk6Jl6UJ4r336A87VIKQ5BVyEgowXG_raXdFBMvmUhmz1LLc07GavyC9J6pZ4YHqJ/pub?gid=650761999&single=true&output=csv") request.then { it.text().then { results = Dsv() .parseRows(it) .drop(1) .map { parseWeather(it) } .filter { it.year == year } chart = vc.chart(results) { title = "Arrow-selection: focus (click) on chart and use arrows" config { cursor { show = true } legend { show = LegendVisibility.Show } events { selectionMode = SelectionMode.None highlightMode = HighlightMode.None } } series = discrete( { domain.city } ) val monthDim = discrete( { domain.month } ) { formatter = { "${months[this - 1]} "} } val tempDim = quantitative( { domain.avgTemp } ) { name = "Average temperature for the month" formatter = { "$this°F" } } area(monthDim, tempDim) { stacking = Stacking.Standard curve = MarkCurves.Curved size = constant(30.0) marker = constant(Symbols.Circle) showMarkers = true } } } } val keyListener = object : EventListener { override fun handleEvent(event: Event) { (event as KeyboardEvent).apply { event.preventDefault() when (event.code) { "ArrowLeft" -> selectedIndex = max(0, selectedIndex-1) "ArrowRight" -> selectedIndex = min(11, selectedIndex+1) "ArrowDown" -> selectedSeries = max(0, selectedSeries-1) "ArrowUp" -> selectedSeries = min(4, selectedSeries+1) else -> return } chart.select(listOf(results[(selectedSeries * 12) + selectedIndex])) } } } document.body?.addEventListener("keydown", keyListener) }
pierre avatar

Sketch created by

pierre