chart = {
let container = html`<div>`;
var svg = d3
.select(container)
.append("svg")
.attr("width", width)
.attr("height", chart_height + 100);
svg
.append("g")
.attr('id', 'x_axis_g')
.call(d3.axisTop(x).tickFormat(d3.format("d")));
svg.select('#x_axis_g').style('transform', 'translate(110px, 50px)');
let circles_count = svg
.append('g')
.style('transform', 'translate(110px, 50px)')
.attr('id', 'g_circles_count')
.selectAll('circle')
.data(places_counts)
.enter()
.append('circle')
.attr('class', 'circles_count')
.attr('cx', d => -circle_radius * (d.count / places_counts[0].count))
.attr('cy', d => y(d.place) + box_height / 2)
.attr('r', d => circle_radius * (d.count / places_counts[0].count))
.attr('fill', d => d3.interpolatePuBuGn(d.count / places_counts[0].count))
.append('title')
.text(d => d.count + ' classifications');
svg
.append("g")
.attr('id', 'y_axis_g')
.call(d3.axisLeft(y));
svg.select('#y_axis_g').style('transform', 'translate(110px, 50px)');
svg
.select('#y_axis_g')
.selectAll('.tick')
.select('text')
.style(
'transform',
`translate(0px, ${chart_height / places.length / 2}px)`
);
// Duplicate y ticks text - so we can add white outline behind
svg
.select('#y_axis_g')
.selectAll('.tick')
.select('text')
.attr('class', 'y_ticks_below')
.clone('deep')
.attr('class', 'y_ticks_above');
// Extend ticks to make gridlines
svg
.select('#y_axis_g')
.selectAll('.tick')
.select('line')
.attr('x1', chart_width)
.attr('stroke', 'lightgray');
// Extend y axis to cover the final tick
let path_d = svg
.select('#y_axis_g')
.select('path')
.attr('d')
.split('V');
let path_d_value = path_d[1].split('H');
svg
.select('#y_axis_g')
.select('path')
.attr(
'd',
path_d[0] +
"V" +
String(+path_d_value[0] + box_height) +
"H" +
path_d_value[1]
);
svg
.select('#x_axis_g')
.selectAll('.tick')
.select('line')
.attr('y1', chart_height)
.attr('stroke', 'lightgray');
// Add y axis label
svg
.append('text')
.text('Places ordered by classification count →')
.attr('x', 20)
.attr('y', 100)
.style('transform', 'translateX(120px) translatey(270px) rotate(90deg)')
.style('font-family', 'var(--sans-serif)')
.style('font-size', '13px');
let data_text = svg
.append('g')
.attr('id', 'data_text')
.style('transform', 'translate(110px, 50px)');
// Draw data
data_byPlace_top5_10yrStep.forEach(function(place_data, i) {
place_data.data_byYear.forEach(function(year_data, j) {
year_data.data.forEach(function(machine, k) {
data_text
.append('rect')
.attr('y', y(place_data.place) + (box_height / 5 - 2) * k)
.attr('width', machineCountRect_scale(machine.count))
.attr('height', box_height / 5)
.attr('x', x(year_data.x0))
.attr('fill', '#73FBD3');
data_text
.append('text')
.attr('y', y(place_data.place))
.attr('x', x(year_data.x0) + 1)
.attr('dy', (box_height / 5 - 2) * k + 10)
.text(
machine.machine.length > 18
? machine.machine.slice(0, 18).concat('…')
: machine.machine
)
.attr('font-family', 'var(--sans-serif)')
.attr('font-size', '11px')
.append('title')
.text(machine.machine + ": " + machine.count);
});
});
});
return container;
}