Browse Source

Refactors circular dependencies (#2389)

* Refactors circular dependencies

 - Adds src/chart-internal.js
 - doesn't need to pass c3.js as argument to rollup
 - don't commit c3.js nor c3.min.js
 - formatting rollup.config.js
 - keep util.js format
 - remove unused imports from axis, core and util

* adds more tests for axis and zoom

* restores the way in which chart-internal calls d3 #2060

* fixes linter warnings on axis-spec
pull/2400/head
Felipe Figueroa 7 years ago committed by Yoshiya Hinosawa
parent
commit
22b06bb28b
  1. 2
      package.json
  2. 9
      rollup.config.js
  3. 24
      spec/api.axis-spec.js
  4. 11
      spec/api.zoom-spec.js
  5. 145
      spec/axis-spec.js
  6. 3
      src/axis.js
  7. 9
      src/chart-internal.js
  8. 66
      src/core.js
  9. 41
      src/util.js

2
package.json

@ -9,7 +9,7 @@
"docs": "bundle exec middleman",
"build": "npm run build:js && npm run build:css",
"build:js": "npm run build:js:rollup && npm run build:js:uglify",
"build:js:rollup": "rollup -c > c3.js",
"build:js:rollup": "rollup -c",
"build:js:uglify": "uglifyjs c3.js --compress --mangle --comments -o c3.min.js",
"build:css": "npm run build:css:sass && npm run build:css:min",
"build:css:sass": "node-sass src/scss/main.scss > c3.css",

9
rollup.config.js

@ -4,9 +4,13 @@ import pkg from './package.json'
export default {
input: 'src/index.js',
output: {
file: 'c3.js',
name: 'c3',
format: 'umd',
banner: `/* @license C3.js v${pkg.version} | (c) C3 Team and other contributors | http://c3js.org/ */`
banner: `/* @license C3.js v${pkg.version} | (c) C3 Team and other contributors | http://c3js.org/ */`,
globals:{
d3:'d3'
}
},
plugins: [babel({
presets: [['es2015', {
@ -15,5 +19,6 @@ export default {
plugins: [
'external-helpers'
]
})]
})],
external: ['d3'],
};

24
spec/api.axis-spec.js

@ -49,5 +49,29 @@ describe('c3 api axis', function () {
expect(label.attr('dy')).toBe('-0.5em');
});
it('updates axis max values', function () {
chart.axis.max({x: 100, y: 300, y2: 100});
var max_values = chart.axis.max();
expect(max_values.x).toBe(100);
expect(max_values.y).toBe(300);
expect(max_values.y2).toBe(100);
});
it('updates axis min values', function () {
chart.axis.min({x: 0, y: 20, y2: 50});
var min_values = chart.axis.min();
expect(min_values.x).toBe(0);
expect(min_values.y).toBe(20);
expect(min_values.y2).toBe(50);
});
it('updates axis range', function () {
chart.axis.range({min: 5, max: 250});
var range = chart.axis.range();
expect(range.max.y).toBe(250);
expect(range.min.y).toBe(5);
});
});
});

11
spec/api.zoom-spec.js

@ -48,6 +48,17 @@ describe('c3 api zoom', function () {
expect(domain[1]).toBe(target[1]);
});
it('should set the max zoom properly', function () {
chart.zoom.max(100);
expect(chart.zoom.max()).toBe(100);
});
it('should set the min zoom properly', function () {
chart.zoom.min(-1);
expect(chart.zoom.min()).toBe(-1);
});
describe('with timeseries data', function () {
beforeAll(function(){
args = {

145
spec/axis-spec.js

@ -90,6 +90,145 @@ describe('c3 chart axis', function () {
});
});
describe('axis x timeseries with seconds', function() {
beforeAll(function() {
args = {
data: {
type: 'line',
columns: [
["epoch", 1401879600000, 1401883200000, 1401886800000],
["y", 1955, 2419, 2262]
],
xs: {
y: "epoch"
}
},
axis: {
x: {
type: "timeseries",
min: new Date(1401879600000),
max: new Date(1401969600000),
localtime: false
}
}
};
});
it('should have 3 ticks on x axis', function() {
var ticksSize = d3.select('.c3-axis-x').selectAll('g.tick').size();
expect(ticksSize).toBe(3);
});
it('should have specified 1 hour intervals', function() {
var prevValue;
d3.select('.c3-axis-x').selectAll('g.tick').each(function(d, i) {
if (i !== 0) {
var result = d - prevValue;
expect(result).toEqual(3600000); // expressed in milliseconds
}
prevValue = d;
});
});
describe('changing min x time and columns', function() {
beforeAll(function() {
args.axis.x.min = new Date(1401876000000);
args.axis.x.max = new Date(1401876075000);
args.data.columns = [
["epoch", 1401876000000, 1401876015000, 1401876030000, 1401876045000, 1401876060000, 1401876075000],
["y", 1968, 1800, 1955, 2419, 2262, 1940]
];
});
it('should have 6 ticks on x axis', function() {
var ticksSize = d3.select('.c3-axis-x').selectAll('g.tick').size();
expect(ticksSize).toBe(6); // the count starts at initial value and increments by the set interval
});
it('should have specified 15 seconds intervals', function() {
var prevValue;
d3.select('.c3-axis-x').selectAll('g.tick').each(function(d, i) {
if (i !== 0) {
var result = d - prevValue;
expect(result).toEqual(15000); // expressed in milliseconds
}
prevValue = d;
});
});
describe('with axis.x.time.format %Y-%m-%d %H:%M:%S', function() {
beforeAll(function() {
args.axis.x.tick = {
format: "%M:%S" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format
};
});
var textDates = [
'00:00',
'00:15',
'00:30',
'00:45',
'01:00',
'01:15'
];
it('should format x ticks as dates with time', function() {
var ticks = d3.select('.c3-axis-x').selectAll('g.tick').selectAll('tspan').each(function(d) {
expect(d.splitted).toEqual(textDates[d.index]);
});
expect(ticks.size()).toBe(6);
});
});
});
});
describe('axis x timeseries with iso dates', function() {
beforeAll(function() {
args = {
data: {
type: 'line',
columns: [
["epoch", 1527811200000, 1527897600000, 1527984000000],
["y", 1955, 2419, 2262]
],
xs: {
y: "epoch"
}
},
axis: {
x: {
type: "timeseries",
min: new Date('2018-06-01'),
max: new Date('2018-06-03'),
localtime: false,
tick: {
format: "%Y-%m-%dT%H:%M:%S" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format
}
}
}
};
});
var textDates = [
'2018-06-01T00:00:00',
'2018-06-02T00:00:00',
'2018-06-03T00:00:00'
];
it('should format x ticks as dates', function() {
var ticks = d3.select('.c3-axis-x').selectAll('g.tick').selectAll('tspan').each(function(d) {
expect(d.splitted).toEqual(textDates[d.index]);
});
expect(ticks.size()).toBe(3);
});
});
describe('axis y timeseries', function() {
beforeAll(function() {
args = {
@ -102,8 +241,7 @@ describe('c3 chart axis', function () {
y: {
type: 'timeseries',
tick: {
time: {
}
time: {}
}
}
}
@ -159,8 +297,7 @@ describe('c3 chart axis', function () {
args.data = {
x: 'x',
columns: [
['x'].concat(xValues),
['data1', 30, 200, 100, 400, 150, 250],
['x'].concat(xValues), ['data1', 30, 200, 100, 400, 150, 250],
]
};
});

3
src/axis.js

@ -1,6 +1,5 @@
import CLASS from './class';
import { Component } from './core';
import { isValue, isFunction, isString, isEmpty } from './util';
import {isValue, isFunction, isString, isEmpty, Component } from './util';
export var c3_axis_fn;
export var c3_axis_internal_fn;

9
src/chart-internal.js

@ -0,0 +1,9 @@
export function ChartInternal(api) {
var $$ = this;
$$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined;
$$.api = api;
$$.config = $$.getDefaultConfig();
$$.data = {};
$$.cache = {};
$$.axes = {};
}

66
src/core.js

@ -1,56 +1,28 @@
import Axis from './axis';
import CLASS from './class';
import { isValue, isFunction, isString, isUndefined, isDefined, ceil10, asHalfPixel, diffDomain, isEmpty, notEmpty, getOption, hasValue, sanitise, getPathBox } from './util';
export var c3 = { version: "0.6.2" };
import {
c3,
isEmpty,
notEmpty,
isValue,
isFunction,
isString,
isUndefined,
isDefined,
ceil10,
asHalfPixel,
diffDomain,
getOption,
hasValue,
sanitise,
getPathBox
} from './util';
export {c3};
export var c3_chart_fn;
export var c3_chart_internal_fn;
export function Component(owner, componentKey, fn) {
this.owner = owner;
c3.chart.internal[componentKey] = 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);
}
function ChartInternal(api) {
var $$ = this;
$$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined;
$$.api = api;
$$.config = $$.getDefaultConfig();
$$.data = {};
$$.cache = {};
$$.axes = {};
}
c3.generate = function (config) {
return new Chart(config);
};
c3.chart = {
fn: Chart.prototype,
internal: {
fn: ChartInternal.prototype,
}
};
c3_chart_fn = c3.chart.fn;
c3_chart_internal_fn = c3.chart.internal.fn;

41
src/util.js

@ -1,4 +1,41 @@
import { c3_chart_internal_fn } from './core';
import {ChartInternal} from './chart-internal';
export var c3 = { version: "0.6.2" ,
chart: {
fn: Chart.prototype,
internal: {
fn: ChartInternal.prototype,
}
}
};
export 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.generate = function (config) {
return new Chart(config);
};
export function Component(owner, componentKey, fn) {
this.owner = owner;
c3.chart.internal[componentKey] = fn;
}
export var isValue = function (v) {
return v || v === 0;
@ -31,7 +68,7 @@ export var isEmpty = function (o) {
return typeof o === 'undefined' || o === null || (isString(o) && o.length === 0) || (typeof o === 'object' && Object.keys(o).length === 0);
};
export var notEmpty = function (o) {
return !c3_chart_internal_fn.isEmpty(o);
return !c3.chart.internal.fn.isEmpty(o);
};
export var getOption = function (options, key, defaultValue) {
return isDefined(options[key]) ? options[key] : defaultValue;

Loading…
Cancel
Save