JSFiddle - React, Tailwind, and code Playground

by Gary Cline

HTML

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.chart-container {
    position: relative;
}

.chart-container .controls {
    position: absolute;
    top: 12px;
    left: 18px;
}

.chart path,
.chart line,
.chart rect {
    shape-rendering: crispEdges;
}

.chart .axis path,
.chart .axis line {
    fill: none;
    stroke: #000;
}

.chart .linear .point {
    fill: steelblue;
}

.chart .pow .point {
    fill: #CD4638;
}

</style>
<body>

<div class="chart-container js-chart-container">
    <form class="controls">
        Scale:
        <label><input type="radio" name="x-scale" value="power2" checked>Power2</label>
        <label><input type="radio" name="x-scale" value="linear">Linear</label>
        <label><input type="radio" name="x-scale" value="sqrt">SquareRoot</label>
        <label><input type="radio" name="x-scale" value="log2">Log2</label>
        <label><input type="radio" name="x-scale" value="log10">Log10</label>
    </form>
    <svg class="chart js-chart"></svg>
</div>

<script src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript">

JavaScript

"use strict";
var chart = {
    margin: { top: 40, right: 25, bottom: 20, left: 25 },

    animationDuration: 400,

    scales: {
        power2: d3.scalePow().exponent(2),
        linear: d3.scaleLinear(),
        sqrt:   d3.scalePow().exponent(0.7),
        log2:   d3.scaleLog().base(2),
        log10:  d3.scaleLog().base(10)
    },

    init: function (container, data) {
        this.el = d3.select(".js-chart")
            .attr("width", container.width)
            .attr("height", container.height);

        this.width  = container.width - this.margin.left - this.margin.right;
        this.height = container.height - this.margin.top - this.margin.bottom;

        this.adaptScales();
        this.setXScale();
        this.draw(data);

        d3.selectAll(".js-chart-container input").on("click", this.changeXScale.bind(this));
    },

    draw: function (data) {
        var mainGroup, series;

        mainGroup = this.el.append("g")
            .attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");

        series = mainGroup.selectAll(".series").data(data)
            .enter().append("g")
                .attr("class", function (d) { return "series " + d.name; });

        this.points = series.selectAll(".point").data(function (d) { return d.points; })
            .enter().append("circle")
                .attr("class", "point")
                .attr("cx", this.xScale)
                .attr("cy", this.height / 2)
                .attr("r", 6);

        this.points.append("title")
           .text(String);

        this.xAxis = d3.axisBottom()
            .scale(this.xScale);

        this.domXAxis = mainGroup.append("g")
            .attr("class", "axis axis--x")
            .attr("transform", "translate(0," + this.height + ")")
            .call(this.xAxis);
    },

    redraw: function () {
        this.domXAxis.transition()
            .duration(this.animationDuration)
            .call(this.xAxis.scale(this.xScale));
       ...