From 18f7de7e213696e4ca3f7c029139d85b6ab3776a Mon Sep 17 00:00:00 2001 From: Masayuki Tanaka Date: Tue, 11 Aug 2015 17:33:26 +0100 Subject: [PATCH] Add bubble chart extension --- extensions/chart-bubble/bubble.js | 112 +++++++++++++++++++++++++++++ extensions/chart-bubble/c3.css | 1 + extensions/chart-bubble/c3.min.js | 1 + extensions/chart-bubble/index.html | 38 ++++++++++ 4 files changed, 152 insertions(+) create mode 100644 extensions/chart-bubble/bubble.js create mode 120000 extensions/chart-bubble/c3.css create mode 120000 extensions/chart-bubble/c3.min.js create mode 100644 extensions/chart-bubble/index.html diff --git a/extensions/chart-bubble/bubble.js b/extensions/chart-bubble/bubble.js new file mode 100644 index 0000000..8dfe607 --- /dev/null +++ b/extensions/chart-bubble/bubble.js @@ -0,0 +1,112 @@ +(function() { + var extra = {}; + + c3.chart.internal.fn.additionalConfig = { + data_pairs: [], + }; + + c3.chart.internal.fn.beforeInit = function (config) { + + var that = this; + + // update internals only when chart type is "bubble" + if (config.data.type !== 'bubble') { + return; + } + + // Set extra to ba able to be used in other part + this.extra = extra; + + extra.getKey = function (x, y) { + return x + '::' + y; + }; + + this.config.data_type = 'scatter'; + + this.config.axis_x_padding = 0; + this.config.axis_y_padding = 0; + this.config.axis_x_tick_centered = true; + this.config.axis_x_tick_format = function (d) { + return extra.names[d]; + }; + this.config.axis_y_tick_format = function (d) { + return extra.names[d]; + }; + + if (!config.color || !config.color.pattern) { + this.config.color_pattern = ['#1f77b4']; + } + + this.config.point_r = function (d) { + var names = extra.names, values = extra.values, base_length = extra.base_length, + x = names[d.x], y = d.id, key = extra.getKey(x, y), max, min, a, value, r; + + if (!base_length) { + base_length = extra.base_length = d3.min([ + that.svg.select('.c3-axis.c3-axis-y path').node().getTotalLength(), + that.svg.select('.c3-axis.c3-axis-x path').node().getTotalLength(), + ]); + } + + max = d3.max(Object.keys(values).map(function (key) { return values[key]; })); + min = d3.min(Object.keys(values).map(function (key) { return values[key]; })), + a = ((base_length / (names.length * 2)) - 1) / (Math.log(max + 1) - Math.log(min + 1)); + + value = !values[key] ? 0 : values[key]; + r = (Math.log(value + 1) - Math.log(min + 1)) * a; + + return r > 0 ? r : 0; + }; + this.config.point_sensitivity = 25; + this.config.point_focus_expand_enabled = false; + + this.config.legend_show = false; + + if (!config.tooltip || !config.tooltip.contents) { + this.config.tooltip_contents = function (d, defaultTitleFormat, defaultValueFormat, color) { + var x = extra.names[d[0].x], y = d[0].name, v = extra.values[extra.getKey(x, y)], text; + + text = ""; + text += ""; + text += ""; + text += "
" + x + " / " + y + "
" + (!v ? 0 : v) + "
"; + + return text; + }; + } + + // construct bubble chart data and setup config based on the values + + var xs = this.config.data_pairs.map(function (pair) { return pair.x; }), + ys = this.config.data_pairs.map(function (pair) { return pair.y; }); + + extra.names = d3.set(xs.concat(ys)).values().sort(); + + this.config.axis_y_tick_values = extra.names.map(function (name, i) { return i; }); + + var data_xs = {}; + extra.names.forEach(function (name) { + data_xs[name] = name + '_x'; + }); + var data_columns_xs = Object.keys(data_xs).map(function (key) { + return [data_xs[key]].concat(extra.names.map(function (name, i) { return i; })); + }); + var data_columns_values = extra.names.map(function (name, i) { + return [name].concat(extra.names.map(function (name) { return i; })); + }); + this.config.data_xs = data_xs; + this.config.data_columns = data_columns_xs.concat(data_columns_values); + + var values = {}; + this.config.data_pairs.forEach(function (pair) { + if (!pair.x || !pair.y) { + throw "x and y are required in data."; + } + values[extra.getKey(pair.x, pair.y)] = pair.value; + }); + extra.values = values; + + this.config.axis_x_min = this.config.axis_y_min = -0.5; + this.config.axis_x_max = this.config.axis_y_max = extra.names.length - 0.5; + }; +})(window); diff --git a/extensions/chart-bubble/c3.css b/extensions/chart-bubble/c3.css new file mode 120000 index 0000000..4052640 --- /dev/null +++ b/extensions/chart-bubble/c3.css @@ -0,0 +1 @@ +../../c3.css \ No newline at end of file diff --git a/extensions/chart-bubble/c3.min.js b/extensions/chart-bubble/c3.min.js new file mode 120000 index 0000000..a221dd2 --- /dev/null +++ b/extensions/chart-bubble/c3.min.js @@ -0,0 +1 @@ +../../c3.min.js \ No newline at end of file diff --git a/extensions/chart-bubble/index.html b/extensions/chart-bubble/index.html new file mode 100644 index 0000000..ede5f27 --- /dev/null +++ b/extensions/chart-bubble/index.html @@ -0,0 +1,38 @@ + + + + + +
+ + + + + + +