multiChart = {
replay2;
let width;
width =
window.innerWidth > 500 ? window.innerWidth * 0.75 : window.innerWidth;
const height = 500;
const margin = {
top: height * 0.1,
right: height * 0.1,
bottom: height * 0.1,
left: height * 0.1
};
const xMax = 1.2;
const yMax = d3.max(multiEmojiData, (d) => d.favoriteCount);
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto; height: intrinsic;");
const xScale = d3
.scaleLinear()
.domain([0, xMax])
.nice()
.rangeRound([margin.left, width - margin.right]);
const yScale = d3
// // .base(2)
// .constant(15000)
.scaleLinear()
.domain([0, yMax])
.nice()
.range([height - margin.top, margin.bottom]);
//declare image dimensions
const imageDims = { height: height * 0.075, width: height * 0.075 };
//declare x/y position getters
const xGet = (d) => xScale(d.diff);
const yGet = (d) => yScale(d.favoriteCount);
const xPos = (d) => xGet(d) - imageDims.width / 2;
const yPos = (d) => yGet(d) - imageDims.height / 2;
//create axes
const xAxis = d3.axisBottom(xScale).tickValues([0, 0.3, 0.6, 0.9]);
const yAxis = d3
.axisLeft(yScale)
.tickValues([0, 5000, 10000, 15000, 20000, 25000, 28500]);
//create tooltip
const tooltip = d3
.select("body")
.append("div")
.attr("class", "svg-tooltip")
.style("position", "absolute")
.style("visibility", "hidden");
//add x axis
svg
.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(xAxis)
.call((g) => g.select(".domain").remove())
.call((g) =>
g
.selectAll(".tick line")
.clone()
.attr("y2", margin.top + margin.bottom - height)
.attr("stroke-opacity", 0.1)
)
.call((g) =>
g
.append("text")
.attr("x", width - margin.right)
.attr("y", margin.bottom - 10)
.attr("fill", "currentColor")
.attr("text-anchor", "end")
.attr("font-size", 14)
.text("Difference in emoji sentiment →")
)
.call(transitionOpacity);
//add y axis
svg
.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(yAxis)
.call((g) => g.select(".domain").remove())
.call((g) =>
g
.selectAll(".tick line")
.clone()
.attr("x2", width - margin.left - margin.right)
.attr("stroke-opacity", 0.1)
)
.call((g) =>
g
.append("text")
.attr("x", margin.left)
.attr("y", margin.top - 5)
.attr("fill", "currentColor")
.attr("text-anchor", "end")
.attr("font-size", 14)
.text("↑ Favorites")
)
.call(transitionOpacity);
//add images
svg
.append("g")
.selectAll("svg")
.data(multiEmojiData)
.join("svg")
.attr("x", xPos)
.attr("y", yPos)
.attr("width", imageDims.width)
.attr("height", imageDims.height)
.attr("opacity", 0)
.call(emojiInteractions, tooltip, xGet, yGet, imageDims)
.transition()
.duration(1000)
.ease(d3.easeCubicOut)
.attr("x", xPos)
.attr("y", yPos)
.attr("opacity", 1);
svg
.selectAll("svg")
.data(multiEmojiData)
.join("svg")
.append("image")
.attr("xlink:href", (d) => d.media_url)
.attr("width", "100%")
.attr("height", "100%")
.attr("preserveAspectRatio", "xMidYMid slice")
.style("mix-blend-mode", "multiply") //these styles remove the white background
.style("filter", "contrast(1)") //these styles remove the white background
.style("cursor", "pointer")
.call(transitionOpacity, 500);
return svg.node();
}
//TODO: comments