Skip to content

Commit

Permalink
fix(zoom): Correct zoom resizing (#139)
Browse files Browse the repository at this point in the history
For zoomed chart axis wasn't reflecting resize. When zoom scale exist, use zoom scale.
Also fixed to react resize event after zoom out.

Closed #60
Fixed #139
  • Loading branch information
netil authored and sculove committed Sep 13, 2017
1 parent f3b80d3 commit 67e863e
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 52 deletions.
108 changes: 90 additions & 18 deletions spec/zoom-spec.js
Expand Up @@ -4,30 +4,40 @@
*/
/* eslint-disable */
/* global describe, beforeEach, it, expect */
import CLASS from "../src/config/classes";
import util from "./assets/util";

describe("ZOOM", function() {
const chart = util.generate({
data: {
columns: [
["data1", 30, 200, 100, 400, 3150, 250],
["data2", 50, 20, 10, 40, 15, 6025]
]
},
axis: {
x: {
extent: [[1, 0], [2, 60]]
}
},
zoom: {
enable: true
},
subchart: {
show: true
}
let chart;
let args;

beforeEach(() => {
chart = util.generate(args);
});

describe("default extent", () => {
before(() => {
args = {
data: {
columns: [
["data1", 30, 200, 100, 400, 3150, 250],
["data2", 50, 20, 10, 40, 15, 6025]
]
},
axis: {
x: {
extent: [[1, 0], [2, 60]]
}
},
zoom: {
enable: true
},
subchart: {
show: true
}
};
});

describe("main chart domain", () => {
it("should have original y domain", () => {
const yDomain = chart.internal.y.domain();
Expand Down Expand Up @@ -58,4 +68,66 @@ describe("ZOOM", function() {
});
});
});

describe("zoom event", () => {
before(() => {
args = {
size: {
width: 300,
height: 250
},
data: {
columns: [
["data1", 30, 200, 100, 400, 3150, 250],
["data2", 50, 20, 10, 40, 15, 6025]
]
},
zoom: {
enable: true
}
};
});

it("check for data zoom", () => {
const main = chart.internal.main;
const xValue = +main.select(`.${CLASS.eventRect}-2`).attr("x");

// when
chart.zoom([0,3]); // zoom in

expect(+main.select(`.${CLASS.eventRect}-2`).attr("x")).to.be.above(xValue);
});

it("check for x axis resize after zoom", () => {
const main = chart.internal.main;
const rx = /H(\d+)/;

const domain = main.select(`.${CLASS.axisX} > .domain`);
const pathValue = +domain.attr("d").match(rx)[1];

chart.zoom([0,4]);
chart.resize({width:400});

expect(+domain.attr("d").match(rx)[1]).to.be.above(pathValue);
});

it("check for x axis resize after zoom in/out", () => {
const main = chart.internal.main;
const rx = /H(\d+)/;

const domain = main.select(`.${CLASS.axisX} > .domain`);
const pathValue = +domain.attr("d").match(rx)[1];

chart.zoom([0,4]); // zoom in
chart.zoom([0,6]); // zoom out

expect(+domain.attr("d").match(rx)[1]).to.be.equal(pathValue);

// resize
chart.resize({width:400});

// check if chart react on resize
expect(+domain.attr("d").match(rx)[1]).to.be.above(pathValue);
});
});
});
12 changes: 7 additions & 5 deletions src/axis/Axis.js
Expand Up @@ -67,10 +67,11 @@ export default class Axis {
tickWidth: config.axis_x_tick_width,
tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,
withoutTransition,
orgXScale: $$.x
};

const axis = bbAxis(axisParams)
.scale(scale)
.scale($$.zoomScale || scale)
.orient(orient);

let newTickValues = tickValues;
Expand Down Expand Up @@ -595,11 +596,12 @@ export default class Axis {

redraw(transitions, isHidden) {
const $$ = this.owner;
const opacity = isHidden ? "0" : "1";

$$.axes.x.style("opacity", isHidden ? "0" : "1");
$$.axes.y.style("opacity", isHidden ? "0" : "1");
$$.axes.y2.style("opacity", isHidden ? "0" : "1");
$$.axes.subx.style("opacity", isHidden ? "0" : "1");
$$.axes.x.style("opacity", opacity);
$$.axes.y.style("opacity", opacity);
$$.axes.y2.style("opacity", opacity);
$$.axes.subx.style("opacity", opacity);

transitions.axisX.call($$.xAxis);
transitions.axisY.call($$.yAxis);
Expand Down
4 changes: 3 additions & 1 deletion src/axis/bb.axis.js
Expand Up @@ -157,7 +157,9 @@ export default function(params = {}) {
let tickX;
let tickY;

const range = scale.rangeExtent ? scale.rangeExtent() : scaleExtent(scale.range());
const range = scale.rangeExtent ?
scale.rangeExtent() :
scaleExtent((params.orgXScale || scale).range());

// update selection - data join
const path = g.selectAll(".domain").data([0]);
Expand Down
21 changes: 18 additions & 3 deletions src/interactions/zoom.js
Expand Up @@ -10,7 +10,7 @@ import {
} from "d3";
import ChartInternal from "../internals/ChartInternal";
import CLASS from "../config/classes";
import {extend, diffDomain} from "../internals/util";
import {extend, diffDomain, isFunction} from "../internals/util";

extend(ChartInternal.prototype, {
/**
Expand Down Expand Up @@ -46,7 +46,8 @@ extend(ChartInternal.prototype, {

$$.redrawEventRect();
$$.updateZoom();
config.zoom_onzoomend.call($$.api, $$.x.orgDomain());

isFunction(config.zoom_onzoomend) && config.zoom_onzoomend.call($$.api, $$.x.orgDomain());
});

$$.zoom.orgScaleExtent = () => {
Expand All @@ -60,6 +61,7 @@ extend(ChartInternal.prototype, {
const extent = this.orgScaleExtent();

this.scaleExtent([extent[0] * ratio, extent[1] * ratio]);

return this;
};

Expand Down Expand Up @@ -100,6 +102,18 @@ extend(ChartInternal.prototype, {
// .call(z)
// .on("dblclick.zoom", null);

if ($$.zoomScale) {
const range1 = $$.zoomScale.domain()[0];
const range2 = $$.x.domain()[0];
const delta = 0.015;

// reset scale when zoom is out as initial
if (range1 <= range2 || (range1 - delta) <= range2) {
$$.zoomScale = null;
$$.xAxis.scale($$.x);
}
}

$$.main.select(`.${CLASS.eventRects}`)
.call(z)
.on("dblclick.zoom", null);
Expand All @@ -116,6 +130,7 @@ extend(ChartInternal.prototype, {
if (!config.zoom_enabled) {
return;
}

const zoom = $$.zoom;
const x = $$.x;
const event = d3Event;
Expand Down Expand Up @@ -149,6 +164,6 @@ extend(ChartInternal.prototype, {
$$.cancelClick = true;
}

config.zoom_onzoom.call($$.api, x.orgDomain());
isFunction(config.zoom_onzoom) && config.zoom_onzoom.call($$.api, x.orgDomain());
},
});
33 changes: 9 additions & 24 deletions src/internals/ChartInternal.js
Expand Up @@ -568,6 +568,7 @@ export default class ChartInternal {

if (targetsToShow.length) {
$$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain);

if (!config.axis_x_tick_values) {
tickValues = $$.axis.updateXAxisTickValues(targetsToShow);
}
Expand Down Expand Up @@ -904,11 +905,15 @@ export default class ChartInternal {
}

xx(d) {
if (this.config.zoom_enabled && this.zoomScale) {
return d ? this.zoomScale(d.x) : null;
} else {
return d ? this.x(d.x) : null;
const x = d ? d.x : null;
let scale = null;

if (x) {
scale = this.config.zoom_enabled && this.zoomScale ?
this.zoomScale(x) : this.x(x);
}

return scale;
}

xv(d) {
Expand Down Expand Up @@ -1134,26 +1139,6 @@ export default class ChartInternal {
});

addEvent(window, "resize", $$.resizeFunction);

// if (window.attachEvent) {
// window.attachEvent("onresize", $$.resizeFunction);
// } else if (window.addEventListener) {
// window.addEventListener("resize", $$.resizeFunction, false);
// } else {
// // fallback to this, if this is a very old browser
// let wrapper = window.onresize;
// if (!wrapper) {
// // create a wrapper that will call all charts
// wrapper = $$.generateResize();
// } else if (!wrapper.add || !wrapper.remove) {
// // there is already a handler registered, make sure we call it too
// wrapper = $$.generateResize();
// wrapper.add(window.onresize);
// }
// // add this graph to the wrapper, we will be removed if the user calls destroy
// wrapper.add($$.resizeFunction);
// window.onresize = wrapper;
// }
}

generateResize() {
Expand Down
2 changes: 1 addition & 1 deletion src/internals/legend.js
Expand Up @@ -511,5 +511,5 @@ extend(ChartInternal.prototype, {
// Update g positions
$$.transformAll(withTransitionForTransform, transitions);
$$.legendHasRendered = true;
},
}
});

0 comments on commit 67e863e

Please sign in to comment.