Public
Edited
Apr 14, 2023
Insert cell
Insert cell
Insert cell
grouped = d3.group(data,d=>d.CHR);
Insert cell
height = 500
Insert cell
chart = {
const width = 2000;
const padding = 30;
const plotWidth = width / grouped.size;
const plotHeight = height - padding * 2;

const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

const g = svg
.append("g").attr("transform", `translate(60)`);

// X AXIS SCALE
const xScale = d3.scaleLinear()
.domain(d3.extent(data, d => d.BP))
.range([0, plotWidth])
// Y AXIS SCALE
const yScale = d3.scaleLog()
.domain(d3.extent(data, d => d.P)).nice()
.range([0, plotHeight]);
// HIGHLIGHT P VALUE LOWER THAN 10^-5
const color = (data, chr) => {
if(chr % 2 == 0) return (data < 10 ** -5) ? "#69ff40" : "#000000"
else return (data < 10 ** -5) ? "#69ff40" : "#3d3d3d"
}

// TRANSLATE EACH PLOT (EACH CHR) BASED ON SIZE
const xPosition = {}
const plots = g.selectAll(null)
.data(grouped)
.enter()
.append("g")
.attr("transform", (data, index) => {

// const max = d3.max(data[1], obj => obj.BP)
// xPosition[index] = (index > 0) ? max + xPosition[index-1] : 0
// const translateX = xScale([xPosition[index]]) + padding

const translateX = [index *(plotWidth)]
return `translate(${translateX})`
})

// LOOP THROUGH
plots.selectAll(null)
.data(d => d[1])
.enter()
.append("circle")
.attr("r", 4)
.attr("cx", d => xScale(d.BP))
.attr("cy", d => yScale(d.P))
.style("fill", d => color(d.P, d.CHR))

// X AXIS LABEL
plots.append("text")
// .attr("x", (data, index) => {
// const max = d3.max(data[1], obj => obj.BP)
// return xScale(max)/2
// })
.attr("y", plotHeight + padding)
.text(d => d[1][0].CHR)

// Y AXIS LABEL
g.append("g").call(
d3.axisLeft(yScale)
.tickArguments([5,".0s"])
.tickFormat(function(d) {
return -Math.log10(d);
})
)
// X AXIS TITLE
g.append("text")
.attr("x", plotWidth)
.attr("y", plotHeight + padding * 2)
.text("Chromosome")
// Y AXIS TITLE
g.append("text")
.attr("x", (plotHeight * -1)/2)
.attr("y", padding * -1)
.attr('text-anchor', 'middle')
.text("-log10(P)")
.attr('transform', 'rotate(-90)')

return svg.node();
}
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