|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<meta name="viewport" content="width=device-width"> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<title>Radial User Prototype</title> |
|
<style> |
|
body { |
|
margin: 0px; |
|
} |
|
.domain { |
|
display: none; |
|
} |
|
.tick line { |
|
stroke: #C0C0BB; |
|
stroke-width: 1; |
|
} |
|
.tick text { |
|
fill: #8E8883; |
|
font-size: 10pt; |
|
font-family: sans-serif; |
|
} |
|
.axis-label { |
|
fill: #635F5D; |
|
font-size: 12pt; |
|
font-family: sans-serif; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<svg width="700" height="500"></svg> |
|
<script> |
|
|
|
|
|
const xValue = d => d.dteday; |
|
const xLabel = 'Date'; |
|
const y1Value = d => d.registered; |
|
const y2Value = d => d.casual; |
|
const y3Value = d => d.atemp; |
|
const yLabel = 'Bike Share Users'; |
|
const yLabelRight = 'Apparent Temperature'; |
|
const margin = { left: 60, right: 60, top: 60, bottom: 60 }; |
|
|
|
const svg = d3.select('svg'); |
|
const width = svg.attr('width'); |
|
const height = svg.attr('height'); |
|
const innerWidth = width - margin.left - margin.right; |
|
const innerHeight = height - margin.top - margin.bottom; |
|
yAxis2Position = innerWidth |
|
|
|
const g = svg.append('g') |
|
.attr('transform', `translate(${innerWidth/2+margin.left},${innerHeight/2+margin.top})`); |
|
const xAxisG = g.append('g') |
|
.attr('transform', `translate(0, ${innerHeight})`); |
|
const yAxisG = g.append('g'); |
|
|
|
function tickEndPoint(angle,radius){ |
|
x = radius * Math.cos(angle) |
|
y = radius * Math.sin(angle) |
|
return [x,y]}; |
|
|
|
const tickAngles = function(numberOfTicks){ |
|
let tickAngles = [] |
|
console.log(numberOfTicks) |
|
for(i=0; i<numberOfTicks; i++){ |
|
console.log(i/numberOfTicks) |
|
console.log(Math.PI *2) |
|
angle = Math.PI *2 * i/numberOfTicks |
|
console.log(angle) |
|
tickAngles.push(angle) } |
|
return tickAngles}; |
|
|
|
|
|
function tickCoordinates(numberOfTicks,tickRadius){ |
|
let tickAngle = tickAngles(numberOfTicks) |
|
let xTickArray =[] |
|
for (i = 0; i <tickAngle.length; i++){ |
|
xy = tickEndPoint(tickAngle[i],tickRadius) |
|
xTickArray.push(xy) |
|
} |
|
return xTickArray |
|
}; |
|
let numTicks =12; |
|
let t = tickAngles(numTicks); |
|
let yScaleMax = innerHeight/2; |
|
let xTickLength = yScaleMax *1.05; |
|
let xTickArray = tickCoordinates (numTicks,xTickLength) |
|
|
|
console.log(t) |
|
console.log(xTickArray) |
|
|
|
|
|
yTicks = [.25,.5,.75,1]; |
|
|
|
for (i in yTicks){ |
|
g.append('circle') |
|
.attr('cx',0) |
|
.attr('cy',0) |
|
.attr('fill', 'none') |
|
.attr('stroke', 'lightgrey') |
|
.attr('stroke-width', 1) |
|
.attr('r', yScaleMax * yTicks[i]) |
|
}; |
|
|
|
|
|
xTickLabel = ['Jan','Feb', 'Mar', |
|
'Apr','May','Jun', |
|
'Jul','Aug','Sep', |
|
'Oct','Nov','Dec']; |
|
|
|
for (i in xTickArray){ |
|
g.append('line') |
|
.attr('x1',0) |
|
.attr('y1',0) |
|
.attr('x2',xTickArray[i][0]) |
|
.attr('y2',xTickArray[i][1]) |
|
.attr('fill', 'none') |
|
.attr('stroke', 'lightgrey') |
|
.attr('stroke-width', 1); |
|
g.append('text') |
|
.attr('class', "tick text") |
|
.text("xtick") |
|
.attr('text-anchor', 'middle') |
|
.attr("x", xTickArray[i][0]) |
|
.attr("y",xTickArray[i][1]) |
|
.attr('transform',`rotate(${90+(t[i])*360/(2*Math.PI)},${xTickArray[i][0]},${xTickArray[i][1]})`) |
|
.attr('font-family', 'sans-serif') |
|
.attr('fill',"grey") |
|
.attr('font-size', 11) |
|
.text(xTickLabel[i]) |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const xScale = d3.scaleTime(); |
|
const yScaleLeft = d3.scaleLinear(); |
|
|
|
|
|
|
|
function deltaDays(date1, date2){ |
|
const dayms = 1000 * 60 * 60 * 24; |
|
var date1ms = date1.geTime(); |
|
var date2ms = date2.getTime(); |
|
var deltams = date1ms-date2ms |
|
return (deltams/dayms) |
|
}; |
|
|
|
const minDate = new Date(2012,1,1) |
|
const offset = innerHeight/2; |
|
//getting a |
|
//const days = d => deltaDays(d.dteday,minDate); |
|
|
|
const days = d =>(d.dteday.getTime()/(1000*60*60*24)) |
|
const angleDays = d => (days(d)/365 *Math.PI*2); |
|
const radialScale = d => (innerHeight/2* d.cnt/maxUser.Total); |
|
|
|
const radialScale1 = d => (innerHeight/2* d.casual/8000); |
|
const radialScale2 = d => (innerHeight/2* d.registered/8000); |
|
const radialX = d => (radialScale(d) * Math.cos(theta(d))+offset); |
|
const radialY = d => (radialScale(d) * Math.sin(theta(d))+offset); |
|
|
|
|
|
const curveFunction = d3.curveCatmullRom; |
|
const radialPath = d3.lineRadial() |
|
.angle(d => angleDays(d)) |
|
.radius(d => radialScale2(d)) |
|
.curve(curveFunction); |
|
|
|
var parseTime = d3.timeParse("%Y-$m-%d"); |
|
const row = d => { |
|
d.dteday = new Date(d.dteday); |
|
d.season = +d.season; |
|
d.yr = +d.yr; |
|
d.mnth = +d.mnth; |
|
d.holiday = +d.holiday; |
|
d.weekday = +d.weekday; |
|
d.workingday = +d.workingday; |
|
d.weathersit = +d.weathersit; |
|
d.temp = +d.temp; |
|
d.atemp = +d.atemp; |
|
d.hum = +d.hum; |
|
d.windspeed = +d.windspeed; |
|
d.casual = +d.casual; |
|
d.registered = +d.registered; |
|
d.cnt = +d.cnt; |
|
return d; |
|
}; |
|
|
|
|
|
d3.csv('day.csv', row, data => { |
|
|
|
|
|
|
|
|
|
g.append('path') |
|
.attr('fill', 'none') |
|
.attr('stroke', 'green') |
|
.attr('stroke-width', 2) |
|
.attr('d', radialPath(data)); |
|
|
|
|
|
|
|
|
|
|
|
}); |
|
</script> |
|
</body> |
|
</html> |