Dual axis chart

import io.data2viz.charts.* 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.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 kotlinx.browser.window import kotlin.js.Promise import kotlinx.datetime.Instant val width = 800.0 val height = 500.0 // The dataset holds : Auckland, Mumbai, Beijing, Chicago and San Diego private val city = "Chicago" // 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.") 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 { // Parse all result, keep only one city and one year val results = Dsv() .parseRows(it) .drop(1) .map { parseWeather(it) } .filter { it.city == city } .filter { it.year == year } vc.chart(results) { title = "Monthly average temperature and total precipitation in $city, $year" config { cursor { show = true type = CursorType.Vertical } } // The month is a discrete dimension val monthDim = discrete( { domain.month } ) { formatter = { "${months[this - 1]} "} } // The temperatures and precipitations are quantitative dimensions val tempDim = quantitative( { domain.avgTemp } ) { name = "Average temperature for the month" formatter = { "$this°F" } } val precipDim = quantitative( { domain.precip } ) { name = "Total precipitations for the month" formatter = { "$this\"" } } // First display the precipitation using a BarMark bar(monthDim, precipDim) { y { end = 10.0 layoutPosition = LayoutPosition.Right // Use a bluish color to identify this axis as the same as the "bars" strokeColor = "#4956B4".col tickStroke = "#4956B4".col fontColor = "#4956B4".col } } // Then display the temperature using a LineMark line(monthDim, tempDim) { curve = MarkCurves.Curved size = constant(30.0) marker = constant(Symbols.Circle) showMarkers = true strokeColor = constant(Colors.Web.black) strokeColorHighlight = constant(Colors.Web.black) strokeWidth = constant(2.0) y { start = .0 end = 80.0 } } } } } }
pierre avatar

Sketch created by

pierre

This chart displays the average temperatures and total precipitations for each month using 2 different marks: a bar and a line. The data is loaded from an external spreadsheet.

comments