Skip to content

Commit

Permalink
feat(options): Intent to ship legend.item.tile.type
Browse files Browse the repository at this point in the history
Implement 'circle' shape for legend item tile.

Ref #2874
  • Loading branch information
netil committed Sep 26, 2022
1 parent 1490b63 commit 2bb9878
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 64 deletions.
133 changes: 88 additions & 45 deletions demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -2877,6 +2877,51 @@ var demos = {
},

Legend: {
CustomLegend: {
options: {
data: {
columns: [
["data1", 100],
["data2", 300],
["data3", 200]
],
type: "pie"
},
legend: {
show: false
}
},
func: function(chart) {
function toggle(id) { chart.toggle(id); }

d3.select(".chart_area")
.insert("div", ".chart")
.attr("class", "legend")
.selectAll("span")
.data(["data1", "data2", "data3"])
.enter()
.append("span")
.attr('data-id', function(id) {
return id;
})
.html(function(id) {
return id;
})
.each(function(id) {
d3.select(this)
.style('background-color', chart.color(id));
})
.on("mouseover", function(event, id) {
chart.focus(id);
})
.on("mouseout", function(event, id) {
chart.revert();
})
.on("click", function(event, id) {
chart.toggle(id);
});
}
},
HideLegend: {
options: {
data: {
Expand All @@ -2890,6 +2935,49 @@ var demos = {
}
}
},
LegendItemTileType: [
{
options: {
data: {
columns: [
["data1", 100],
["data2", 300],
["data3", 200]
],
type: "pie"
},
legend: {
item: {
tile: {
type: "circle",
r: 7
},
}
}
},
},
{
options: {
data: {
columns: [
["data1", 100],
["data2", 300],
["data3", 200]
],
type: "pie"
},
legend: {
item: {
tile: {
type: "rectangle",
width: 15,
height: 15
},
}
}
}
}
],
LegendPosition: {
options: {
data: {
Expand Down Expand Up @@ -2961,51 +3049,6 @@ var demos = {
}
}
},
CustomLegend: {
options: {
data: {
columns: [
["data1", 100],
["data2", 300],
["data3", 200]
],
type: "pie"
},
legend: {
show: false
}
},
func: function(chart) {
function toggle(id) { chart.toggle(id); }

d3.select(".chart_area")
.insert("div", ".chart")
.attr("class", "legend")
.selectAll("span")
.data(["data1", "data2", "data3"])
.enter()
.append("span")
.attr('data-id', function(id) {
return id;
})
.html(function(id) {
return id;
})
.each(function(id) {
d3.select(this)
.style('background-color', chart.color(id));
})
.on("mouseover", function(event, id) {
chart.focus(id);
})
.on("mouseout", function(event, id) {
chart.revert();
})
.on("click", function(event, id) {
chart.toggle(id);
});
}
},
usePoint: {
options: {
data: {
Expand Down
63 changes: 49 additions & 14 deletions src/ChartInternal/internals/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,15 +454,26 @@ export default {
updateLegendElement(targetIds: string[], options): void {
const $$ = this;
const {config, state, $el: {legend}, $T} = $$;
const legendType = config.legend_item_tile_type;
const isRectangle = legendType !== "circle";
const legendItemR = config.legend_item_tile_r;

const itemTileSize = {
width: isRectangle ? config.legend_item_tile_width : legendItemR * 2,
height: isRectangle ? config.legend_item_tile_height : legendItemR * 2
};

const paddingTop = 4;
const paddingRight = 10;
const posMin = 10;
const tileWidth = config.legend_item_tile_width + 5;
const tileWidth = itemTileSize.width + 5;

let maxWidth = 0;
let maxHeight = 0;
let xForLegend;
let yForLegend;
let totalLength = 0;

const offsets = {};
const widths = {};
const heights = {};
Expand Down Expand Up @@ -570,10 +581,10 @@ export default {
yForLegend = id => maxHeight * steps[id];
}

const xForLegendText = (id, i?: number) => xForLegend(id, i) + 4 + config.legend_item_tile_width;
const xForLegendText = (id, i?: number) => xForLegend(id, i) + 4 + itemTileSize.width;
const xForLegendRect = (id, i?: number) => xForLegend(id, i);
const x1ForLegendTile = (id, i?: number) => xForLegend(id, i) - 2;
const x2ForLegendTile = (id, i?: number) => xForLegend(id, i) - 2 + config.legend_item_tile_width;
const x2ForLegendTile = (id, i?: number) => xForLegend(id, i) - 2 + itemTileSize.width;

const yForLegendText = (id, i?: number) => yForLegend(id, i) + 9;
const yForLegendRect = (id, i?: number) => yForLegend(id, i) - 5;
Expand Down Expand Up @@ -643,15 +654,26 @@ export default {
return nodeName === "use" ? `#${state.datetimeId}-point${id}` : undefined;
});
} else {
l.append("line")
l.append(isRectangle ? "line" : legendType)
.attr("class", $LEGEND.legendItemTile)
.style("stroke", getColor)
.style("pointer-events", $$.getStylePropValue("none"))
.attr("x1", isLegendRightOrInset ? x1ForLegendTile : pos)
.attr("y1", isLegendRightOrInset ? pos : yForLegendTile)
.attr("x2", isLegendRightOrInset ? x2ForLegendTile : pos)
.attr("y2", isLegendRightOrInset ? pos : yForLegendTile)
.attr("stroke-width", config.legend_item_tile_height);
.call(selection => {
if (legendType === "circle") {
selection
.attr("r", legendItemR)
.style("fill", getColor)
.attr("cx", isLegendRightOrInset ? x2ForLegendTile : pos)
.attr("cy", isLegendRightOrInset ? pos : yForLegendTile);
} else if (isRectangle) {
selection
.attr("stroke-width", itemTileSize.height)
.attr("x1", isLegendRightOrInset ? x1ForLegendTile : pos)
.attr("y1", isLegendRightOrInset ? pos : yForLegendTile)
.attr("x2", isLegendRightOrInset ? x2ForLegendTile : pos)
.attr("y2", isLegendRightOrInset ? pos : yForLegendTile);
}
});
}

// Set background for inset legend
Expand Down Expand Up @@ -723,15 +745,28 @@ export default {
.attr("height", height);
});
} else {
const tiles = legend.selectAll(`line.${$LEGEND.legendItemTile}`)
const tiles = legend.selectAll(`.${$LEGEND.legendItemTile}`)
.data(targetIdz);

$T(tiles, withTransition)
.style("stroke", getColor)
.attr("x1", x1ForLegendTile)
.attr("y1", yForLegendTile)
.attr("x2", x2ForLegendTile)
.attr("y2", yForLegendTile);
.call(selection => {
if (legendType === "circle") {
selection
.attr("cx", d => {
const x2 = x2ForLegendTile(d);

return x2 - ((x2 - x1ForLegendTile(d)) / 2);
})
.attr("cy", yForLegendTile);
} else if (isRectangle) {
selection
.attr("x1", x1ForLegendTile)
.attr("y1", yForLegendTile)
.attr("x2", x2ForLegendTile)
.attr("y2", yForLegendTile);
}
});
}

if (background) {
Expand Down
21 changes: 18 additions & 3 deletions src/config/Options/common/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,15 @@ export default {
* @property {Function} [legend.item.onclick=undefined] Set click event handler to the legend item.
* @property {Function} [legend.item.onover=undefined] Set mouse/touch over event handler to the legend item.
* @property {Function} [legend.item.onout=undefined] Set mouse/touch out event handler to the legend item.
* @property {number} [legend.item.tile.width=10] Set width of item tile element
* @property {number} [legend.item.tile.height=10] Set height of item tile element
* @property {number} [legend.item.tile.width=10] Set width for 'rectangle' legend item tile element.
* @property {number} [legend.item.tile.height=10] ㄹ
* @property {number} [legend.item.tile.r=5] Set the radius for 'circle' legend item tile type.
* @property {string} [legend.item.tile.type="rectangle"] Set legend item shape type.<br>
* - **Available Values:**
* - circle
* - rectangle
* @property {boolean} [legend.usePoint=false] Whether to use custom points in legend.
* @see [Demo: item.tile.type](https://naver.github.io/billboard.js/demo/#Legend.LegendItemTileType)
* @see [Demo: position](https://naver.github.io/billboard.js/demo/#Legend.LegendPosition)
* @see [Demo: contents.template](https://naver.github.io/billboard.js/demo/#Legend.LegendTemplate1)
* @see [Demo: usePoint](https://naver.github.io/billboard.js/demo/#Legend.usePoint)
Expand Down Expand Up @@ -85,8 +91,15 @@ export default {
*
* // set tile's size
* tile: {
* width: 20,
* // set tile type
* type: "circle" // or "rectangle" (default)
*
* // width & height, are only applicable for 'rectangle' legend type
* width: 15,
* height: 15
*
* // radis is only applicable for 'circle' legend type
* r: 10
* }
* },
* usePoint: true
Expand All @@ -108,5 +121,7 @@ export default {
legend_padding: 0,
legend_item_tile_width: 10,
legend_item_tile_height: 10,
legend_item_tile_r: 5,
legend_item_tile_type: <"rectangle"|"circle"> "rectangle",
legend_usePoint: false
};
58 changes: 58 additions & 0 deletions test/internals/legend-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,4 +708,62 @@ describe("LEGEND", () => {
}, 50);
});
});

describe("item.tile.type option", () => {
before(() => {
args = {
data: {
columns: [
["data1", 100],
["data2", 300],
["data3", 200]
],
type: "pie", // for ESM specify as: pie()
},
legend: {
item: {
tile: {
type: "circle"
},
}
}
};
});

it("should item tile's shapes are 'circle'?", () => {
const legendItems = chart.$.legend.selectAll("circle");

expect(legendItems.size()).to.be.equal(chart.data().length);

legendItems.each(function() {
expect(+this.getAttribute("r")).to.be.equal(5);
});
});

it("set options: legend.item.tile.r=7", () => {
args.legend.item.tile.r = 7;
});

it("check 'circle' item's radius", () => {
const legendItems = chart.$.legend.selectAll("circle");

expect(legendItems.size()).to.be.equal(chart.data().length);

legendItems.each(function() {
expect(+this.getAttribute("r")).to.be.equal(args.legend.item.tile.r);
});
});

it("set options: legend.item.tile='rectangle'", () => {
args.legend.item.tile = {
type: "rectangle"
};
});

it("should item tile's shapes are 'rectangle'?", () => {
const legendItems = chart.$.legend.selectAll("line");

expect(legendItems.size()).to.be.equal(chart.data().length);
});
});
});
14 changes: 12 additions & 2 deletions types/options.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1000,14 +1000,24 @@ export interface LegendOptions {
*/
tile?: {
/**
* Tile width.
* Set width for 'rectangle' legend item tile element.
*/
width?: number;

/**
* Tile height
* Set height for 'rectangle' legend item tile element.
*/
height?: number;

/**
* Set legend item shape type.
*/
type?: "circle" | "recntangle";

/**
* Set the radius for 'circle' legend item tile type.
*/
r?: number;
};
/**
* Set click event handler to the legend item.
Expand Down

0 comments on commit 2bb9878

Please sign in to comment.