// create some test data
const prng = d3.randomNormal();

const data = d3.range(1e3).map(d => ({
    x: prng(),
    y: prng()
}));

const x = d3.scaleLinear().domain([-5, 5]);
const y = d3.scaleLinear().domain([-5, 5]);

const area = fc
    .seriesCanvasPoint()
    .crossValue(d => d.x)
    .mainValue(d => d.y)
    .size(4);

// create a d3fc-zoom that handles the mouse / touch interactions
const zoom = fc.zoom().on('zoom', render);

// the chart!
const chart = fc
    .chartCartesian(x, y)
    .chartLabel('Canvas Zoom 1,000 Points')
    .canvasPlotArea(area)
    .decorate(sel => {
        // add the zoom interaction on the enter selection
        // use selectAll to avoid interfering with the existing data joins
        sel.enter()
            .selectAll('.plot-area')
            .call(zoom, x, y);
        sel.enter()
            .selectAll('.x-axis')
            .call(zoom, x, null);
        sel.enter()
            .selectAll('.y-axis')
            .call(zoom, null, y);
    });

function clamp(
    domain,
    scaleExtent = [Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY],
    translateExtent = [Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY]
) {
    let [min, max] = domain;
    const [scaleMin, scaleMax] = scaleExtent;
    const [translateMin, translateMax] = translateExtent;
    min = Math.max(translateMin, min);
    max = Math.min(translateMax, max);
    if (max - min < scaleMin) {
        min -= (scaleMin - (max - min)) / 2;
        max += (scaleMin - (max - min)) / 2;
    }
    if (max - min > scaleMax) {
        min -= (scaleMax - (max - min)) / 2;
        max += (scaleMax - (max - min)) / 2;
    }
    return [min, max];
}

function render() {
    x.domain(clamp(x.domain(), [1, 10], [-5, 5]));
    y.domain(clamp(y.domain(), [1, 10], [-5, 5]));
    d3.select('#zoom-chart')
        .datum(data)
        .call(chart);
}

render();

@@ -1001,792 +1001,18 @@
 ion 
-clamp(%0A    domain,%0A    scaleExtent = %5BNumber.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY%5D,%0A    translateExtent = %5BNumber.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY%5D%0A) %7B%0A    let %5Bmin, max%5D = domain;%0A    const %5BscaleMin, scaleMax%5D = scaleExtent;%0A    const %5BtranslateMin, translateMax%5D = translateExtent;%0A    min = Math.max(translateMin, min);%0A    max = Math.min(translateMax, max);%0A    if (max - min %3C scaleMin) %7B%0A        min -= (scaleMin - (max - min)) / 2;%0A        max += (scaleMin - (max - min)) / 2;%0A    %7D%0A    if (max - min %3E scaleMax) %7B%0A        min -= (scaleMax - (max - min)) / 2;%0A        max += (scaleMax - (max - min)) / 2;%0A    %7D%0A    return %5Bmin, max%5D;%0A%7D%0A%0Afunction render() %7B%0A    x.domain(clamp(x.domain(), %5B1, 10%5D, %5B-5, 5%5D));%0A    y.domain(clamp(y.domain(), %5B1, 10%5D, %5B-5, 5%5D));
+render() %7B
 %0A   

remove clamp function