Skip to content

Commit 533aff5

Browse files
Add files via upload
updated tooltip
1 parent b7335d6 commit 533aff5

1 file changed

Lines changed: 82 additions & 34 deletions

File tree

main.js

Lines changed: 82 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,116 @@
1-
// Data
1+
// Data
22
let data = [
33
{ gender: 'Female', 'Physical Activity': 2.43, 'Study Time': 4.49, 'Screen Time': 6.44, 'Sleep': 7.31 },
4-
{ gender: 'Male', 'Physical Activity': 3.05, 'Study Time': 4.58, 'Screen Time': 8.5, 'Sleep': 7.14 }
5-
];
4+
{ gender: 'Male', 'Physical Activity': 3.05, 'Study Time': 4.58, 'Screen Time': 8.5, 'Sleep': 7.14 }
5+
];
6+
7+
const keys = ['Physical Activity', 'Study Time', 'Screen Time', 'Sleep'];
8+
const colors = ['#dbdb8d', '#aec7e8', '#ff9896', '#ffbb78'];
9+
10+
let width = 600,
11+
height = 400;
12+
13+
let margin = { top: 50, bottom: 60, left: 60, right: 160 };
14+
15+
let svg = d3.select('body')
16+
.append('svg')
17+
.attr('width', width)
18+
.attr('height', height);
619

7-
const keys = ['Physical Activity', 'Study Time', 'Screen Time', 'Sleep'];
8-
const colors = ['#dbdb8d', '#aec7e8', '#ff9896', '#ffbb78'];
9-
let width = 600,
10-
height = 400;
11-
let margin = { top: 50, bottom: 60, left: 60, right: 160 };
12-
let svg = d3.select('#chart')
13-
.append('svg')
14-
.attr('width', width)
15-
.attr('height', height);
16-
let stack = d3.stack().keys(keys);
17-
let series = stack(data);
18-
let maxVal = d3.max(series, s => d3.max(s, d => d[1]));
19-
let yScale = d3.scaleLinear()
20+
let tooltip = d3.select('body')
21+
.append('div')
22+
.style('position', 'absolute')
23+
.style('background', 'rgba(0,0,0,0.75)')
24+
.style('color', '#fff')
25+
.style('padding', '8px 12px')
26+
.style('font-size', '13px')
27+
.style('pointer-events', 'none')
28+
.style('opacity', 0);
29+
30+
let stack = d3.stack().keys(keys);
31+
let series = stack(data);
32+
33+
let maxVal = d3.max(series, s => d3.max(s, d => d[1]));
34+
35+
let yScale = d3.scaleLinear()
2036
.domain([0, Math.ceil(maxVal)])
2137
.range([height - margin.bottom, margin.top]);
22-
let xScale = d3.scaleBand()
38+
39+
let xScale = d3.scaleBand()
2340
.domain(data.map(d => d.gender))
2441
.range([margin.left, width - margin.right])
2542
.padding(0.35);
2643

27-
let yAxis = svg.append('g')
44+
let yAxis = svg.append('g')
2845
.call(d3.axisLeft(yScale).ticks(6))
2946
.attr('transform', `translate(${margin.left}, 0)`);
30-
let xAxis = svg.append('g')
47+
48+
let xAxis = svg.append('g')
3149
.call(d3.axisBottom(xScale).tickSize(0))
3250
.attr('transform', `translate(0, ${height - margin.bottom})`);
33-
34-
// Input axis labels
35-
svg.append('text')
51+
52+
// Input axis labels
53+
svg.append('text')
3654
.attr('x', -(height / 2))
3755
.attr('y', 18)
3856
.attr('transform', 'rotate(-90)')
3957
.attr('text-anchor', 'middle')
4058
.text('Average hours per day');
41-
svg.append('text')
59+
60+
svg.append('text')
4261
.attr('x', margin.left + (width - margin.left - margin.right) / 2)
4362
.attr('y', height - 10)
4463
.attr('text-anchor', 'middle')
45-
.text('Gender');
46-
let groups = svg.selectAll('g.series')
64+
.text('Sex');
65+
66+
let groups = svg.selectAll('g.series')
4767
.data(series)
4868
.enter()
4969
.append('g')
5070
.attr('class', 'series')
5171
.attr('fill', (d, i) => colors[i]);
52-
groups.selectAll('rect')
72+
73+
groups.selectAll('rect')
5374
.data(d => d)
5475
.enter()
5576
.append('rect')
56-
.attr('x', d => xScale(d.data.gender))
57-
.attr('y', d => yScale(d[1]))
58-
.attr('width', xScale.bandwidth())
59-
.attr('height', d => yScale(d[0]) - yScale(d[1]));
77+
.attr('x', d => xScale(d.data.gender))
78+
.attr('y', d => yScale(d[1]))
79+
.attr('width', xScale.bandwidth())
80+
.attr('height', d => yScale(d[0]) - yScale(d[1]))
81+
.style('cursor', 'pointer')
82+
.on('mouseover', function(event, d) {
83+
const key = d3.select(this.parentNode).datum().key;
84+
const rawVal = d.data[key];
85+
const total = keys.reduce((sum, k) => sum + d.data[k], 0);
86+
const pct = ((rawVal / total) * 100).toFixed(1);
87+
88+
tooltip
89+
.style('opacity', 1)
90+
.html(`
91+
<strong>${d.data.gender}</strong><br/>
92+
<span style="color:#ccc">${key}</span><br/>
93+
${rawVal.toFixed(2)} hrs &nbsp;|&nbsp; ${pct}%
94+
`);
6095

61-
// Create the legend
62-
let legend = svg.append('g')
96+
d3.select(this).style('filter', 'brightness(1.2)');
97+
})
98+
.on('mousemove', function(event) {
99+
tooltip
100+
.style('left', (event.pageX + 14) + 'px')
101+
.style('top', (event.pageY - 36) + 'px');
102+
})
103+
.on('mouseout', function() {
104+
tooltip.style('opacity', 0);
105+
d3.select(this).style('filter', null);
106+
});
107+
108+
// Create the legend
109+
let legend = svg.append('g')
63110
.attr('transform', `translate(${width - margin.right + 16}, ${margin.top})`);
64-
keys.forEach((key, i) => {
111+
112+
keys.forEach((key, i) => {
65113
let row = legend.append('g').attr('transform', `translate(0, ${i * 24})`);
66114
row.append('rect').attr('width', 12).attr('height', 12).attr('fill', colors[i]);
67115
row.append('text').attr('x', 18).attr('y', 10).style('font-size', '12px').text(key);
68-
})
116+
});

0 commit comments

Comments
 (0)