Skip to content

Commit

Permalink
feat(subchart): Intent to ship subchart.showHandle
Browse files Browse the repository at this point in the history
Implement subchart.showHandle option

Close #2044
  • Loading branch information
netil committed Apr 19, 2021
1 parent 967bf1b commit 219bff3
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 20 deletions.
3 changes: 2 additions & 1 deletion demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -2612,7 +2612,8 @@ var demos = {
type: "line"
},
subchart: {
show: "subchart()"
show: "subchart()",
showHandle: true
}
},
description: "Drag over subchart area to zoom main chart.<br>When is zoomed, try dragging zoom selection element or expand it dragging each edge(left/right)"
Expand Down
89 changes: 73 additions & 16 deletions src/ChartInternal/interactions/subchart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ export default {
const $$ = this;
const {config, scale, $el: {subchart}} = $$;
const isRotated = config.axis_rotated;
let lastDomain;
let timeout;

// set the brush
$$.brush = isRotated ? d3BrushY() : d3BrushX();
$$.brush = (
isRotated ? d3BrushY() : d3BrushX()
).handleSize(5);

// set "brush" event
const brushHandler = () => {
$$.redrawForBrush();
};
const getBrushSize = () => {
const brush = $$.$el.svg.select(`.${CLASS.brush} .overlay`);
const brushSize = {width: 0, height: 0};
Expand All @@ -40,18 +40,38 @@ export default {
return brushSize[isRotated ? "width" : "height"];
};

let lastDomain;
let timeout;
// bind brush event
$$.brush.on("start brush end", event => {
const {selection, target, type} = event;

$$.brush
.on("start", () => {
if (type === "start") {
$$.state.inputType === "touch" && $$.hideTooltip();
brushHandler();
})
.on("brush", brushHandler)
.on("end", () => {
}

if (/(start|brush)/.test(type)) {
$$.redrawForBrush();
}

if (type === "end") {
lastDomain = scale.x.orgDomain();
});
}

// handle brush's handle position & visibility
if (target?.handle) {
if (selection === null) {
$$.brush.handle.attr("display", "none");
} else {
$$.brush.handle.attr("display", null)
.attr("transform", (d, i) => {
const pos = isRotated ?
[33, selection[i] - (i === 0 ? 30 : 24)] : [selection[i], 3];

return `translate(${pos})`;
});
}
}
});


$$.brush.updateResize = function() {
timeout && clearTimeout(timeout);
Expand Down Expand Up @@ -149,11 +169,13 @@ export default {
});

// Add extent rect for Brush
main.append("g")
const brush = main.append("g")
.attr("clip-path", clipPath)
.attr("class", CLASS.brush)
.call($$.brush);

config.subchart_showHandle && $$.addBrushHandle(brush);

// ATTENTION: This must be called AFTER chart added
// Add Axis
axis.subX = main.append("g")
Expand All @@ -163,6 +185,42 @@ export default {
.style("visibility", config.subchart_axis_x_show ? visibility : "hidden");
},

/**
* Add brush handle
* Enabled when: subchart.showHandle=true
* @param {d3Selection} brush Brush selection
* @private
*/
addBrushHandle(brush): void {
const $$ = this;
const {config} = $$;
const isRotated = config.axis_rotated;
const initRange = config.subchart_init_range;
const customHandleClass = "handle--custom";

// brush handle shape's path
const path = isRotated ? [
"M 5.2491724,29.749209 a 6,6 0 0 0 -5.50000003,-6.5 H -5.7508276 a 6,6 0 0 0 -6.0000004,6.5 z m -5.00000003,-2 H -6.7508276 m 6.99999997,-2 H -6.7508276Z",
"M 5.2491724,23.249172 a 6,-6 0 0 1 -5.50000003,6.5 H -5.7508276 a 6,-6 0 0 1 -6.0000004,-6.5 z m -5.00000003,2 H -6.7508276 m 6.99999997,2 H -6.7508276Z"
] : [
"M 0 18 A 6 6 0 0 0 -6.5 23.5 V 29 A 6 6 0 0 0 0 35 Z M -2 23 V 30 M -4 23 V 30Z",
"M 0 18 A 6 6 0 0 1 6.5 23.5 V 29 A 6 6 0 0 1 0 35 Z M 2 23 V 30 M 4 23 V 30Z"
];


$$.brush.handle = brush.selectAll(`.${customHandleClass}`)
.data(isRotated ?
[{type: "n"}, {type: "s"}] :
[{type: "w"}, {type: "e"}]
)
.enter()
.append("path")
.attr("class", customHandleClass)
.attr("cursor", `${isRotated ? "ns" : "ew"}-resize`)
.attr("d", d => path[+/[se]/.test(d.type)])
.attr("display", initRange ? null : "none");
},

/**
* Update sub chart
* @param {object} targets $$.data.targets
Expand Down Expand Up @@ -268,7 +326,6 @@ export default {
$$.brush.getSelection(),
initRange.map($$.scale.x)
);
// .call($$.brush.move, initRange.map($$.scale.x));
}
}
},
Expand Down
3 changes: 3 additions & 0 deletions src/config/Options/interaction/subchart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default {
* @property {boolean} [subchart.show=false] Show sub chart on the bottom of the chart.
* - **NOTE:** for ESM imports, needs to import 'subchart' exports and instantiate it by calling `subchart()`.
* - `show: subchart()`
* @property {boolean} [subchart.showHandle=false] Show sub chart's handle.
* @property {boolean} [subchart.axis.x.show=true] Show or hide x axis.
* @property {boolean} [subchart.axis.x.tick.show=true] Show or hide x axis tick line.
* @property {boolean} [subchart.axis.x.tick.text.show=true] Show or hide x axis tick text.
Expand All @@ -27,6 +28,7 @@ export default {
* @example
* subchart: {
* show: true,
* showHandle: true,
* size: {
* height: 20
* },
Expand Down Expand Up @@ -57,6 +59,7 @@ export default {
* }
*/
subchart_show: false,
subchart_showHandle: false,
subchart_size_height: 60,
subchart_axis_x_show: true,
subchart_axis_x_tick_show: true,
Expand Down
58 changes: 55 additions & 3 deletions test/interactions/subchart-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,59 @@ describe("SUBCHART", () => {
});
});

describe("", () => {
it
})
describe("subchart handle", () => {
before(() => {
args = {
data: {
columns: [
["data1", 30, 200, 100, 400, 150]
],
type: "line"
},
subchart: {
show: true,
init: {
range: [0,0.5]
},
showHandle: true
}
}
});

it("check the handlebar visiblity", () => {
const handlebar = chart.internal.brush.getSelection()
.selectAll(".handle--custom")
.each((d, i) => {
expect(d.type).to.be.equal(["w", "e"][i]);
});

const currDomain = chart.internal.scale.x.domain();

// when
util.doDrag(handlebar.node(), undefined, {clientX: 400, clientY: 100}, chart);

expect(chart.internal.scale.x.domain()).to.be.not.deep.equal(currDomain);
});

it("set options axis.rotated=true", () => {
args.axis = {
rotated: true
};
});

it("check the handlebar visiblity for rotated axis", () => {
const handlebar = chart.internal.brush.getSelection()
.selectAll(".handle--custom")
.each((d, i) => {
expect(d.type).to.be.equal(["n", "s"][i]);
});

const currDomain = chart.internal.scale.x.domain();

// when
util.doDrag(handlebar.node(), undefined, {clientX: 100, clientY: 0}, chart);

expect(chart.internal.scale.x.domain()).to.be.not.deep.equal(currDomain);
});
});
});
6 changes: 6 additions & 0 deletions types/options.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,12 @@ export interface SubchartOptions {
* Show sub chart on the bottom of the chart.
*/
show?: boolean;

/**
* Show sub chart's handle.
*/
showHandle?: boolean;

size?: {
/**
* Change the height of the subchart.
Expand Down

0 comments on commit 219bff3

Please sign in to comment.