Published
Edited
Mar 18, 2020
1 fork
Insert cell
md`# read json and draw somethin`
Insert cell
d3 = require("d3@5") // loads the highest version of D3 5.x.
Insert cell
_ = require('lodash'); // Use underscore to treat array easily
Insert cell
//css style;
html`<style>
.bar {
height:30px;
text-aline: center;
margin: 10px;
line-height: 30px;
background-color: #cccccc;
}
</style>`
Insert cell
diamondPath = "M 0,0 L -10,-15 -10,-35 0,-50 L 10,-35 10,-15 0,0"
Insert cell
smoothPath = "M 0,-5 C -10,-20 -10,-35 0,-45 C 10,-35 10,-20 0,-5"
Insert cell
html`
<svg width="100" height ="100">
<g transform ="translate(50,50)"> //
<path d="${diamondPath}" fill="transparent" stroke="black"/>
<path d="${smoothPath}" fill="transparent" stroke="black"/>
<circle cx ="0" cy ="-25" r ="5" stroke="black"/>
</g>
</svg>`
Insert cell
//Import json: imdb: Largely based on Shirly Wu's code and her project
movie_data = d3.json('https://raw.githubusercontent.com/sxywu/filmflowers/master/movies.json').then(data =>_.values(data)); // _.values: Creates an array of the own enumerable string keyed property values of object: https://lodash.com/docs/4.17.15#values
Insert cell
//All functions of D3: https://github.com/d3/d3/blob/master/API.md
{
let w = 1000, h = 800, dim = 85;
let svg = DOM.svg(w,h);
//
let ratingMinMax = d3.extent(movie_data, d => +d.imdbRating); // 0 - 10
let votesMinMax = d3.extent(movie_data, d => +d.imdbVotes.replace(',','')); // min max as array
//create two scale functions
let sizeScaleF = d3.scaleLinear().domain(ratingMinMax).range([0.1, 1]);
let numScaleF = d3.scaleQuantize().domain(votesMinMax).range([3,6,9,12]);//Quantize: Continuous -> discrete
//---------Create a js object literal (comma-separated list of name-value pairs) ----------//
let drawingsData = _.map(movie_data, d => {
let numDrawing = numScaleF(+d.imdbVotes.replace(',',''));
let drawingSize = sizeScaleF(+d.imdbRating);
//
return {
drawingSize,
//_.times: an alternative to loops, forEach: https://dustinpfister.github.io/2017/10/11/lodash_times/
// angle is calculated here;
drawings: _.times(numDrawing, i =>
{return {angle: 270 * i / numDrawing, diamondPath, smoothPath}}),
numDrawing
}
});
console.log(drawingsData)

//--------- Create svg element and enter the data ----------//
let drawings = d3.select(svg)
.selectAll('g')
.data(drawingsData)
.enter() // enter -> create all values
.append('g') //d -> data, i -> index
.attr('transform', (d, i) => `translate(${(i % 10) * dim}, ${Math.floor(i / 10) * dim}) scale(${d.drawingSize})`);

// enter the first path
drawings.selectAll('g')
.data(d => d.drawings).enter().append('path')
.attr('d', d => d.smoothPath)
.attr('transform', d => `rotate(${d.angle})`)
.attr('fill', 'transparent')
.attr('stroke', (d, i) => d3.interpolateWarm(d.angle / 360));

// enter the second path
drawings.selectAll('g')
.data(d => d.drawings).enter().append('path')
.attr('d', d => d.diamondPath)
.attr('transform', d => `rotate(${d.angle})`)
.attr('fill', 'transparent')
.attr('stroke', (d, i) => d3.interpolateWarm(d.angle / 360));

// enter the third svg element - circle
drawings.selectAll('g')
.data(d => d.drawings).enter().append('circle')
.attr('cx', '0')
.attr('cy', '-25')
.attr('r', '5')
.attr('transform', d => `rotate(${d.angle})`)
.attr('fill', (d, i) => d3.interpolateCool(d.angle / 360))
.attr('stroke', 'none');
return svg;



}//end of all js.
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more