How To Import Submodules From D3 To Easily Create Legend?
I'm relatively new to JavaScript and D3 so please keep that in mind. I've created a visualization to show the visit frequency to particular locations in a warehouse and would like
Solution 1:
Given the relative path of that module name that import
will only work in a Observable's cell. If that's not your case, simply copy the whole function, which you'll find below (click "Show code snippet"), or save it as a file (and then you can do an import
with the adequate module name):
functionlegend({
color,
title,
tickSize = 6,
width = 320,
height = 44 + tickSize,
marginTop = 18,
marginRight = 0,
marginBottom = 16 + tickSize,
marginLeft = 0,
ticks = width / 64,
tickFormat,
tickValues
} = {}) {
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.style("overflow", "visible")
.style("display", "block");
let x;
// Continuousif (color.interpolator) {
x = Object.assign(color.copy()
.interpolator(d3.interpolateRound(marginLeft, width - marginRight)), {
range() {
return [marginLeft, width - marginRight];
}
});
svg.append("image")
.attr("x", marginLeft)
.attr("y", marginTop)
.attr("width", width - marginLeft - marginRight)
.attr("height", height - marginTop - marginBottom)
.attr("preserveAspectRatio", "none")
.attr("xlink:href", ramp(color.interpolator()).toDataURL());
// scaleSequentialQuantile doesn’t implement ticks or tickFormat.if (!x.ticks) {
if (tickValues === undefined) {
const n = Math.round(ticks + 1);
tickValues = d3.range(n).map(i => d3.quantile(color.domain(), i / (n - 1)));
}
if (typeof tickFormat !== "function") {
tickFormat = d3.format(tickFormat === undefined ? ",f" : tickFormat);
}
}
}
// Discreteelseif (color.invertExtent) {
const thresholds = color.thresholds ? color.thresholds() // scaleQuantize
:
color.quantiles ? color.quantiles() // scaleQuantile
:
color.domain(); // scaleThresholdconst thresholdFormat = tickFormat === undefined ? d => d :
typeof tickFormat === "string" ? d3.format(tickFormat) :
tickFormat;
x = d3.scaleLinear()
.domain([-1, color.range().length - 1])
.rangeRound([marginLeft, width - marginRight]);
svg.append("g")
.selectAll("rect")
.data(color.range())
.join("rect")
.attr("x", (d, i) =>x(i - 1))
.attr("y", marginTop)
.attr("width", (d, i) =>x(i) - x(i - 1))
.attr("height", height - marginTop - marginBottom)
.attr("fill", d => d);
tickValues = d3.range(thresholds.length);
tickFormat = i =>thresholdFormat(thresholds[i], i);
}
svg.append("g")
.attr("transform", `translate(0, ${height - marginBottom})`)
.call(d3.axisBottom(x)
.ticks(ticks, typeof tickFormat === "string" ? tickFormat : undefined)
.tickFormat(typeof tickFormat === "function" ? tickFormat : undefined)
.tickSize(tickSize)
.tickValues(tickValues))
.call(g => g.selectAll(".tick line").attr("y1", marginTop + marginBottom - height))
.call(g => g.select(".domain").remove())
.call(g => g.append("text")
.attr("y", marginTop + marginBottom - height - 6)
.attr("fill", "currentColor")
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text(title));
return svg.node();
}
However, there is another hurdle: currently that function will also only work in an Observable's cell. If you want it to work on a regular web page, change its returned value (or append the SVG as a side effect).
Post a Comment for "How To Import Submodules From D3 To Easily Create Legend?"