Browse Source

gh-1765 Building with Rollup

separates Chart.prototype fns from ChartInternal.prototype fns (api.flow and api.transform)
separates Chart.prototype fns from ChartInternal.prototype fns (api.flow and api.transform)
separates sources into 3 modules + core

moves API and inherit functions to their own file, inside axis folder

moves ChartInternal constructor from core.js to chartinternal/index.js file

moves Chart constructor from core.js to chart/index.js file

moves Chart constructor from core.js to chart/index.js file

separates core.js into start.js and end.js

separates remaining core.js logic  into head.js and tail.js

polyfill should be in the global namespace

concatenate using the new paths

creates multitask to generate modules axis, chart and chartinternal

runs tests against new module structures

adds rollup script

module concat tasks also add their imports and exports

es6_modules folder, which also contains rollup.entry skeleton

adds rollup task

renames api_inherits

multitask build_rollup
v1-dev
Amenadiel 9 years ago committed by Ændrew Rininsland
parent
commit
403465bc56
No known key found for this signature in database
GPG Key ID: ADBCD4C867F9B2DA
  1. 237
      Gruntfile.coffee
  2. 9848
      c3.js
  3. 736
      es6_modules/axis.js
  4. 764
      es6_modules/chart.js
  5. 5948
      es6_modules/chartinternal.js
  6. 31
      es6_modules/rollup.entry.js
  7. 35
      package.json
  8. 292
      src/api.flow.js
  9. 16
      src/api.transform.js
  10. 0
      src/axis/axis.js
  11. 0
      src/axis/c3.axis.js
  12. 18
      src/axis/index.js
  13. 0
      src/chart/api.axis.js
  14. 0
      src/chart/api.category.js
  15. 0
      src/chart/api.chart.js
  16. 0
      src/chart/api.color.js
  17. 0
      src/chart/api.data.js
  18. 143
      src/chart/api.flow.js
  19. 0
      src/chart/api.focus.js
  20. 0
      src/chart/api.grid.js
  21. 0
      src/chart/api.group.js
  22. 0
      src/chart/api.legend.js
  23. 0
      src/chart/api.load.js
  24. 0
      src/chart/api.region.js
  25. 0
      src/chart/api.selection.js
  26. 0
      src/chart/api.show.js
  27. 0
      src/chart/api.tooltip.js
  28. 5
      src/chart/api.transform.js
  29. 0
      src/chart/api.x.js
  30. 0
      src/chart/api.zoom.js
  31. 23
      src/chart/index.js
  32. 0
      src/chartinternal/arc.js
  33. 0
      src/chartinternal/cache.js
  34. 0
      src/chartinternal/category.js
  35. 0
      src/chartinternal/class.js
  36. 0
      src/chartinternal/clip.js
  37. 0
      src/chartinternal/color.js
  38. 0
      src/chartinternal/config.js
  39. 0
      src/chartinternal/data.convert.js
  40. 0
      src/chartinternal/data.js
  41. 0
      src/chartinternal/data.load.js
  42. 0
      src/chartinternal/domain.js
  43. 0
      src/chartinternal/drag.js
  44. 155
      src/chartinternal/flow.js
  45. 0
      src/chartinternal/format.js
  46. 0
      src/chartinternal/grid.js
  47. 378
      src/chartinternal/index.js
  48. 0
      src/chartinternal/interaction.js
  49. 0
      src/chartinternal/legend.js
  50. 0
      src/chartinternal/region.js
  51. 0
      src/chartinternal/scale.js
  52. 0
      src/chartinternal/selection.js
  53. 0
      src/chartinternal/shape.bar.js
  54. 0
      src/chartinternal/shape.js
  55. 0
      src/chartinternal/shape.line.js
  56. 0
      src/chartinternal/size.js
  57. 0
      src/chartinternal/subchart.js
  58. 0
      src/chartinternal/text.js
  59. 0
      src/chartinternal/title.js
  60. 0
      src/chartinternal/tooltip.js
  61. 10
      src/chartinternal/transform.js
  62. 0
      src/chartinternal/type.js
  63. 0
      src/chartinternal/ua.js
  64. 0
      src/chartinternal/util.js
  65. 0
      src/chartinternal/zoom.js
  66. 12
      src/head.js
  67. 24
      src/tail.js

237
Gruntfile.coffee

@ -1,7 +1,24 @@
module.exports = (grunt) ->
require('load-grunt-tasks') grunt, pattern: ['grunt-contrib-*', 'grunt-sass', 'grunt-karma']
require('load-grunt-tasks') grunt, pattern: ['grunt-contrib-*', 'grunt-sass', 'grunt-karma', 'grunt-rollup']
grunt.initConfig
rollup:
options:
external: ['d3']
format: "umd"
moduleName: "c3"
globals:
d3: 'd3'
files:
src: 'es6_modules/rollup.entry.js'
dest: 'c3.es6.js'
watch:
concat:
tasks: 'concat'
@ -11,6 +28,102 @@ module.exports = (grunt) ->
files: ['src/scss/*.scss']
concat:
axis:
options:
process: (src, filepath) ->
if filepath.indexOf('axis/index')!=-1
src= "import {CLASS,isValue,isFunction,isString,isUndefined,isDefined,ceil10,asHalfPixel,diffDomain,isEmpty,notEmpty,getOption,hasValue,sanitise,getPathBox, ChartInternal} from './chartinternal.js';"+'\n'+src;
if filepath.indexOf('axis/axis')!=-1
src = src + 'export {Axis};'+'\n'+'export default Axis;';
return src
src: [
'src/axis/index.js',
'src/axis/c3.axis.js',
'src/axis/axis.js',
]
dest: 'es6_modules/axis.js'
chart:
options:
process: (src, filepath) ->
if filepath.indexOf('chart/index')!=-1
src= "import {CLASS,isValue,isFunction,isString,isUndefined,isDefined,ceil10,asHalfPixel,diffDomain,isEmpty,notEmpty,getOption,hasValue,sanitise,getPathBox, ChartInternal} from './chartinternal.js';"+'\n'+src;
if filepath.indexOf('chart/api.tooltip')!=-1
src = src + 'export {Chart};'+'\n'+'export default Chart;';
return src
src: [
'src/chart/index.js',
'src/chart/api.focus.js',
'src/chart/api.show.js',
'src/chart/api.zoom.js',
'src/chart/api.load.js',
'src/chart/api.flow.js',
'src/chart/api.selection.js',
'src/chart/api.transform.js',
'src/chart/api.group.js',
'src/chart/api.grid.js',
'src/chart/api.region.js',
'src/chart/api.data.js',
'src/chart/api.category.js',
'src/chart/api.color.js',
'src/chart/api.x.js',
'src/chart/api.axis.js',
'src/chart/api.legend.js',
'src/chart/api.chart.js',
'src/chart/api.tooltip.js'
]
dest: 'es6_modules/chart.js'
chartinternal:
options:
process: (src, filepath) ->
if filepath.indexOf('chartinternal/index')!=-1
src= "import d3 from 'd3';"+'\n'+src;
src= "import {Axis} from './axis.js';"+'\n'+src;
if filepath.indexOf('chartinternal/ua')!=-1
src = src + 'export {CLASS,isValue,isFunction,isString,isUndefined,isDefined,ceil10,asHalfPixel,diffDomain,isEmpty,notEmpty,getOption,hasValue,sanitise,getPathBox, ChartInternal};'+'\n'+'export default ChartIntenal;'
return src
src: [
'src/chartinternal/index.js',
'src/chartinternal/config.js',
'src/chartinternal/scale.js',
'src/chartinternal/domain.js',
'src/chartinternal/data.js',
'src/chartinternal/data.convert.js',
'src/chartinternal/data.load.js',
'src/chartinternal/category.js',
'src/chartinternal/interaction.js',
'src/chartinternal/size.js',
'src/chartinternal/shape.js',
'src/chartinternal/shape.line.js',
'src/chartinternal/shape.bar.js',
'src/chartinternal/text.js',
'src/chartinternal/type.js',
'src/chartinternal/grid.js',
'src/chartinternal/tooltip.js',
'src/chartinternal/legend.js',
'src/chartinternal/title.js',
'src/chartinternal/clip.js',
'src/chartinternal/arc.js',
'src/chartinternal/region.js',
'src/chartinternal/drag.js',
'src/chartinternal/selection.js',
'src/chartinternal/subchart.js',
'src/chartinternal/zoom.js',
'src/chartinternal/color.js',
'src/chartinternal/format.js',
'src/chartinternal/cache.js',
'src/chartinternal/class.js',
'src/chartinternal/util.js',
'src/chartinternal/transform.js',
'src/chartinternal/flow.js',
'src/chartinternal/ua.js'
]
dest: 'es6_modules/chartinternal.js'
dist:
options:
process: (src, filepath) ->
@ -22,60 +135,71 @@ module.exports = (grunt) ->
return src
src: [
'src/head.js',
'src/core.js',
'src/config.js',
'src/scale.js',
'src/domain.js',
'src/data.js',
'src/data.convert.js',
'src/data.load.js',
'src/category.js',
'src/interaction.js',
'src/size.js',
'src/shape.js',
'src/shape.line.js',
'src/shape.bar.js',
'src/text.js',
'src/type.js',
'src/grid.js',
'src/tooltip.js',
'src/legend.js',
'src/title.js',
'src/axis.js',
'src/clip.js',
'src/arc.js',
'src/region.js',
'src/drag.js',
'src/selection.js',
'src/subchart.js',
'src/zoom.js',
'src/color.js',
'src/format.js',
'src/cache.js',
'src/class.js',
'src/util.js',
'src/api.focus.js',
'src/api.show.js',
'src/api.zoom.js',
'src/api.load.js',
'src/api.flow.js',
'src/api.selection.js',
'src/api.transform.js',
'src/api.group.js',
'src/api.grid.js',
'src/api.region.js',
'src/api.data.js',
'src/api.category.js',
'src/api.color.js',
'src/api.x.js',
'src/api.axis.js',
'src/api.legend.js',
'src/api.chart.js',
'src/api.tooltip.js',
'src/c3.axis.js',
'src/ua.js',
'src/polyfill.js',
'src/tail.js'
'src/axis/index.js',
'src/axis/c3.axis.js',
'src/axis/axis.js',
'src/chartinternal/index.js',
'src/chartinternal/config.js',
'src/chartinternal/scale.js',
'src/chartinternal/domain.js',
'src/chartinternal/data.js',
'src/chartinternal/data.convert.js',
'src/chartinternal/data.load.js',
'src/chartinternal/category.js',
'src/chartinternal/interaction.js',
'src/chartinternal/size.js',
'src/chartinternal/shape.js',
'src/chartinternal/shape.line.js',
'src/chartinternal/shape.bar.js',
'src/chartinternal/text.js',
'src/chartinternal/type.js',
'src/chartinternal/grid.js',
'src/chartinternal/tooltip.js',
'src/chartinternal/legend.js',
'src/chartinternal/title.js',
'src/chartinternal/clip.js',
'src/chartinternal/arc.js',
'src/chartinternal/region.js',
'src/chartinternal/drag.js',
'src/chartinternal/selection.js',
'src/chartinternal/subchart.js',
'src/chartinternal/zoom.js',
'src/chartinternal/color.js',
'src/chartinternal/format.js',
'src/chartinternal/cache.js',
'src/chartinternal/class.js',
'src/chartinternal/util.js',
'src/chartinternal/transform.js',
'src/chartinternal/flow.js',
'src/chartinternal/ua.js',
'src/chart/index.js',
'src/chart/api.focus.js',
'src/chart/api.show.js',
'src/chart/api.zoom.js',
'src/chart/api.load.js',
'src/chart/api.flow.js',
'src/chart/api.selection.js',
'src/chart/api.transform.js',
'src/chart/api.group.js',
'src/chart/api.grid.js',
'src/chart/api.region.js',
'src/chart/api.data.js',
'src/chart/api.category.js',
'src/chart/api.color.js',
'src/chart/api.x.js',
'src/chart/api.axis.js',
'src/chart/api.legend.js',
'src/chart/api.chart.js',
'src/chart/api.tooltip.js',
'src/tail.js',
'src/polyfill.js'
]
dest: 'c3.js'
@ -109,6 +233,7 @@ module.exports = (grunt) ->
grunt.registerTask 'lint', ['jshint']
grunt.registerTask 'test', ['karma']
grunt.registerTask 'build', ['concat', 'sass']
grunt.registerTask 'build', ['concat:dist', 'sass']
grunt.registerTask 'minify', ['cssmin', 'uglify']
grunt.registerTask 'default', ['lint', 'build', 'test', 'minify']
grunt.registerTask 'build_rollup', ['concat:axis', 'concat:chart', 'concat:chartinternal','rollup']

9848
c3.js

File diff suppressed because it is too large Load Diff

736
es6_modules/axis.js

@ -0,0 +1,736 @@
import {CLASS,isValue,isFunction,isString,isUndefined,isDefined,ceil10,asHalfPixel,diffDomain,isEmpty,notEmpty,getOption,hasValue,sanitise,getPathBox, ChartInternal} from './chartinternal.js';
function API(owner) {
this.owner = owner;
}
function inherit(base, derived) {
if (Object.create) {
derived.prototype = Object.create(base.prototype);
} else {
var f = function f() {};
f.prototype = base.prototype;
derived.prototype = new f();
}
derived.prototype.constructor = derived;
return derived;
}
// Features:
// 1. category axis
// 2. ceil values of translate/x/y to int for half pixel antialiasing
// 3. multiline tick text
var tickTextCharSize;
function c3_axis(d3, params) {
var scale = d3.scale.linear(), orient = "bottom", innerTickSize = 6, outerTickSize, tickPadding = 3, tickValues = null, tickFormat, tickArguments;
var tickOffset = 0, tickCulling = true, tickCentered;
params = params || {};
outerTickSize = params.withOuterTick ? 6 : 0;
function axisX(selection, x) {
selection.attr("transform", function (d) {
return "translate(" + Math.ceil(x(d) + tickOffset) + ", 0)";
});
}
function axisY(selection, y) {
selection.attr("transform", function (d) {
return "translate(0," + Math.ceil(y(d)) + ")";
});
}
function scaleExtent(domain) {
var start = domain[0], stop = domain[domain.length - 1];
return start < stop ? [ start, stop ] : [ stop, start ];
}
function generateTicks(scale) {
var i, domain, ticks = [];
if (scale.ticks) {
return scale.ticks.apply(scale, tickArguments);
}
domain = scale.domain();
for (i = Math.ceil(domain[0]); i < domain[1]; i++) {
ticks.push(i);
}
if (ticks.length > 0 && ticks[0] > 0) {
ticks.unshift(ticks[0] - (ticks[1] - ticks[0]));
}
return ticks;
}
function copyScale() {
var newScale = scale.copy(), domain;
if (params.isCategory) {
domain = scale.domain();
newScale.domain([domain[0], domain[1] - 1]);
}
return newScale;
}
function textFormatted(v) {
var formatted = tickFormat ? tickFormat(v) : v;
return typeof formatted !== 'undefined' ? formatted : '';
}
function getSizeFor1Char(tick) {
if (tickTextCharSize) {
return tickTextCharSize;
}
var size = {
h: 11.5,
w: 5.5
};
tick.select('text').text(textFormatted).each(function (d) {
var box = this.getBoundingClientRect(),
text = textFormatted(d),
h = box.height,
w = text ? (box.width / text.length) : undefined;
if (h && w) {
size.h = h;
size.w = w;
}
}).text('');
tickTextCharSize = size;
return size;
}
function transitionise(selection) {
return params.withoutTransition ? selection : d3.transition(selection);
}
function axis(g) {
g.each(function () {
var g = axis.g = d3.select(this);
var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = copyScale();
var ticks = tickValues ? tickValues : generateTicks(scale1),
tick = g.selectAll(".tick").data(ticks, scale1),
tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6),
// MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.
tickExit = tick.exit().remove(),
tickUpdate = transitionise(tick).style("opacity", 1),
tickTransform, tickX, tickY;
var range = scale.rangeExtent ? scale.rangeExtent() : scaleExtent(scale.range()),
path = g.selectAll(".domain").data([ 0 ]),
pathUpdate = (path.enter().append("path").attr("class", "domain"), transitionise(path));
tickEnter.append("line");
tickEnter.append("text");
var lineEnter = tickEnter.select("line"),
lineUpdate = tickUpdate.select("line"),
textEnter = tickEnter.select("text"),
textUpdate = tickUpdate.select("text");
if (params.isCategory) {
tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);
tickX = tickCentered ? 0 : tickOffset;
tickY = tickCentered ? tickOffset : 0;
} else {
tickOffset = tickX = 0;
}
var text, tspan, sizeFor1Char = getSizeFor1Char(g.select('.tick')), counts = [];
var tickLength = Math.max(innerTickSize, 0) + tickPadding,
isVertical = orient === 'left' || orient === 'right';
// this should be called only when category axis
function splitTickText(d, maxWidth) {
var tickText = textFormatted(d),
subtext, spaceIndex, textWidth, splitted = [];
if (Object.prototype.toString.call(tickText) === "[object Array]") {
return tickText;
}
if (!maxWidth || maxWidth <= 0) {
maxWidth = isVertical ? 95 : params.isCategory ? (Math.ceil(scale1(ticks[1]) - scale1(ticks[0])) - 12) : 110;
}
function split(splitted, text) {
spaceIndex = undefined;
for (var i = 1; i < text.length; i++) {
if (text.charAt(i) === ' ') {
spaceIndex = i;
}
subtext = text.substr(0, i + 1);
textWidth = sizeFor1Char.w * subtext.length;
// if text width gets over tick width, split by space index or crrent index
if (maxWidth < textWidth) {
return split(
splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)),
text.slice(spaceIndex ? spaceIndex + 1 : i)
);
}
}
return splitted.concat(text);
}
return split(splitted, tickText + "");
}
function tspanDy(d, i) {
var dy = sizeFor1Char.h;
if (i === 0) {
if (orient === 'left' || orient === 'right') {
dy = -((counts[d.index] - 1) * (sizeFor1Char.h / 2) - 3);
} else {
dy = ".71em";
}
}
return dy;
}
function tickSize(d) {
var tickPosition = scale(d) + (tickCentered ? 0 : tickOffset);
return range[0] < tickPosition && tickPosition < range[1] ? innerTickSize : 0;
}
text = tick.select("text");
tspan = text.selectAll('tspan')
.data(function (d, i) {
var splitted = params.tickMultiline ? splitTickText(d, params.tickWidth) : [].concat(textFormatted(d));
counts[i] = splitted.length;
return splitted.map(function (s) {
return { index: i, splitted: s };
});
});
tspan.enter().append('tspan');
tspan.exit().remove();
tspan.text(function (d) { return d.splitted; });
var rotate = params.tickTextRotate;
function textAnchorForText(rotate) {
if (!rotate) {
return 'middle';
}
return rotate > 0 ? "start" : "end";
}
function textTransform(rotate) {
if (!rotate) {
return '';
}
return "rotate(" + rotate + ")";
}
function dxForText(rotate) {
if (!rotate) {
return 0;
}
return 8 * Math.sin(Math.PI * (rotate / 180));
}
function yForText(rotate) {
if (!rotate) {
return tickLength;
}
return 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1);
}
switch (orient) {
case "bottom":
{
tickTransform = axisX;
lineEnter.attr("y2", innerTickSize);
textEnter.attr("y", tickLength);
lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", tickSize);
textUpdate.attr("x", 0).attr("y", yForText(rotate))
.style("text-anchor", textAnchorForText(rotate))
.attr("transform", textTransform(rotate));
tspan.attr('x', 0).attr("dy", tspanDy).attr('dx', dxForText(rotate));
pathUpdate.attr("d", "M" + range[0] + "," + outerTickSize + "V0H" + range[1] + "V" + outerTickSize);
break;
}
case "top":
{
// TODO: rotated tick text
tickTransform = axisX;
lineEnter.attr("y2", -innerTickSize);
textEnter.attr("y", -tickLength);
lineUpdate.attr("x2", 0).attr("y2", -innerTickSize);
textUpdate.attr("x", 0).attr("y", -tickLength);
text.style("text-anchor", "middle");
tspan.attr('x', 0).attr("dy", "0em");
pathUpdate.attr("d", "M" + range[0] + "," + -outerTickSize + "V0H" + range[1] + "V" + -outerTickSize);
break;
}
case "left":
{
tickTransform = axisY;
lineEnter.attr("x2", -innerTickSize);
textEnter.attr("x", -tickLength);
lineUpdate.attr("x2", -innerTickSize).attr("y1", tickY).attr("y2", tickY);
textUpdate.attr("x", -tickLength).attr("y", tickOffset);
text.style("text-anchor", "end");
tspan.attr('x', -tickLength).attr("dy", tspanDy);
pathUpdate.attr("d", "M" + -outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + -outerTickSize);
break;
}
case "right":
{
tickTransform = axisY;
lineEnter.attr("x2", innerTickSize);
textEnter.attr("x", tickLength);
lineUpdate.attr("x2", innerTickSize).attr("y2", 0);
textUpdate.attr("x", tickLength).attr("y", 0);
text.style("text-anchor", "start");
tspan.attr('x', tickLength).attr("dy", tspanDy);
pathUpdate.attr("d", "M" + outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + outerTickSize);
break;
}
}
if (scale1.rangeBand) {
var x = scale1, dx = x.rangeBand() / 2;
scale0 = scale1 = function (d) {
return x(d) + dx;
};
} else if (scale0.rangeBand) {
scale0 = scale1;
} else {
tickExit.call(tickTransform, scale1);
}
tickEnter.call(tickTransform, scale0);
tickUpdate.call(tickTransform, scale1);
});
}
axis.scale = function (x) {
if (!arguments.length) { return scale; }
scale = x;
return axis;
};
axis.orient = function (x) {
if (!arguments.length) { return orient; }
orient = x in {top: 1, right: 1, bottom: 1, left: 1} ? x + "" : "bottom";
return axis;
};
axis.tickFormat = function (format) {
if (!arguments.length) { return tickFormat; }
tickFormat = format;
return axis;
};
axis.tickCentered = function (isCentered) {
if (!arguments.length) { return tickCentered; }
tickCentered = isCentered;
return axis;
};
axis.tickOffset = function () {
return tickOffset;
};
axis.tickInterval = function () {
var interval, length;
if (params.isCategory) {
interval = tickOffset * 2;
}
else {
length = axis.g.select('path.domain').node().getTotalLength() - outerTickSize * 2;
interval = length / axis.g.selectAll('line').size();
}
return interval === Infinity ? 0 : interval;
};
axis.ticks = function () {
if (!arguments.length) { return tickArguments; }
tickArguments = arguments;
return axis;
};
axis.tickCulling = function (culling) {
if (!arguments.length) { return tickCulling; }
tickCulling = culling;
return axis;
};
axis.tickValues = function (x) {
if (typeof x === 'function') {
tickValues = function () {
return x(scale.domain());
};
}
else {
if (!arguments.length) { return tickValues; }
tickValues = x;
}
return axis;
};
return axis;
}
function Axis(owner) {
API.call(this, owner);
}
inherit(API, Axis);
Axis.prototype.init = function init() {
var $$ = this.owner, config = $$.config, main = $$.main;
$$.axes.x = main.append("g")
.attr("class", CLASS.axis + ' ' + CLASS.axisX)
.attr("clip-path", $$.clipPathForXAxis)
.attr("transform", $$.getTranslate('x'))
.style("visibility", config.axis_x_show ? 'visible' : 'hidden');
$$.axes.x.append("text")
.attr("class", CLASS.axisXLabel)
.attr("transform", config.axis_rotated ? "rotate(-90)" : "")
.style("text-anchor", this.textAnchorForXAxisLabel.bind(this));
$$.axes.y = main.append("g")
.attr("class", CLASS.axis + ' ' + CLASS.axisY)
.attr("clip-path", config.axis_y_inner ? "" : $$.clipPathForYAxis)
.attr("transform", $$.getTranslate('y'))
.style("visibility", config.axis_y_show ? 'visible' : 'hidden');
$$.axes.y.append("text")
.attr("class", CLASS.axisYLabel)
.attr("transform", config.axis_rotated ? "" : "rotate(-90)")
.style("text-anchor", this.textAnchorForYAxisLabel.bind(this));
$$.axes.y2 = main.append("g")
.attr("class", CLASS.axis + ' ' + CLASS.axisY2)
// clip-path?
.attr("transform", $$.getTranslate('y2'))
.style("visibility", config.axis_y2_show ? 'visible' : 'hidden');
$$.axes.y2.append("text")
.attr("class", CLASS.axisY2Label)
.attr("transform", config.axis_rotated ? "" : "rotate(-90)")
.style("text-anchor", this.textAnchorForY2AxisLabel.bind(this));
};
Axis.prototype.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {
var $$ = this.owner, config = $$.config,
axisParams = {
isCategory: $$.isCategorized(),
withOuterTick: withOuterTick,
tickMultiline: config.axis_x_tick_multiline,
tickWidth: config.axis_x_tick_width,
tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,
withoutTransition: withoutTransition,
},
axis = c3_axis($$.d3, axisParams).scale(scale).orient(orient);
if ($$.isTimeSeries() && tickValues && typeof tickValues !== "function") {
tickValues = tickValues.map(function (v) { return $$.parseDate(v); });
}
// Set tick
axis.tickFormat(tickFormat).tickValues(tickValues);
if ($$.isCategorized()) {
axis.tickCentered(config.axis_x_tick_centered);
if (isEmpty(config.axis_x_tick_culling)) {
config.axis_x_tick_culling = false;
}
}
return axis;
};
Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(targets, axis) {
var $$ = this.owner, config = $$.config, tickValues;
if (config.axis_x_tick_fit || config.axis_x_tick_count) {
tickValues = this.generateTickValues($$.mapTargetsToUniqueXs(targets), config.axis_x_tick_count, $$.isTimeSeries());
}
if (axis) {
axis.tickValues(tickValues);
} else {
$$.xAxis.tickValues(tickValues);
$$.subXAxis.tickValues(tickValues);
}
return tickValues;
};
Axis.prototype.getYAxis = function getYAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {
var $$ = this.owner, config = $$.config,
axisParams = {
withOuterTick: withOuterTick,
withoutTransition: withoutTransition,
tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate
},
axis = c3_axis($$.d3, axisParams).scale(scale).orient(orient).tickFormat(tickFormat);
if ($$.isTimeSeriesY()) {
axis.ticks($$.d3.time[config.axis_y_tick_time_value], config.axis_y_tick_time_interval);
} else {
axis.tickValues(tickValues);
}
return axis;
};
Axis.prototype.getId = function getId(id) {
var config = this.owner.config;
return id in config.data_axes ? config.data_axes[id] : 'y';
};
Axis.prototype.getXAxisTickFormat = function getXAxisTickFormat() {
var $$ = this.owner, config = $$.config,
format = $$.isTimeSeries() ? $$.defaultAxisTimeFormat : $$.isCategorized() ? $$.categoryName : function (v) { return v < 0 ? v.toFixed(0) : v; };
if (config.axis_x_tick_format) {
if (isFunction(config.axis_x_tick_format)) {
format = config.axis_x_tick_format;
} else if ($$.isTimeSeries()) {
format = function (date) {
return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : "";
};
}
}
return isFunction(format) ? function (v) { return format.call($$, v); } : format;
};
Axis.prototype.getTickValues = function getTickValues(tickValues, axis) {
return tickValues ? tickValues : axis ? axis.tickValues() : undefined;
};
Axis.prototype.getXAxisTickValues = function getXAxisTickValues() {
return this.getTickValues(this.owner.config.axis_x_tick_values, this.owner.xAxis);
};
Axis.prototype.getYAxisTickValues = function getYAxisTickValues() {
return this.getTickValues(this.owner.config.axis_y_tick_values, this.owner.yAxis);
};
Axis.prototype.getY2AxisTickValues = function getY2AxisTickValues() {
return this.getTickValues(this.owner.config.axis_y2_tick_values, this.owner.y2Axis);
};
Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(axisId) {
var $$ = this.owner, config = $$.config, option;
if (axisId === 'y') {
option = config.axis_y_label;
} else if (axisId === 'y2') {
option = config.axis_y2_label;
} else if (axisId === 'x') {
option = config.axis_x_label;
}
return option;
};
Axis.prototype.getLabelText = function getLabelText(axisId) {
var option = this.getLabelOptionByAxisId(axisId);
return isString(option) ? option : option ? option.text : null;
};
Axis.prototype.setLabelText = function setLabelText(axisId, text) {
var $$ = this.owner, config = $$.config,
option = this.getLabelOptionByAxisId(axisId);
if (isString(option)) {
if (axisId === 'y') {
config.axis_y_label = text;
} else if (axisId === 'y2') {
config.axis_y2_label = text;
} else if (axisId === 'x') {
config.axis_x_label = text;
}
} else if (option) {
option.text = text;
}
};
Axis.prototype.getLabelPosition = function getLabelPosition(axisId, defaultPosition) {
var option = this.getLabelOptionByAxisId(axisId),
position = (option && typeof option === 'object' && option.position) ? option.position : defaultPosition;
return {
isInner: position.indexOf('inner') >= 0,
isOuter: position.indexOf('outer') >= 0,
isLeft: position.indexOf('left') >= 0,
isCenter: position.indexOf('center') >= 0,
isRight: position.indexOf('right') >= 0,
isTop: position.indexOf('top') >= 0,
isMiddle: position.indexOf('middle') >= 0,
isBottom: position.indexOf('bottom') >= 0
};
};
Axis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() {
return this.getLabelPosition('x', this.owner.config.axis_rotated ? 'inner-top' : 'inner-right');
};
Axis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() {
return this.getLabelPosition('y', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');
};
Axis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() {
return this.getLabelPosition('y2', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');
};
Axis.prototype.getLabelPositionById = function getLabelPositionById(id) {
return id === 'y2' ? this.getY2AxisLabelPosition() : id === 'y' ? this.getYAxisLabelPosition() : this.getXAxisLabelPosition();
};
Axis.prototype.textForXAxisLabel = function textForXAxisLabel() {
return this.getLabelText('x');
};
Axis.prototype.textForYAxisLabel = function textForYAxisLabel() {
return this.getLabelText('y');
};
Axis.prototype.textForY2AxisLabel = function textForY2AxisLabel() {
return this.getLabelText('y2');
};
Axis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) {
var $$ = this.owner;
if (forHorizontal) {
return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width;
} else {
return position.isBottom ? -$$.height : position.isMiddle ? -$$.height / 2 : 0;
}
};
Axis.prototype.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) {
if (forHorizontal) {
return position.isLeft ? "0.5em" : position.isRight ? "-0.5em" : "0";
} else {
return position.isTop ? "-0.5em" : position.isBottom ? "0.5em" : "0";
}
};
Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(forHorizontal, position) {
if (forHorizontal) {
return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end';
} else {
return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end';
}
};
Axis.prototype.xForXAxisLabel = function xForXAxisLabel() {
return this.xForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());
};
Axis.prototype.xForYAxisLabel = function xForYAxisLabel() {
return this.xForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());
};
Axis.prototype.xForY2AxisLabel = function xForY2AxisLabel() {
return this.xForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());
};
Axis.prototype.dxForXAxisLabel = function dxForXAxisLabel() {
return this.dxForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());
};
Axis.prototype.dxForYAxisLabel = function dxForYAxisLabel() {
return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());
};
Axis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() {
return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());
};
Axis.prototype.dyForXAxisLabel = function dyForXAxisLabel() {
var $$ = this.owner, config = $$.config,
position = this.getXAxisLabelPosition();
if (config.axis_rotated) {
return position.isInner ? "1.2em" : -25 - this.getMaxTickWidth('x');
} else {
return position.isInner ? "-0.5em" : config.axis_x_height ? config.axis_x_height - 10 : "3em";
}
};
Axis.prototype.dyForYAxisLabel = function dyForYAxisLabel() {
var $$ = this.owner,
position = this.getYAxisLabelPosition();
if ($$.config.axis_rotated) {
return position.isInner ? "-0.5em" : "3em";
} else {
return position.isInner ? "1.2em" : -10 - ($$.config.axis_y_inner ? 0 : (this.getMaxTickWidth('y') + 10));
}
};
Axis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() {
var $$ = this.owner,
position = this.getY2AxisLabelPosition();
if ($$.config.axis_rotated) {
return position.isInner ? "1.2em" : "-2.2em";
} else {
return position.isInner ? "-0.5em" : 15 + ($$.config.axis_y2_inner ? 0 : (this.getMaxTickWidth('y2') + 15));
}
};
Axis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() {
var $$ = this.owner;
return this.textAnchorForAxisLabel(!$$.config.axis_rotated, this.getXAxisLabelPosition());
};
Axis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() {
var $$ = this.owner;
return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getYAxisLabelPosition());
};
Axis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() {
var $$ = this.owner;
return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getY2AxisLabelPosition());
};
Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute) {
var $$ = this.owner, config = $$.config,
maxWidth = 0, targetsToShow, scale, axis, dummy, svg;
if (withoutRecompute && $$.currentMaxTickWidths[id]) {
return $$.currentMaxTickWidths[id];
}
if ($$.svg) {
targetsToShow = $$.filterTargetsToShow($$.data.targets);
if (id === 'y') {
scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));
axis = this.getYAxis(scale, $$.yOrient, config.axis_y_tick_format, $$.yAxisTickValues, false, true, true);
} else if (id === 'y2') {
scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));
axis = this.getYAxis(scale, $$.y2Orient, config.axis_y2_tick_format, $$.y2AxisTickValues, false, true, true);
} else {
scale = $$.x.copy().domain($$.getXDomain(targetsToShow));
axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true);
this.updateXAxisTickValues(targetsToShow, axis);
}
dummy = $$.d3.select('body').append('div').classed('c3', true);
svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0),
svg.append('g').call(axis).each(function () {
$$.d3.select(this).selectAll('text').each(function () {
var box = this.getBoundingClientRect();
if (maxWidth < box.width) { maxWidth = box.width; }
});
dummy.remove();
});
}
$$.currentMaxTickWidths[id] = maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth;
return $$.currentMaxTickWidths[id];
};
Axis.prototype.updateLabels = function updateLabels(withTransition) {
var $$ = this.owner;
var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel),
axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel),
axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label);
(withTransition ? axisXLabel.transition() : axisXLabel)
.attr("x", this.xForXAxisLabel.bind(this))
.attr("dx", this.dxForXAxisLabel.bind(this))
.attr("dy", this.dyForXAxisLabel.bind(this))
.text(this.textForXAxisLabel.bind(this));
(withTransition ? axisYLabel.transition() : axisYLabel)
.attr("x", this.xForYAxisLabel.bind(this))
.attr("dx", this.dxForYAxisLabel.bind(this))
.attr("dy", this.dyForYAxisLabel.bind(this))
.text(this.textForYAxisLabel.bind(this));
(withTransition ? axisY2Label.transition() : axisY2Label)
.attr("x", this.xForY2AxisLabel.bind(this))
.attr("dx", this.dxForY2AxisLabel.bind(this))
.attr("dy", this.dyForY2AxisLabel.bind(this))
.text(this.textForY2AxisLabel.bind(this));
};
Axis.prototype.getPadding = function getPadding(padding, key, defaultValue, domainLength) {
var p = typeof padding === 'number' ? padding : padding[key];
if (!isValue(p)) {
return defaultValue;
}
if (padding.unit === 'ratio') {
return padding[key] * domainLength;
}
// assume padding is pixels if unit is not specified
return this.convertPixelsToAxisPadding(p, domainLength);
};
Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(pixels, domainLength) {
var $$ = this.owner,
length = $$.config.axis_rotated ? $$.width : $$.height;
return domainLength * (pixels / length);
};
Axis.prototype.generateTickValues = function generateTickValues(values, tickCount, forTimeSeries) {
var tickValues = values, targetCount, start, end, count, interval, i, tickValue;
if (tickCount) {
targetCount = isFunction(tickCount) ? tickCount() : tickCount;
// compute ticks according to tickCount
if (targetCount === 1) {
tickValues = [values[0]];
} else if (targetCount === 2) {
tickValues = [values[0], values[values.length - 1]];
} else if (targetCount > 2) {
count = targetCount - 2;
start = values[0];
end = values[values.length - 1];
interval = (end - start) / (count + 1);
// re-construct unique values
tickValues = [start];
for (i = 0; i < count; i++) {
tickValue = +start + interval * (i + 1);
tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue);
}
tickValues.push(end);
}
}
if (!forTimeSeries) { tickValues = tickValues.sort(function (a, b) { return a - b; }); }
return tickValues;
};
Axis.prototype.generateTransitions = function generateTransitions(duration) {
var $$ = this.owner, axes = $$.axes;
return {
axisX: duration ? axes.x.transition().duration(duration) : axes.x,
axisY: duration ? axes.y.transition().duration(duration) : axes.y,
axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2,
axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx
};
};
Axis.prototype.redraw = function redraw(transitions, isHidden) {
var $$ = this.owner;
$$.axes.x.style("opacity", isHidden ? 0 : 1);
$$.axes.y.style("opacity", isHidden ? 0 : 1);
$$.axes.y2.style("opacity", isHidden ? 0 : 1);
$$.axes.subx.style("opacity", isHidden ? 0 : 1);
transitions.axisX.call($$.xAxis);
transitions.axisY.call($$.yAxis);
transitions.axisY2.call($$.y2Axis);
transitions.axisSubX.call($$.subXAxis);
};
export {Axis};
export default Axis;

764
es6_modules/chart.js

@ -0,0 +1,764 @@
import {CLASS,isValue,isFunction,isString,isUndefined,isDefined,ceil10,asHalfPixel,diffDomain,isEmpty,notEmpty,getOption,hasValue,sanitise,getPathBox, ChartInternal} from './chartinternal.js';
var c3_chart_fn;
function Chart(config) {
var $$ = this.internal = new ChartInternal(this);
$$.loadConfig(config);
$$.beforeInit(config);
$$.init();
$$.afterInit(config);
// bind "this" to nested API
(function bindThis(fn, target, argThis) {
Object.keys(fn).forEach(function(key) {
target[key] = fn[key].bind(argThis);
if (Object.keys(fn[key]).length > 0) {
bindThis(fn[key], target[key], argThis);
}
});
})(c3_chart_fn, this, this);
}
c3_chart_fn = Chart.prototype;
c3_chart_fn.focus = function (targetIds) {
var $$ = this.internal, candidates;
targetIds = $$.mapToTargetIds(targetIds);
candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))),
this.revert();
this.defocus();
candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false);
if ($$.hasArcType()) {
$$.expandArc(targetIds);
}
$$.toggleFocusLegend(targetIds, true);
$$.focusedTargetIds = targetIds;
$$.defocusedTargetIds = $$.defocusedTargetIds.filter(function (id) {
return targetIds.indexOf(id) < 0;
});
};
c3_chart_fn.defocus = function (targetIds) {
var $$ = this.internal, candidates;
targetIds = $$.mapToTargetIds(targetIds);
candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))),
candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true);
if ($$.hasArcType()) {
$$.unexpandArc(targetIds);
}
$$.toggleFocusLegend(targetIds, false);
$$.focusedTargetIds = $$.focusedTargetIds.filter(function (id) {
return targetIds.indexOf(id) < 0;
});
$$.defocusedTargetIds = targetIds;
};
c3_chart_fn.revert = function (targetIds) {
var $$ = this.internal, candidates;
targetIds = $$.mapToTargetIds(targetIds);
candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets
candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false);
if ($$.hasArcType()) {
$$.unexpandArc(targetIds);
}
if ($$.config.legend_show) {
$$.showLegend(targetIds.filter($$.isLegendToShow.bind($$)));
$$.legend.selectAll($$.selectorLegends(targetIds))
.filter(function () {
return $$.d3.select(this).classed(CLASS.legendItemFocused);
})
.classed(CLASS.legendItemFocused, false);
}
$$.focusedTargetIds = [];
$$.defocusedTargetIds = [];
};
c3_chart_fn.show = function (targetIds, options) {
var $$ = this.internal, targets;
targetIds = $$.mapToTargetIds(targetIds);
options = options || {};
$$.removeHiddenTargetIds(targetIds);
targets = $$.svg.selectAll($$.selectorTargets(targetIds));
targets.transition()
.style('opacity', 1, 'important')
.call($$.endall, function () {
targets.style('opacity', null).style('opacity', 1);
});
if (options.withLegend) {
$$.showLegend(targetIds);
}
$$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true});
};
c3_chart_fn.hide = function (targetIds, options) {
var $$ = this.internal, targets;
targetIds = $$.mapToTargetIds(targetIds);
options = options || {};
$$.addHiddenTargetIds(targetIds);
targets = $$.svg.selectAll($$.selectorTargets(targetIds));
targets.transition()
.style('opacity', 0, 'important')
.call($$.endall, function () {
targets.style('opacity', null).style('opacity', 0);
});
if (options.withLegend) {
$$.hideLegend(targetIds);
}
$$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true});
};
c3_chart_fn.toggle = function (targetIds, options) {
var that = this, $$ = this.internal;
$$.mapToTargetIds(targetIds).forEach(function (targetId) {
$$.isTargetToShow(targetId) ? that.hide(targetId, options) : that.show(targetId, options);
});
};
c3_chart_fn.zoom = function (domain) {
var $$ = this.internal;
if (domain) {
if ($$.isTimeSeries()) {
domain = domain.map(function (x) { return $$.parseDate(x); });
}
$$.brush.extent(domain);
$$.redraw({withUpdateXDomain: true, withY: $$.config.zoom_rescale});
$$.config.zoom_onzoom.call(this, $$.x.orgDomain());
}
return $$.brush.extent();
};
c3_chart_fn.zoom.enable = function (enabled) {
var $$ = this.internal;
$$.config.zoom_enabled = enabled;
$$.updateAndRedraw();
};
c3_chart_fn.unzoom = function () {
var $$ = this.internal;
$$.brush.clear().update();
$$.redraw({withUpdateXDomain: true});
};
c3_chart_fn.zoom.max = function (max) {
var $$ = this.internal, config = $$.config, d3 = $$.d3;
if (max === 0 || max) {
config.zoom_x_max = d3.max([$$.orgXDomain[1], max]);
}
else {
return config.zoom_x_max;
}
};
c3_chart_fn.zoom.min = function (min) {
var $$ = this.internal, config = $$.config, d3 = $$.d3;
if (min === 0 || min) {
config.zoom_x_min = d3.min([$$.orgXDomain[0], min]);
}
else {
return config.zoom_x_min;
}
};
c3_chart_fn.zoom.range = function (range) {
if (arguments.length) {
if (isDefined(range.max)) { this.domain.max(range.max); }
if (isDefined(range.min)) { this.domain.min(range.min); }
} else {
return {
max: this.domain.max(),
min: this.domain.min()
};
}
};
c3_chart_fn.load = function (args) {
var $$ = this.internal, config = $$.config;
// update xs if specified
if (args.xs) {
$$.addXs(args.xs);
}
// update names if exists
if ('names' in args) {
c3_chart_fn.data.names.bind(this)(args.names);
}
// update classes if exists
if ('classes' in args) {
Object.keys(args.classes).forEach(function (id) {
config.data_classes[id] = args.classes[id];
});
}
// update categories if exists
if ('categories' in args && $$.isCategorized()) {
config.axis_x_categories = args.categories;
}
// update axes if exists
if ('axes' in args) {
Object.keys(args.axes).forEach(function (id) {
config.data_axes[id] = args.axes[id];
});
}
// update colors if exists
if ('colors' in args) {
Object.keys(args.colors).forEach(function (id) {
config.data_colors[id] = args.colors[id];
});
}
// use cache if exists
if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) {
$$.load($$.getCaches(args.cacheIds), args.done);
return;
}
// unload if needed
if ('unload' in args) {
// TODO: do not unload if target will load (included in url/rows/columns)
$$.unload($$.mapToTargetIds((typeof args.unload === 'boolean' && args.unload) ? null : args.unload), function () {
$$.loadFromArgs(args);
});
} else {
$$.loadFromArgs(args);
}
};
c3_chart_fn.unload = function (args) {
var $$ = this.internal;
args = args || {};
if (args instanceof Array) {
args = {ids: args};
} else if (typeof args === 'string') {
args = {ids: [args]};
}
$$.unload($$.mapToTargetIds(args.ids), function () {
$$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true});
if (args.done) { args.done(); }
});
};
c3_chart_fn.flow = function(args) {
var $$ = this.internal,
targets, data, notfoundIds = [],
orgDataCount = $$.getMaxDataCount(),
dataCount, domain, baseTarget, baseValue, length = 0,
tail = 0,
diff, to;
if (args.json) {
data = $$.convertJsonToData(args.json, args.keys);
} else if (args.rows) {
data = $$.convertRowsToData(args.rows);
} else if (args.columns) {
data = $$.convertColumnsToData(args.columns);
} else {
return;
}
targets = $$.convertDataToTargets(data, true);
// Update/Add data
$$.data.targets.forEach(function(t) {
var found = false,
i, j;
for (i = 0; i < targets.length; i++) {
if (t.id === targets[i].id) {
found = true;
if (t.values[t.values.length - 1]) {
tail = t.values[t.values.length - 1].index + 1;
}
length = targets[i].values.length;
for (j = 0; j < length; j++) {
targets[i].values[j].index = tail + j;
if (!$$.isTimeSeries()) {
targets[i].values[j].x = tail + j;
}
}
t.values = t.values.concat(targets[i].values);
targets.splice(i, 1);
break;
}
}
if (!found) { notfoundIds.push(t.id); }
});
// Append null for not found targets
$$.data.targets.forEach(function(t) {
var i, j;
for (i = 0; i < notfoundIds.length; i++) {
if (t.id === notfoundIds[i]) {
tail = t.values[t.values.length - 1].index + 1;
for (j = 0; j < length; j++) {
t.values.push({
id: t.id,
index: tail + j,
x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,
value: null
});
}
}
}
});
// Generate null values for new target
if ($$.data.targets.length) {
targets.forEach(function(t) {
var i, missing = [];
for (i = $$.data.targets[0].values[0].index; i < tail; i++) {
missing.push({
id: t.id,
index: i,
x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,
value: null
});
}
t.values.forEach(function(v) {
v.index += tail;
if (!$$.isTimeSeries()) {
v.x += tail;
}
});
t.values = missing.concat(t.values);
});
}
$$.data.targets = $$.data.targets.concat(targets); // add remained
// check data count because behavior needs to change when it's only one
dataCount = $$.getMaxDataCount();
baseTarget = $$.data.targets[0];
baseValue = baseTarget.values[0];
// Update length to flow if needed
if (isDefined(args.to)) {
length = 0;
to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;
baseTarget.values.forEach(function(v) {
if (v.x < to) { length++; }
});
} else if (isDefined(args.length)) {
length = args.length;
}
// If only one data, update the domain to flow from left edge of the chart
if (!orgDataCount) {
if ($$.isTimeSeries()) {
if (baseTarget.values.length > 1) {
diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;
} else {
diff = baseValue.x - $$.getXDomain($$.data.targets)[0];
}
} else {
diff = 1;
}
domain = [baseValue.x - diff, baseValue.x];
$$.updateXDomain(null, true, true, false, domain);
} else if (orgDataCount === 1) {
if ($$.isTimeSeries()) {
diff = (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;
domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];
$$.updateXDomain(null, true, true, false, domain);
}
}
// Set targets
$$.updateTargets($$.data.targets);
// Redraw with new targets
$$.redraw({
flow: {
index: baseValue.index,
length: length,
duration: isValue(args.duration) ? args.duration : $$.config.transition_duration,
done: args.done,
orgDataCount: orgDataCount,
},
withLegend: true,
withTransition: orgDataCount > 1,
withTrimXDomain: false,
withUpdateXAxis: true,
});
};
c3_chart_fn.selected = function (targetId) {
var $$ = this.internal, d3 = $$.d3;
return d3.merge(
$$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId)).selectAll('.' + CLASS.shape)
.filter(function () { return d3.select(this).classed(CLASS.SELECTED); })
.map(function (d) { return d.map(function (d) { var data = d.__data__; return data.data ? data.data : data; }); })
);
};
c3_chart_fn.select = function (ids, indices, resetOther) {
var $$ = this.internal, d3 = $$.d3, config = $$.config;
if (! config.data_selection_enabled) { return; }
$$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
var shape = d3.select(this), id = d.data ? d.data.id : d.id,
toggle = $$.getToggle(this, d).bind($$),
isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,
isTargetIndex = !indices || indices.indexOf(i) >= 0,
isSelected = shape.classed(CLASS.SELECTED);
// line/area selection not supported yet
if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
return;
}
if (isTargetId && isTargetIndex) {
if (config.data_selection_isselectable(d) && !isSelected) {
toggle(true, shape.classed(CLASS.SELECTED, true), d, i);
}
} else if (isDefined(resetOther) && resetOther) {
if (isSelected) {
toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
}
}
});
};
c3_chart_fn.unselect = function (ids, indices) {
var $$ = this.internal, d3 = $$.d3, config = $$.config;
if (! config.data_selection_enabled) { return; }
$$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
var shape = d3.select(this), id = d.data ? d.data.id : d.id,
toggle = $$.getToggle(this, d).bind($$),
isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,
isTargetIndex = !indices || indices.indexOf(i) >= 0,
isSelected = shape.classed(CLASS.SELECTED);
// line/area selection not supported yet
if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
return;
}
if (isTargetId && isTargetIndex) {
if (config.data_selection_isselectable(d)) {
if (isSelected) {
toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
}
}
}
});
};
c3_chart_fn.transform = function(type, targetIds) {
var $$ = this.internal,
options = ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null;
$$.transformTo(targetIds, type, options);
};
c3_chart_fn.groups = function (groups) {
var $$ = this.internal, config = $$.config;
if (isUndefined(groups)) { return config.data_groups; }
config.data_groups = groups;
$$.redraw();
return config.data_groups;
};
c3_chart_fn.xgrids = function (grids) {
var $$ = this.internal, config = $$.config;
if (! grids) { return config.grid_x_lines; }
config.grid_x_lines = grids;
$$.redrawWithoutRescale();
return config.grid_x_lines;
};
c3_chart_fn.xgrids.add = function (grids) {
var $$ = this.internal;
return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : []));
};
c3_chart_fn.xgrids.remove = function (params) { // TODO: multiple
var $$ = this.internal;
$$.removeGridLines(params, true);
};
c3_chart_fn.ygrids = function (grids) {
var $$ = this.internal, config = $$.config;
if (! grids) { return config.grid_y_lines; }
config.grid_y_lines = grids;
$$.redrawWithoutRescale();
return config.grid_y_lines;
};
c3_chart_fn.ygrids.add = function (grids) {
var $$ = this.internal;
return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : []));
};
c3_chart_fn.ygrids.remove = function (params) { // TODO: multiple
var $$ = this.internal;
$$.removeGridLines(params, false);
};
c3_chart_fn.regions = function (regions) {
var $$ = this.internal, config = $$.config;
if (!regions) { return config.regions; }
config.regions = regions;
$$.redrawWithoutRescale();
return config.regions;
};
c3_chart_fn.regions.add = function (regions) {
var $$ = this.internal, config = $$.config;
if (!regions) { return config.regions; }
config.regions = config.regions.concat(regions);
$$.redrawWithoutRescale();
return config.regions;
};
c3_chart_fn.regions.remove = function (options) {
var $$ = this.internal, config = $$.config,
duration, classes, regions;
options = options || {};
duration = $$.getOption(options, "duration", config.transition_duration);
classes = $$.getOption(options, "classes", [CLASS.region]);
regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) { return '.' + c; }));
(duration ? regions.transition().duration(duration) : regions)
.style('opacity', 0)
.remove();
config.regions = config.regions.filter(function (region) {
var found = false;
if (!region['class']) {
return true;
}
region['class'].split(' ').forEach(function (c) {
if (classes.indexOf(c) >= 0) { found = true; }
});
return !found;
});
return config.regions;
};
c3_chart_fn.data = function (targetIds) {
var targets = this.internal.data.targets;
return typeof targetIds === 'undefined' ? targets : targets.filter(function (t) {
return [].concat(targetIds).indexOf(t.id) >= 0;
});
};
c3_chart_fn.data.shown = function (targetIds) {
return this.internal.filterTargetsToShow(this.data(targetIds));
};
c3_chart_fn.data.values = function (targetId) {
var targets, values = null;
if (targetId) {
targets = this.data(targetId);
values = targets[0] ? targets[0].values.map(function (d) { return d.value; }) : null;
}
return values;
};
c3_chart_fn.data.names = function (names) {
this.internal.clearLegendItemTextBoxCache();
return this.internal.updateDataAttributes('names', names);
};
c3_chart_fn.data.colors = function (colors) {
return this.internal.updateDataAttributes('colors', colors);
};
c3_chart_fn.data.axes = function (axes) {
return this.internal.updateDataAttributes('axes', axes);
};
c3_chart_fn.category = function (i, category) {
var $$ = this.internal, config = $$.config;
if (arguments.length > 1) {
config.axis_x_categories[i] = category;
$$.redraw();
}
return config.axis_x_categories[i];
};
c3_chart_fn.categories = function (categories) {
var $$ = this.internal, config = $$.config;
if (!arguments.length) { return config.axis_x_categories; }
config.axis_x_categories = categories;
$$.redraw();
return config.axis_x_categories;
};
// TODO: fix
c3_chart_fn.color = function (id) {
var $$ = this.internal;
return $$.color(id); // more patterns
};
c3_chart_fn.x = function (x) {
var $$ = this.internal;
if (arguments.length) {
$$.updateTargetX($$.data.targets, x);
$$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true});
}
return $$.data.xs;
};
c3_chart_fn.xs = function (xs) {
var $$ = this.internal;
if (arguments.length) {
$$.updateTargetXs($$.data.targets, xs);
$$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true});
}
return $$.data.xs;
};
c3_chart_fn.axis = function () {};
c3_chart_fn.axis.labels = function (labels) {
var $$ = this.internal;
if (arguments.length) {
Object.keys(labels).forEach(function (axisId) {
$$.axis.setLabelText(axisId, labels[axisId]);
});
$$.axis.updateLabels();
}
// TODO: return some values?
};
c3_chart_fn.axis.max = function (max) {
var $$ = this.internal, config = $$.config;
if (arguments.length) {
if (typeof max === 'object') {
if (isValue(max.x)) { config.axis_x_max = max.x; }
if (isValue(max.y)) { config.axis_y_max = max.y; }
if (isValue(max.y2)) { config.axis_y2_max = max.y2; }
} else {
config.axis_y_max = config.axis_y2_max = max;
}
$$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true});
} else {
return {
x: config.axis_x_max,
y: config.axis_y_max,
y2: config.axis_y2_max
};
}
};
c3_chart_fn.axis.min = function (min) {
var $$ = this.internal, config = $$.config;
if (arguments.length) {
if (typeof min === 'object') {
if (isValue(min.x)) { config.axis_x_min = min.x; }
if (isValue(min.y)) { config.axis_y_min = min.y; }
if (isValue(min.y2)) { config.axis_y2_min = min.y2; }
} else {
config.axis_y_min = config.axis_y2_min = min;
}
$$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true});
} else {
return {
x: config.axis_x_min,
y: config.axis_y_min,
y2: config.axis_y2_min
};
}
};
c3_chart_fn.axis.range = function (range) {
if (arguments.length) {
if (isDefined(range.max)) { this.axis.max(range.max); }
if (isDefined(range.min)) { this.axis.min(range.min); }
} else {
return {
max: this.axis.max(),
min: this.axis.min()
};
}
};
c3_chart_fn.legend = function () {};
c3_chart_fn.legend.show = function (targetIds) {
var $$ = this.internal;
$$.showLegend($$.mapToTargetIds(targetIds));
$$.updateAndRedraw({withLegend: true});
};
c3_chart_fn.legend.hide = function (targetIds) {
var $$ = this.internal;
$$.hideLegend($$.mapToTargetIds(targetIds));
$$.updateAndRedraw({withLegend: true});
};
c3_chart_fn.resize = function (size) {
var $$ = this.internal, config = $$.config;
config.size_width = size ? size.width : null;
config.size_height = size ? size.height : null;
this.flush();
};
c3_chart_fn.flush = function () {
var $$ = this.internal;
$$.updateAndRedraw({withLegend: true, withTransition: false, withTransitionForTransform: false});
};
c3_chart_fn.destroy = function () {
var $$ = this.internal;
window.clearInterval($$.intervalForObserveInserted);
if ($$.resizeTimeout !== undefined) {
window.clearTimeout($$.resizeTimeout);
}
if (window.detachEvent) {
window.detachEvent('onresize', $$.resizeFunction);
} else if (window.removeEventListener) {
window.removeEventListener('resize', $$.resizeFunction);
} else {
var wrapper = window.onresize;
// check if no one else removed our wrapper and remove our resizeFunction from it
if (wrapper && wrapper.add && wrapper.remove) {
wrapper.remove($$.resizeFunction);
}
}
$$.selectChart.classed('c3', false).html("");
// MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen.
Object.keys($$).forEach(function (key) {
$$[key] = null;
});
return null;
};
c3_chart_fn.tooltip = function () {};
c3_chart_fn.tooltip.show = function (args) {
var $$ = this.internal, index, mouse;
// determine mouse position on the chart
if (args.mouse) {
mouse = args.mouse;
}
// determine focus data
if (args.data) {
if ($$.isMultipleX()) {
// if multiple xs, target point will be determined by mouse
mouse = [$$.x(args.data.x), $$.getYScale(args.data.id)(args.data.value)];
index = null;
} else {
// TODO: when tooltip_grouped = false
index = isValue(args.data.index) ? args.data.index : $$.getIndexByX(args.data.x);
}
}
else if (typeof args.x !== 'undefined') {
index = $$.getIndexByX(args.x);
}
else if (typeof args.index !== 'undefined') {
index = args.index;
}
// emulate mouse events to show
$$.dispatchEvent('mouseover', index, mouse);
$$.dispatchEvent('mousemove', index, mouse);
$$.config.tooltip_onshow.call($$, args.data);
};
c3_chart_fn.tooltip.hide = function () {
// TODO: get target data by checking the state of focus
this.internal.dispatchEvent('mouseout', 0);
this.internal.config.tooltip_onhide.call(this);
};
export {Chart};
export default Chart;

5948
es6_modules/chartinternal.js

File diff suppressed because it is too large Load Diff

31
es6_modules/rollup.entry.js

@ -0,0 +1,31 @@
// This file is only the entry point for rollup
import {
ChartInternal
} from './chartinternal.js';
import {
Chart
} from './chart.js';
import {
Axis
} from './axis.js';
var version = "0.4.11",
generate = function(config) {
return new Chart(config);
},
chart = {
fn: Chart.prototype,
internal: {
fn: ChartInternal.prototype,
axis: {
fn: Axis.prototype
}
}
};
export {
version,
generate,
chart
}

35
package.json

@ -22,26 +22,27 @@
"gitHead": "84e03109d9a590f9c8ef687c03d751f666080c6f",
"readmeFilename": "README.md",
"dependencies": {
"d3": "~3.5.0"
"d3": "^3.5.17"
},
"devDependencies": {
"codecov.io": "^0.1.6",
"grunt": "^0.4.5",
"grunt-contrib-concat": "~0.5.0",
"grunt-contrib-cssmin": "^0.10.0",
"grunt": "^1.0.1",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-cssmin": "^1.0.1",
"grunt-contrib-jshint": "^1.0.0",
"grunt-contrib-uglify": "~0.4.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-karma": "^0.12.1",
"grunt-sass": "^1.0.0",
"jasmine-core": "^2.3.4",
"jshint-stylish": "^2.1.0",
"karma": "^0.13.10",
"karma-coverage": "^0.5.2",
"karma-jasmine": "^0.3.6",
"karma-phantomjs-launcher": "^0.2.1",
"karma-spec-reporter": "0.0.20",
"load-grunt-tasks": "~0.2.0",
"phantomjs": "^1.9.18"
"grunt-contrib-uglify": "^1.0.1",
"grunt-contrib-watch": "^1.0.0",
"grunt-karma": "^2.0.0",
"grunt-rollup": "^0.7.1",
"grunt-sass": "^1.2.0",
"jasmine-core": "^2.4.1",
"jshint-stylish": "^2.2.0",
"karma": "^1.1.1",
"karma-coverage": "^1.1.0",
"karma-jasmine": "^1.0.2",
"karma-phantomjs-launcher": "^1.0.1",
"karma-spec-reporter": "0.0.26",
"load-grunt-tasks": "^3.5.0",
"phantomjs-prebuilt": "^2.1.7"
}
}

292
src/api.flow.js

@ -1,292 +0,0 @@
c3_chart_fn.flow = function (args) {
var $$ = this.internal,
targets, data, notfoundIds = [], orgDataCount = $$.getMaxDataCount(),
dataCount, domain, baseTarget, baseValue, length = 0, tail = 0, diff, to;
if (args.json) {
data = $$.convertJsonToData(args.json, args.keys);
}
else if (args.rows) {
data = $$.convertRowsToData(args.rows);
}
else if (args.columns) {
data = $$.convertColumnsToData(args.columns);
}
else {
return;
}
targets = $$.convertDataToTargets(data, true);
// Update/Add data
$$.data.targets.forEach(function (t) {
var found = false, i, j;
for (i = 0; i < targets.length; i++) {
if (t.id === targets[i].id) {
found = true;
if (t.values[t.values.length - 1]) {
tail = t.values[t.values.length - 1].index + 1;
}
length = targets[i].values.length;
for (j = 0; j < length; j++) {
targets[i].values[j].index = tail + j;
if (!$$.isTimeSeries()) {
targets[i].values[j].x = tail + j;
}
}
t.values = t.values.concat(targets[i].values);
targets.splice(i, 1);
break;
}
}
if (!found) { notfoundIds.push(t.id); }
});
// Append null for not found targets
$$.data.targets.forEach(function (t) {
var i, j;
for (i = 0; i < notfoundIds.length; i++) {
if (t.id === notfoundIds[i]) {
tail = t.values[t.values.length - 1].index + 1;
for (j = 0; j < length; j++) {
t.values.push({
id: t.id,
index: tail + j,
x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,
value: null
});
}
}
}
});
// Generate null values for new target
if ($$.data.targets.length) {
targets.forEach(function (t) {
var i, missing = [];
for (i = $$.data.targets[0].values[0].index; i < tail; i++) {
missing.push({
id: t.id,
index: i,
x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,
value: null
});
}
t.values.forEach(function (v) {
v.index += tail;
if (!$$.isTimeSeries()) {
v.x += tail;
}
});
t.values = missing.concat(t.values);
});
}
$$.data.targets = $$.data.targets.concat(targets); // add remained
// check data count because behavior needs to change when it's only one
dataCount = $$.getMaxDataCount();
baseTarget = $$.data.targets[0];
baseValue = baseTarget.values[0];
// Update length to flow if needed
if (isDefined(args.to)) {
length = 0;
to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;
baseTarget.values.forEach(function (v) {
if (v.x < to) { length++; }
});
} else if (isDefined(args.length)) {
length = args.length;
}
// If only one data, update the domain to flow from left edge of the chart
if (!orgDataCount) {
if ($$.isTimeSeries()) {
if (baseTarget.values.length > 1) {
diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;
} else {
diff = baseValue.x - $$.getXDomain($$.data.targets)[0];
}
} else {
diff = 1;
}
domain = [baseValue.x - diff, baseValue.x];
$$.updateXDomain(null, true, true, false, domain);
} else if (orgDataCount === 1) {
if ($$.isTimeSeries()) {
diff = (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;
domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];
$$.updateXDomain(null, true, true, false, domain);
}
}
// Set targets
$$.updateTargets($$.data.targets);
// Redraw with new targets
$$.redraw({
flow: {
index: baseValue.index,
length: length,
duration: isValue(args.duration) ? args.duration : $$.config.transition_duration,
done: args.done,
orgDataCount: orgDataCount,
},
withLegend: true,
withTransition: orgDataCount > 1,
withTrimXDomain: false,
withUpdateXAxis: true,
});
};
c3_chart_internal_fn.generateFlow = function (args) {
var $$ = this, config = $$.config, d3 = $$.d3;
return function () {
var targets = args.targets,
flow = args.flow,
drawBar = args.drawBar,
drawLine = args.drawLine,
drawArea = args.drawArea,
cx = args.cx,
cy = args.cy,
xv = args.xv,
xForText = args.xForText,
yForText = args.yForText,
duration = args.duration;
var translateX, scaleX = 1, transform,
flowIndex = flow.index,
flowLength = flow.length,
flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex),
flowEnd = $$.getValueOnIndex($$.data.targets[0].values, flowIndex + flowLength),
orgDomain = $$.x.domain(), domain,
durationForFlow = flow.duration || duration,
done = flow.done || function () {},
wait = $$.generateWait();
var xgrid = $$.xgrid || d3.selectAll([]),
xgridLines = $$.xgridLines || d3.selectAll([]),
mainRegion = $$.mainRegion || d3.selectAll([]),
mainText = $$.mainText || d3.selectAll([]),
mainBar = $$.mainBar || d3.selectAll([]),
mainLine = $$.mainLine || d3.selectAll([]),
mainArea = $$.mainArea || d3.selectAll([]),
mainCircle = $$.mainCircle || d3.selectAll([]);
// set flag
$$.flowing = true;
// remove head data after rendered
$$.data.targets.forEach(function (d) {
d.values.splice(0, flowLength);
});
// update x domain to generate axis elements for flow
domain = $$.updateXDomain(targets, true, true);
// update elements related to x scale
if ($$.updateXGrid) { $$.updateXGrid(true); }
// generate transform to flow
if (!flow.orgDataCount) { // if empty
if ($$.data.targets[0].values.length !== 1) {
translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
} else {
if ($$.isTimeSeries()) {
flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0);
flowEnd = $$.getValueOnIndex($$.data.targets[0].values, $$.data.targets[0].values.length - 1);
translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
} else {
translateX = diffDomain(domain) / 2;
}
}
} else if (flow.orgDataCount === 1 || (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) {
translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
} else {
if ($$.isTimeSeries()) {
translateX = ($$.x(orgDomain[0]) - $$.x(domain[0]));
} else {
translateX = ($$.x(flowStart.x) - $$.x(flowEnd.x));
}
}
scaleX = (diffDomain(orgDomain) / diffDomain(domain));
transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)';
$$.hideXGridFocus();
d3.transition().ease('linear').duration(durationForFlow).each(function () {
wait.add($$.axes.x.transition().call($$.xAxis));
wait.add(mainBar.transition().attr('transform', transform));
wait.add(mainLine.transition().attr('transform', transform));
wait.add(mainArea.transition().attr('transform', transform));
wait.add(mainCircle.transition().attr('transform', transform));
wait.add(mainText.transition().attr('transform', transform));
wait.add(mainRegion.filter($$.isRegionOnX).transition().attr('transform', transform));
wait.add(xgrid.transition().attr('transform', transform));
wait.add(xgridLines.transition().attr('transform', transform));
})
.call(wait, function () {
var i, shapes = [], texts = [], eventRects = [];
// remove flowed elements
if (flowLength) {
for (i = 0; i < flowLength; i++) {
shapes.push('.' + CLASS.shape + '-' + (flowIndex + i));
texts.push('.' + CLASS.text + '-' + (flowIndex + i));
eventRects.push('.' + CLASS.eventRect + '-' + (flowIndex + i));
}
$$.svg.selectAll('.' + CLASS.shapes).selectAll(shapes).remove();
$$.svg.selectAll('.' + CLASS.texts).selectAll(texts).remove();
$$.svg.selectAll('.' + CLASS.eventRects).selectAll(eventRects).remove();
$$.svg.select('.' + CLASS.xgrid).remove();
}
// draw again for removing flowed elements and reverting attr
xgrid
.attr('transform', null)
.attr($$.xgridAttr);
xgridLines
.attr('transform', null);
xgridLines.select('line')
.attr("x1", config.axis_rotated ? 0 : xv)
.attr("x2", config.axis_rotated ? $$.width : xv);
xgridLines.select('text')
.attr("x", config.axis_rotated ? $$.width : 0)
.attr("y", xv);
mainBar
.attr('transform', null)
.attr("d", drawBar);
mainLine
.attr('transform', null)
.attr("d", drawLine);
mainArea
.attr('transform', null)
.attr("d", drawArea);
mainCircle
.attr('transform', null)
.attr("cx", cx)
.attr("cy", cy);
mainText
.attr('transform', null)
.attr('x', xForText)
.attr('y', yForText)
.style('fill-opacity', $$.opacityForText.bind($$));
mainRegion
.attr('transform', null);
mainRegion.select('rect').filter($$.isRegionOnX)
.attr("x", $$.regionX.bind($$))
.attr("width", $$.regionWidth.bind($$));
if (config.interaction_enabled) {
$$.redrawEventRect();
}
// callback for end of flow
done();
$$.flowing = false;
});
};
};

16
src/api.transform.js

@ -1,16 +0,0 @@
c3_chart_fn.transform = function (type, targetIds) {
var $$ = this.internal,
options = ['pie', 'donut'].indexOf(type) >= 0 ? {withTransform: true} : null;
$$.transformTo(targetIds, type, options);
};
c3_chart_internal_fn.transformTo = function (targetIds, type, optionsForRedraw) {
var $$ = this,
withTransitionForAxis = !$$.hasArcType(),
options = optionsForRedraw || {withTransitionForAxis: withTransitionForAxis};
options.withTransitionForTransform = false;
$$.transiting = false;
$$.setTargetType(targetIds, type);
$$.updateTargets($$.data.targets); // this is needed when transforming to arc
$$.updateAndRedraw(options);
};

0
src/axis.js → src/axis/axis.js

0
src/c3.axis.js → src/axis/c3.axis.js

18
src/axis/index.js

@ -0,0 +1,18 @@
function API(owner) {
this.owner = owner;
}
function inherit(base, derived) {
if (Object.create) {
derived.prototype = Object.create(base.prototype);
} else {
var f = function f() {};
f.prototype = base.prototype;
derived.prototype = new f();
}
derived.prototype.constructor = derived;
return derived;
}

0
src/api.axis.js → src/chart/api.axis.js

0
src/api.category.js → src/chart/api.category.js

0
src/api.chart.js → src/chart/api.chart.js

0
src/api.color.js → src/chart/api.color.js

0
src/api.data.js → src/chart/api.data.js

143
src/chart/api.flow.js

@ -0,0 +1,143 @@
c3_chart_fn.flow = function(args) {
var $$ = this.internal,
targets, data, notfoundIds = [],
orgDataCount = $$.getMaxDataCount(),
dataCount, domain, baseTarget, baseValue, length = 0,
tail = 0,
diff, to;
if (args.json) {
data = $$.convertJsonToData(args.json, args.keys);
} else if (args.rows) {
data = $$.convertRowsToData(args.rows);
} else if (args.columns) {
data = $$.convertColumnsToData(args.columns);
} else {
return;
}
targets = $$.convertDataToTargets(data, true);
// Update/Add data
$$.data.targets.forEach(function(t) {
var found = false,
i, j;
for (i = 0; i < targets.length; i++) {
if (t.id === targets[i].id) {
found = true;
if (t.values[t.values.length - 1]) {
tail = t.values[t.values.length - 1].index + 1;
}
length = targets[i].values.length;
for (j = 0; j < length; j++) {
targets[i].values[j].index = tail + j;
if (!$$.isTimeSeries()) {
targets[i].values[j].x = tail + j;
}
}
t.values = t.values.concat(targets[i].values);
targets.splice(i, 1);
break;
}
}
if (!found) { notfoundIds.push(t.id); }
});
// Append null for not found targets
$$.data.targets.forEach(function(t) {
var i, j;
for (i = 0; i < notfoundIds.length; i++) {
if (t.id === notfoundIds[i]) {
tail = t.values[t.values.length - 1].index + 1;
for (j = 0; j < length; j++) {
t.values.push({
id: t.id,
index: tail + j,
x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,
value: null
});
}
}
}
});
// Generate null values for new target
if ($$.data.targets.length) {
targets.forEach(function(t) {
var i, missing = [];
for (i = $$.data.targets[0].values[0].index; i < tail; i++) {
missing.push({
id: t.id,
index: i,
x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,
value: null
});
}
t.values.forEach(function(v) {
v.index += tail;
if (!$$.isTimeSeries()) {
v.x += tail;
}
});
t.values = missing.concat(t.values);
});
}
$$.data.targets = $$.data.targets.concat(targets); // add remained
// check data count because behavior needs to change when it's only one
dataCount = $$.getMaxDataCount();
baseTarget = $$.data.targets[0];
baseValue = baseTarget.values[0];
// Update length to flow if needed
if (isDefined(args.to)) {
length = 0;
to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;
baseTarget.values.forEach(function(v) {
if (v.x < to) { length++; }
});
} else if (isDefined(args.length)) {
length = args.length;
}
// If only one data, update the domain to flow from left edge of the chart
if (!orgDataCount) {
if ($$.isTimeSeries()) {
if (baseTarget.values.length > 1) {
diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;
} else {
diff = baseValue.x - $$.getXDomain($$.data.targets)[0];
}
} else {
diff = 1;
}
domain = [baseValue.x - diff, baseValue.x];
$$.updateXDomain(null, true, true, false, domain);
} else if (orgDataCount === 1) {
if ($$.isTimeSeries()) {
diff = (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;
domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];
$$.updateXDomain(null, true, true, false, domain);
}
}
// Set targets
$$.updateTargets($$.data.targets);
// Redraw with new targets
$$.redraw({
flow: {
index: baseValue.index,
length: length,
duration: isValue(args.duration) ? args.duration : $$.config.transition_duration,
done: args.done,
orgDataCount: orgDataCount,
},
withLegend: true,
withTransition: orgDataCount > 1,
withTrimXDomain: false,
withUpdateXAxis: true,
});
};

0
src/api.focus.js → src/chart/api.focus.js

0
src/api.grid.js → src/chart/api.grid.js

0
src/api.group.js → src/chart/api.group.js

0
src/api.legend.js → src/chart/api.legend.js

0
src/api.load.js → src/chart/api.load.js

0
src/api.region.js → src/chart/api.region.js

0
src/api.selection.js → src/chart/api.selection.js

0
src/api.show.js → src/chart/api.show.js

0
src/api.tooltip.js → src/chart/api.tooltip.js

5
src/chart/api.transform.js

@ -0,0 +1,5 @@
c3_chart_fn.transform = function(type, targetIds) {
var $$ = this.internal,
options = ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null;
$$.transformTo(targetIds, type, options);
};

0
src/api.x.js → src/chart/api.x.js

0
src/api.zoom.js → src/chart/api.zoom.js

23
src/chart/index.js

@ -0,0 +1,23 @@
var c3_chart_fn;
function Chart(config) {
var $$ = this.internal = new ChartInternal(this);
$$.loadConfig(config);
$$.beforeInit(config);
$$.init();
$$.afterInit(config);
// bind "this" to nested API
(function bindThis(fn, target, argThis) {
Object.keys(fn).forEach(function(key) {
target[key] = fn[key].bind(argThis);
if (Object.keys(fn[key]).length > 0) {
bindThis(fn[key], target[key], argThis);
}
});
})(c3_chart_fn, this, this);
}
c3_chart_fn = Chart.prototype;

0
src/arc.js → src/chartinternal/arc.js

0
src/cache.js → src/chartinternal/cache.js

0
src/category.js → src/chartinternal/category.js

0
src/class.js → src/chartinternal/class.js

0
src/clip.js → src/chartinternal/clip.js

0
src/color.js → src/chartinternal/color.js

0
src/config.js → src/chartinternal/config.js

0
src/data.convert.js → src/chartinternal/data.convert.js

0
src/data.js → src/chartinternal/data.js

0
src/data.load.js → src/chartinternal/data.load.js

0
src/domain.js → src/chartinternal/domain.js

0
src/drag.js → src/chartinternal/drag.js

155
src/chartinternal/flow.js

@ -0,0 +1,155 @@
c3_chart_internal_fn.generateFlow = function(args) {
var $$ = this,
config = $$.config,
d3 = $$.d3;
return function() {
var targets = args.targets,
flow = args.flow,
drawBar = args.drawBar,
drawLine = args.drawLine,
drawArea = args.drawArea,
cx = args.cx,
cy = args.cy,
xv = args.xv,
xForText = args.xForText,
yForText = args.yForText,
duration = args.duration;
var translateX, scaleX = 1,
transform,
flowIndex = flow.index,
flowLength = flow.length,
flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex),
flowEnd = $$.getValueOnIndex($$.data.targets[0].values, flowIndex + flowLength),
orgDomain = $$.x.domain(),
domain,
durationForFlow = flow.duration || duration,
done = flow.done || function() {},
wait = $$.generateWait();
var xgrid = $$.xgrid || d3.selectAll([]),
xgridLines = $$.xgridLines || d3.selectAll([]),
mainRegion = $$.mainRegion || d3.selectAll([]),
mainText = $$.mainText || d3.selectAll([]),
mainBar = $$.mainBar || d3.selectAll([]),
mainLine = $$.mainLine || d3.selectAll([]),
mainArea = $$.mainArea || d3.selectAll([]),
mainCircle = $$.mainCircle || d3.selectAll([]);
// set flag
$$.flowing = true;
// remove head data after rendered
$$.data.targets.forEach(function(d) {
d.values.splice(0, flowLength);
});
// update x domain to generate axis elements for flow
domain = $$.updateXDomain(targets, true, true);
// update elements related to x scale
if ($$.updateXGrid) { $$.updateXGrid(true); }
// generate transform to flow
if (!flow.orgDataCount) { // if empty
if ($$.data.targets[0].values.length !== 1) {
translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
} else {
if ($$.isTimeSeries()) {
flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0);
flowEnd = $$.getValueOnIndex($$.data.targets[0].values, $$.data.targets[0].values.length - 1);
translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
} else {
translateX = diffDomain(domain) / 2;
}
}
} else if (flow.orgDataCount === 1 || (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) {
translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
} else {
if ($$.isTimeSeries()) {
translateX = ($$.x(orgDomain[0]) - $$.x(domain[0]));
} else {
translateX = ($$.x(flowStart.x) - $$.x(flowEnd.x));
}
}
scaleX = (diffDomain(orgDomain) / diffDomain(domain));
transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)';
$$.hideXGridFocus();
d3.transition().ease('linear').duration(durationForFlow).each(function() {
wait.add($$.axes.x.transition().call($$.xAxis));
wait.add(mainBar.transition().attr('transform', transform));
wait.add(mainLine.transition().attr('transform', transform));
wait.add(mainArea.transition().attr('transform', transform));
wait.add(mainCircle.transition().attr('transform', transform));
wait.add(mainText.transition().attr('transform', transform));
wait.add(mainRegion.filter($$.isRegionOnX).transition().attr('transform', transform));
wait.add(xgrid.transition().attr('transform', transform));
wait.add(xgridLines.transition().attr('transform', transform));
})
.call(wait, function() {
var i, shapes = [],
texts = [],
eventRects = [];
// remove flowed elements
if (flowLength) {
for (i = 0; i < flowLength; i++) {
shapes.push('.' + CLASS.shape + '-' + (flowIndex + i));
texts.push('.' + CLASS.text + '-' + (flowIndex + i));
eventRects.push('.' + CLASS.eventRect + '-' + (flowIndex + i));
}
$$.svg.selectAll('.' + CLASS.shapes).selectAll(shapes).remove();
$$.svg.selectAll('.' + CLASS.texts).selectAll(texts).remove();
$$.svg.selectAll('.' + CLASS.eventRects).selectAll(eventRects).remove();
$$.svg.select('.' + CLASS.xgrid).remove();
}
// draw again for removing flowed elements and reverting attr
xgrid
.attr('transform', null)
.attr($$.xgridAttr);
xgridLines
.attr('transform', null);
xgridLines.select('line')
.attr("x1", config.axis_rotated ? 0 : xv)
.attr("x2", config.axis_rotated ? $$.width : xv);
xgridLines.select('text')
.attr("x", config.axis_rotated ? $$.width : 0)
.attr("y", xv);
mainBar
.attr('transform', null)
.attr("d", drawBar);
mainLine
.attr('transform', null)
.attr("d", drawLine);
mainArea
.attr('transform', null)
.attr("d", drawArea);
mainCircle
.attr('transform', null)
.attr("cx", cx)
.attr("cy", cy);
mainText
.attr('transform', null)
.attr('x', xForText)
.attr('y', yForText)
.style('fill-opacity', $$.opacityForText.bind($$));
mainRegion
.attr('transform', null);
mainRegion.select('rect').filter($$.isRegionOnX)
.attr("x", $$.regionX.bind($$))
.attr("width", $$.regionWidth.bind($$));
if (config.interaction_enabled) {
$$.redrawEventRect();
}
// callback for end of flow
done();
$$.flowing = false;
});
};
};

0
src/format.js → src/chartinternal/format.js

0
src/grid.js → src/chartinternal/grid.js

378
src/core.js → src/chartinternal/index.js

@ -1,47 +1,3 @@
var c3 = { version: "0.4.11" };
var c3_chart_fn,
c3_chart_internal_fn,
c3_chart_internal_axis_fn;
function API(owner) {
this.owner = owner;
}
function inherit(base, derived) {
if (Object.create) {
derived.prototype = Object.create(base.prototype);
} else {
var f = function f() {};
f.prototype = base.prototype;
derived.prototype = new f();
}
derived.prototype.constructor = derived;
return derived;
}
function Chart(config) {
var $$ = this.internal = new ChartInternal(this);
$$.loadConfig(config);
$$.beforeInit(config);
$$.init();
$$.afterInit(config);
// bind "this" to nested API
(function bindThis(fn, target, argThis) {
Object.keys(fn).forEach(function (key) {
target[key] = fn[key].bind(argThis);
if (Object.keys(fn[key]).length > 0) {
bindThis(fn[key], target[key], argThis);
}
});
})(c3_chart_fn, this, this);
}
function ChartInternal(api) {
var $$ = this;
$$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined;
@ -52,67 +8,51 @@ function ChartInternal(api) {
$$.axes = {};
}
c3.generate = function (config) {
return new Chart(config);
};
c3.chart = {
fn: Chart.prototype,
internal: {
fn: ChartInternal.prototype,
axis: {
fn: Axis.prototype
}
}
};
c3_chart_fn = c3.chart.fn;
c3_chart_internal_fn = c3.chart.internal.fn;
c3_chart_internal_axis_fn = c3.chart.internal.axis.fn;
var c3_chart_internal_fn = ChartInternal.prototype;
c3_chart_internal_fn.beforeInit = function () {
c3_chart_internal_fn.beforeInit = function() {
// can do something
};
c3_chart_internal_fn.afterInit = function () {
c3_chart_internal_fn.afterInit = function() {
// can do something
};
c3_chart_internal_fn.init = function () {
var $$ = this, config = $$.config;
c3_chart_internal_fn.init = function() {
var $$ = this,
config = $$.config;
$$.initParams();
if (config.data_url) {
$$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData);
}
else if (config.data_json) {
} else if (config.data_json) {
$$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));
}
else if (config.data_rows) {
} else if (config.data_rows) {
$$.initWithData($$.convertRowsToData(config.data_rows));
}
else if (config.data_columns) {
} else if (config.data_columns) {
$$.initWithData($$.convertColumnsToData(config.data_columns));
}
else {
} else {
throw Error('url or json or rows or columns is required.');
}
};
c3_chart_internal_fn.initParams = function () {
var $$ = this, d3 = $$.d3, config = $$.config;
c3_chart_internal_fn.initParams = function() {
var $$ = this,
d3 = $$.d3,
config = $$.config;
// MEMO: clipId needs to be unique because it conflicts when multiple charts exist
$$.clipId = "c3-" + (+new Date()) + '-clip',
$$.clipIdForXAxis = $$.clipId + '-xaxis',
$$.clipIdForYAxis = $$.clipId + '-yaxis',
$$.clipIdForGrid = $$.clipId + '-grid',
$$.clipIdForSubchart = $$.clipId + '-subchart',
$$.clipPath = $$.getClipPath($$.clipId),
$$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis),
$$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);
$$.clipIdForXAxis = $$.clipId + '-xaxis',
$$.clipIdForYAxis = $$.clipId + '-yaxis',
$$.clipIdForGrid = $$.clipId + '-grid',
$$.clipIdForSubchart = $$.clipId + '-subchart',
$$.clipPath = $$.getClipPath($$.clipId),
$$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis),
$$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);
$$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid),
$$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart),
$$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart),
$$.dragStart = null;
$$.dragStart = null;
$$.dragging = false;
$$.flowing = false;
$$.cancelClick = false;
@ -125,14 +65,30 @@ c3_chart_internal_fn.initParams = function () {
$$.dataTimeFormat = config.data_xLocaltime ? d3.time.format : d3.time.format.utc;
$$.axisTimeFormat = config.axis_x_localtime ? d3.time.format : d3.time.format.utc;
$$.defaultAxisTimeFormat = $$.axisTimeFormat.multi([
[".%L", function (d) { return d.getMilliseconds(); }],
[":%S", function (d) { return d.getSeconds(); }],
["%I:%M", function (d) { return d.getMinutes(); }],
["%I %p", function (d) { return d.getHours(); }],
["%-m/%-d", function (d) { return d.getDay() && d.getDate() !== 1; }],
["%-m/%-d", function (d) { return d.getDate() !== 1; }],
["%-m/%-d", function (d) { return d.getMonth(); }],
["%Y/%-m/%-d", function () { return true; }]
[".%L", function(d) {
return d.getMilliseconds();
}],
[":%S", function(d) {
return d.getSeconds();
}],
["%I:%M", function(d) {
return d.getMinutes();
}],
["%I %p", function(d) {
return d.getHours();
}],
["%-m/%-d", function(d) {
return d.getDay() && d.getDate() !== 1;
}],
["%-m/%-d", function(d) {
return d.getDate() !== 1;
}],
["%-m/%-d", function(d) {
return d.getMonth();
}],
["%Y/%-m/%-d", function() {
return true;
}]
]);
$$.hiddenTargetIds = [];
@ -170,7 +126,7 @@ c3_chart_internal_fn.initParams = function () {
$$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js
};
c3_chart_internal_fn.initChartElements = function () {
c3_chart_internal_fn.initChartElements = function() {
if (this.initBar) { this.initBar(); }
if (this.initLine) { this.initLine(); }
if (this.initArc) { this.initArc(); }
@ -178,8 +134,10 @@ c3_chart_internal_fn.initChartElements = function () {
if (this.initText) { this.initText(); }
};
c3_chart_internal_fn.initWithData = function (data) {
var $$ = this, d3 = $$.d3, config = $$.config;
c3_chart_internal_fn.initWithData = function(data) {
var $$ = this,
d3 = $$.d3,
config = $$.config;
var defs, main, binding = true;
$$.axis = new Axis($$);
@ -190,11 +148,9 @@ c3_chart_internal_fn.initWithData = function (data) {
if (!config.bindto) {
$$.selectChart = d3.selectAll([]);
}
else if (typeof config.bindto.node === 'function') {
} else if (typeof config.bindto.node === 'function') {
$$.selectChart = config.bindto;
}
else {
} else {
$$.selectChart = d3.select(config.bindto);
}
if ($$.selectChart.empty()) {
@ -249,8 +205,12 @@ c3_chart_internal_fn.initWithData = function (data) {
// Define svgs
$$.svg = $$.selectChart.append("svg")
.style("overflow", "hidden")
.on('mouseenter', function () { return config.onmouseover.call($$); })
.on('mouseleave', function () { return config.onmouseout.call($$); });
.on('mouseenter', function() {
return config.onmouseover.call($$);
})
.on('mouseleave', function() {
return config.onmouseout.call($$);
});
if ($$.config.svg_classname) {
$$.svg.attr('class', $$.config.svg_classname);
@ -339,10 +299,10 @@ c3_chart_internal_fn.initWithData = function (data) {
$$.api.element = $$.selectChart.node();
};
c3_chart_internal_fn.smoothLines = function (el, type) {
c3_chart_internal_fn.smoothLines = function(el, type) {
var $$ = this;
if (type === 'grid') {
el.each(function () {
el.each(function() {
var g = $$.d3.select(this),
x1 = g.attr('x1'),
x2 = g.attr('x2'),
@ -359,8 +319,9 @@ c3_chart_internal_fn.smoothLines = function (el, type) {
};
c3_chart_internal_fn.updateSizes = function () {
var $$ = this, config = $$.config;
c3_chart_internal_fn.updateSizes = function() {
var $$ = this,
config = $$.config;
var legendHeight = $$.legend ? $$.getLegendHeight() : 0,
legendWidth = $$.legend ? $$.getLegendWidth() : 0,
legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight,
@ -429,7 +390,7 @@ c3_chart_internal_fn.updateSizes = function () {
}
};
c3_chart_internal_fn.updateTargets = function (targets) {
c3_chart_internal_fn.updateTargets = function(targets) {
var $$ = this;
/*-- Main --*/
@ -453,16 +414,23 @@ c3_chart_internal_fn.updateTargets = function (targets) {
// Fade-in each chart
$$.showTargets();
};
c3_chart_internal_fn.showTargets = function () {
c3_chart_internal_fn.showTargets = function() {
var $$ = this;
$$.svg.selectAll('.' + CLASS.target).filter(function (d) { return $$.isTargetToShow(d.id); })
.transition().duration($$.config.transition_duration)
$$.svg.selectAll('.' + CLASS.target).filter(function(d) {
return $$.isTargetToShow(d.id);
})
.transition().duration($$.config.transition_duration)
.style("opacity", 1);
};
c3_chart_internal_fn.redraw = function (options, transitions) {
var $$ = this, main = $$.main, d3 = $$.d3, config = $$.config;
var areaIndices = $$.getShapeIndices($$.isAreaType), barIndices = $$.getShapeIndices($$.isBarType), lineIndices = $$.getShapeIndices($$.isLineType);
c3_chart_internal_fn.redraw = function(options, transitions) {
var $$ = this,
main = $$.main,
d3 = $$.d3,
config = $$.config;
var areaIndices = $$.getShapeIndices($$.isAreaType),
barIndices = $$.getShapeIndices($$.isBarType),
lineIndices = $$.getShapeIndices($$.isLineType);
var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis,
withTransform, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain, withLegend,
withEventRect, withDimension, withUpdateXAxis;
@ -470,8 +438,10 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
var drawArea, drawBar, drawLine, xForText, yForText;
var duration, durationForExit, durationForAxis;
var waitForDraw, flow;
var targetsToShow = $$.filterTargetsToShow($$.data.targets), tickValues, i, intervalForCulling, xDomainForZoom;
var xv = $$.xv.bind($$), cx, cy;
var targetsToShow = $$.filterTargetsToShow($$.data.targets),
tickValues, i, intervalForCulling, xDomainForZoom;
var xv = $$.xv.bind($$),
cx, cy;
options = options || {};
withY = getOption(options, "withY", true);
@ -547,7 +517,7 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
break;
}
}
$$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function (e) {
$$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function(e) {
var index = tickValues.indexOf(e);
if (index >= 0) {
d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block');
@ -579,7 +549,7 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
.attr("x", $$.width / 2)
.attr("y", $$.height / 2)
.text(config.data_empty_label_text)
.transition()
.transition()
.style('opacity', targetsToShow.length ? 0 : 1);
// grid
@ -649,40 +619,39 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
if ((duration || flow) && $$.isTabVisible()) { // Only use transition if tab visible. See #938.
// transition should be derived from one transition
d3.transition().duration(duration).each(function () {
var transitionsToWait = [];
// redraw and gather transitions
[
$$.redrawBar(drawBar, true),
$$.redrawLine(drawLine, true),
$$.redrawArea(drawArea, true),
$$.redrawCircle(cx, cy, true),
$$.redrawText(xForText, yForText, options.flow, true),
$$.redrawRegion(true),
$$.redrawGrid(true),
].forEach(function (transitions) {
transitions.forEach(function (transition) {
transitionsToWait.push(transition);
d3.transition().duration(duration).each(function() {
var transitionsToWait = [];
// redraw and gather transitions
[
$$.redrawBar(drawBar, true),
$$.redrawLine(drawLine, true),
$$.redrawArea(drawArea, true),
$$.redrawCircle(cx, cy, true),
$$.redrawText(xForText, yForText, options.flow, true),
$$.redrawRegion(true),
$$.redrawGrid(true),
].forEach(function(transitions) {
transitions.forEach(function(transition) {
transitionsToWait.push(transition);
});
});
});
// Wait for end of transitions to call flow and onrendered callback
waitForDraw = $$.generateWait();
transitionsToWait.forEach(function (t) {
waitForDraw.add(t);
// Wait for end of transitions to call flow and onrendered callback
waitForDraw = $$.generateWait();
transitionsToWait.forEach(function(t) {
waitForDraw.add(t);
});
})
.call(waitForDraw, function() {
if (flow) {
flow();
}
if (config.onrendered) {
config.onrendered.call($$);
}
});
})
.call(waitForDraw, function () {
if (flow) {
flow();
}
if (config.onrendered) {
config.onrendered.call($$);
}
});
}
else {
} else {
$$.redrawBar(drawBar);
$$.redrawLine(drawLine);
$$.redrawArea(drawArea);
@ -696,13 +665,15 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
}
// update fadein condition
$$.mapToIds($$.data.targets).forEach(function (id) {
$$.mapToIds($$.data.targets).forEach(function(id) {
$$.withoutFadeIn[id] = true;
});
};
c3_chart_internal_fn.updateAndRedraw = function (options) {
var $$ = this, config = $$.config, transitions;
c3_chart_internal_fn.updateAndRedraw = function(options) {
var $$ = this,
config = $$.config,
transitions;
options = options || {};
// same with redraw
options.withTransition = getOption(options, "withTransition", true);
@ -727,7 +698,7 @@ c3_chart_internal_fn.updateAndRedraw = function (options) {
// Draw with new sizes & scales
$$.redraw(options, transitions);
};
c3_chart_internal_fn.redrawWithoutRescale = function () {
c3_chart_internal_fn.redrawWithoutRescale = function() {
this.redraw({
withY: false,
withSubchart: false,
@ -736,23 +707,26 @@ c3_chart_internal_fn.redrawWithoutRescale = function () {
});
};
c3_chart_internal_fn.isTimeSeries = function () {
c3_chart_internal_fn.isTimeSeries = function() {
return this.config.axis_x_type === 'timeseries';
};
c3_chart_internal_fn.isCategorized = function () {
c3_chart_internal_fn.isCategorized = function() {
return this.config.axis_x_type.indexOf('categor') >= 0;
};
c3_chart_internal_fn.isCustomX = function () {
var $$ = this, config = $$.config;
c3_chart_internal_fn.isCustomX = function() {
var $$ = this,
config = $$.config;
return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs));
};
c3_chart_internal_fn.isTimeSeriesY = function () {
c3_chart_internal_fn.isTimeSeriesY = function() {
return this.config.axis_y_type === 'timeseries';
};
c3_chart_internal_fn.getTranslate = function (target) {
var $$ = this, config = $$.config, x, y;
c3_chart_internal_fn.getTranslate = function(target) {
var $$ = this,
config = $$.config,
x, y;
if (target === 'main') {
x = asHalfPixel($$.margin.left);
y = asHalfPixel($$.margin.top);
@ -780,48 +754,48 @@ c3_chart_internal_fn.getTranslate = function (target) {
}
return "translate(" + x + "," + y + ")";
};
c3_chart_internal_fn.initialOpacity = function (d) {
c3_chart_internal_fn.initialOpacity = function(d) {
return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0;
};
c3_chart_internal_fn.initialOpacityForCircle = function (d) {
c3_chart_internal_fn.initialOpacityForCircle = function(d) {
return d.value !== null && this.withoutFadeIn[d.id] ? this.opacityForCircle(d) : 0;
};
c3_chart_internal_fn.opacityForCircle = function (d) {
c3_chart_internal_fn.opacityForCircle = function(d) {
var opacity = this.config.point_show ? 1 : 0;
return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0;
};
c3_chart_internal_fn.opacityForText = function () {
c3_chart_internal_fn.opacityForText = function() {
return this.hasDataLabel() ? 1 : 0;
};
c3_chart_internal_fn.xx = function (d) {
c3_chart_internal_fn.xx = function(d) {
return d ? this.x(d.x) : null;
};
c3_chart_internal_fn.xv = function (d) {
var $$ = this, value = d.value;
c3_chart_internal_fn.xv = function(d) {
var $$ = this,
value = d.value;
if ($$.isTimeSeries()) {
value = $$.parseDate(d.value);
}
else if ($$.isCategorized() && typeof d.value === 'string') {
} else if ($$.isCategorized() && typeof d.value === 'string') {
value = $$.config.axis_x_categories.indexOf(d.value);
}
return Math.ceil($$.x(value));
};
c3_chart_internal_fn.yv = function (d) {
c3_chart_internal_fn.yv = function(d) {
var $$ = this,
yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y;
return Math.ceil(yScale(d.value));
};
c3_chart_internal_fn.subxx = function (d) {
c3_chart_internal_fn.subxx = function(d) {
return d ? this.subX(d.x) : null;
};
c3_chart_internal_fn.transformMain = function (withTransition, transitions) {
c3_chart_internal_fn.transformMain = function(withTransition, transitions) {
var $$ = this,
xAxis, yAxis, y2Axis;
if (transitions && transitions.axisX) {
xAxis = transitions.axisX;
} else {
xAxis = $$.main.select('.' + CLASS.axisX);
xAxis = $$.main.select('.' + CLASS.axisX);
if (withTransition) { xAxis = xAxis.transition(); }
}
if (transitions && transitions.axisY) {
@ -842,14 +816,14 @@ c3_chart_internal_fn.transformMain = function (withTransition, transitions) {
y2Axis.attr("transform", $$.getTranslate('y2'));
$$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc'));
};
c3_chart_internal_fn.transformAll = function (withTransition, transitions) {
c3_chart_internal_fn.transformAll = function(withTransition, transitions) {
var $$ = this;
$$.transformMain(withTransition, transitions);
if ($$.config.subchart_show) { $$.transformContext(withTransition, transitions); }
if ($$.legend) { $$.transformLegend(withTransition); }
};
c3_chart_internal_fn.updateSvgSize = function () {
c3_chart_internal_fn.updateSvgSize = function() {
var $$ = this,
brush = $$.svg.select(".c3-brush .background");
$$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);
@ -877,7 +851,7 @@ c3_chart_internal_fn.updateSvgSize = function () {
};
c3_chart_internal_fn.updateDimension = function (withoutAxis) {
c3_chart_internal_fn.updateDimension = function(withoutAxis) {
var $$ = this;
if (!withoutAxis) {
if ($$.config.axis_rotated) {
@ -894,18 +868,19 @@ c3_chart_internal_fn.updateDimension = function (withoutAxis) {
$$.transformAll(false);
};
c3_chart_internal_fn.observeInserted = function (selection) {
var $$ = this, observer;
c3_chart_internal_fn.observeInserted = function(selection) {
var $$ = this,
observer;
if (typeof MutationObserver === 'undefined') {
window.console.error("MutationObserver not defined.");
return;
}
observer= new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList' && mutation.previousSibling) {
observer.disconnect();
// need to wait for completion of load because size calculation requires the actual sizes determined after that completion
$$.intervalForObserveInserted = window.setInterval(function () {
$$.intervalForObserveInserted = window.setInterval(function() {
// parentNode will NOT be null when completed
if (selection.node().parentNode) {
window.clearInterval($$.intervalForObserveInserted);
@ -926,29 +901,30 @@ c3_chart_internal_fn.observeInserted = function (selection) {
}
});
});
observer.observe(selection.node(), {attributes: true, childList: true, characterData: true});
observer.observe(selection.node(), { attributes: true, childList: true, characterData: true });
};
c3_chart_internal_fn.bindResize = function () {
var $$ = this, config = $$.config;
c3_chart_internal_fn.bindResize = function() {
var $$ = this,
config = $$.config;
$$.resizeFunction = $$.generateResize();
$$.resizeFunction.add(function () {
$$.resizeFunction.add(function() {
config.onresize.call($$);
});
if (config.resize_auto) {
$$.resizeFunction.add(function () {
$$.resizeFunction.add(function() {
if ($$.resizeTimeout !== undefined) {
window.clearTimeout($$.resizeTimeout);
}
$$.resizeTimeout = window.setTimeout(function () {
$$.resizeTimeout = window.setTimeout(function() {
delete $$.resizeTimeout;
$$.api.flush();
}, 100);
});
}
$$.resizeFunction.add(function () {
$$.resizeFunction.add(function() {
config.onresized.call($$);
});
@ -973,17 +949,18 @@ c3_chart_internal_fn.bindResize = function () {
}
};
c3_chart_internal_fn.generateResize = function () {
c3_chart_internal_fn.generateResize = function() {
var resizeFunctions = [];
function callResizeFunctions() {
resizeFunctions.forEach(function (f) {
resizeFunctions.forEach(function(f) {
f();
});
}
callResizeFunctions.add = function (f) {
callResizeFunctions.add = function(f) {
resizeFunctions.push(f);
};
callResizeFunctions.remove = function (f) {
callResizeFunctions.remove = function(f) {
for (var i = 0; i < resizeFunctions.length; i++) {
if (resizeFunctions[i] === f) {
resizeFunctions.splice(i, 1);
@ -994,20 +971,20 @@ c3_chart_internal_fn.generateResize = function () {
return callResizeFunctions;
};
c3_chart_internal_fn.endall = function (transition, callback) {
c3_chart_internal_fn.endall = function(transition, callback) {
var n = 0;
transition
.each(function () { ++n; })
.each("end", function () {
.each(function() {++n; })
.each("end", function() {
if (!--n) { callback.apply(this, arguments); }
});
};
c3_chart_internal_fn.generateWait = function () {
c3_chart_internal_fn.generateWait = function() {
var transitionsToWait = [],
f = function (transition, callback) {
var timer = setInterval(function () {
f = function(transition, callback) {
var timer = setInterval(function() {
var done = 0;
transitionsToWait.forEach(function (t) {
transitionsToWait.forEach(function(t) {
if (t.empty()) {
done += 1;
return;
@ -1024,14 +1001,15 @@ c3_chart_internal_fn.generateWait = function () {
}
}, 10);
};
f.add = function (transition) {
f.add = function(transition) {
transitionsToWait.push(transition);
};
return f;
};
c3_chart_internal_fn.parseDate = function (date) {
var $$ = this, parsedDate;
c3_chart_internal_fn.parseDate = function(date) {
var $$ = this,
parsedDate;
if (date instanceof Date) {
parsedDate = date;
} else if (typeof date === 'string') {
@ -1045,7 +1023,7 @@ c3_chart_internal_fn.parseDate = function (date) {
return parsedDate;
};
c3_chart_internal_fn.isTabVisible = function () {
c3_chart_internal_fn.isTabVisible = function() {
var hidden;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
hidden = "hidden";

0
src/interaction.js → src/chartinternal/interaction.js

0
src/legend.js → src/chartinternal/legend.js

0
src/region.js → src/chartinternal/region.js

0
src/scale.js → src/chartinternal/scale.js

0
src/selection.js → src/chartinternal/selection.js

0
src/shape.bar.js → src/chartinternal/shape.bar.js

0
src/shape.js → src/chartinternal/shape.js

0
src/shape.line.js → src/chartinternal/shape.line.js

0
src/size.js → src/chartinternal/size.js

0
src/subchart.js → src/chartinternal/subchart.js

0
src/text.js → src/chartinternal/text.js

0
src/title.js → src/chartinternal/title.js

0
src/tooltip.js → src/chartinternal/tooltip.js

10
src/chartinternal/transform.js

@ -0,0 +1,10 @@
c3_chart_internal_fn.transformTo = function(targetIds, type, optionsForRedraw) {
var $$ = this,
withTransitionForAxis = !$$.hasArcType(),
options = optionsForRedraw || { withTransitionForAxis: withTransitionForAxis };
options.withTransitionForTransform = false;
$$.transiting = false;
$$.setTargetType(targetIds, type);
$$.updateTargets($$.data.targets); // this is needed when transforming to arc
$$.updateAndRedraw(options);
};

0
src/type.js → src/chartinternal/type.js

0
src/ua.js → src/chartinternal/ua.js

0
src/util.js → src/chartinternal/util.js

0
src/zoom.js → src/chartinternal/zoom.js

12
src/head.js

@ -1,4 +1,8 @@
(function (window) {
'use strict';
/*global define, module, exports, require */
/*global define, module, exports, require */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('d3')) :
typeof define === 'function' && define.amd ? define(['d3'],factory) :
(global.c3 = factory(global.d3));
}(this, function (d3) {
'use strict';
var c3 = { version: "0.4.11-rc4" };

24
src/tail.js

@ -1,9 +1,17 @@
if (typeof define === 'function' && define.amd) {
define("c3", ["d3"], function () { return c3; });
} else if ('undefined' !== typeof exports && 'undefined' !== typeof module) {
module.exports = c3;
} else {
window.c3 = c3;
}
c3.generate = function(config) {
return new Chart(config);
};
})(window);
c3.chart = {
fn: Chart.prototype,
internal: {
fn: ChartInternal.prototype,
axis: {
fn: Axis.prototype
}
}
};
return c3;
}));
Loading…
Cancel
Save