Public
Edited
Aug 1, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
<a id="link">click link</a>
Insert cell
import { serialize, download_icon } from '@kelleyvanevert/little-things'
Insert cell
exampleButton = svgDownloadButton(svgnode)
Insert cell
function svgDownloadButton(svgnode, filename = 'download.svg') {
const downloadButton = html`<a class="download" download="${filename}" href="#" style="display: flex; align-items: center;">${download_icon.outerHTML} Save ${filename}</a>`;

downloadButton.onclick = function(e) {
var url = (downloadButton.href = URL.createObjectURL(serialize(svgnode)));
setTimeout(function() {
URL.revokeObjectURL(url);
}, 50);
};

return downloadButton;
}
Insert cell
svgnode= { const svg = d3.create('svg').attr('id', 'svg_vis1').attr('viewBox', [0,0,width, height]).style('background', secondary)

const wrapper = svg.append('g').attr("transform", `translate(${margin.left},${margin.top})`)

// wrapper.selectAll('.line').data(novel_titles).join("line").attr('x1', d=>x(d)).attr('x2', d=>x(d)).attr('y1',0).attr('y2', innerHeight)
// .style('stroke', primary).style('stroke-width', 0.2)
// const chart = svg.append('g')
// .attr('class', 'chart')
// .attr('transform', `translate(${innerWidth/2},${innerHeight*0.8})`)
// .style('font-size', 8)
// .style('font-family', 'sans-serif')
wrapper.selectAll('text').data(novel_titles).join('text').style('font-size', 12)
.style('fill', primary)
.attr('transform', d=> `translate(${x(d)}, ${-10}) rotate(-90)`).text(d => d)

wrapper.selectAll('circle').data(quote_dataset).join('circle').attr('cx', d=>x(d['Novel Title'])).attr('cy', d=>y(d.quote_pos)).attr('r', d=>r_scaler(d.quote_len)).style('fill', d=> {
if(d.speaker_gender == 'M') {
return c4
// return m_colorScale(d.quote_pos)
} else if (d.speaker_gender == 'F'){
return c2
// return f_colorScale(d.quote_pos)
} else {
return "#1e1e1e"
}
}).style('opacity', 0.75)
.attr('stroke','#1e1e1e').attr('stroke-width', 0.1)

// quoteID: "Q0"
// quoteText: "Was anyone hurt?"
// speaker: "John Beaver"
// speaker_gender: "M"
// address_gender: "F"
// Novel Title: "AHandfulOfDust"
// Author: "Evelyn Waugh"
// Author Gender: "M"
// quote_len: 16
// quote_pos: 44
// // special
// const arc = d3.arc()
// .innerRadius(d => y(0))
// .outerRadius(d => y(1))
// .startAngle(d => x(d.Title))
// .endAngle(d => x(d.Title) + x.bandwidth())
// .padAngle(0.05)
// .padRadius(innerRadius)

// //
// const arc_m = d3.arc()
// .cornerRadius(cornerR)
// .innerRadius(d => y(0))
// .outerRadius(d => y(d.M))
// .startAngle(d => x(d.Title))
// .endAngle(d => x(d.Title) + x.bandwidth())
// .padAngle(0.1)
// .padRadius(innerRadius)

// const arc_f = d3.arc()
// .cornerRadius(cornerR)
// .innerRadius(d => y(d.M + d.Other)+4)
// .outerRadius(d => y(1)+4)
// .startAngle(d => x(d.Title))
// .endAngle(d => x(d.Title) + x.bandwidth())
// .padAngle(0.1)
// .padRadius(innerRadius)

// chart.selectAll('.path-m').data(data).join('path').attr('d', arc_m)
// .style('fill', c4)

// chart.selectAll('.path-f').data(data).join('path').attr('d', arc_f)
// .style('fill', c2)

// let annotate_grouping = chart.selectAll('.anno_group').data(data).join('g').attr("transform", (d,i,arr) => `rotate(${ (x(d.Title)+x.step()/2)*(180/Math.PI)-90 }) translate(${outerRadius+10}, 0)`)

// // text
// annotate_grouping.append('text').style('font-size', 12)
// .style('fill', primary)
// .attr('dominant-baseline', 'central')
// .attr('transform', d => ((x(d.Title)+x.step()/2)*(180/Math.PI)-90 < -90) ? `rotate(180)` :`rotate(0)`)
// .attr('text-anchor', d => ((x(d.Title)+x.step()/2)*(180/Math.PI)-90 < -90) ? `end` :`begin`)
// .text(d => d.Title)
return svg.node()
}

Insert cell
d3.mean(quote_dataset.map(d => d.quote_len))
Insert cell
innerHeight = height - margin.top - margin.bottom
Insert cell
innerWidth = width - margin.left - margin.right
Insert cell
viewof cornerR = Inputs.range([0, 60], {value: 25, step: 1, label: "Corner Radius"})
Insert cell
viewof innerRadius = Inputs.range([5, 300], {value: 102, step: 1, label: "Inner Radius"})
Insert cell
viewof outerRadius = Inputs.range([30, width/2], {value: 550, step: 1, label: "Outer Radius"})
Insert cell
viewof pi_deficit = Inputs.range([0, 5], {value: 0.25, step: 0.05, label: "Angle Deficit"})
Insert cell
// xAxis = g => g
// .call(d3.axisBottom(x))
// .call(g => g.selectAll('.tick text').remove())
// .call(g => g.selectAll('.domain').remove())
// // .call(g => g.selectAll('.tick line').remove())
// yAxis = g => g
// .call(d3.axisLeft(y))
Insert cell
r_scaler = d3.scaleLinear().domain([1, 500]).range([1, 4.5])
Insert cell
y = d3.scaleLinear().domain([0, max_pos[1]]).range([0, innerHeight])
Insert cell
novel_titles
Insert cell
x = d3.scaleBand().domain(novel_titles).range([0, innerWidth]).padding(1)
Insert cell
quote_dataset = FileAttachment("quote_dataset.json").json()
Insert cell
max_pos = d3.extent(quote_dataset, d => d['quote_pos'])
Insert cell
max_len = d3.extent(quote_dataset, d => d['quote_len'])
Insert cell
data_groups = d3.group(quote_dataset, d => d['Novel Title'])
Insert cell
novel_titles = [...data_groups.keys()]
Insert cell
m_colorScale= d3.scaleSequential()
.domain([0, max_pos[1]])
.interpolator(d3.interpolate('#6c5a7c', '#6d478f'));
Insert cell
f_colorScale=d3.scaleSequential().domain([0, max_pos[1]])
.interpolator(d3.interpolate('#d4949b', '#F67280'));
Insert cell
Insert cell
viewof secondary = colorPicker("#F8B195")
Insert cell
viewof c2 = colorPicker("#F67280") // #d4949b
Insert cell
viewof c3 = colorPicker("#C06C84") //
Insert cell

viewof c4 = colorPicker("#6d478f") //#6c5a7c
Insert cell
viewof primary = colorPicker("#355C7D")
Insert cell
import {colorPicker} from "@shaunlebron/color-picker"
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