import io.data2viz.axis.* import io.data2viz.color.* import io.data2viz.geom.* import io.data2viz.scale.* import io.data2viz.viz.* import kotlin.math.ln import kotlin.math.round var superscript = "⁰¹²³⁴⁵⁶⁷⁸⁹" val margins = Margins(40.5, 30.5, 50.5, 50.5) val chartWidth = 960.0 - margins.hMargins val chartHeight = 500.0 - margins.vMargins // linear scale domain 0..100 is mapped to 0..width val xScale = Scales.Continuous.linear { domain = listOf(.0, 100.0) range = listOf(.0, chartWidth) } // log scale val yScale = Scales.Continuous.log (kotlin.math.E) { domain = listOf(kotlin.math.exp(0.0), kotlin.math.exp(9.0)) range = listOf(chartHeight, .0) // <- y is mapped in the reverse order (in SVG, javafx (0,0) is top left. } // the mathematical function val functionToPlot = { x:Double -> x * x + x + 1} //100 points to define the curve val points = (0 until 100).map { i -> Point(i.toDouble(), functionToPlot(i.toDouble()))} fun main() { viz { size = size(960, 500) group { transform { translate(x = margins.left, y = margins.top) } group { transform { translate(x = -10.0) } axis(Orient.LEFT, yScale) { tickFormat = { "e${superscript[round(ln(it)).toInt()]}" } // <- specific formatter to add exponents (ex: e¹) } } group { transform { translate(y = chartHeight + 10.0) } axis(Orient.BOTTOM, xScale) } group { path { fill = null strokeColor = Colors.Web.steelblue strokeWidth = 1.5 moveTo(xScale(points[0].x), yScale(points[0].y)) (1 until 100).forEach { lineTo(xScale(points[it].x), yScale(points[it].y)) } } } } }.bindRendererOnNewCanvas() }