JSFiddle - React, Tailwind, and code Playground

by askhflajsf

HTML

<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3fc.io/lib/d3fc.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<content>
  <h2><a href="https://d3fc.io/examples/simple/">Basic D3FC line chart</a> showing trade value/volume vs. countries/currencies like <a href="https://anacoinda.github.io/localbitcoins/aggregates/all.html">Anacoinda</a></h2>
  <p>Also see <a href="https://jsfiddle.net/askhflajsf/h62nrcxf/">candlestick/OHLC price chart</a></p>
  <hr>
  <div id="app-container">
    <select id="currency">
      <option value="eur">EUR</option>
      <option value="gbp">GBP</option>
      <option value="cny">CNY</option>
    </select>
    <form id="value_volume">
      <label for="value">Value</label>
      <input type="radio" name="chart" id="value" value="value" checked>
      <label for="volume">Volume</label>
      <input type="radio" name="chart" id="volume" value="volume">
    </form>
    <form id="time_links">
      <label for="10m">10m</label>
      <input type="radio" name="time_link" id="10m" value="10m" checked>
      <label for="1h">1h</label>
      <input type="radio" name="time_link" id="1h" value="1h">
      <label for="3h">3h</label>
      <input type="radio" name="time_link" id="3h" value="3h">
      <label for="12h">12h</label>
      <input type="radio" name="time_link" id="12h" value="12h">
      <label for="24h">24h</label>
      <input type="radio" name="time_link" id="24h" value="24h">
      <label for="3d">3d</label>
      <input type="radio" name="time_link" id="3d" value="3d">
      <label for="7d">7d</label>
      <input type="radio" name="time_link" id="7d" value="7d">
    </form>
    <div id="chart" class="chart large"></div>
  </div>
  <hr>
  <h2>Todo</h2>
  <ol>
    <li>Blue outlined bars in the background&mdash;<a...

CSS

.x-axis svg,
.y-axis svg {
  stroke: white;
  stroke-width: 0.5;
}

.gridline-x,
.gridline-y {
  stroke: none;
}

.line,
.bar {
  stroke: yellow;
  stroke-opacity: 0.7;
  stroke-width: 3;
}

.area,
.bar {
  fill: lightgreen;
  fill-opacity: 0.5;
}

body {
  background: #263337;
  color: #fff;
}

content {
  border: 7px solid blue;
  position: fixed;
  width: 100%;
  height: 100%;
  overflow-y: scroll;
  overflow-x: hidden;
  padding: 0 10px;
}

select {
  color: #000 !important;
}

select *, form label {
  font-size: 12px;
  font-weight: 400;
}

content > * a,
content > ul li a,
content > ol li a {
  color: blue;
  text-decoration: underline;
}

content > ul li span,
content > ol li span {
  font-family: Monospace;
  color: #aaa;
}


/* app.css */

.chart-label {
  font-size: 1.5em;
  line-height: normal;
}

.chart {
  margin: 10px 0;
  width: 100%;
  height: 250px;
}

.chart svg {
  overflow: visible !important;
}

.chart.large {
  height: 400px;
}

.plot-area {
  background-color: #263337;
}

.x-axis-label,
.y-axis-label {
  color: white;
}

.y-axis-label {
  white-space: nowrap;
}

JavaScript

var btcExchangeAPI = 'https://cors-anywhere.herokuapp.com/localbitcoins.com/bitcoincharts/',
  bitcoinData;

getTradeData('eur');

function getTradeData(country) {
  $.getJSON(btcExchangeAPI + country + '/trades.json', function(data) {
    data = data.sort((a, b) => a.date - b.date).slice(0, 10);
    bitcoinData = data;
    drawChart(data, 'price', '#chart', 'Daily Transaction Value');
  });
}

function update(sel) {
  getTradeData(sel.value);
}

var dateFromEpoch = (e) => new Date(e * 1000);

function drawChart(data, parameter, selector, label) {
  var xExtent = fc.extentDate()
    .accessors([d => dateFromEpoch(d.date)]);

  var yExtent = fc.extentLinear()
    .accessors([d => parseFloat(d[parameter])])
    .pad([0.4, 0.4])
    .padUnit('domain');

  // create a chart

  var chart = fc.chartSvgCartesian(
      d3.scaleTime(),
      d3.scaleLinear())
    .yDomain(yExtent(data))
    .yOrient('left')
    .xDomain(xExtent(data))
    .chartLabel(label);

  // create a pair of series and some gridlines

  var line = fc.seriesSvgLine()
    .crossValue(d => dateFromEpoch(d.date))
    .mainValue(d => parseFloat(d[parameter]));

  var area = fc.seriesSvgArea()
    .crossValue(d => dateFromEpoch(d.date))
    .mainValue(d => parseFloat(d[parameter]));

  var bar = fc.seriesSvgBar()
    .crossValue(d => dateFromEpoch(d.date))
    .mainValue(d => parseFloat(d[parameter]));

  // combine using a multi-series
  var multi = fc.seriesSvgMulti()
    .series([area, line, bar]);

  chart.plotArea(multi);

  let svg = d3.select(selector);
  svg.selectAll('*').remove();
  svg.datum(data).call(chart);

};

$('#currency').change(function() {
  getTradeData($(this).val());
});

$('#volume_chart').hide();

$('#value').click(function() {
  drawChart(bitcoinData, 'price', '#chart', 'Daily Transaction Value');
})

$('#volume').click(function() {
  drawChart(bitcoinData, 'amount', '#chart', 'Daily Transaction Volume');
})