Initial Commit

This commit is contained in:
2021-03-04 20:06:19 -03:00
commit 5d11cb56b8
47 changed files with 2639 additions and 0 deletions

View 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
View 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)
})

View 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
View 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
View 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
View File

52
public/js/montly-bills.js Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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')
})

View 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
View 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')
})
})

View 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)

View 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)

View 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)

View 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)
})