Skip to content

Commit

Permalink
feat(plugin): Intent to ship sparkline
Browse files Browse the repository at this point in the history
Implement sparkline plugin

Ref naver#2285
  • Loading branch information
netil committed Sep 3, 2021
1 parent 27cd82e commit ddb008a
Show file tree
Hide file tree
Showing 19 changed files with 566 additions and 26 deletions.
3 changes: 2 additions & 1 deletion config/rollup/esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ const plugins = [
preventAssignment: true
})
];

const external = id => /^d3-/.test(id);

const bbPlugins = readdirSync(resolvePath("../../src/Plugin/"), {
const bbPlugins = readdirSync(resolvePath("../src/Plugin/"), {
withFileTypes: true
})
.filter(dirent => dirent.isDirectory())
Expand Down
2 changes: 1 addition & 1 deletion config/webpack/plugin.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ module.exports = (common, env) => {
return mergeWithCustomize({
customizeObject: customizeObject({
entry: "replace",
output: "replace"
output: "append"
})
})(common, config);
};
18 changes: 14 additions & 4 deletions demo/chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,14 +395,24 @@ code.data;

this.$chartArea.appendChild($el);

if (/^(legend|tooltip)Template/.test(key)) {
if (/^(legend|tooltip)Template/.test(key) || /(sparkline)/.test(key)) {
const name = RegExp.$1;
let attrName = "id";

template = document.createElement("div");
template.id = this.getLowerFirstCase(RegExp.$1);

if (key === "sparkline") {
attrName = "className";
}

template[attrName] = this.getLowerFirstCase(RegExp.$1);
template.style.textAlign = "center";

this.$chartArea.appendChild(template);
template = "<div id=\""+ template.id +"\"></div>";
} else if (typeKey[0] === "Plugins") {
template = "<div "+ attrName.replace(/name/i, "") +"=\""+ template[attrName] +"\"></div>";
}

if (typeKey[0] === "Plugins") {
type.options._plugins.forEach(function(v) {
plugins = Object.keys(v).map(function(p) {
return new bb.plugin[p](v[p]);
Expand Down
70 changes: 70 additions & 0 deletions demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -3078,6 +3078,76 @@ d3.select(".chart_area")
}
}]
}
},
Sparkline: {
description: "Generates multiple tiny charts from single instance.<br>Must load or import plugin before the use.",
options: {
size: {
width: 150,
height: 50
},
data: {
columns: [
["data1", 130, 200, 150, 140, 160, 150],
["data2", 200, 130, 90, 240, 130, 220],
["data3", 300, 200, 160, 400, 250, 250],
["data4", 300, 200, 160, 400, 250, 250],
["data5", 30, 120, 250, 340, 160, 50],
["data6", 290, 270, 220, 250, 260, 120],
["data7", 283, 170, 275, 143, 220, 255],
["data8", 130, 220, 350, 340, 260, 150],
["data9", 330, 220, 150, 240, 360, 250],
["data10", 300, 200, 160, 400, 250, 250],
["data11", 230, 320, 510, 140, 160, 150],
["data12", 200, 130, 90, 240, 130, 220],
["data13", 300, 200, 160, 400, 250, 250],
["data14", 230, 230, 390, 200, 290, 220],
["data15", 130, 120, 150, 140, 160, 150],
["data16", 290, 270, 220, 250, 160, 120],
["data17", 283, 170, 275, 143, 220, 255],
["data18", 130, 220, 150, 240, 360, 250],
["data19", 350, 230, 390, 222, 321, 123],
["data20", 300, 200, 160, 400, 250, 250],
["data21", 330, 320, 350, 240, 260, 250],
["data22", 200, 130, 90, 240, 130, 220],
["data23", 300, 200, 160, 400, 250, 250],
["data24", 321, 231, 129, 297, 333, 220],
["data25", 230, 320, 250, 340, 260, 350],
["data26", 290, 170, 210, 150, 160, 220],
["data27", 283, 170, 275, 143, 220, 255],
["data28", 330, 320, 350, 340, 360, 350],
["data29", 50, 330, 90, 340, 130, 320],
["data30", 300, 200, 160, 400, 250, 250],
],
type: "area",
types: {
data1: "area",
data2: "area",
data4: "area-spline",
data5: "step",
data8: "area-step",
data9: "spline",
data10: "bar",
data12: "spline",
data15: "bar",
data20: "area-spline",
data21: "area",
data22: "area",
data23: "bar",
data24: "area-spline",
data25: "step",
data27: "area-step",
data28: "area-step",
data29: "spline",
data30: "bar",
}
},
_plugins: [{
sparkline: {
selector: ".sparkline"
}
}]
}
}
},
Point: {
Expand Down
3 changes: 3 additions & 0 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ <h4 class="sub_tit">Sample code</h4>
}),
plugins_tableview: path.map(function(p) {
return p + "plugin/billboardjs-plugin-tableview.js"
}),
plugins_sparkline: path.map(function(p) {
return p + "plugin/billboardjs-plugin-sparkline.js"
})
});

Expand Down
14 changes: 14 additions & 0 deletions demo/tomorrow.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,18 @@ pre code {
#description {
font-size: 13px;
color: gray;
}

.sparkline {
border: solid 1px #eee;
width: 150px;
height: 50px;
float: left;
}

.chart_area::after {
display: block;
float: none;
clear: left;
content: "";
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@
"style-loader": "^3.2.1",
"terser-webpack-plugin": "^5.1.4",
"tslib": "^2.3.1",
"typescript": "^4.4.2",
"typescript": "^4.3.5",
"webpack": "^5.51.1",
"webpack-bundle-analyzer": "^4.4.2",
"webpack-clean": "^1.2.5",
Expand Down
2 changes: 1 addition & 1 deletion src/ChartInternal/shape/bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default {
// Bars for each data
mainBarEnter.append("g")
.attr("class", classBars)
.style("cursor", d => (isSelectable?.bind($$.api)(d) ? "pointer" : null));
.style("cursor", d => (isSelectable?.bind?.($$.api)(d) ? "pointer" : null));
},

/**
Expand Down
20 changes: 12 additions & 8 deletions src/ChartInternal/shape/point.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,21 +250,25 @@ export default {
};
},

getCircles(i: number, id: string) {
const $$ = this;
const suffix = (isValue(i) ? `-${i}` : ``);
// getCircles(i: number, id: string) {
// const $$ = this;
// const suffix = (isValue(i) ? `-${i}` : ``);

return (id ? $$.$el.main.selectAll(`.${CLASS.circles}${$$.getTargetSelectorSuffix(id)}`) : $$.$el.main)
.selectAll(`.${CLASS.circle}${suffix}`);
},
// if (!$$.$el.circle.empty()) {
// return $$.$el.circle.filter(d => d.id === (id || d.id) && (isValue(i) ? d.index === i : true));
// }

// return (id ? $$.$el.main.selectAll(`.${CLASS.circles}${$$.getTargetSelectorSuffix(id)}`) : $$.$el.main)
// .selectAll(`.${CLASS.circle}${suffix}`);
// },

expandCircles(i: number, id: string, reset?: boolean): void {
const $$ = this;
const r = $$.pointExpandedR.bind($$);

reset && $$.unexpandCircles();

const circles = $$.getCircles(i, id).classed(CLASS.EXPANDED, true);
const circles = $$.getShapeByIndex("circle", i, id).classed(CLASS.EXPANDED, true);
const scale = r(circles) / $$.config.point_r;
const ratio = 1 - scale;

Expand Down Expand Up @@ -292,7 +296,7 @@ export default {
const $$ = this;
const r = $$.pointR.bind($$);

const circles = $$.getCircles(i)
const circles = $$.getShapeByIndex("circle", i)
.filter(function() {
return d3Select(this).classed(CLASS.EXPANDED);
})
Expand Down
23 changes: 17 additions & 6 deletions src/ChartInternal/shape/shape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
curveStep as d3CurveStep
} from "d3-shape";
import {select as d3Select} from "d3-selection";
import {d3Selection} from "types/types";
import CLASS from "../../config/classes";
import {capitalize, getUnique, isObjectType, isNumber, isValue, isUndefined, notEmpty} from "../../module/util";

Expand Down Expand Up @@ -156,7 +157,7 @@ export default {
);

return d => {
const ind = $$.getIndices(indices, d.id);
const ind = $$.getIndices(indices, d.id, "getShapeX");
const index = d.id in ind ? ind[d.id] : 0;
const targetsNum = (ind.__max__ || 0) + 1;
let x = 0;
Expand Down Expand Up @@ -348,14 +349,24 @@ export default {
* @returns {d3Selection}
* @private
*/
getShapeByIndex(shapeName: string, i: number, id?: string) {
getShapeByIndex(shapeName: string, i: number, id?: string): d3Selection {
const $$ = this;
const {main} = $$.$el;
const {$el} = $$;
const suffix = (isValue(i) ? `-${i}` : ``);
let shape = $el[shapeName];

// filter from shape reference if has
if (shape && !shape.empty()) {
shape = shape
.filter(d => (id ? d.id === id : true))
.filter(d => (isValue(i) ? d.index === i : true));
} else {
shape = (id ? $el.main
.selectAll(`.${CLASS[`${shapeName}s`]}${$$.getTargetSelectorSuffix(id)}`) : $el.main)
.selectAll(`.${CLASS[shapeName]}${suffix}`);
}

return (id ? main
.selectAll(`.${CLASS[`${shapeName}s`]}${$$.getTargetSelectorSuffix(id)}`) : main)
.selectAll(`.${CLASS[shapeName]}${suffix}`);
return shape;
},

isWithinShape(that, d): boolean {
Expand Down
2 changes: 1 addition & 1 deletion src/Plugin/bubblecompare/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import Plugin from "../Plugin";
* });
* @example
* import {bb} from "billboard.js";
* import BubbleCompare from "billboard.js/dist/billboardjs-plugin-bubblecompare.esm";
* import BubbleCompare from "billboard.js/dist/billboardjs-plugin-bubblecompare";
*
* bb.generate({
* plugins: [
Expand Down
29 changes: 29 additions & 0 deletions src/Plugin/sparkline/Options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright (c) 2021 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Sparkline plugin option class
* @class SparklineOptions
* @param {Options} options Sparkline plugin options
* @augments Plugin
* @returns {TableviewOptions}
* @private
*/
export default class Options {
constructor() {
return {
/**
* Specify sparkline charts holder selector.
* - **NOTE:** The amount of holder should match with the amount of data. If has less, will append necessaray amount nodes as sibling of main chart.
* @name selector
* @memberof plugin-sparkline
* @type {string}
* @default undefined
* @example
* selector: ".sparkline"
*/
selector: undefined
};
}
}
Loading

0 comments on commit ddb008a

Please sign in to comment.