Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save EllyLoel/ddb3553b7015fbdc72841799a53612fc to your computer and use it in GitHub Desktop.
Save EllyLoel/ddb3553b7015fbdc72841799a53612fc to your computer and use it in GitHub Desktop.
Accessible graph - improvement 8: extra improvements (D3.js)
<div class="chart">
<h1>Daily visitors</h1>
<p>The daily amount of unique visitors of <a href="fossheim.io">fossheim.io</a>, measured during the last week (11 May 2020 to 17 May 2020). Days where the visitor count was below your predefined threshold of 100 are highlighted.</p>
</div>
<svg width="0" height="0">
<defs>
<pattern id="dots" x="0" y="0" width="3" height="3" patternUnits="userSpaceOnUse">
<rect fill="#5D92F6" x="0" y="0" width="3" height="3"></rect>
<circle fill="#11419B" cx="1" cy="1" r="1">
</circle>
</pattern>
<pattern id="lines" x="0" y="0" width="3" height="3" patternUnits="userSpaceOnUse">
<rect fill="#F06B5A" x="0" y="0" width="3" height="3"></rect>
<rect fill="#B91919" x="0" y="0" width="3" height="1"></rect>
</pattern>
</defs>
</svg>
const data = [
{day: "Mon", visitors: 100},
{day: "Tue", visitors: 174},
{day: "Wed", visitors: 92},
{day: "Thu", visitors: 193},
{day: "Fri", visitors: 103},
{day: "Sat", visitors: 104},
{day: "Sun", visitors: 294}];
const margin = {left: 50, right: 50, top: 100, bottom: 50};
const width = 700 - margin.left - margin.right;
const height = 450 - margin.top - margin.bottom;
const chart = d3.select(".chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
const x = d3.scaleLinear().rangeRound([0, width]);
const y = d3.scaleLinear().rangeRound([0, height]);
const maxYValue = d3.max(data, row => row.visitors) || 10;
x.domain([0, data.length]);
y.domain([maxYValue + 10, 0]);
const legend = chart.append("g")
.attr("class", "legend")
.attr("aria-label", "Legend")
.attr("x", 0)
.attr("y", -margin.top);
legend.append("rect")
.attr("fill", "url(#dots)")
.attr("width", 13)
.attr("height", 13)
.attr("rx", 2)
.attr("x", margin.left / 2)
.attr("y", 0);
legend.append("text")
.text("Over 100 daily visitors")
.attr("x", margin.left / 2 + 20)
.attr("y", 10);
legend.append("rect")
.attr("fill", "url(#lines)")
.attr("width", 13)
.attr("height", 13)
.attr("rx", 2)
.attr("x", margin.left / 2)
.attr("y", 30);
legend.append("text")
.text("Under or equal to 100 daily visitors")
.attr("x", margin.left / 2 + 20)
.attr("y", 40);
const xLabel = chart.append("text");
xLabel.append("tspan")
.text("X Axis")
.attr("class", "xAxis")
.attr("text-anchor", "middle")
.attr("x", -width)
.attr("y", -height);
xLabel.append("tspan")
.text("Days of the week (11/05 to 17/05)")
.attr("class", "xAxis")
.attr("text-anchor", "middle")
.attr("x", (width + margin.left + margin.right) / 2)
.attr("y", height + margin.top + margin.bottom / 1.5);
const xTicks = chart.append("g")
.attr("aria-label", "Range of the X-axis");
xTicks.selectAll(".xTicks")
.data(data)
.enter().append("text")
.text((data) => data.day)
.attr("class", "xTicks")
.attr("x", function(row, index) { return x(index + 1) + 5; })
.attr("y", height + margin.top)
.attr("width", 30)
.attr("text-anchor", "middle");
const yLabel = chart.append("text")
.attr("transform", "rotate(-90)")
.attr("class", "yAxis");
yLabel.append("tspan")
.text("Y Axis")
.attr("x", -width)
.attr("y", -height);
yLabel.append("tspan")
.text("Amount of unique visitors")
.attr("text-anchor", "middle")
.attr("x", -height / 2 - margin.top )
.attr("y", margin.left / 2 + 5);
const yRange = [];
const topYValue = Math.ceil(maxYValue/100)*100;
for(var i = 0; i <= (topYValue / 100); i++) {
yRange.push(i * 100);
}
const yTicks = chart.append("g")
.attr("class", "yTicks")
.attr("aria-label", "Range of the Y-axis");
yTicks.selectAll(".tick")
.data(yRange)
.enter()
.append("text")
.text(row => row)
.attr("x", row => row >= 100 ? margin.left - 5 : margin.left + 5)
.attr("y", row => y(row) + margin.top - 13)
.attr("opacity", 0.75)
.attr("width", 30);
yTicks.selectAll(".line")
.data(yRange)
.enter()
.append("line")
.attr("x1", margin.left + 20)
.attr("x2", width + margin.left )
.attr("y1", row => y(row) + margin.top - 15)
.attr("y2", row => y(row) + margin.top - 15)
.attr("stroke", "#49456C")
.attr("stroke-width", 1)
.attr("opacity", 0.15);
/* const yTicks = chart.append("g")
.attr("transform", "translate(" + (margin.left + 20) + ", " + (margin.top - 15) + ")")
.attr("class", "yTicks")
.call(d3.axisLeft(y).ticks(5)); */
chart.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", row => row.visitors > 100 ? "bar" : "bar danger")
.attr("x", (row, index) => x(index + 1) )
.attr("y", row => y(row.visitors) + margin.top - 15)
.attr("width", 10)
.attr("height", row => height - y(row.visitors))
.attr("rx", 5);
const barLabels = chart.selectAll(".label")
.data(data)
.enter().append("text").attr("class","label");
barLabels.append("tspan")
.text(row => row.day)
.attr("text-anchor", "middle")
.attr("x", -width)
.attr("y", -height);
barLabels.append("tspan")
.text(row => row.visitors)
.attr("text-anchor", "middle")
.attr("x", (row, index) => x(index + 1) + 5)
.attr("y", row => y(row.visitors) + margin.top - 20);
body {
background-color: #F6F6FC;
font-family: sans-serif;
}
h1 {
margin-left: 1.5rem;
font-size: 1.25rem;
color: #110952;
}
p {
margin-left: 1.5rem;
padding-right: 1.5rem;
color: #49456C;
}
.chart {
width: 700px;
min-height: 450px;
margin: 60px auto 0 auto;
background-color: #fff;
border-radius: 10px;
box-shadow: 0 0 10px #D8D8E9;
padding: 20px;
}
text {
font-family: sans-serif;
font-size: 0.65rem;
fill: #49456C;
}
.bar {
fill: #5D92F6;
fill: url(#dots)
}
.bar.danger {
fill: #F06B5A;
fill: url(#lines);
}
.yTicks .domain, .yTicks .tick line {
opacity: 0;
}
.yTicks .tick text {
opacity: 0.75;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment