Initial Commit
This commit is contained in:
40
public/js/animated-scaled-line.js
Normal file
40
public/js/animated-scaled-line.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const margin = { top: 200, right: 200, bottom: 200, left: 200 }
|
||||
const width = window.innerWidth - margin.right - margin.left
|
||||
const height = (window.innerHeight / 2) - margin.top - margin.bottom
|
||||
|
||||
const div = d3.select('body')
|
||||
|
||||
const svg = div.append('svg')
|
||||
.attr('height', height + margin.top + margin.bottom)
|
||||
.attr('width', width + margin.left + margin.right)
|
||||
.style('background-color', 'rgb(255, 218, 241)')
|
||||
.append('g').attr('transform', `translate(${margin.left}, ${margin.bottom})`)
|
||||
|
||||
const data = Array(100).fill().map(() => d3.randomUniform(1)())
|
||||
|
||||
const xScale = d3.scaleLinear()
|
||||
.domain([0, data.length-1])
|
||||
.range([0, width])
|
||||
|
||||
const yScale = d3.scaleLinear()
|
||||
.domain([0, d3.max(data)])
|
||||
.range([height, 0])
|
||||
|
||||
const line = d3.line()
|
||||
.x((d, i) => xScale(i))
|
||||
.y((d, i) => yScale(d))
|
||||
.curve(d3.curveNatural)
|
||||
|
||||
const path = svg.append('path')
|
||||
.datum(data)
|
||||
.style('fill', 'none')
|
||||
.style('stroke', 'darkblue')
|
||||
.style('stroke-width', 1)
|
||||
.attr('d', line)
|
||||
|
||||
const totalLength = path.node().getTotalLength()
|
||||
path.attr('stroke-dasharray', `${totalLength} ${totalLength}`)
|
||||
.attr('stroke-dashoffset', totalLength)
|
||||
.transition().duration(5000).ease(d3.easeQuad)
|
||||
.attr('stroke-dashoffset', 0)
|
||||
|
||||
70
public/js/area-chart.js
Normal file
70
public/js/area-chart.js
Normal file
@@ -0,0 +1,70 @@
|
||||
const margin = { top: 200, right: 200, bottom: 200, left: 200 }
|
||||
const width = window.innerWidth - margin.right - margin.left
|
||||
const height = window.innerHeight - margin.top - margin.bottom
|
||||
const data = Array(11).fill().map(() => d3.randomUniform(100)())
|
||||
|
||||
const div = d3.select('body')
|
||||
|
||||
const svg = div.append('svg')
|
||||
.attr('height', height + margin.top + margin.bottom)
|
||||
.attr('width', width + margin.left + margin.right)
|
||||
.append('g').attr('transform', `translate(${margin.left}, ${margin.bottom})`)
|
||||
|
||||
const xScale = d3.scaleLinear()
|
||||
.domain([0, data.length-1])
|
||||
.range([0, width])
|
||||
|
||||
const yScale = d3.scaleLinear()
|
||||
.domain([0, d3.max(data)])
|
||||
.range([height, 0])
|
||||
|
||||
const area = d3.area()
|
||||
.x((d, i) => xScale(i))
|
||||
.y0(yScale(0))
|
||||
.y1((d, i) => yScale(d))
|
||||
|
||||
const xAxis = svg.append('g')
|
||||
.attr('class', 'x axis')
|
||||
.attr('transform', `translate(0, ${height})`)
|
||||
.call(d3.axisBottom(xScale))
|
||||
|
||||
const yAxis = svg.append('g')
|
||||
.attr('class', 'y axis')
|
||||
.call(d3.axisLeft(yScale))
|
||||
|
||||
const path = svg.append('path')
|
||||
.datum(data)
|
||||
.attr('class', 'data-line')
|
||||
.style('stroke', 'white')
|
||||
.style('stroke-width', 2)
|
||||
.style('fill', 'white')
|
||||
.style('fill-opacity', 0.15)
|
||||
.attr('d', area)
|
||||
|
||||
const circles = svg.selectAll('.circle')
|
||||
.data(data).enter().append('circle')
|
||||
.attr('class', 'circle')
|
||||
.attr('cx', (d, i) => xScale(i))
|
||||
.attr('cy', -300)
|
||||
.attr('r', 8)
|
||||
.style('fill', 'white')
|
||||
.style('stroke', 'rgb(51, 57, 68)')
|
||||
.style('stroke-width', 3)
|
||||
|
||||
circles.transition()
|
||||
.duration(1000)
|
||||
.delay((d, i) => i * 80)
|
||||
.attr('cy', (d, i) => yScale(d))
|
||||
|
||||
|
||||
circles.on('mouseover', function(d) {
|
||||
d3.select(this)
|
||||
.transition().duration(500)
|
||||
.attr('r', 14)
|
||||
})
|
||||
|
||||
circles.on('mouseout', function(d) {
|
||||
d3.select(this)
|
||||
.transition().duration(500)
|
||||
.attr('r', 8)
|
||||
})
|
||||
63
public/js/basic-line-chart.js
Normal file
63
public/js/basic-line-chart.js
Normal file
@@ -0,0 +1,63 @@
|
||||
const margin = { top: 200, right: 200, bottom: 200, left: 200 }
|
||||
const width = window.innerWidth - margin.right - margin.left
|
||||
const height = window.innerHeight - margin.top - margin.bottom
|
||||
const data = Array(11).fill().map(() => d3.randomUniform(100)())
|
||||
|
||||
const div = d3.select('body')
|
||||
|
||||
const svg = div.append('svg')
|
||||
.attr('height', height + margin.top + margin.bottom)
|
||||
.attr('width', width + margin.left + margin.right)
|
||||
.style('background-color', 'rgb(51, 57, 68)')
|
||||
.append('g').attr('transform', `translate(${margin.left}, ${margin.bottom})`)
|
||||
|
||||
const xScale = d3.scaleLinear()
|
||||
.domain([0, data.length-1])
|
||||
.range([0, width])
|
||||
|
||||
const yScale = d3.scaleLinear()
|
||||
.domain([0, d3.max(data)])
|
||||
.range([height, 0])
|
||||
|
||||
const line = d3.line()
|
||||
.x((d, i) => xScale(i))
|
||||
.y((d, i) => yScale(d))
|
||||
.curve(d3.curveCatmullRom)
|
||||
|
||||
const xAxis = svg.append('g')
|
||||
.attr('class', 'x axis')
|
||||
.attr('transform', `translate(0, ${height})`)
|
||||
.call(d3.axisBottom(xScale))
|
||||
|
||||
const yAxis = svg.append('g')
|
||||
.attr('class', 'y axis')
|
||||
.call(d3.axisLeft(yScale))
|
||||
|
||||
const path = svg.append('path')
|
||||
.datum(data)
|
||||
.style('fill', 'none')
|
||||
.style('stroke', 'white')
|
||||
.style('stroke-width', 2)
|
||||
.attr('d', line)
|
||||
|
||||
const circles = svg.selectAll('.circle')
|
||||
.data(data).enter().append('circle')
|
||||
.attr('class', 'circle')
|
||||
.attr('cx', (d, i) => xScale(i))
|
||||
.attr('cy', (d, i) => yScale(d))
|
||||
.attr('r', '5')
|
||||
.style('fill', 'white')
|
||||
.style('stroke', 'rgb(51, 57, 68)')
|
||||
.style('stroke-width', 3)
|
||||
|
||||
circles.on('mouseover', function(d) {
|
||||
d3.select(this)
|
||||
.transition().duration(500)
|
||||
.attr('r', '10')
|
||||
})
|
||||
|
||||
circles.on('mouseout', function(d) {
|
||||
d3.select(this)
|
||||
.transition().duration(500)
|
||||
.attr('r', '5')
|
||||
})
|
||||
29
public/js/confetti.js
Normal file
29
public/js/confetti.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const width = window.innerWidth
|
||||
const height = window.innerHeight
|
||||
|
||||
const svg = d3.select('body').style('margin', 0)
|
||||
.append('svg')
|
||||
.style('width', width)
|
||||
.style('height', height)
|
||||
//.style('background', 'darkblue')
|
||||
|
||||
const data = Array(3000).fill().map(_ => {
|
||||
return {
|
||||
cx: Math.round(Math.random() * width),
|
||||
cy: Math.round(Math.random() * height)
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
const color = d3.scaleOrdinal(d3.schemePastel1)
|
||||
|
||||
const circle = svg.selectAll('circle')
|
||||
.data(data).enter()
|
||||
.append('circle')
|
||||
.attr('cx', d => d.cx)
|
||||
.attr('cy', d => d.cy)
|
||||
.attr('r', (d, i) => i % 2 == 0 ? 10 : 5)
|
||||
.style('stroke', (d, i) => color(i))
|
||||
.style('stroke-width', 2)
|
||||
.style('fill', 'none')
|
||||
|
||||
52
public/js/flower-chart.js
Normal file
52
public/js/flower-chart.js
Normal file
@@ -0,0 +1,52 @@
|
||||
const data = [12, 6, 15, 4, 28, 5, 14, 4, 7, 5]
|
||||
|
||||
const width = window.innerWidth
|
||||
const height = window.innerHeight - 200
|
||||
const radius = Math.min(width, height) * .50
|
||||
const colorScale = d3.scaleOrdinal(d3.schemeSet3)
|
||||
|
||||
const svg = d3.select('body').append('svg')
|
||||
.attr('height', height)
|
||||
.attr('width', width)
|
||||
.append('g').attr('transform', `translate(${width / 2}, ${height / 2})`)
|
||||
|
||||
const pie = d3.pie().value(d => d).sort(null)
|
||||
|
||||
const zeroArc = d3.arc().outerRadius(1).innerRadius(0).cornerRadius(1)
|
||||
const arc = d3.arc().outerRadius(radius).innerRadius(0).cornerRadius(radius)
|
||||
const hoverArc = d3.arc().outerRadius(radius + 30).innerRadius(0).cornerRadius(radius)
|
||||
const labelArc = d3.arc().outerRadius(radius * 1.7).innerRadius(0)
|
||||
|
||||
const g = svg.selectAll('.arc')
|
||||
.data(pie(data))
|
||||
.enter().append('g').attr('class', 'arc')
|
||||
|
||||
g.append('path')
|
||||
.attr('d', zeroArc)
|
||||
.attr('class', 'arc')
|
||||
.style('fill', (d, i) => colorScale(i))
|
||||
.style('fill-opacity', .7)
|
||||
.style('stroke', 'hsl(201, 81%, 8%)')
|
||||
.style('stroke-width', 4)
|
||||
.on('mouseover', function(d, i) {
|
||||
d3.select(this)
|
||||
.style('fill-opacity', 1)
|
||||
.transition().duration(250)
|
||||
.attr('d', hoverArc)
|
||||
})
|
||||
.on('mouseout', function(d, i) {
|
||||
d3.select(this)
|
||||
.style('fill-opacity', .7)
|
||||
.transition().duration(250)
|
||||
.attr('d', arc)
|
||||
})
|
||||
.transition().duration(500).delay((d, i) => i * 100)
|
||||
.attr('d', arc)
|
||||
|
||||
g.append('text')
|
||||
.attr('transform', d => `translate(${labelArc.centroid(d)})`)
|
||||
.text(d => `${d.data}%`)
|
||||
.attr('class', 'text')
|
||||
.attr('fill-opacity', 0)
|
||||
.transition().duration(500).delay((d, i) => i * 100)
|
||||
.attr('fill-opacity', 1)
|
||||
0
public/js/index.js
Normal file
0
public/js/index.js
Normal file
52
public/js/montly-bills.js
Normal file
52
public/js/montly-bills.js
Normal file
@@ -0,0 +1,52 @@
|
||||
const data = d3.csv('/data/bills.csv').then(rawData => {
|
||||
const data = rawData.map(d => {
|
||||
return {
|
||||
type: d.type,
|
||||
cost_percent: +d.cost_percent
|
||||
}
|
||||
})
|
||||
|
||||
const width = window.innerWidth
|
||||
const height = window.innerHeight
|
||||
|
||||
const radius = Math.min(width, height) / 2
|
||||
const colorScale = d3.scaleOrdinal(['#7326AB', '#2A59A9', '#E5A1D4', '#00A0B0', '#1C9FE9'])
|
||||
|
||||
const svg = d3.select('body').append('svg')
|
||||
.attr('height', height)
|
||||
.attr('width', width)
|
||||
.append('g').attr('transform', `translate(${width / 2}, ${height / 2})`)
|
||||
|
||||
const pie = d3.pie().value(d => d.cost_percent).sort(null)
|
||||
const arc = d3.arc().outerRadius(radius * .75).innerRadius(0)
|
||||
const hoverArc = d3.arc().outerRadius(radius * .85).innerRadius(0)
|
||||
|
||||
const g = svg.selectAll('.arc')
|
||||
.data(pie(data))
|
||||
.enter().append('g').attr('class', 'arc')
|
||||
|
||||
g.append('path')
|
||||
.attr('d', arc)
|
||||
.attr('class', 'arc')
|
||||
.style('fill', (d, i) => colorScale(i))
|
||||
.style('fill-opacity', 0.8)
|
||||
.style('stroke', 'hsl(200, 77%, 5%)')
|
||||
.style('stroke-width', 4)
|
||||
.on('mouseover', function(d, i) {
|
||||
d3.select(this)
|
||||
.style('fill-opacity', 1)
|
||||
.transition().duration(500)
|
||||
.attr('d', hoverArc)
|
||||
})
|
||||
.on('mouseout', function(d, i) {
|
||||
d3.select(this)
|
||||
.style('fill-opacity', .8)
|
||||
.transition().duration(500)
|
||||
.attr('d', arc)
|
||||
})
|
||||
|
||||
g.append('text')
|
||||
.attr('transform', d => `translate(${arc.centroid(d)})`)
|
||||
.text(d => `${d.data.type} ${d.data.cost_percent}%`)
|
||||
.attr('class', 'text')
|
||||
})
|
||||
15
public/js/one-box.js
Normal file
15
public/js/one-box.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const svg = d3.select('body')
|
||||
.attr('margin', 0)
|
||||
.append('svg')
|
||||
.style('width', window.innerWidth)
|
||||
.style('height', window.innerHeight)
|
||||
.style('background', 'darkblue')
|
||||
|
||||
svg.append('rect')
|
||||
.attr('x', (window.innerWidth / 2) - 100)
|
||||
.attr('y', (window.innerHeight / 2) - 150)
|
||||
.attr('width', 100)
|
||||
.attr('height', 150)
|
||||
.style('fill', 'white')
|
||||
.style('stroke', 'yellow')
|
||||
.style('stroke-width', 5)
|
||||
32
public/js/one-circle.js
Normal file
32
public/js/one-circle.js
Normal file
@@ -0,0 +1,32 @@
|
||||
const width = 1000
|
||||
const height = 700
|
||||
|
||||
const svg = d3.select('body')
|
||||
.attr('margin', 0)
|
||||
.append('svg')
|
||||
.attr('width', width)
|
||||
.attr('height', height)
|
||||
|
||||
const circle = svg.append('circle')
|
||||
.attr('cx', width / 2)
|
||||
.attr('cy', height / 2)
|
||||
.attr('r', 100)
|
||||
.style('fill', 'purple')
|
||||
|
||||
circle.on('click', function(d, i) {
|
||||
d3.select(this)
|
||||
.transition().duration(1000).ease(d3.easeQuad)
|
||||
.attr('r', 200)
|
||||
})
|
||||
|
||||
circle.on('mouseover', function(d, i) {
|
||||
d3.select(this)
|
||||
.transition().duration(1000).ease(d3.easeQuad)
|
||||
.style('fill', 'red')
|
||||
})
|
||||
|
||||
circle.on('mouseout', function(d, i) {
|
||||
d3.select(this)
|
||||
.transition().duration(1000).ease(d3.easeQuad)
|
||||
.style('fill', 'purple')
|
||||
})
|
||||
25
public/js/one-line.js
Normal file
25
public/js/one-line.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const width = window.innerWidth
|
||||
const height = window.innerHeight
|
||||
|
||||
const svg = d3.select('body')
|
||||
.attr('margin', 0)
|
||||
.append('svg')
|
||||
|
||||
svg
|
||||
.attr('width', width)
|
||||
.attr('height', height)
|
||||
.style('background-color', '#8AF2F7')
|
||||
|
||||
const coordinates = [
|
||||
{ x: width / 4, y: height / 2 },
|
||||
{ x: (width / 4) * 3, y: height / 2 }
|
||||
]
|
||||
|
||||
const line = d3.line().x(d => d.x).y(d => d.y)
|
||||
|
||||
const path = svg.append('path')
|
||||
.datum(coordinates)
|
||||
.style('fill', 'none')
|
||||
.style('stroke', '#0e0e0e')
|
||||
.style('stroke-width', '5')
|
||||
.attr('d', line)
|
||||
27
public/js/peace-sign.js
Normal file
27
public/js/peace-sign.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const data = [35, 15, 15, 35]
|
||||
|
||||
const width = window.innerWidth
|
||||
const height = window.innerHeight
|
||||
|
||||
const radius = Math.min(width, height) / 2
|
||||
const colorScale = d3.scaleOrdinal(['#7326AB', '#2A59A9', '#E5A1D4', '#00A0B0'])
|
||||
|
||||
const svg = d3.select('body').append('svg')
|
||||
.attr('height', height)
|
||||
.attr('width', width)
|
||||
.append('g').attr('transform', `translate(${width / 2}, ${height / 2})`)
|
||||
|
||||
const pie = d3.pie().value(d => d).sort(null)
|
||||
const arc = d3.arc().outerRadius(radius * .75).innerRadius(0)
|
||||
|
||||
const g = svg.selectAll('.arc')
|
||||
.data(pie(data))
|
||||
.enter().append('g').attr('class', 'arc')
|
||||
|
||||
g.append('path')
|
||||
.attr('d', arc)
|
||||
.attr('class', 'arc')
|
||||
.style('fill', (d, i) => colorScale(i))
|
||||
.style('stroke', 'hsl(84, 77%, 82%)')
|
||||
.style('stroke-width', 4)
|
||||
|
||||
98
public/js/planets.js
Normal file
98
public/js/planets.js
Normal file
@@ -0,0 +1,98 @@
|
||||
const data = d3.json('/data/planets.json').then(data => {
|
||||
const margin = { top: 200, right: 200, bottom: 200, left: 200 }
|
||||
const width = window.innerWidth - margin.right - margin.left
|
||||
const height = window.innerHeight - margin.top - margin.bottom
|
||||
|
||||
const planets = data.planetDiameters
|
||||
|
||||
const div = d3.select('body')
|
||||
|
||||
const svg = div.append('svg')
|
||||
.attr('height', height + margin.top + margin.bottom)
|
||||
.attr('width', width + margin.left + margin.right)
|
||||
.append('g').attr('transform', `translate(${margin.left}, ${margin.bottom})`)
|
||||
|
||||
const xScale = d3.scaleBand()
|
||||
.domain(planets.map(d => d.planet))
|
||||
.range([0, width])
|
||||
.padding(0.1)
|
||||
|
||||
const yScale = d3.scaleLinear()
|
||||
.domain([0, d3.max(planets.map(d => d.diameter))])
|
||||
.rangeRound([height, 0])
|
||||
|
||||
const xAxis = svg.append('g')
|
||||
.attr('class', 'x axis')
|
||||
.attr('transform', `translate(0, ${height})`)
|
||||
.call(d3.axisBottom(xScale))
|
||||
.append('text')
|
||||
.attr('class', 'text')
|
||||
.attr('x', width / 2)
|
||||
.attr('y', 30)
|
||||
.style('text-anchor', 'middle')
|
||||
.text('Planets')
|
||||
|
||||
const yAxis = svg.append('g')
|
||||
.attr('class', 'y axis')
|
||||
.call(d3.axisLeft(yScale))
|
||||
.append('text').attr('class', 'text')
|
||||
.style('text-anchor', 'end')
|
||||
.attr('class', 'text')
|
||||
.attr('y', 6)
|
||||
.attr('dy', '0.75em')
|
||||
.attr('transform', 'rotate(-90)')
|
||||
.text('Diameter (km)')
|
||||
|
||||
const bars = svg.selectAll('.bar')
|
||||
.data(planets)
|
||||
.enter().append('rect')
|
||||
.attr('class', 'bar')
|
||||
.style('fill', 'white')
|
||||
.style('fill-opacity', .2)
|
||||
.style('stroke', 'white')
|
||||
.style('stroke-width', 2)
|
||||
|
||||
bars.on('mouseover', function(d, i) {
|
||||
d3.select(this)
|
||||
.transition().duration(500)
|
||||
.style('fill-opacity', 1)
|
||||
})
|
||||
|
||||
bars.on('mouseout', function(d, i) {
|
||||
d3.select(this)
|
||||
.transition().duration(500)
|
||||
.style('fill-opacity', .2)
|
||||
})
|
||||
|
||||
bars.attr('x', d => xScale(d.planet))
|
||||
.attr('y', height)
|
||||
.attr('width', xScale.bandwidth())
|
||||
.transition().duration(250).delay((d, i) => i * 200)
|
||||
.attr('y', d => yScale(d.diameter))
|
||||
.attr('height', d => height - yScale(d.diameter))
|
||||
|
||||
const formatter = d3.format(',')
|
||||
|
||||
const barText = svg.selectAll('.diameters')
|
||||
.data(planets).enter().append('text')
|
||||
.attr('class', 'diameters text')
|
||||
.attr('x', d => xScale(d.planet))
|
||||
.attr('dx', d => xScale.bandwidth() / 2)
|
||||
.attr('y', d => yScale(d.diameter))
|
||||
.attr('dy', "-0.75em")
|
||||
.style('fill', 'white')
|
||||
.style('text-anchor', 'middle')
|
||||
.style('opacity', 0)
|
||||
.text(d => formatter(d.diameter))
|
||||
.transition().duration(500).delay((d, i) => i * 200)
|
||||
.style('opacity', 1)
|
||||
|
||||
const title = svg.append('text')
|
||||
.attr('class', 'text')
|
||||
.attr('x', width / 2)
|
||||
.attr('y', -100)
|
||||
.style('text-anchor', 'middle')
|
||||
.style('text-decoration', 'underline')
|
||||
.style('fill', 'white')
|
||||
.text('Planet diameters')
|
||||
})
|
||||
32
public/js/scaled-line.js
Normal file
32
public/js/scaled-line.js
Normal file
@@ -0,0 +1,32 @@
|
||||
const margin = { top: 200, right: 200, bottom: 200, left: 200 }
|
||||
const width = window.innerWidth - margin.right - margin.left
|
||||
const height = window.innerHeight - margin.top - margin.bottom
|
||||
|
||||
const div = d3.select('body')
|
||||
|
||||
const svg = div.append('svg')
|
||||
.attr('height', height + margin.top + margin.bottom)
|
||||
.attr('width', width + margin.left + margin.right)
|
||||
.append('g').attr('transform', `translate(${margin.left}, ${margin.bottom})`)
|
||||
|
||||
const data = Array(25).fill().map(() => d3.randomUniform(1)())
|
||||
|
||||
const xScale = d3.scaleLinear()
|
||||
.domain([0, data.length-1])
|
||||
.range([0, width])
|
||||
|
||||
const yScale = d3.scaleLinear()
|
||||
.domain(d3.extent(data))
|
||||
.range([0, height])
|
||||
|
||||
const line = d3.line()
|
||||
.x((d, i) => xScale(i))
|
||||
.y((d, i) => yScale(d))
|
||||
.curve(d3.curveNatural)
|
||||
|
||||
svg.append('path')
|
||||
.datum(data)
|
||||
.style('fill', 'none')
|
||||
.style('stroke', 'darkblue')
|
||||
.style('stroke-width', 1)
|
||||
.attr('d', line)
|
||||
100
public/js/scores.js
Normal file
100
public/js/scores.js
Normal file
@@ -0,0 +1,100 @@
|
||||
const data = d3.csv('/data/scorecard.csv').then(rawData => {
|
||||
const margin = { top: 200, right: 200, bottom: 200, left: 200 }
|
||||
const width = window.innerWidth - margin.right - margin.left
|
||||
const height = window.innerHeight - margin.top - margin.bottom
|
||||
|
||||
const data = rawData.map(d => {
|
||||
return {
|
||||
player: d.player,
|
||||
points: +d.points
|
||||
}
|
||||
})
|
||||
|
||||
const div = d3.select('body')
|
||||
|
||||
const svg = div.append('svg')
|
||||
.attr('height', height + margin.top + margin.bottom)
|
||||
.attr('width', width + margin.left + margin.right)
|
||||
.append('g').attr('transform', `translate(${margin.left}, ${margin.bottom})`)
|
||||
|
||||
const xScale = d3.scaleLinear()
|
||||
.domain([0, d3.max(data.map(d => d.points))])
|
||||
.rangeRound([0, width])
|
||||
|
||||
const yScale = d3.scaleBand()
|
||||
.domain(data.map(d => d.player))
|
||||
.range([height, 0])
|
||||
.padding(0.1)
|
||||
|
||||
const xAxis = svg.append('g')
|
||||
.attr('class', 'x axis')
|
||||
.attr('transform', `translate(0, ${height})`)
|
||||
.call(d3.axisBottom(xScale))
|
||||
.append('text')
|
||||
.attr('class', 'text')
|
||||
.attr('x', width / 2)
|
||||
.attr('y', 30)
|
||||
.attr('dy', '.75em')
|
||||
.style('text-anchor', 'middle')
|
||||
.text('Points')
|
||||
|
||||
const yAxis = svg.append('g')
|
||||
.attr('class', 'y axis')
|
||||
.call(d3.axisLeft(yScale))
|
||||
.append('text').attr('class', 'text')
|
||||
.style('text-anchor', 'end')
|
||||
.attr('class', 'text')
|
||||
.attr('y', -20)
|
||||
.text('Players')
|
||||
|
||||
const bars = svg.selectAll('.bar')
|
||||
.data(data)
|
||||
.enter().append('rect')
|
||||
.attr('class', 'bar')
|
||||
.style('fill', 'white')
|
||||
.style('fill-opacity', .2)
|
||||
.style('stroke', 'white')
|
||||
.style('stroke-width', 2)
|
||||
|
||||
bars.on('mouseover', function(d, i) {
|
||||
d3.select(this)
|
||||
.transition().duration(500)
|
||||
.style('fill-opacity', .75)
|
||||
})
|
||||
|
||||
bars.on('mouseout', function(d, i) {
|
||||
d3.select(this)
|
||||
.transition().duration(500)
|
||||
.style('fill-opacity', .2)
|
||||
})
|
||||
|
||||
bars
|
||||
.attr('x', 0)
|
||||
.attr('y', d => yScale(d.player))
|
||||
.attr('height', yScale.bandwidth())
|
||||
.transition().duration(250).delay((d, i) => i * 100)
|
||||
.attr('width', d => xScale(d.points))
|
||||
|
||||
const barText = svg.selectAll('.points')
|
||||
.data(data).enter().append('text')
|
||||
.attr('class', 'points text')
|
||||
.attr('x', d => xScale(d.points))
|
||||
.attr('dx', -30)
|
||||
.attr('y', d => yScale(d.player))
|
||||
.attr('dy', yScale.bandwidth() / 2 + 5)
|
||||
.text(d => d.points)
|
||||
.style('fill', 'white')
|
||||
.style('text-anchor', 'middle')
|
||||
.style('opacity', 0)
|
||||
.transition().duration(250).delay((d, i) => i * 100)
|
||||
.style('opacity', 1)
|
||||
|
||||
const title = svg.append('text')
|
||||
.attr('class', 'text')
|
||||
.attr('x', width / 2)
|
||||
.attr('y', -100)
|
||||
.style('text-anchor', 'middle')
|
||||
.style('text-decoration', 'underline')
|
||||
.style('fill', 'white')
|
||||
.text('Game 1 Final Scores')
|
||||
})
|
||||
57
public/js/stacked-circles.js
Normal file
57
public/js/stacked-circles.js
Normal file
@@ -0,0 +1,57 @@
|
||||
const width = 1000
|
||||
const height = 700
|
||||
|
||||
const svg = d3.select('body').style('margin', 0)
|
||||
.append('svg')
|
||||
.style('width', width)
|
||||
.style('height', height)
|
||||
|
||||
const data = Array(1000).fill().map(_ => {
|
||||
return {
|
||||
cx: Math.round(Math.random() * width),
|
||||
cy: Math.round(Math.random() * height)
|
||||
}
|
||||
});
|
||||
|
||||
const color = d3.scaleOrdinal(d3.schemeSet3)
|
||||
|
||||
const circles_1 = svg.selectAll('.circle_1')
|
||||
.data(data).enter()
|
||||
.append('circle')
|
||||
.attr('class', '.circle_1')
|
||||
.attr('cx', d => d.cx)
|
||||
.attr('cy', -10)
|
||||
.style('fill', 'none')
|
||||
.attr('r', 10)
|
||||
|
||||
circles_1.transition().duration(1000).delay((d, i) => i).ease(d3.easeElastic)
|
||||
.attr('cy', d => d.cy)
|
||||
.style('fill', (d, i) => color(i))
|
||||
|
||||
const circles_2 = svg.selectAll('.circle_2')
|
||||
.data(data).enter()
|
||||
.append('circle')
|
||||
.attr('class', '.circle_2')
|
||||
.attr('cx', d => d.cx)
|
||||
.attr('cy', -10)
|
||||
.style('stroke', 'none')
|
||||
.attr('r', 20)
|
||||
.style('fill', 'none')
|
||||
.style('stroke-width', 2)
|
||||
|
||||
circles_2.transition().duration(1000).delay((d, i) => i).ease(d3.easeElastic)
|
||||
.attr('cy', d => d.cy)
|
||||
.style('stroke', (d, i) => color(i))
|
||||
|
||||
|
||||
circles_1.on('click', function(d, i) {
|
||||
d3.select(this)
|
||||
.transition().duration(1000)
|
||||
.style('fill', 'red')
|
||||
})
|
||||
|
||||
circles_2.on('click', function(d, i) {
|
||||
d3.select(this)
|
||||
.transition().duration(1000)
|
||||
.style('stroke', 'red')
|
||||
})
|
||||
86
public/js/time-chart.js
Normal file
86
public/js/time-chart.js
Normal file
@@ -0,0 +1,86 @@
|
||||
const data = d3.csv('/data/timeScaleData.csv').then(data => {
|
||||
const margin = { top: 200, right: 200, bottom: 200, left: 200 }
|
||||
const width = window.innerWidth - margin.right - margin.left
|
||||
const height = window.innerHeight - margin.top - margin.bottom
|
||||
|
||||
const parseDate = d3.timeParse('%Y-%m-%d')
|
||||
const formatedData = data.map(d => { return {
|
||||
date: parseDate(d.date),
|
||||
value: +d.value
|
||||
}});
|
||||
|
||||
const div = d3.select('body')
|
||||
|
||||
const svg = div.append('svg')
|
||||
.attr('height', height + margin.top + margin.bottom)
|
||||
.attr('width', width + margin.left + margin.right)
|
||||
.append('g').attr('transform', `translate(${margin.left}, ${margin.bottom})`)
|
||||
|
||||
const xScale = d3.scaleTime()
|
||||
.domain(d3.extent(formatedData.map(d => d.date)))
|
||||
.range([0, width])
|
||||
|
||||
const yScale = d3.scaleLinear()
|
||||
.domain([0, d3.max(formatedData.map(d => d.value))])
|
||||
.range([height, 0])
|
||||
|
||||
const xAxis = svg.append('g')
|
||||
.attr('class', 'x axis')
|
||||
.attr('transform', `translate(0, ${height})`)
|
||||
.call(d3.axisBottom(xScale))
|
||||
|
||||
const yAxis = svg.append('g')
|
||||
.attr('class', 'y axis')
|
||||
.call(d3.axisLeft(yScale))
|
||||
.append('text')
|
||||
.attr('x', 0)
|
||||
.attr('y', -25)
|
||||
.text('Orders')
|
||||
|
||||
const title = svg.append('text')
|
||||
.attr('class', 'title')
|
||||
.attr('x', width / 2)
|
||||
.attr('y', -25)
|
||||
.text('Orders in 2019')
|
||||
|
||||
const line = d3.line()
|
||||
.x(d => xScale(d.date))
|
||||
.y(d => yScale(d.value))
|
||||
.curve(d3.curveCardinal)
|
||||
|
||||
svg.append('path')
|
||||
.datum(formatedData)
|
||||
.attr('class', 'line')
|
||||
.attr('d', line)
|
||||
.style('stroke', 'white')
|
||||
.style('fill', 'none')
|
||||
.style('stroke-width', 2)
|
||||
|
||||
const circles = svg.selectAll('.circle')
|
||||
.data(formatedData).enter().append('circle')
|
||||
.attr('class', 'circle')
|
||||
.attr('cx', d => xScale(d.date))
|
||||
.attr('cy', d => -400)
|
||||
.attr('r', '5')
|
||||
.style('fill', 'white')
|
||||
.style('stroke', 'rgb(51, 57, 68)')
|
||||
.style('stroke-width', 3)
|
||||
|
||||
circles.transition()
|
||||
.duration(1000)
|
||||
.delay((d, i) => xScale(d.date))
|
||||
.attr('cy', (d, i) => yScale(d.value))
|
||||
|
||||
circles.on('mouseover', function(d) {
|
||||
d3.select(this)
|
||||
.transition().duration(500)
|
||||
.attr('r', '10')
|
||||
})
|
||||
|
||||
circles.on('mouseout', function(d) {
|
||||
d3.select(this)
|
||||
.transition().duration(500)
|
||||
.attr('r', '5')
|
||||
})
|
||||
})
|
||||
|
||||
33
public/js/updated-circle.js
Normal file
33
public/js/updated-circle.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const width = window.innerWidth
|
||||
const height = window.innerHeight - 200
|
||||
const radius = Math.min(width, height) * .50
|
||||
|
||||
const svg = d3.select('body').append('svg')
|
||||
.attr('height', height)
|
||||
.attr('width', width)
|
||||
.append('g')
|
||||
|
||||
const update = (data) => {
|
||||
const circle = svg.selectAll('.circle').data(data)
|
||||
|
||||
circle.enter().append('circle')
|
||||
.merge(circle)
|
||||
.attr('class', 'circle')
|
||||
.attr('cx', (d, i) => (i + 1) * 350)
|
||||
.attr('cy', height / 2)
|
||||
.transition().duration(600)
|
||||
.attr('r', d => d)
|
||||
|
||||
circle.exit().remove()
|
||||
}
|
||||
|
||||
d3.interval(() => {
|
||||
update([
|
||||
d3.randomUniform(50, 300)(),
|
||||
d3.randomUniform(50, 300)(),
|
||||
d3.randomUniform(50, 300)(),
|
||||
d3.randomUniform(50, 300)()
|
||||
])
|
||||
}, 600)
|
||||
|
||||
|
||||
73
public/js/updating-bar-chart.js
Normal file
73
public/js/updating-bar-chart.js
Normal file
@@ -0,0 +1,73 @@
|
||||
const margin = { top: 100, right: 100, bottom: 100, left: 100 }
|
||||
const width = window.innerWidth - margin.left - margin.right
|
||||
const height = window.innerHeight - margin.bottom - margin.top
|
||||
|
||||
const svg = d3.select('body').append('svg')
|
||||
.attr('height', height + margin.left + margin.right)
|
||||
.attr('width', width + margin.bottom + margin.top)
|
||||
.append('g')
|
||||
.attr('transform', `translate(${margin.left}, ${margin.bottom})`)
|
||||
|
||||
const stores = ['Walmart', 'Sams Club', 'Target', 'Costco', 'BJs']
|
||||
const getData = () => stores.map((store) => {
|
||||
return {
|
||||
store: stores[Math.floor(Math.random() * stores.length)],
|
||||
profit: Math.round(d3.randomUniform(100000000)())
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const colorScale = d3.scaleOrdinal().domain(stores).range(d3.schemePastel2)
|
||||
const xScale = d3.scaleBand().rangeRound([0, width]).padding(.1)
|
||||
const yScale = d3.scaleLinear().range([height, 0])
|
||||
const xAxis = d3.axisBottom(xScale)
|
||||
const yAxis = d3.axisLeft(yScale)
|
||||
|
||||
svg.append('g').attr('class', 'x axis')
|
||||
.attr('transform', `translate(0, ${height})`)
|
||||
.append('text').attr('class', 'title')
|
||||
.attr('x', width / 2)
|
||||
.attr('y', 50)
|
||||
.text('Stores')
|
||||
|
||||
svg.append('g').attr('class', 'y axis')
|
||||
.append('text').attr('class', 'title')
|
||||
.attr('x', 0)
|
||||
.attr('y', -20)
|
||||
.text('Profit (USD)')
|
||||
|
||||
const update = (data) => {
|
||||
xScale.domain(data.map(d => d.store))
|
||||
yScale.domain([0, d3.max(data.map(d => d.profit))])
|
||||
|
||||
svg.select('.x.axis')
|
||||
.transition().duration(1000)
|
||||
.call(xAxis)
|
||||
|
||||
svg.select('.y.axis')
|
||||
.transition().duration(1000)
|
||||
.call(yAxis)
|
||||
|
||||
const bar = svg.selectAll('.bar').data(data)
|
||||
|
||||
bar.enter().append('rect')
|
||||
.merge(bar).attr('class', 'bar')
|
||||
|
||||
.attr('x', d => xScale(d.store))
|
||||
.attr('y', d => yScale(0))
|
||||
|
||||
.attr('width', xScale.bandwidth())
|
||||
.attr('height', 0)
|
||||
|
||||
.transition().duration(500)
|
||||
|
||||
.attr('y', d => yScale(d.profit))
|
||||
.attr('height', d => height - yScale(d.profit))
|
||||
|
||||
.attr('fill', d => colorScale(d.store))
|
||||
|
||||
bar.exit().remove()
|
||||
}
|
||||
|
||||
update(getData())
|
||||
d3.interval(() => update(getData()), 5000)
|
||||
49
public/js/updating-pie-chart.js
Normal file
49
public/js/updating-pie-chart.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const width = 800
|
||||
const height = 600
|
||||
|
||||
const radius = Math.min(width, height) / 2
|
||||
const colorScale = d3.scaleOrdinal(['#9b5de5', '#f15bb5', '#fee440', '#00bbf9', '#00f5d4'])
|
||||
|
||||
const svg = d3.select('body').append('svg')
|
||||
.attr('height', height)
|
||||
.attr('width', width)
|
||||
.append('g').attr('transform', `translate(${width / 2}, ${height / 2})`)
|
||||
|
||||
const pie = d3.pie().value(d => d).sort(null)
|
||||
const arc = d3.arc().outerRadius(radius * .75).innerRadius(0)
|
||||
|
||||
const data = [
|
||||
[2.380952380952381+ 16.666666666666664, 5.714285714285714, 8.095238095238095, 36.666666666666664, 30.476190476190478],
|
||||
[6.451612903225806+ 14.336917562724013, 11.469534050179211, 32.97491039426524, 21.863799283154123, 12.903225806451612],
|
||||
[5.405405405405405+ 13.127413127413126, 25.482625482625483, 15.444015444015443, 31.27413127413127, 9.266409266409266],
|
||||
[14.24802110817942+ 19.788918205804748, 16.62269129287599, 17.41424802110818, 12.66490765171504, 19.261213720316622],
|
||||
[12.558139534883722+ 10.930232558139535, 10.0, 22.790697674418606, 22.55813953488372, 21.16279069767442],
|
||||
[18.663594470046082+ 22.350230414746544, 23.04147465437788, 9.67741935483871, 17.972350230414747, 8.294930875576037],
|
||||
[21.38364779874214+ 21.38364779874214, 5.031446540880504, 30.81761006289308, 13.836477987421384, 7.547169811320755],
|
||||
[34.78260869565217+ 9.565217391304348, 38.69565217391304, 0.43478260869565216, 6.086956521739131, 10.434782608695652]
|
||||
]
|
||||
|
||||
function arcTween(a) {
|
||||
const i = d3.interpolate(this._current, a)
|
||||
this._current = i(1)
|
||||
return t => arc(i(t))
|
||||
}
|
||||
|
||||
const update = data => {
|
||||
const path = svg.selectAll('path').data(pie(data))
|
||||
path.transition().duration(700).attrTween('d', arcTween)
|
||||
|
||||
path.enter().append('path')
|
||||
.attr('class', 'arc')
|
||||
.attr('d', arc)
|
||||
.each(function(d) { this._current = d })
|
||||
.style('fill', (d, i) => colorScale(i))
|
||||
}
|
||||
|
||||
update(data[0])
|
||||
|
||||
let i = 1
|
||||
d3.interval(() => {
|
||||
update(data[i++])
|
||||
i %= data.length
|
||||
}, 1000)
|
||||
105
public/js/user-updating-bar-chart.js
Normal file
105
public/js/user-updating-bar-chart.js
Normal file
@@ -0,0 +1,105 @@
|
||||
const margin = { top: 100, right: 100, bottom: 100, left: 100 }
|
||||
const width = window.innerWidth - margin.left - margin.right
|
||||
const height = window.innerHeight - margin.bottom - margin.top
|
||||
|
||||
const svg = d3.select('body').append('svg')
|
||||
.attr('height', height + margin.left + margin.right)
|
||||
.attr('width', width + margin.bottom + margin.top)
|
||||
.append('g')
|
||||
.attr('transform', `translate(${margin.left}, ${margin.bottom})`)
|
||||
|
||||
const stores = ['Walmart', 'Sams Club', 'Target', 'Costco', 'BJs']
|
||||
const years = ['2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021']
|
||||
|
||||
const getData = () => {
|
||||
return new Array(5000).fill().map(_ => {
|
||||
return {
|
||||
store: stores[Math.floor(Math.random() * stores.length)],
|
||||
profit: Math.round(d3.randomUniform(100000000)()),
|
||||
year: years[Math.floor(Math.random() * years.length)],
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const filterDataByYear = data => year => data.filter(d => d.year === year)
|
||||
|
||||
const formatData = data => {
|
||||
const obj = data.reduce((acc, d) => {
|
||||
|
||||
if(!acc[d.store]) acc[d.store] = { profit: 0, year: d.year, store: d.store }
|
||||
acc[d.store].profit += d.profit
|
||||
|
||||
return acc
|
||||
|
||||
}, {})
|
||||
|
||||
return Object.values(obj)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const colorScale = d3.scaleOrdinal().domain(stores).range(d3.schemeCategory10)
|
||||
const xScale = d3.scaleBand().rangeRound([0, width]).padding(.1)
|
||||
const yScale = d3.scaleLinear().range([height, 0])
|
||||
const xAxis = d3.axisBottom(xScale)
|
||||
const yAxis = d3.axisLeft(yScale)
|
||||
|
||||
svg.append('g').attr('class', 'x axis')
|
||||
.attr('transform', `translate(0, ${height})`)
|
||||
.append('text').attr('class', 'title')
|
||||
.attr('x', width / 2)
|
||||
.attr('y', 50)
|
||||
.text('Stores')
|
||||
|
||||
svg.append('g').attr('class', 'y axis')
|
||||
.append('text').attr('class', 'title')
|
||||
.attr('x', 0)
|
||||
.attr('y', -20)
|
||||
.text('Profit (USD)')
|
||||
|
||||
const update = (data) => {
|
||||
xScale.domain(data.map(d => d.store))
|
||||
yScale.domain([0, d3.max(data.map(d => d.profit))])
|
||||
|
||||
svg.select('.x.axis')
|
||||
.transition().duration(1000)
|
||||
.call(xAxis)
|
||||
|
||||
svg.select('.y.axis')
|
||||
.transition().duration(1000)
|
||||
.call(yAxis)
|
||||
|
||||
const bar = svg.selectAll('.bar').data(data)
|
||||
|
||||
bar.enter().append('rect')
|
||||
.merge(bar).attr('class', 'bar')
|
||||
.attr('x', d => xScale(d.store))
|
||||
.attr('y', d => yScale(0))
|
||||
.attr('width', xScale.bandwidth())
|
||||
.attr('height', 0)
|
||||
.transition().duration(500)
|
||||
.attr('y', d => yScale(d.profit))
|
||||
.attr('height', d => height - yScale(d.profit))
|
||||
.attr('fill', d => colorScale(d.store))
|
||||
|
||||
bar.exit().remove()
|
||||
}
|
||||
|
||||
const select = d3.select('body')
|
||||
.append('select').attr('class', 'select')
|
||||
|
||||
const options = select.selectAll('option')
|
||||
.data(years).enter()
|
||||
.append('option').attr('class', 'option')
|
||||
.text(d => d)
|
||||
|
||||
const dataset = getData()
|
||||
const originalData = formatData(filterDataByYear(dataset)('2010'))
|
||||
update(originalData)
|
||||
|
||||
select.on('change', function(d, i) {
|
||||
const s = d3.select(this).node()
|
||||
const year = s.options[s.selectedIndex].textContent
|
||||
const updatedData = formatData(filterDataByYear(dataset)(year))
|
||||
update(updatedData)
|
||||
})
|
||||
Reference in New Issue
Block a user