Published
Edited
Jun 18, 2020
1 fork
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
ppDataFile = FileAttachment("time_cpaintings.json")
Insert cell
ppData = await ppDataFile.json()
Insert cell
sampleData = d3.csv(
await "https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/5_OneCatSevNumOrdered_wide.csv"
)
Insert cell
streamGraph(ppData)
Insert cell
Insert cell
timeFrames
Insert cell
streamGraph = data => {
const margin = {
t: 10,
l: 50,
r: 10,
b: 40
};
const w = width - margin.l - margin.r;
const height = 500;
const h = height - margin.t - margin.b;

const allColors = d3.keys(ppData.map(d => d.value)[0]);

const xScale = d3
.scalePoint()
.domain(timeFrames)
.range([margin.l, w]);

const xAxisScale = d3
.scalePoint()
.domain(d3.range(0, timeFrames.length))
.range([margin.l, w]);

const svg = d3
.select(html`<svg></svg>`)
.attr('width', width)
.attr('height', h);

//stack the data
const stack = d3
.stack()
// .offset(d3.stackOffsetSilhouette)
// .offset(d3.stackOffsetExpand)
.keys(allColors);

const stackedData = stack(ppData.map(d => d.value));
console.log('stackedData', stackedData);
console.log(
'+++',
d3.max(stackedData[stackedData.length - 1].map(d => d[1]))
);

const yAxisScale = d3
.scaleLinear()
.domain([
d3.min(stackedData[0].map(d => d[0])),
d3.max(stackedData[stackedData.length - 1].map(d => d[1]))
])
.range([h - margin.b, margin.t]);

// Mostra l'area
svg
.selectAll("mylayers")
.data(stackedData)
.enter()
.append("path")
.style("fill", d => d.key)
.attr(
"d",
d3
.area()
.x((d, i) => xAxisScale(i))
.y0(d => yAxisScale(d[0]))
.y1(d => yAxisScale(d[1]))
.curve(d3.curveCatmullRom.alpha(1))
);

// Asse y
svg
.append("g")
.attr("transform", "translate(" + margin.l + "," + 0 + ")")
.call(d3.axisLeft(yAxisScale));

// Asse X
svg
.append("g")
.attr("transform", "translate(0," + (h - margin.b) + ")")
.call(d3.axisBottom(xScale));

return Object.assign(svg.node());
}
Insert cell
md`# Bubblechart`
Insert cell
Insert cell
bubbleChart = wordCloud(bubbleData, 'color', 'freq', 25, 'timeFrame')
// declare type column only if you have a label you want to use to color bubbles
Insert cell
Insert cell
Insert cell
timeFrames = d3.set(bubbleData.map(d => d.timeFrame)).values()
Insert cell
wordCloud = (data, word, frequency, maxSize, type) => {
if (type === undefined) {
data.map(d => (d.type = 0));
}
const height = 300;
const margin = {
t: 0,
l: 30,
r: 20,
b: 0
};
const padding = 2;
// create the SVG container

let x = d3
.scalePoint()
.domain(timeFrames)
.range([margin.l, width - margin.l - margin.r]);

let svg = d3
.select(html`<svg></svg>`)
.attr('width', width)
.attr('height', height);

const colors = d3.schemeSet1.slice(0, new Set(data.map(d => d[type])).size);

// color text black or white according to the luminance value of the node
const luminance = 50;
const textColor = d3
.scaleQuantile()
.range(["#fff", "#000"])
.domain([0, luminance, 100]);

// define scale for radius
const r = d3
.scaleSqrt()
.domain([0, d3.max(data, d => d[frequency])])
.range([0, maxSize]);

// define the simualtion engine
const simulation = d3
.forceSimulation(data)
// .force("x", d3.forceX(width / 2).strength(0.2))
.force("x", d3.forceX(d => x(d[type])).strength(1))
.force("y", d3.forceY(height / 2).strength(0.2))
.force(
"collide",
d3
.forceCollide()
.radius(d => r(d[frequency]) + padding)
.iterations(10)
)
.alpha(0.2);

// create a layer or group
let gBubble = svg.selectAll('gBubble').data(data);
gBubble.exit().remove();

let bubble = gBubble
.enter()
.append('g')
.classed('gBubble', true)
.attr('id', d => d[word]);

bubble
.append('circle')
.attr('r', d => r(d[frequency]))
.attr('fill', d => d[word])
.attr('fill-opacity', 0.4)
.attr('stroke', d => d[word])
.attr('stroke-width', 1);

// let text = bubble.append('text');

// const textLabels = text
// .text(d => d[word])
// .style('text-anchor', 'middle')
// .attr("dominant-baseline", "central")
// .attr('font-family', 'sans-serif')
// .attr('font-size', '6px')
// .attr('font-weight', 'normal');

gBubble = gBubble.merge(bubble);

gBubble.call(drag(simulation));

simulation.nodes(data).on('tick', () => {
gBubble.attr('transform', d => 'translate(' + d.x + ',' + d.y + ')');
});

const xaxis = svg
.append("g")
.attr("transform", `translate(0,${height - 50})`)
.call(d3.axisBottom(x));

return Object.assign(svg.node());
}
Insert cell
xScale = d3
.scaleBand()
.domain(timeFrames)
.range([0, 900])
Insert cell
xScale("1801-1850")
Insert cell
drag = simulation => {
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}

function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}

function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}

return d3
.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}
Insert cell
Insert cell
paintings = {
return await d3.csv(
"https://raw.githubusercontent.com/danielefadda/Web-Gallery-of-Art/master/data/paintings.csv"
);
}
Insert cell
Insert cell
allC = d3.keys(ppData.map(d => d.value)[0])
Insert cell
Insert cell
[
{ color: "blue", "1400-1450": 23, "1451-1500": 50 },
{ color: "red", "1400-1450": 23, "1451-1500": 50 }
]
Insert cell
pcData = allC.map(d => {
let obj = {};
obj['color'] = d;
ppData.map(v => {
obj[v.key] = +v.value[d];
});
return obj;
})
Insert cell
// la scala serve per mappare i colori tra 0 e 1, come vuole la prorpietà colorscale
linearScale = d3
.scaleLinear()
.domain(d3.extent(d3.range(allC.length)))
.range([0, 1])
Insert cell
maxColor = d3.max(pcData.map(d => d3.max(d3.values(d).splice(1))))
Insert cell
pPlot = {
// elenco dei
const periods = d3.keys(pcData[0]).slice(1);
console.log("periods", periods);
const myColorScale = allC.map((d, i) => {
return [linearScale(i), d];
});

const data = [
{
type: 'parcoords',
line: {
color: pcData.map((d, i) => i),
colorscale: myColorScale
},
dimensions: periods.map((d, i) => {
// console.log('timeframe', d);
// console.log('values', pcData.map(c => c[d]));
// console.log('extent', d3.extent(pcData.map(c => c[d])));
return {
label: d,
values: pcData.map(c => c[d]),
range: [0, d3.max(pcData.map(c => c[d]))],
// range: [0, 250],
tickvals: i === 0 ? pcData.map(c => c[d]) : null,
ticktext: i === 0 ? pcData.map(c => c.color) : null
};
})
}
];
// console.log(data);
const layout = { width: 900 };
const div = DOM.element('div');
Plotly.newPlot(div, data, layout);
return div;
}
Insert cell
Insert cell
d3 = require("d3@5", "d3-sankey@0.12")
Insert cell
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