Public
Edited
Feb 9, 2023
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Define intersection points

// Default behavior:
// Each point defined here gets droplines and a circle (open circle if isPrimary = false)
// The droplines will take the color of the first label in the labels array.
// the first label in labels will define the color of the horizontal dropline
// the second label in labels will define the color of the vertical dropline

intersectionPoints = [
{
labels: ["MP curve", "IS curve"],
isPrimary: true,
drawHorizontalDropline: false,
drawVerticalDropline: true,
verticalLabelOffset: [0, 0],
verticalLabelColor: 'black',
horizontalLabelOffset: [0, 0],
verticalLabelFormat: ".2%",
horizontalLabelFormat: ".1%",
horizontalLabelColor: colors.supplyRed
}
];
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function appendIntersectionObjects(isAwayFromOrigin = false) {


if (isAwayFromOrigin) {
d3.select('circle.staticIntersection').raise();
d3.selectAll("text.staticIntersection").remove();
const tempX = d3.select("circle.staticIntersection").attr("cx")
const tempY = d3.select("circle.staticIntersection").attr("cy")
svg.append('text')
.classed("staticIntersection", true)
.attr('x', tempX )
.attr('y', tempY)
.style('fill', 'gray')
.style('text-shadow', textShadow)
.style("font-size", 14)
// .style("font-weight", 'bold')
.text("Old equilibrium");

}

// remove last objects before appending updated objects
svg.selectAll("circle.intersection").remove();
svg.selectAll("line.hDrop").remove();
svg.selectAll("line.vDrop").remove();
svg.selectAll('text.vDropLabel').remove();
svg.selectAll('text.hDropLabel').remove();


intersectionPoints.map( pair => {

// Guard: in bounds
const point = intersectLines(getLineByLabel(pair.labels[0]), getLineByLabel(pair.labels[1]));

if (point.x >= xAxisScale.domain[0] && point.x <= xAxisScale.domain[1] &&
point.y >= yAxisScale.domain[0] && point.y <= yAxisScale.domain[1])
{
// TODO: enable styling with CSS
// moving vertical drop line
if (pair.drawVerticalDropline) {
svg.append("line")
.classed('vDrop', true)
.style('stroke-width', dropLines.width)
.style('stroke-dasharray', dropLines.dashCSS)
.style('stroke', 'black')
.attr("x1", xScale(point.x)).attr("y1", height - margin.bottom)
.attr("x2", xScale(point.x)).attr("y2", yScale(point.y));
}

// moving horizontal drop line
if(pair.drawHorizontalDropline) {
svg.append("line")
.classed('hDrop', true)
.style('stroke-width', dropLines.width)
.style('stroke-dasharray', dropLines.dashCSS)
.style('stroke', 'black')
.attr("x1", xScale(xAxisScale.domain[0])).attr("y1", yScale(point.y))
.attr("x2", xScale(point.x)).attr("y2", yScale(point.y))
}

// moving intersection line
svg.append("circle")
.classed("intersection", true)
.attr('cx', xScale(point.x))
.attr('cy', yScale(point.y))
.attr('r','5px')
.style("stroke", () => {
return (pair.isPrimary) ? 'none' : '#5A5A5A'
})
.style("stroke-width", "2px")
.style('fill', () => {
return (pair.isPrimary) ? 'black' : 'none'
})

// moving numbers
d3.selectAll('text.vDropLabel').remove();
d3.selectAll('text.hDropLabel').remove();
svg.append('text')
.classed("vDropLabel", true)
.attr('x', xScale(point.x) + pair.verticalLabelOffset[0])
.attr('y', height - margin.bottom + pair.verticalLabelOffset[1])
.style('fill', pair.verticalLabelColor)
.style('text-shadow', textShadow)
.style("font-size", 18)
.style("font-weight", 'bold')
.text(() => `${d3.format(pair.verticalLabelFormat)(point.x/100)}`)

svg.append('text')
.classed("hDropLabel", true)
.attr('x', xScale(xAxisScale.domain[0]) + pair.horizontalLabelOffset[0])
.attr('y', yScale(point.y) + pair.horizontalLabelOffset[1])
.style('fill', pair.horizontalLabelColor)
.style('text-shadow', textShadow)
.style("font-size", 18)
.style("font-weight", 'bold')
.text(() => `${d3.format(pair.horizontalLabelFormat)(point.y/100)}`)



}
})
}
Insert cell
// if the x1 or x2 attributes on the line have been changed due to crossing the border, append the label there instead .

function appendLabels() {
svg.selectAll("text.label").remove();
svg.selectAll("text.label")
.data(lines)
.enter().append('text')
.classed('label', true)
.style("font-size", d => d.labelSize)
.style('fill', d => getColor(d))
.style('text-shadow', textShadow)
.attr("x", d => {
return ('x2' in d) ? d.x2 : xScale(d.point2[0])
})
.attr("y", d => {
return ('y2' in d) ? d.y2 : yScale(d.point2[1])
})
.text(d => d.label);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more