Skip to content

Commit

Permalink
fix(zoom): Fix on rotated axis (#892)
Browse files Browse the repository at this point in the history
- Fix on rotated drag & wheel zooming
- Fix cursor style when is rotated
- Remove unused altKey zooming

Fix #736
Fix #818
  • Loading branch information
netil committed May 21, 2019
1 parent 585d607 commit 983d970
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 25 deletions.
154 changes: 153 additions & 1 deletion spec/interactions/zoom-spec.js
Expand Up @@ -248,7 +248,7 @@ describe("ZOOM", function() {
});

it("check with rescale option", () => {
const eventRect = chart.$.main.select(".bb-event-rect-2").node();
const eventRect = chart.$.main.select(`.${CLASS.eventRect}-2`).node();
const orgDomain = {
x: chart.internal.x.domain(),
y: chart.internal.y.domain()
Expand Down Expand Up @@ -611,4 +611,156 @@ describe("ZOOM", function() {
});
});
});

describe("zoom for rotated axis", () => {
before(() => {
args = {
size: {
width: 300,
height: 250
},
data: {
columns: [
["data1", 30, 200, 100, 400, 3150, 250],
["data2", 6025, 20, 10, 40, 15, 25]
]
},
axis: {
rotated: true
},
zoom: {
rescale: true,
enabled: {
type: "drag"
}
}
};
});

it("check on drag zooming", done => {
const internal = chart.internal;
const main = chart.$.main;
const eventRect = main.select(`.${CLASS.eventRect}-2`).node();
const zoomedDomain = internal.x.domain();
const size = {w: 0, h: 0};
let brush;
let yAxisTickText;

new Promise((resolve, reject) => {
util.fireEvent(eventRect, "mousedown", {
clientX: 100,
clientY: 100
}, chart);

brush = main.select(`.${CLASS.zoomBrush}`);
yAxisTickText = +chart.$.main.selectAll(`.${CLASS.axisY} .tick tspan`).nodes().pop().textContent;

size.w = +brush.attr("width");
size.h = +brush.attr("height");

resolve();
}).then(() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
util.fireEvent(eventRect, "mousemove", {
clientX: 100,
clientY: 130
}, chart);

resolve();
}, 500);
});
}).then(() => {
setTimeout(() => {
expect(+brush.attr("width")).to.be.equal(size.w);
expect(+brush.attr("height")).to.be.above(size.h);
expect(+brush.attr("height")).to.be.equal(30);

//console.log(size, brush.attr("width"), brush.attr("height"));
util.fireEvent(eventRect, "mouseup", {
clientX: 100,
clientY: 200
}, chart);

// y axis rescaled?
const tickText = +chart.$.main.selectAll(`.${CLASS.axisY} .tick tspan`).nodes().pop().textContent;

expect(tickText).to.be.below(yAxisTickText);
expect(tickText).to.be.equal(400);

internal.x.domain().forEach((v, i) => {
expect(v).to.be[i ? "below" : "above"](zoomedDomain[i]);
});

done();
}, 500);
});
});

it("set options", () => {
args = {
data: {
columns: [
["data1", 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
],
type: "bar"
},
axis: {
rotated: true,
x: {
type: "category",
tick: {
rotate: 40,
multiline: false
}
}
},
bar: {
width: {
ratio: 0.6
}
},
zoom: {
enabled: true,
rescale: true
}
};
});

it("check on wheel zooming", () => {
const eventRect = chart.$.main.select(`.${CLASS.eventRect}-40`).node();
const orgDomain = {
x: chart.internal.x.domain(),
y: chart.internal.y.domain()
};

// when zoom in
util.fireEvent(eventRect, "wheel", {
deltaX: 0,
deltaY: -200,
clientX: 159,
clientY: 137
});

const expected = {
x: [7.738255334651066, 84.52408366017097],
y: [0, 101.2]
};

["x", "y"].forEach(id => {
const domain = chart.internal[id].domain();
const org = orgDomain[id];

if (id === "x") {
expect(
domain.every((v, i) => i > 0 ? v < org[i] : v > org[i])
).to.be.true;
} else {
expect(
domain.every((v, i) => i > 0 ? v < org[i] : v === org[i])
).to.be.true;
}
});
});
});
});
5 changes: 3 additions & 2 deletions src/api/api.zoom.js
Expand Up @@ -9,8 +9,9 @@ import {callFn, extend, getMinMax, isDefined, isObject, isString} from "../inter

/**
* Zoom by giving x domain.
* - **NOTE:** For `wheel` type zoom, the minimum zoom range will be set as the given domain.<br>
* To get the initial state, [.unzoom()](#unzoom) should be called.
* - **NOTE:**
* - For `wheel` type zoom, the minimum zoom range will be set as the given domain. To get the initial state, [.unzoom()](#unzoom) should be called.
* - To be used [zoom.enabled](Options.html#.zoom) option should be set as `truthy`.
* @method zoom
* @instance
* @memberof Chart
Expand Down
8 changes: 4 additions & 4 deletions src/interactions/interaction.js
Expand Up @@ -34,13 +34,13 @@ extend(ChartInternal.prototype, {
redrawEventRect() {
const $$ = this;
const config = $$.config;
const zoomEnabled = config.zoom_enabled;
const isMultipleX = $$.isMultipleX();

let eventRectUpdate;

const zoomEnabled = config.zoom_enabled;
const eventRects = $$.main.select(`.${CLASS.eventRects}`)
.style("cursor", zoomEnabled && (zoomEnabled === true || zoomEnabled.type === "wheel") ? (
config.axis_rotate ? "ns-resize" : "ew-resize"
.style("cursor", zoomEnabled && zoomEnabled.type !== "drag" ? (
config.axis_rotated ? "ns-resize" : "ew-resize"
) : null)
.classed(CLASS.eventRectsMultiple, isMultipleX)
.classed(CLASS.eventRectsSingle, !isMultipleX);
Expand Down
36 changes: 18 additions & 18 deletions src/interactions/zoom.js
Expand Up @@ -90,7 +90,10 @@ extend(ChartInternal.prototype, {
$$.orgXScale && $$.orgXScale.range($$.x.range());

// rescale from the original scale
const newScale = transform.rescaleX($$.orgXScale || $$.x);
const newScale = transform[
config.axis_rotated ? "rescaleY" : "rescaleX"
]($$.orgXScale || $$.x);

const domain = $$.trimXDomain(newScale.domain());
const rescale = config.zoom_rescale;

Expand Down Expand Up @@ -121,9 +124,6 @@ extend(ChartInternal.prototype, {
return;
}

$$.zoom.altDomain = event.altKey ?
$$.x.orgDomain() : null;

$$.zoom.startEvent = event;
callFn($$.config.zoom_onzoomstart, $$.api, event);
},
Expand All @@ -150,12 +150,6 @@ extend(ChartInternal.prototype, {
return;
}

if (isMousemove && $$.zoom.altDomain) {
$$.x.domain($$.zoom.altDomain);
transform.scale($$.zoomScale).updateScaleExtent();
return;
}

if ($$.isCategorized() && $$.x.orgDomain()[0] === $$.orgXDomain[0]) {
$$.x.domain([$$.orgXDomain[0] - 1e-10, $$.x.orgDomain()[1]]);
}
Expand Down Expand Up @@ -264,6 +258,12 @@ extend(ChartInternal.prototype, {
let end = 0;
let zoomRect = null;

const prop = {
axis: isRotated ? "y" : "x",
attr: isRotated ? "height" : "width",
index: isRotated ? 1 : 0
};

$$.zoomBehaviour = d3Drag()
.clickDistance(4)
.on("start", function() {
Expand All @@ -277,30 +277,30 @@ extend(ChartInternal.prototype, {
.attr("height", isRotated ? 0 : $$.height);
}

start = d3Mouse(this)[0];
start = d3Mouse(this)[prop.index];
end = start;

zoomRect
.attr("x", start)
.attr("width", 0);
.attr(prop.axis, start)
.attr(prop.attr, 0);

$$.onZoomStart();
})
.on("drag", function() {
end = d3Mouse(this)[0];
end = d3Mouse(this)[prop.index];

zoomRect
.attr("x", Math.min(start, end))
.attr("width", Math.abs(end - start));
.attr(prop.axis, Math.min(start, end))
.attr(prop.attr, Math.abs(end - start));
})
.on("end", function(d) {
const scale = $$.zoomScale || $$.x;

$$.setDragStatus(false);

zoomRect
.attr("x", 0)
.attr("width", 0);
.attr(prop.axis, 0)
.attr(prop.attr, 0);

if (start > end) {
[start, end] = [end, start];
Expand Down

0 comments on commit 983d970

Please sign in to comment.