chartSlope_v4 = {
const svg = d3.create('svg')
.attr('height', height)
.attr('width', width)
.style('font-family', 'sans-serif')
.style('font-size', 12)
const threshhold = 70;
const green = '#689F38'
const red = '#B71C1C'
const gray = 'lightgray'
const c = d3.scaleOrdinal()
.domain([true, false, null])
.range([green, red, gray]);
const planet_outer_radius = (Math.min(width, height) / 2) ;
const planet_inner_radius = planet_outer_radius * 0.65;
const donut_outer_radius = planet_inner_radius;
const donut_inner_radius = donut_outer_radius * 0.6;
const donut_center_radius = (donut_outer_radius + donut_inner_radius) / 2;
const human_outer_radius = donut_inner_radius;
const human_inner_radius = human_outer_radius * 0.0;
const stroke_width = 14;
const donut_donut = svg.append('g')
.attr('transform', `translate(${width/2},${height/2})`)
donut_donut.append("circle")
.attr('r', donut_center_radius)
.attr('fill', 'transparent')
.attr('stroke', 'transparent')
.attr('stroke-width', (donut_outer_radius - donut_inner_radius));
const ceilingRadius = donut_outer_radius - stroke_width/2;
const ceilingStroke = donut_donut.append("circle")
.attr('id', 'ecological_ceiling')
.attr('r', ceilingRadius)
.attr('fill', 'transparent')
.attr('stroke', green)
.attr('stroke-width', stroke_width);
const labelFontSize = 12;
const labelHeight = labelFontSize * 0.7;
const ceilingTextRadius = ceilingRadius - 0.5 * labelHeight;
donut_donut.append("path")
.attr('id', 'eco_ceiling_curve')
.attr('d', `M-${ceilingTextRadius},0 A${ceilingTextRadius},${ceilingTextRadius} 0 0,1 ${ceilingTextRadius},0`)
.attr('fill', 'none')
.attr('opacity', 0.3)
donut_donut.append("text")
.attr('font-family', 'sans-serif')
.attr('font-size', labelFontSize)
.attr('fill', 'white')
.append("textPath")
.attr('xlink:href', '#eco_ceiling_curve')
.text("ECOLOGICAL CEILING")
.attr('text-anchor', 'middle')
.attr('startOffset', '50%')
const socialRadius = donut_inner_radius + stroke_width/2;
const socialStroke = donut_donut.append("circle")
.attr('id', 'social_foundation')
.attr('r', socialRadius)
.attr('fill', 'transparent')
.attr('stroke', green)
.attr('stroke-width', stroke_width);
const socialTextRadius = socialRadius - 0.5 * labelHeight;
donut_donut.append("path")
.attr('id', 'social_foundation_curve')
.attr('d', `M-${socialTextRadius},0 A${socialTextRadius},${socialTextRadius} 0 0,1 ${socialTextRadius},0`)
.attr('fill', 'transparent')
.attr('opacity', 0.3)
donut_donut.append("text")
.attr('font-family', 'sans-serif')
.attr('font-size', labelFontSize)
.attr('fill', 'white')
.append("textPath")
.attr('xlink:href', '#social_foundation_curve')
.text("SOCIAL FOUNDATION")
.attr('text-anchor', 'middle')
.attr('startOffset', '50%')
const planet_outsideDonut_scale = d3.scaleLinear()
.domain([threshhold-1, 0])
.range([planet_inner_radius, planet_outer_radius]);
const human_outsideDonut_scale = d3.scaleLinear()
.domain([0, threshhold])
.range([human_inner_radius, human_outer_radius - 1]);
const planet_insideDonut_arc = d3.arc()
.innerRadius(donut_center_radius + 1)
.outerRadius(donut_outer_radius - stroke_width + 1)
.padRadius(0.5 * planet_outer_radius)
.padAngle(2/(0.65 * planet_outer_radius))
.cornerRadius(0)
const planet_outsideDonut_arc = d3.arc()
.innerRadius(planet_inner_radius)
.outerRadius(d => planet_outsideDonut_scale(d.data.percentage === null ? 0 : d.data.percentage))
.padRadius(0.5 * planet_outer_radius)
.padAngle(2/(0.65 * planet_outer_radius))
.cornerRadius(0)
const human_insideDonut_arc = d3.arc()
.innerRadius(donut_inner_radius + stroke_width - 1)
.outerRadius(donut_center_radius - 1)
.padRadius(0.5 * planet_outer_radius)
.padAngle(2/(0.65 * planet_outer_radius))
.cornerRadius(0)
const human_outsideDonut_arc = d3.arc()
.innerRadius(d => human_outsideDonut_scale(d.data.percentage === null? 0 : d.data.percentage))
.outerRadius(human_outer_radius)
.padRadius(0.5 * planet_outer_radius)
.padAngle(2/(0.65 * planet_outer_radius))
.cornerRadius(0)
const planet_pie = d3.pie()
.padAngle(0.00)
.sort(null)
.value(1)
const human_pie = d3.pie()
.padAngle(0.00)
.sort(null)
.value(1)
const planet_data = data_new.filter(d => d.inner_or_outer == "Outer");
const human_data = data_new.filter(d => d.inner_or_outer == "Inner");
const planet_arcs = planet_pie(planet_data);
const human_arcs = human_pie(human_data);
const planet_donut = svg.append('g')
.attr('transform', `translate(${width/2},${height/2})`)
const human_donut = svg.append('g')
.attr('transform', `translate(${width/2},${height/2})`)
planet_donut.selectAll('path')
.data(planet_arcs)
.join('path')
.attr('fill', d => c(d.data.percentage === null ? null : d.data.percentage >= threshhold))
.attr('d', d => d.data.percentage === null ? planet_outsideDonut_arc(d) :
d.data.percentage >= threshhold ? planet_insideDonut_arc(d) : planet_outsideDonut_arc(d))
.append('title')
.text(d => `Ecological: ${d.data.category} at ${d.data.percentage}%`);
human_donut.selectAll('path')
.data(human_arcs)
.join('path')
.attr('fill', d => c(d.data.percentage === null ? null : d.data.percentage >= threshhold))
.attr('d', d => d.data.percentage === null ? human_outsideDonut_arc(d) :
d.data.percentage >= threshhold ? human_insideDonut_arc(d) : human_outsideDonut_arc(d))
.append('title')
.text(d => `Social: ${d.data.category} at ${d.data.percentage}%`);
const planet_default_text_arc = d3.arc()
.innerRadius(planet_inner_radius)
.outerRadius(planet_outer_radius)
.padRadius(0.5 * planet_outer_radius)
.padAngle(2/(0.65 * planet_outer_radius))
.cornerRadius(0)
planet_donut.append('g')
.attr('font-family', 'sans-serif')
.attr('font-size', 12)
.attr('text-anchor', 'middle')
.selectAll('text')
.data(planet_arcs)
.join('text')
.attr('transform', d => `translate(${planet_default_text_arc.centroid(d)})`)
.call(text => text.append('tspan')
.attr('y', '-0.4em')
.attr('font-weight', 'bold')
.text(d => d.data.category))
.call(text => text.filter(d => (d.endAngle - d.startAngle) > 0.25).append('tspan')
.attr('x', 0)
.attr('y', '0.7em')
.attr('fill-opacity', 0.7)
.text(d => d.data.percentage === null ? "no data" : d.data.percentage.toLocaleString() + "%"));
const human_text_radius = donut_inner_radius + stroke_width + 3;
const human_text_arc = d3.arc()
.innerRadius(human_text_radius)
.outerRadius(human_text_radius)
const human_donut_text = svg.append('g')
.attr('transform', `translate(${width/2},${height/2})`)
human_donut_text.selectAll('path')
.data(human_arcs)
.join('path')
.attr('id', function(d,i) {return "humanTextArc_"+i;})
.attr('fill', 'none')
.attr('d', human_text_arc)
human_donut_text.append('g')
.attr('font-family', 'sans-serif')
.attr('font-size', 12)
.selectAll('text')
.data(human_arcs)
.join('text')
.append('textPath')
.attr('xlink:href', function(d,i){return "#humanTextArc_"+i;})
.attr('text-anchor', 'middle')
.attr('startOffset', '25%')
.call(text => text.append('tspan')
.attr('font-weight', 'bold')
.text(d => d.data.category + " " +
(d.data.percentage === null ? "no data" : d.data.percentage.toLocaleString() + "%")))
return svg.node()
}