Skip to content

Commit

Permalink
feat(resize): Container based auto resize
Browse files Browse the repository at this point in the history
Implement auto resize based on parent node size changes

Ref #3955
  • Loading branch information
netil authored and netil committed Feb 28, 2025
1 parent 93cc1b4 commit d155819
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 7 deletions.
22 changes: 22 additions & 0 deletions demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -5736,6 +5736,28 @@ d3.select(".chart_area")
clipPath: false
}
},
resizeParent: {
description: "Resize chart when parent node is resized.",
options: {
data: {
columns: [
["sample", 30, 200, 120, 400, 230, 250]
],
type: "line"
},
resize: {
auto: "parent",
timer: false
}
},
func: function(chart) {
chart.timer = [
setTimeout(function() {
document.querySelector(".chart_area").style.width="300px";
}, 1000),
];
},
},
resizeViewBox: [
{
options: {
Expand Down
4 changes: 4 additions & 0 deletions demo/simple-sidebar.css
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,10 @@ div.row {
transform: translateY(-20px);
}

.chart_area:has(#resizeParent) {
border: solid 1px red;
}

/* Style For Region */
#styleForRegion .bb-region-0 {fill:red;}
#styleForRegion .bb-region.foo {fill:green;}
Expand Down
2 changes: 2 additions & 0 deletions src/Chart/api/chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export default {

if (notEmpty($$)) {
$$.callPluginHook("$willDestroy");

$$.charts.splice($$.charts.indexOf(this), 1);

// detach events
Expand All @@ -114,6 +115,7 @@ export default {
svg.select("*").interrupt();
$$.resizeFunction.clear();

$$.resizeFunction.resizeObserver?.disconnect();
window.removeEventListener("resize", $$.resizeFunction);
chart.classed("bb", false)
.style("position", null)
Expand Down
11 changes: 8 additions & 3 deletions src/ChartInternal/ChartInternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -787,13 +787,13 @@ export default class ChartInternal {

bindResize(): void {
const $$ = <any>this;
const {config, state} = $$;
const {$el, config, state} = $$;
const resizeFunction = generateResize(config.resize_timer);
const list: Function[] = [];

list.push(() => callFn(config.onresize, $$.api));

if (config.resize_auto === true) {
if (/^(true|parent)$/.test(config.resize_auto)) {
list.push(() => {
state.resizing = true;

Expand All @@ -818,7 +818,12 @@ export default class ChartInternal {
$$.resizeFunction = resizeFunction;

// attach resize event
window.addEventListener("resize", $$.resizeFunction = resizeFunction);
if (config.resize_auto === "parent") {
($$.resizeFunction.resizeObserver = new ResizeObserver($$.resizeFunction.bind($$)))
.observe($el.chart.node().parentNode);
} else {
window.addEventListener("resize", $$.resizeFunction);
}
}

/**
Expand Down
9 changes: 7 additions & 2 deletions src/config/Options/common/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,18 +166,23 @@ export default {
* - **NOTE:** Available options
* - true: Enables automatic resize.
* - false: Disables automatic resize.
* - "parent": Enables automatic resize when the parent node is resized.
* - "viewBox": Enables automatic resize, and size will be fixed based on the viewbox.
* @property {boolean|number} [resize.timer=true] Set resize timer option.
* - **NOTE:** Available options
* - The resize function will be called using:
* - true: `setTimeout()`
* - false: `requestIdleCallback()`
* - Given number(delay in ms) value, resize function will be triggered using `setTimeout()` with given delay.
* @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.resizeViewBox)
* @see [Demo: resize "parent"](https://naver.github.io/billboard.js/demo/#ChartOptions.resizeParent)
* @see [Demo: resize "viewBox"](https://naver.github.io/billboard.js/demo/#ChartOptions.resizeViewBox)
* @example
* resize: {
* auto: false,
*
* // set resize based on parent node width value
* auto: "parent",
*
* // set resize based on viewBox value
* auto: "viewBox",
*
Expand All @@ -191,7 +196,7 @@ export default {
* timer: 100
* }
*/
resize_auto: <boolean | "viewBox">true,
resize_auto: <boolean | "parent" | "viewBox">true,
resize_timer: true,

/**
Expand Down
37 changes: 36 additions & 1 deletion test/internals/bb-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ describe("Interface & initialization", () => {
});
});

describe("auto resize", () => {
describe.only("auto resize", () => {
let chart;
const containerName = "container";
let container;
Expand Down Expand Up @@ -321,6 +321,41 @@ describe("Interface & initialization", () => {

expect(svg.attr("viewBox")).to.be.equal("0 0 640 480");
});

it("check 'parent' resize", () => {
let width = 300;

container.style.width = `${width}px`;
container.innerHTML = '<div id="chartResize"></div>';

const args = {
data: {
columns: [
["data1", 30]
]
},
transition: {
duration: 0
},
resize: {
auto: "parent"
},
bindto: "#chartResize"
};

const chart = util.generate(args);

expect(+chart.$.svg.attr("width")).to.be.equal(width);

// when
container.style.width = `${width = 500}px`;

// should resize on parent element
setTimeout(() => {
expect(+chart.$.svg.attr("width")).to.be.equal(width);
}, 300);
});

});

describe("set defaults options", () => {
Expand Down
3 changes: 2 additions & 1 deletion types/options.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,10 @@ export interface ChartOptions {
* - **NOTE:** Available options
* - true: Enables automatic resize.
* - false: Disables automatic resize.
* - "parent": Enables automatic resize when the parent node is resized.
* - "viewBox": Enables automatic resize, and size will be fixed based on the viewbox.
*/
auto?: boolean | "viewBox";
auto?: boolean | "parent" | "viewBox";

/**
* Set resize timer option.
Expand Down

0 comments on commit d155819

Please sign in to comment.