{
const svg = d3.create('svg')
.attr('width', 1200)
.attr('height', 900);
const race_graph = svg.append('g').attr('transform', 'translate(-350,0)');
let height = 250;
let radius = Math.min(width, height) / 2;
let margin = {top: 10, right: 10, bottom: 10, left: 10}
let colorScale = d3.scaleOrdinal(d3.schemeCategory10);
let totals = RaceYear.map((element) => element.value);
let grandTotal = totals.reduce((a, b) => a + b);
let arc = d3.arc()
.outerRadius(radius - 25)
.innerRadius(1.5);
let labelArc = d3.arc()
.outerRadius(radius - 60)
.innerRadius(radius - 60);
let pie = d3.pie()
.sort((a, b) => d3.ascending(a, b))
.value((d) => d.value)
.padAngle(0.01);
let arcGroup = race_graph.append("g")
.attr("class", "arc-group")
.attr("transform", `translate(${width/2 - margin.left - margin.right}, ${height/2 + margin.top + margin.bottom})`);
let arcs = arcGroup.selectAll(".arc")
.data(pie(RaceYear)).enter()
.append("g")
.attr("class", "arc");
arcs.append("path")
.attr("d", arc)
.style("fill", (d) => colorScale(d.data.name));
let legendPadding = 5;
let legendBox = race_graph.append("g")
.attr("class", "legend-group")
.attr("transform", `translate(${width/2+radius}, ${(3/4) * radius})`);
let legend = legendBox.selectAll(".legend")
.data(RaceYear).enter()
.append("g")
.attr("class", "legend")
.attr("transform", (d, i) => `translate(${0}, ${i * 20 + 20})`);
let displacement = "0.4em"
legend.append("circle")
.attr("class", "legend-color")
.attr("r", displacement)
.style("fill", (d) => colorScale(d.name));
legend.append("text")
.attr("class", "legend-text")
.attr("x", "1em")
.attr("y", displacement)
.style("font", "14px sans-serif")
.style("text-anchor", "start")
.text((d) => d.name);
arcs.append("text")
.attr("transform", (d) => `translate(${labelArc.centroid(d)})`)
.attr("dy", ".35em")
.style("font", "14px sans-serif")
.style("text-anchor", "middle")
.style("stroke", "white")
.style("stroke-width", "3px")
.style("opacity", 0.8)
.text((d, i) => `${((totals[i] / grandTotal) * 100).toFixed(2)}%`);
arcs.append("text")
.attr("transform", (d) => `translate(${labelArc.centroid(d)})`)
.attr("dy", ".35em")
.style("font", "14px sans-serif")
.style("text-anchor", "middle")
.text((d, i) => `${((totals[i] / grandTotal) * 100).toFixed(2)}%`);
race_graph.append("text")
.attr("x", width/2-25)
.attr("y", 30)
.style("text-anchor", "middle")
.style("font", "14px sans-serif")
.text("Race Distribution");
// flee pie
const flee_graph = svg.append('g').attr('transform', 'translate(0, 0)');
let colorScale2 = d3.scaleOrdinal(d3.schemeCategory10);
let totals2 = FleeYear.map((element) => element.value);
let grandTotal2 = totals2.reduce((a, b) => a + b);
let arc2 = d3.arc()
.outerRadius(radius - 25)
.innerRadius(1.5);
let labelArc2 = d3.arc()
.outerRadius(radius - 60)
.innerRadius(radius - 60);
let pie2 = d3.pie()
.sort((a, b) => d3.ascending(a, b))
.value((d) => d.value)
.padAngle(0.01);
let arcGroup2 = flee_graph.append("g")
.attr("class", "arc-group")
.attr("transform", `translate(${width/2 - margin.left - margin.right}, ${height/2 + margin.top + margin.bottom})`);
let arcs2 = arcGroup2.selectAll(".arc")
.data(pie(FleeYear)).enter()
.append("g")
.attr("class", "arc");
arcs2.append("path")
.attr("d", arc2)
.style("fill", (d) => colorScale2(d.data.name));
let legendPadding2 = 5;
let legendBox2 = flee_graph.append("g")
.attr("class", "legend-group")
.attr("transform", `translate(${width/2+radius}, ${(3/4) * radius})`);
let legend2 = legendBox2.selectAll(".legend")
.data(FleeYear).enter()
.append("g")
.attr("class", "legend")
.attr("transform", (d, i) => `translate(${0}, ${i * 20 + 20})`);
let displacement2 = "0.4em"
legend2.append("circle")
.attr("class", "legend-color")
.attr("r", displacement2)
.style("fill", (d) => colorScale2(d.name));
legend2.append("text")
.attr("class", "legend-text")
.attr("x", "1em")
.attr("y", displacement2)
.style("font", "14px sans-serif")
.style("text-anchor", "start")
.text((d) => d.name);
arcs2.append("text")
.attr("transform", (d) => `translate(${labelArc2.centroid(d)})`)
.attr("dy", ".35em")
.style("font", "14px sans-serif")
.style("text-anchor", "middle")
.style("stroke", "white")
.style("stroke-width", "3px")
.style("opacity", 0.8)
.text((d, i) => `${((totals2[i] / grandTotal2) * 100).toFixed(2)}%`);
arcs2.append("text")
.attr("transform", (d) => `translate(${labelArc2.centroid(d)})`)
.attr("dy", ".35em")
.style("font", "14px sans-serif")
.style("text-anchor", "middle")
.text((d, i) => `${((totals2[i] / grandTotal2) * 100).toFixed(2)}%`);
flee_graph.append("text")
.attr("x", width/2-25)
.attr("y", 30)
.style("text-anchor", "middle")
.style("font", "14px sans-serif")
.text("Flee Distribution");
// theat pie
const threat_graph = svg.append('g').attr('transform', 'translate(350,0)');
let colorScale3 = d3.scaleOrdinal(d3.schemeCategory10);
let totals3 = ThreatYear.map((element) => element.value);
let grandTotal3 = totals3.reduce((a, b) => a + b);
let arc3 = d3.arc()
.outerRadius(radius - 25)
.innerRadius(1.5);
let labelArc3 = d3.arc()
.outerRadius(radius - 60)
.innerRadius(radius - 60);
let pie3 = d3.pie()
.sort((a, b) => d3.ascending(a, b))
.value((d) => d.value)
.padAngle(0.01);
let arcGroup3 = threat_graph.append("g")
.attr("class", "arc-group")
.attr("transform", `translate(${width/2 - margin.left - margin.right}, ${height/2 + margin.top + margin.bottom})`);
let arcs3 = arcGroup3.selectAll(".arc")
.data(pie(ThreatYear)).enter()
.append("g")
.attr("class", "arc");
arcs3.append("path")
.attr("d", arc3)
.style("fill", (d) => colorScale3(d.data.name));
let legendPadding3 = 5;
let legendBox3 = threat_graph.append("g")
.attr("class", "legend-group")
.attr("transform", `translate(${width/2+radius}, ${(3/4) * radius})`);
let legend3 = legendBox3.selectAll(".legend")
.data(ThreatYear).enter()
.append("g")
.attr("class", "legend")
.attr("transform", (d, i) => `translate(${0}, ${i * 20 + 20})`);
let displacement3 = "0.4em"
legend3.append("circle")
.attr("class", "legend-color")
.attr("r", displacement3)
.style("fill", (d) => colorScale3(d.name));
legend3.append("text")
.attr("class", "legend-text")
.attr("x", "1em")
.attr("y", displacement3)
.style("font", "14px sans-serif")
.style("text-anchor", "start")
.text((d) => d.name);
arcs3.append("text")
.attr("transform", (d) => `translate(${labelArc3.centroid(d)})`)
.attr("dy", ".35em")
.style("font", "14px sans-serif")
.style("text-anchor", "middle")
.style("stroke", "white")
.style("stroke-width", "3px")
.style("opacity", 0.8)
.text((d, i) => `${((totals3[i] / grandTotal3) * 100).toFixed(2)}%`);
arcs3.append("text")
.attr("transform", (d) => `translate(${labelArc3.centroid(d)})`)
.attr("dy", ".35em")
.style("font", "14px sans-serif")
.style("text-anchor", "middle")
.text((d, i) => `${((totals3[i] / grandTotal3) * 100).toFixed(2)}%`);
threat_graph.append("text")
.attr("x", width/2 - 25)
.attr("y", 30)
.style("text-anchor", "middle")
.style("font", "14px sans-serif")
.text("Threat Level Distribution");
// gender bar
const gender_bar = svg.append("g")
.attr('transform', `translate(50, 250)`)
const gender_data = [{name:"Gender", male:GenderYear[0].number, female:GenderYear[1].number}]
const margin2 = {top:50, left:10, right:30, bottom:0}
const visWidth = 1000 - margin2.left - margin2.right
const visHeight = 130 - margin2.top - margin2.bottom
const y_scale = d3.scaleBand()
.domain(["Gender"])
.range([margin2.top ,visHeight])
.padding(0.3)
const male_scale = d3.scaleLinear()
.domain(d3.extent([0, 1000]))
.range([visWidth/2 + 65, visWidth])
const female_scale = d3.scaleLinear()
.domain(d3.extent([0, 1000]))
.range([visWidth/2 - 65, 0])
const male_Axis = d3.axisTop(male_scale)
.ticks(5)
const female_Axis = d3.axisTop(female_scale)
.ticks(5)
gender_bar.append('text')
.text("Female")
.attr('x', visWidth/4)
.attr('y', 20)
.attr('font-size', '12px')
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
gender_bar.append('text')
.text("Male")
.attr('x', visWidth/2 + visWidth/4)
.attr('y', 20)
.attr('font-size', '12px')
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
gender_bar.append('g')
.attr('transform', `translate(0,${margin2.top})`)
.call(male_Axis)
gender_bar.append('g')
.attr('transform', `translate(0,${margin2.top})`)
.call(female_Axis)
gender_bar.selectAll('.col')
.data(gender_data)
.join('g')
.append('text')
.text(d => d.name)
.attr('x', visWidth/2)
.attr('y', d => y_scale(d.name) + 3)
.attr('font-size', '12px')
.attr("text-anchor", "middle")
.attr("dominant-baseline", "hanging")
.attr("font-family", "sans-serif")
gender_bar.append("g")
.selectAll("rect")
.data(gender_data)
.join("rect")
.attr("fill", 'orange')
.attr("x", visWidth/2 + 65)
.attr("y", d => y_scale(d.name))
.attr("width", d => male_scale(d.male) - (visWidth/2 + 65))
.attr("height", y_scale.bandwidth());
gender_bar.append("g")
.selectAll("rect")
.data(gender_data)
.join("rect")
.attr("fill", 'steelblue')
.attr("x", d => female_scale(d.female))
.attr("y", d => y_scale(d.name))
.attr("width", d => (visWidth/2 -65) - female_scale(d.female))
.attr("height", y_scale.bandwidth());
gender_bar.append('line')
.attr('x1', visWidth/2 + 65)
.attr('y1', 50)
.attr('x2', visWidth/2 + 65)
.attr('y2', visHeight)
.attr('stroke', 'red')
.attr('stroke-opacity', 0.3)
gender_bar.append('line')
.attr('x1', visWidth/2 - 65)
.attr('y1', 50)
.attr('x2', visWidth/2 - 65)
.attr('y2', visHeight)
.attr('stroke', 'green')
.attr('stroke-opacity', 0.3)
// signs of mental illness
const mental_bar = svg.append("g")
.attr('transform', `translate(50, 350)`)
const mental_data = [{name:"Signs of Mental Illness", False:MentalYear[0].number, True:MentalYear[1].number}]
const yy_scale = d3.scaleBand()
.domain(["Signs of Mental Illness"])
.range([margin2.top ,visHeight])
.padding(0.3)
const true_scale = d3.scaleLinear()
.domain(d3.extent([0, 1000]))
.range([visWidth/2 + 65, visWidth])
const false_scale = d3.scaleLinear()
.domain(d3.extent([0, 1000]))
.range([visWidth/2 - 65, 0])
const false_Axis = d3.axisTop(false_scale)
.ticks(5)
const true_Axis = d3.axisTop(true_scale)
.ticks(5)
mental_bar.append('text')
.text("False")
.attr('x', visWidth/4)
.attr('y', 20)
.attr('font-size', '12px')
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
mental_bar.append('text')
.text("True")
.attr('x', visWidth/2 + visWidth/4)
.attr('y', 20)
.attr('font-size', '12px')
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
mental_bar.append('g')
.attr('transform', `translate(0,${margin2.top})`)
.call(false_Axis)
mental_bar.append('g')
.attr('transform', `translate(0,${margin2.top})`)
.call(true_Axis)
mental_bar.selectAll('.col')
.data(mental_data)
.join('g')
.append('text')
.text(d => d.name)
.attr('x', visWidth/2)
.attr('y', d => yy_scale(d.name) + 3)
.attr('font-size', '12px')
.attr("text-anchor", "middle")
.attr("dominant-baseline", "hanging")
.attr("font-family", "sans-serif")
mental_bar.append("g")
.selectAll("rect")
.data(mental_data)
.join("rect")
.attr("fill", 'orange')
.attr("x", visWidth/2 + 65)
.attr("y", d => yy_scale(d.name))
.attr("width", d => true_scale(d.True) - (visWidth/2 + 65))
.attr("height", yy_scale.bandwidth());
mental_bar.append("g")
.selectAll("rect")
.data(mental_data)
.join("rect")
.attr("fill", 'steelblue')
.attr("x", d => false_scale(d.False))
.attr("y", d => yy_scale(d.name))
.attr("width", d => (visWidth/2 -65) - false_scale(d.False))
.attr("height", yy_scale.bandwidth());
mental_bar.append('line')
.attr('x1', visWidth/2 + 65)
.attr('y1', 50)
.attr('x2', visWidth/2 + 65)
.attr('y2', visHeight)
.attr('stroke', 'red')
.attr('stroke-opacity', 0.3)
mental_bar.append('line')
.attr('x1', visWidth/2 - 65)
.attr('y1', 50)
.attr('x2', visWidth/2 - 65)
.attr('y2', visHeight)
.attr('stroke', 'green')
.attr('stroke-opacity', 0.3)
// body camera
const camera_bar = svg.append("g")
.attr('transform', `translate(50, 450)`)
const camera_data = [{name:"Body Camera", False: CameraYear[0].number, True:CameraYear[1].number}]
const yyy_scale = d3.scaleBand()
.domain(["Body Camera"])
.range([margin2.top ,visHeight])
.padding(0.3)
const true_scale2 = d3.scaleLinear()
.domain(d3.extent([0, 1000]))
.range([visWidth/2 + 65, visWidth])
const false_scale2 = d3.scaleLinear()
.domain(d3.extent([0, 1000]))
.range([visWidth/2 - 65, 0])
const false_Axis2 = d3.axisTop(false_scale2)
.ticks(5)
const true_Axis2 = d3.axisTop(true_scale2)
.ticks(5)
camera_bar.append('text')
.text("False")
.attr('x', visWidth/4)
.attr('y', 20)
.attr('font-size', '12px')
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
camera_bar.append('text')
.text("True")
.attr('x', visWidth/2 + visWidth/4)
.attr('y', 20)
.attr('font-size', '12px')
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
camera_bar.append('g')
.attr('transform', `translate(0,${margin2.top})`)
.call(false_Axis2)
camera_bar.append('g')
.attr('transform', `translate(0,${margin2.top})`)
.call(true_Axis2)
camera_bar.selectAll('.col')
.data(camera_data)
.join('g')
.append('text')
.text(d => d.name)
.attr('x', visWidth/2)
.attr('y', d => yyy_scale(d.name) + 3)
.attr('font-size', '12px')
.attr("text-anchor", "middle")
.attr("dominant-baseline", "hanging")
.attr("font-family", "sans-serif")
camera_bar.append("g")
.selectAll("rect")
.data(camera_data)
.join("rect")
.attr("fill", 'orange')
.attr("x", visWidth/2 + 65)
.attr("y", d => yyy_scale(d.name))
.attr("width", d => true_scale2(d.True) - (visWidth/2 + 65))
.attr("height", yyy_scale.bandwidth());
camera_bar.append("g")
.selectAll("rect")
.data(camera_data)
.join("rect")
.attr("fill", 'steelblue')
.attr("x", d => false_scale2(d.False))
.attr("y", d => yyy_scale(d.name))
.attr("width", d => (visWidth/2 -65) - false_scale2(d.False))
.attr("height", yyy_scale.bandwidth());
camera_bar.append('line')
.attr('x1', visWidth/2 + 65)
.attr('y1', 50)
.attr('x2', visWidth/2 + 65)
.attr('y2', visHeight)
.attr('stroke', 'red')
.attr('stroke-opacity', 0.3)
camera_bar.append('line')
.attr('x1', visWidth/2 - 65)
.attr('y1', 50)
.attr('x2', visWidth/2 - 65)
.attr('y2', visHeight)
.attr('stroke', 'green')
.attr('stroke-opacity', 0.3)
//age bar
const age_bar = svg.append("g")
.attr('transform', `translate(650,600)`);
// turn countryScale into a scalePoint
const age_ranges = AgeYear.map(d => d["age_range"])
const ageScaleBand = d3.scaleBand()
.domain(age_ranges)
// changed from [0, visHeight] to [0, visWidth]
.range([0, 300])
.padding(0.2)
// turn countryScale into a scalePoint
const age_range_scale = d3.scalePoint()
.domain(age_ranges)
// changed from [0, visHeight] to [0, visWidth]
.range([0, 300])
.padding(0.2)
const ageScale = d3.scaleLinear()
.domain([0, d3.max(AgeYear, d=> d.number)])
.nice() // make the domain start and end on round values
// changed from [0, visWidth] to [visHeight, 0]
.range([200, 0])
const agexAxis = d3.axisBottom(age_range_scale)
const ageyAxis = d3.axisLeft(ageScale).tickFormat(d3.format('~s'))
age_bar.append('text')
.attr('fill', 'black')
.attr('font-family', 'sans-serif')
.attr('x', 0)
.attr('y', -20)
.text("Age Distribution");
age_bar.selectAll('rect')
.data(AgeYear)
.join('rect')
.attr('x', d => ageScaleBand(d.age_range))
.attr('width', d => ageScaleBand.bandwidth())
.attr('y', d => ageScale(d.number))
.attr('height', d => 200 - ageScale(d.number))
.attr('fill', 'steelblue');
age_bar.append('g')
.call(ageyAxis);
age_bar.append('g')
.attr('transform', `translate(0, 200)`)
.call(d3.axisBottom(ageScaleBand))
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-55)")
.append('text')
.attr('fill', 'black')
.attr('font-family', 'sans-serif')
.attr('x', 100 / 2)
.attr('y', 40)
.text("age range");
// arm bar
const margin3 = {top: 10, bottom: 100, left: 75, right: 10}
const visWidth3 = 300
const visHeight3 = 200
const arms_graph = svg.append("g")
.attr('transform', `translate(100, 600)`);
arms_graph.append('text')
.attr('fill', 'black')
.attr('font-family', 'sans-serif')
.attr('x', 0)
.attr('y', -20)
.text("Arms Category");
arms_graph.selectAll('line')
.data(ArmsYear)
.join('line')
.attr('x1', d => ArmsScale(d.name))
.attr('x2', d => ArmsScale(d.name))
.attr('y1', d => arms_numberScale(d.value))
.attr('y2', d => visHeight3)
.attr('stroke', 'lightgray');
// bind our data to circles
arms_graph.selectAll('circle')
.data(ArmsYear)
.join('circle')
// countryScale sets the x position instead of y
.attr('cx', d => ArmsScale(d.name))
// populationScale gives y position
.attr('cy', d => arms_numberScale(d.value))
.attr('r', 5)
.attr('fill', 'steelblue');
const meanArmsNumber = d3.mean(ArmsYear, d => d.value);
arms_graph.append('line')
.attr('x1', 0)
.attr('x2', visWidth3)
.attr('y1', arms_numberScale(meanArmsNumber))
.attr('y2', arms_numberScale(meanArmsNumber))
.attr('stroke', 'red');
const yAxis3 = d3.axisLeft(arms_numberScale).tickFormat(d3.format('~s'))
arms_graph.append('g')
.call(yAxis3);
const xAxis3 = d3.axisBottom(ArmsScale)
arms_graph.append('g')
.attr('transform', `translate(0, ${visHeight3})`)
.call(xAxis3)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-55)")
.append('text')
.attr('fill', 'black')
.attr('font-family', 'sans-serif')
.attr('x', visWidth3 / 2)
.attr('y', 40)
.text("arms");
return svg.node();
}