function generateChart(propertyType, mappedPropertyList, dataByProperty){
const maxTodoQty = d3.max(dataByProperty.map(t => t[1].length))
let svg = d3.create('svg')
.attr('width', width + margin.right)
.attr('height', height + margin.bottom)
const scaleX = d3.scaleBand()
.domain(mappedPropertyList.map(p => p.name).reverse())
.range([1, width])
.padding(0.1)
svg.append('g')
.call(d3.axisBottom(scaleX).tickSizeOuter(0))
.attr('transform', `translate(${margin.left}, ${height + margin.top})`)
const scaleY = d3.scaleLinear()
.domain([maxTodoQty, 0])
.range([ 0, height])
.nice()
svg.append('g')
.call(d3.axisLeft(scaleY).ticks(maxTodoQty).tickFormat(d3.format("d")))
.attr('transform', `translate(${margin.left}, ${margin.top})`);
const rectGroup = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
const allRect = rectGroup.selectAll('rect')
.data(dataByProperty)
.enter()
.append('rect')
.attr('height', d => height - scaleY(d[1].length))
.attr('width', scaleX.bandwidth())
.attr('x', d => {
const property = mappedPropertyList.find(p => p[`${propertyType}TypeId`] == d[0])
return scaleX(property.name)
})
.attr('y', d => scaleY(d[1].length))
.attr('fill', (d) => {
return colors[d[1][0].priorityTypeId]
})
const todoQty = svg.append("g")
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.attr("font-family", "sans-serif")
.attr("font-size", 14)
.attr("font-weight", "bold")
todoQty
.selectAll("text")
.data(dataByProperty)
.join("text")
.attr('x', d => {
const property = mappedPropertyList.find(p => p[`${propertyType}TypeId`] == d[0])
return scaleX(property.name) + scaleX.bandwidth()/2 - 3
})
.attr('y', d => {
const distanceFromTop = scaleY(d[1].length)
const rectHeight = height - distanceFromTop
return height - (rectHeight / 2)
})
.text(d => d[1].length)
.style('fill', 'black')
return svg.node()
}