UNPKG

smartdown-gallery

Version:

Example Smartdown documents and associated resources that demonstrate various Smartdown features and serve as raw material for other Smartdown demos.

337 lines (263 loc) 8.35 kB
### D3 Smartdown makes it easy to incorporate [D3](https://d3js.org)-based diagrams and experiences. #### Streaming Financial Chart Meanwhile, a cool graphic where the *stream* is an infinitely generated series of random numbers... Adapted from [Streaming Financial Chart](https://bl.ocks.org/ColinEberhardt/ab7805a9a7af9717e86adc1656fa98d9). ```d3/playable/autoplay smartdown.importCssCode( ` .bollinger .area { fill: #9cf; fill-opacity: 0.5; } .bollinger .line { stroke: #06c; } .chart { height: 200px !important; } `); var target = this.div; target.classList.add('chart'); // create some test data const stream = fc.randomFinancial().stream(); const data = stream.take(110); function renderChart() { if (target.style.display === 'none' && window.intervalId) { window.clearInterval(window.intervalId); return; } // add a new datapoint and remove an old one data.push(stream.next()); data.shift(); const container = d3.select(target); // Create and apply the bollinger algorithm const bollingerAlgorithm = fc.indicatorBollingerBands() .value(function(d) { return d.close; }); const bollingerData = bollingerAlgorithm(data); const mergedData = data.map(function(d, i) { return Object.assign({}, d, { bollinger: bollingerData[i] }); }); // Offset the range to include the full bar for the latest value const DAY_MS = 1000 * 60 * 60 * 24; const xTicks = 10;// $('#streaming-chart').width() >= 700 ? 10 : 5; const xExtent = fc.extentDate() .accessors([function(d) { return d.date; }]) .padUnit('domain') .pad([DAY_MS * -bollingerAlgorithm.period()(mergedData), DAY_MS]); // ensure y extent includes the bollinger bands const yExtent = fc.extentLinear() .accessors([ function(d) { return Math.max(d.bollinger.upper, d.high); }, function(d) { return Math.min(d.bollinger.lower, d.low); } ]); // create a chart const chart = fc.chartSvgCartesian( d3.scaleTime(), d3.scaleLinear() ) .xDomain(xExtent(mergedData)) .xTicks(xTicks) .yDomain(yExtent(mergedData)) .chartLabel('Streaming Candlestick'); // Create the gridlines and series const gridlines = fc.annotationSvgGridline().xTicks(xTicks); const candlestick = fc.seriesSvgCandlestick(); const bollingerBands = function() { const area = fc.seriesSvgArea() .mainValue(function(d) { return d.bollinger.upper; }) .baseValue(function(d) { return d.bollinger.lower; }); const upperLine = fc.seriesSvgLine() .mainValue(function(d) { return d.bollinger.upper; }); const averageLine = fc.seriesSvgLine() .mainValue(function(d) { return d.bollinger.average; }); const lowerLine = fc.seriesSvgLine() .mainValue(function(d) { return d.bollinger.lower; }); const crossValue = function(d) { return d.date; }; area.crossValue(crossValue); upperLine.crossValue(crossValue); averageLine.crossValue(crossValue); lowerLine.crossValue(crossValue); const bollingerMulti = fc.seriesSvgMulti() .series([area, upperLine, lowerLine, averageLine]) .decorate(function(g, datum, index) { g.enter() .attr('class', function(_, i) { return 'multi bollinger ' + ['area', 'upper', 'lower', 'average'][i]; }); }); return bollingerMulti; }; // add them to the chart via a multi-series const multi = fc.seriesSvgMulti() .series([gridlines, bollingerBands(), candlestick]); chart.plotArea(multi); container .datum(mergedData) .call(chart); } // re-render the chart every 200ms renderChart(); if (window.intervalId) { window.clearInterval(window.intervalId); } window.intervalId = setInterval(renderChart, 200); ``` #### Smelly London Line Graph One of the visualizations available via Smelly London is a [Line Chart](https://github.com/Smelly-London/Smelly-London/tree/master/charts). I made some slight changes so that it can be rendered in Smartdown: ```d3/playable var renderDiv = this.div; renderDiv.classList.add('foo'); smartdown.importCssCode( ` body .foo svg { font: 10px sans-serif; background: lightyellow; } .foo .axis path, .foo .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .foo .x.axis path { display: none; } .foo .line { fill: none; stroke: #2091c1; stroke-width: 1.5px; } `); var margin = {top: 20, right: 20, bottom: 30, left: 50}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; // var formatDate = d3.time.format("%d-%b-%y"); var formatDateCarto = d3.timeParse("%Y/%m/%d"); var x = d3.scaleTime() .range([0, width]); var y = d3.scaleLinear() .range([height, 0]); var xAxis = d3.axisBottom() .scale(x); var yAxis = d3.axisLeft() .scale(y); var line = d3.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.number_of_smells); }); var svg = d3.select(renderDiv).append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); // d3.tsv("data/all_records.tsv", type, function(error, data) { // d3.tsv("data/output/Barnet.tsv", type, function(error, data) { // d3.tsv("data/output/Barnet.tsv", type, function(error, data) { // d3.tsv("data/output/Croydon.tsv", type, function(error, data) { const tsvFile = 'https://rawcdn.githack.com/Smelly-London/Smelly-London/master/charts/data/output/Tower Hamlets.tsv'; d3.tsv(tsvFile, type).then( function(data) { x.domain(d3.extent(data, function(d) { return d.date; })); y.domain(d3.extent(data, function(d) { return d.number_of_smells; })); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Number of smells"); svg.append("path") .datum(data) .attr("class", "line") .attr("d", line); }) .catch(function(error) { throw error; }); function type(d) { d.date = formatDateCarto(d.date); d.number_of_smells = +d.number_of_smells; return d; } ``` #### `dc.js` Smartdown now incorporates the [dc.js Dimensional Charting Libary](https://dc-js.github.io/dc.js/) because, why not? The following example adapted from [Sunburst Cat Example](https://dc-js.github.io/dc.js/examples/sunburst-cat.html). ```d3/playable this.div.innerHTML = ` <div style="overflow-x:auto;height:650px;padding:10px;"> <div id="file_chart"></div> <div id="type_chart"></div> </div> `; var fileChart = dc.sunburstChart("#file_chart"); var typeChart = dc.pieChart("#type_chart"); d3.tsv('https://raw.githubusercontent.com/dc-js/dc.js/develop/web-src/examples/cat.tsv').then(function (cats) { var ndx = crossfilter(cats); var picturesDimension = ndx.dimension(function (d) { return d.file.split('/'); }); var picturesGroup = picturesDimension.group().reduceSum(function (d) { return d.size; }); var typeDimension = ndx.dimension(function (d) { return d.type; }); var typeGroup = typeDimension.group().reduceSum(function (d) { return d.size; }); // d3.schemeCategory20b has been removed from D3v5 var d3SchemeCategory20b = [ '#393b79','#5254a3','#6b6ecf','#9c9ede','#637939', '#8ca252','#b5cf6b','#cedb9c','#8c6d31','#bd9e39', '#e7ba52','#e7cb94','#843c39','#ad494a','#d6616b', '#e7969c','#7b4173','#a55194','#ce6dbd','#de9ed6' ]; fileChart .width(700) .height(640) .dimension(picturesDimension) .group(picturesGroup) .colors(d3.scaleOrdinal(d3SchemeCategory20b)) .legend(dc.legend()); typeChart .width(200) .height(200) .innerRadius(50) .dimension(typeDimension) .group(typeGroup); dc.renderAll(); }); ``` --- [Back to Home](:@Home)