-
Notifications
You must be signed in to change notification settings - Fork 0
/
app_linechart.js
127 lines (99 loc) · 3.26 KB
/
app_linechart.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
async function draw() {
// Data
const dataset = await d3.csv('data.csv')
const parseDate = d3.timeParse('%Y-%m-%d')
const xAccessor = d => parseDate(d.date)
const yAccessor = d => parseInt(d.close)
// Dimensions
let dimensions = {
width: 1000,
height: 500,
margins: 50,
};
dimensions.ctrWidth = dimensions.width - dimensions.margins * 2
dimensions.ctrHeight = dimensions.height - dimensions.margins * 2
// Draw Image
const svg = d3.select('#chart')
.append("svg")
.attr("width", dimensions.width)
.attr("height", dimensions.height)
const ctr = svg.append("g") // <g>
.attr(
"transform",
`translate(${dimensions.margins}, ${dimensions.margins})`
)
const tooltip = d3.select('#tooltip')
const tooltipDot = ctr.append('circle')
.attr('r',5)
.attr('fill', '#fc8781')
.attr('stroke','black')
.attr('stroke-width', 2)
.style('opacity', 0)
.style('pointer-events', 'none')
// Scales
const yScale = d3.scaleLinear()
.domain(d3.extent(dataset, yAccessor))
.range([dimensions.ctrHeight, 0])
.nice()
const xScale = d3.scaleUtc()
.domain(d3.extent(dataset, xAccessor))
.range([0, dimensions.ctrWidth])
// console.log(xScale(xAccessor(dataset[0])), dataset[0])
const lineGenerator = d3.line()
.x((d) => xScale(xAccessor(d)))
.y((d) => yScale(yAccessor(d)))
//console.log(lineGenerator(dataset))
ctr.append('path')
.datum(dataset)
.attr('d', lineGenerator)
.attr('fill', 'none')
.attr('stroke', '#30475e')
.attr('stroke-width', 2)
// Axis
const yAxis = d3.axisLeft(yScale)
.tickFormat((d) => `$${d}`)
ctr.append('g')
.call(yAxis)
const xAxis = d3.axisBottom(xScale)
ctr.append('g')
.style('transform', `translateY(${dimensions.ctrHeight}px)`)
.call(xAxis)
// Tooltip
ctr.append('rect')
.attr('width', dimensions.ctrWidth)
.attr('height', dimensions.ctrHeight)
.style('opacity', 0)
.on('touchmouse mousemove', function(event)
{
const mousePos = d3.pointer(event, this)
const date = xScale.invert(mousePos[0])
//console.log(mousePos)
//console.log(date)
//const index = d3.bisect(dataset, date)
//console.log(index)
// Costom Bisector - left, center, right
const bisector = d3.bisector(xAccessor).left
const index = bisector(dataset, date)
const stock = dataset[index-1]
//console.log(stock)
// Update Image
tooltipDot.style('opacity', 1)
.attr('cx', xScale(xAccessor(stock)))
.attr('cy', yScale(yAccessor(stock)))
.raise()
tooltip.style('display', 'block')
.style('top', yScale(yAccessor(stock))- 20 + 'px')
.style('left', xScale(xAccessor(stock)) + "px")
tooltip.select('.price')
.text(`$${yAccessor(stock)}`)
const dateFormatter = d3.timeFormat('%B %-d, %Y')
tooltip.select('.date')
.text(`${dateFormatter(xAccessor(stock))}`)
})
.on('mouseleave', function(event)
{
tooltipDot.style('opacity', 0)
tooltip.style('display', 'none')
})
}
draw()