Commit f1f11d7e authored by Evgeny's avatar Evgeny

Move changes from 0.4.11. Now developing in this branch

parent 76d2df97
...@@ -5,3 +5,12 @@ d3.js ...@@ -5,3 +5,12 @@ d3.js
d3.min.js d3.min.js
components components
build build
# vim
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist
*~
...@@ -22,7 +22,9 @@ ...@@ -22,7 +22,9 @@
"describe": false, "describe": false,
"beforeEach": false, "beforeEach": false,
"it": false, "it": false,
"expect": false "expect": false,
"d3": false,
"wait": false
} }
} }
module.exports = (grunt) -> module.exports = (grunt) ->
require('load-grunt-tasks') grunt, pattern: 'grunt-contrib-*' require('load-grunt-tasks') grunt, pattern: ['grunt-contrib-*', 'grunt-sass']
grunt.initConfig grunt.initConfig
watch: watch:
concat: concat:
tasks: 'concat' tasks: 'concat'
files: ['src/*.js'] files: ['src/*.js']
sass:
tasks: 'sass'
files: ['src/scss/*.scss']
concat: concat:
dist: dist:
...@@ -37,6 +40,7 @@ module.exports = (grunt) -> ...@@ -37,6 +40,7 @@ module.exports = (grunt) ->
'src/grid.js', 'src/grid.js',
'src/tooltip.js', 'src/tooltip.js',
'src/legend.js', 'src/legend.js',
'src/title.js',
'src/axis.js', 'src/axis.js',
'src/clip.js', 'src/clip.js',
'src/arc.js', 'src/arc.js',
...@@ -69,6 +73,7 @@ module.exports = (grunt) -> ...@@ -69,6 +73,7 @@ module.exports = (grunt) ->
'src/api.chart.js', 'src/api.chart.js',
'src/api.tooltip.js', 'src/api.tooltip.js',
'src/c3.axis.js', 'src/c3.axis.js',
'src/ua.js',
'src/polyfill.js', 'src/polyfill.js',
'src/tail.js' 'src/tail.js'
] ]
...@@ -87,7 +92,7 @@ module.exports = (grunt) -> ...@@ -87,7 +92,7 @@ module.exports = (grunt) ->
specs: 'spec/*-spec.js' specs: 'spec/*-spec.js'
helpers: 'spec/*-helper.js' helpers: 'spec/*-helper.js'
styles: 'c3.css' styles: 'c3.css'
vendor: 'http://d3js.org/d3.v3.min.js' vendor: 'bower_components/d3/d3.js'
uglify: uglify:
c3: c3:
...@@ -99,4 +104,7 @@ module.exports = (grunt) -> ...@@ -99,4 +104,7 @@ module.exports = (grunt) ->
src: 'c3.css' src: 'c3.css'
dest: 'c3.min.css' dest: 'c3.min.css'
grunt.registerTask 'default', ['concat', 'jshint', 'jasmine', 'cssmin', 'uglify'] grunt.registerTask 'default', ['concat', 'test', 'posttest']
grunt.registerTask 'test', ['jasmine']
grunt.registerTask 'build', ['concat', 'posttest']
grunt.registerTask 'posttest', ['cssmin', 'uglify']
all:
grunt
test:
grunt test
build:
grunt build
install: clean
npm install
bower install
clean:
rm -rf node_modules
rm -rf bower_components
c3 [![Build Status](https://travis-ci.org/masayuki0812/c3.svg?branch=master)](https://travis-ci.org/masayuki0812/c3) [![Dependency Status](https://david-dm.org/masayuki0812/c3.svg)](https://david-dm.org/masayuki0812/c3) [![devDependency Status](https://david-dm.org/masayuki0812/c3/dev-status.svg)](https://david-dm.org/masayuki0812/c3#info=devDependencies) [![license](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/masayuki0812/c3/blob/master/LICENSE) c3 [![Build Status](https://travis-ci.org/masayuki0812/c3.svg?branch=master)](https://travis-ci.org/masayuki0812/c3) [![Dependency Status](https://david-dm.org/masayuki0812/c3.svg)](https://david-dm.org/masayuki0812/c3) [![devDependency Status](https://david-dm.org/masayuki0812/c3/dev-status.svg)](https://david-dm.org/masayuki0812/c3#info=devDependencies) [![license](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/masayuki0812/c3/blob/master/LICENSE)
== ==
c3 is a D3-based reusable chart library that enables deeper integration of charts into web applications. c3 is a D3-based reusable chart library that enables deeper integration of charts into web applications.
Follow the link for more information: [http://c3js.org](http://c3js.org/) Follow the link for more information: [http://c3js.org](http://c3js.org/)
## Tutorial and Examples ## Why fork?
C3 development got kinda stack in time. As Etersoft uses c3 for its projects we decided to fork it and improve it by outselves. All releases from origin will be merged as soon as they are out.
+ [Getting Started](http://c3js.org/gettingstarted.html) ## How is this differ?
+ [Examples](http://c3js.org/examples.html)
Additional samples can be found in this repository: Our current improvements
+ [https://github.com/masayuki0812/c3/tree/master/htdocs/samples](https://github.com/masayuki0812/c3/tree/master/htdocs/samples)
You can run these samples as: #### Working with data
```
$ cd c3/htdocs **chart.loadColumns([[id, values...], [...]])**
$ python -m SimpleHTTPServer 8080
``` Loads given columns. Alias to chart.load({columns: [[id, values...], ...]});
## Google Group **chart.appendToColumn(column)**
For general C3.js-related discussion, please visit our [Google Group at https://groups.google.com/forum/#!forum/c3js](https://groups.google.com/forum/#!forum/c3js).
## Using the issue queue Append given values to sequence
The [issue queue](https://github.com/masayuki0812/c3/issues) is to be used for reporting defects and problems with C3.js, in addition to feature requests and ideas. It is **not** a catch-all support forum. **For general support enquiries, please use the [Google Group](https://groups.google.com/forum/#!forum/c3js) at https://groups.google.com/forum/#!forum/c3js.** All questions involving the interplay between C3.js and any other library (such as AngularJS) should be posted there first!
Before reporting an issue, please do the following: Usage:
1. [Search for existing issues](https://github.com/masayuki0812/c3/issues) to ensure you're not posting a duplicate. ```js
// Say data was [0, 50]
chart.appendToColumn(['data', 100, 200]);
// Now data is [0, 50, 100, 200]
```
1. [Search the Google Group](https://groups.google.com/forum/#!forum/c3js) to ensure it hasn't been addressed there already. **chart.popFromColumn(id, amount)**
1. Create a JSFiddle or Plunkr highlighting the issue. Please don't include any unnecessary dependencies so we can isolate that the issue is in fact with C3. *Please be advised that custom CSS can modify C3.js output!* Pops given amount from sequence
1. When posting the issue, please use a descriptive title and include the version of C3 (or, if cloning from Git, the commit hash — C3 is under active development and the master branch contains the latest dev commits!), along with any platform/browser/OS information that may be relevant. Usage:
```js
// Say data was [0, 100, 200, 300]
chart.popFromColumn('data', 2);
// Now data is [0, 100]
```
## Pull requests **chart.setValue(id, index, value)**
Pull requests are welcome, though please post an issue first to see whether such a change is desirable.
If you choose to submit a pull request, please do not bump the version number unless asked to, and please include test cases for any new features!
## Playground Sets value for given sequence and index. If no value is presented in index, new value is appended to sequence.
Please fork this fiddle: ```js
+ [http://jsfiddle.net/masayuki0812/7kYJu/](http://jsfiddle.net/masayuki0812/7kYJu/) // Say data was [0, 100, 200, 300]
chart.setValue('data', 2, 400);
// Now data is [0, 100, 400, 300]
## Dependency // Set non-existing value
+ [D3.js](https://github.com/mbostock/d3) `<=3.5.0` chart.setValue('data', 10, 20);
// Now data is [0, 100, 400, 300, 20]
```
## License **chart.getValue(id, index)**
MIT
[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=masayuki0812&url=https://github.com/masayuki0812/c3&title=c3&language=javascript&tags=github&category=software) Gets value for given sequence and index.
```js
// Say data was [0, 100, 200]
chart.getValue('data', 1) === 100
// Non-existing sequence or index
chart.getValue('no such thing', 10) === undefined
chart.getValue('data', 100) === undefined
```
...@@ -5952,6 +5952,74 @@ ...@@ -5952,6 +5952,74 @@
}); });
}; };
c3_chart_fn.appendToColumn = function(col) {
var $$ = this.internal;
var column = $$.api.getDataById(col[0]);
if(!isUndefined(column)){
for(var i = column.length - 1; i > -1; i--){
col.splice(1, 0, column[i].value);
}
}
$$.api.loadColumns([col]);
};
c3_chart_fn.popFromColumn = function(id, amount){
var $$ = this.internal;
var columns = $$.api.getDataById(id);
if(isUndefined(columns)){
throw new Error("Popping values from non-existing sequence");
}
for(var i = 0; i < amount; i++){
columns.pop();
}
$$.api.loadColumns(columns);
};
c3_chart_fn.loadColumns = function(cols){
var $$ = this.internal;
$$.api.load({
columns: cols
});
};
c3_chart_fn.setValue = function(id, i, value){
var $$ = this.internal;
var column = $$.api.getDataById(id);
if(isUndefined(column)){
throw new Error("Setting value to non-existing sequence " + id);
}
if(isUndefined(column[i])){
$$.api.appendToColumn([id, value]);
} else {
column[i] = value;
$$.api.loadColumns([[id].concat(column)]);
}
};
c3_chart_fn.getValue = function(id, i){
var $$ = this.internal;
var column = $$.api.getDataById(id);
if(isUndefined(column)){
return undefined;
}
var v = column[i];
if(isUndefined(v)){
return undefined;
}
return v.value;
};
c3_chart_fn.flow = function (args) { c3_chart_fn.flow = function (args) {
var $$ = this.internal, var $$ = this.internal,
targets, data, notfoundIds = [], orgDataCount = $$.getMaxDataCount(), targets, data, notfoundIds = [], orgDataCount = $$.getMaxDataCount(),
...@@ -6428,6 +6496,15 @@ ...@@ -6428,6 +6496,15 @@
return this.internal.updateDataAttributes('axes', axes); return this.internal.updateDataAttributes('axes', axes);
}; };
c3_chart_fn.getDataById = function(seqId){
var $$ = this.internal;
var t = $$.api.data(seqId)[0];
if(isUndefined(t)) {
return undefined;
}
return t.values;
}
c3_chart_fn.category = function (i, category) { c3_chart_fn.category = function (i, category) {
var $$ = this.internal, config = $$.config; var $$ = this.internal, config = $$.config;
if (arguments.length > 1) { if (arguments.length > 1) {
...@@ -6547,6 +6624,24 @@ ...@@ -6547,6 +6624,24 @@
this.flush(); this.flush();
}; };
c3_chart_fn.width = function(width){
var $$ = this.internal;
if(isUndefined(width)){
return $$.getCurrentWidth();
}
$$.config.size_width = width;
this.flush();
};
c3_chart_fn.height = function(height){
var $$ = this.internal;
if(isUndefined(height)){
return $$.getCurrentHeight();
}
$$.config.size_height = height;
this.flush();
};
c3_chart_fn.flush = function () { c3_chart_fn.flush = function () {
var $$ = this.internal; var $$ = this.internal;
$$.updateAndRedraw({withLegend: true, withTransition: false, withTransitionForTransform: false}); $$.updateAndRedraw({withLegend: true, withTransition: false, withTransitionForTransform: false});
......
This source diff could not be displayed because it is too large. You can view the blob instead.
describe("c3 chart", function(){
'use strict';
var chart;
var args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 5000, 2000, 1000, 4000, 1500, 2500]
]
}
};
beforeEach(function (done) {
chart = window.initChart(chart, args, done);
});
describe("width", function(){
it("should get width when no arguments given", function(done){
// Just some unusual number
chart.resize({ width: 1087, height: 1087 });
wait(function(){
expect(chart.width()).toBe(1087);
done();
});
});
it("should set width", function(done){
chart.width(1087);
wait(function(){
expect(chart.width()).toBe(1087);
done();
});
});
});
describe("height", function(){
it("should get height when no arguments given", function(done){
// Just some unusual number
chart.resize({ width: 1087, height: 1087 });
wait(function(){
expect(chart.height()).toBe(1087);
done();
});
});
it("should set height", function(done){
chart.height(1087);
wait(function(){
expect(chart.height()).toBe(1087);
done();
});
});
});
});
...@@ -170,64 +170,10 @@ describe('c3 api load', function () { ...@@ -170,64 +170,10 @@ describe('c3 api load', function () {
done(); done();
}, 500); }, 500);
}); });
it('should defocus multiple targets after focused', function (done) {
var main = chart.internal.main,
legend = chart.internal.legend;
chart.focus();
setTimeout(function () {
chart.defocus(['data1', 'data2']);
setTimeout(function () {
var targets = {
data1: main.select('.c3-chart-line.c3-target.c3-target-data1'),
data2: main.select('.c3-chart-line.c3-target.c3-target-data2'),
data3: main.select('.c3-chart-line.c3-target.c3-target-data3')
},
legendItems = {
data1: legend.select('.c3-legend-item-data1'),
data2: legend.select('.c3-legend-item-data2'),
data3: legend.select('.c3-legend-item-data3')
};
expect(targets.data1.classed('c3-defocused')).toBeTruthy();
expect(targets.data2.classed('c3-defocused')).toBeTruthy();
expect(targets.data3.classed('c3-defocused')).toBeFalsy();
expect(legendItems.data1.classed('c3-legend-item-focused')).toBeFalsy();
expect(legendItems.data2.classed('c3-legend-item-focused')).toBeFalsy();
expect(legendItems.data3.classed('c3-legend-item-focused')).toBeTruthy();
expect(+legendItems.data1.style('opacity')).toBeCloseTo(0.3);
expect(+legendItems.data2.style('opacity')).toBeCloseTo(0.3);
expect(+legendItems.data3.style('opacity')).toBeCloseTo(1);
done();
}, 500);
});
}, 500);
}); });
describe('revert', function () { describe('revert', function () {
it('should revert all targets after focus', function (done) {
var main = chart.internal.main,
legend = chart.internal.legend;
chart.focus();
setTimeout(function () {
chart.revert();
setTimeout(function () {
var targets = main.select('.c3-chart-line.c3-target'),
legendItems = legend.select('.c3-legend-item');
targets.each(function () {
var line = d3.select(this);
expect(line.classed('c3-focused')).toBeFalsy();
});
legendItems.each(function () {
var item = d3.select(this);
expect(+item.style('opacity')).toBeCloseTo(1);
});
done();
}, 500);
}, 500);
});
it('should revert all targets after defocus', function (done) { it('should revert all targets after defocus', function (done) {
var main = chart.internal.main, var main = chart.internal.main,
legend = chart.internal.legend; legend = chart.internal.legend;
......
describe('c3 api load', function () { describe('c3 api load', function () {
'use strict'; 'use strict';
var chart, d3; var chart, args;
var args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 5000, 2000, 1000, 4000, 1500, 2500]
]
}
};
beforeEach(function (done) { beforeEach(function (done) {
chart = window.initChart(chart, args, done); chart = window.initChart(chart, args, done);
d3 = chart.internal.d3;
}); });
describe('indexed data', function () { describe('indexed data', function () {
describe('as column', function () { describe('as column', function () {
it('should update args', function () {
args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 5000, 2000, 1000, 4000, 1500, 2500]
]
}
};
expect(true).toBeTruthy();
});
it('should load additional data', function (done) { it('should load additional data', function (done) {
var main = chart.internal.main, var main = chart.internal.main,
legend = chart.internal.legend; legend = chart.internal.legend;
...@@ -71,29 +72,6 @@ describe('c3 api load', function () { ...@@ -71,29 +72,6 @@ describe('c3 api load', function () {
legend = chart.internal.legend; legend = chart.internal.legend;
chart.load({ chart.load({
columns: [ columns: [
['data3', 800, 500, 900, 500, 1000, 700]
]
});
setTimeout(function () {
var target = main.select('.c3-chart-line.c3-target.c3-target-data3'),
legendItem = legend.select('.c3-legend-item.c3-legend-item-data3'),
tickTexts = main.selectAll('.c3-axis-x g.tick text'),
expected = ['cat1', 'cat2', 'cat3', 'cat4', 'cat5', 'cat6'];
expect(target.size()).toBe(1);
expect(legendItem.size()).toBe(1);
tickTexts.each(function (d, i) {
var text = d3.select(this).select('tspan').text();
expect(text).toBe(expected[i]);
});
done();
}, 500);
});
it('should load additional data', function (done) {
var main = chart.internal.main,
legend = chart.internal.legend;
chart.load({
columns: [
['x', 'new1', 'new2', 'new3', 'new4', 'new5', 'new6'], ['x', 'new1', 'new2', 'new3', 'new4', 'new5', 'new6'],
['data3', 800, 500, 900, 500, 1000, 700] ['data3', 800, 500, 900, 500, 1000, 700]
] ]
...@@ -117,4 +95,140 @@ describe('c3 api load', function () { ...@@ -117,4 +95,140 @@ describe('c3 api load', function () {
}); });
describe('appendToColumn', function(){
it('should append values to existing column', function(done){
chart.loadColumns([['data1', 0, 100, 200]]);
chart.appendToColumn(['data1', 300, 400, 500]);
setTimeout(function(){
var data = chart.getDataById('data1');
for(var i = 0; i < data.length; i++){
expect(data[i].value).toBe(i*100);
}
done();
}, 500);
});
it('should append values to non-existing column', function(done){
chart.appendToColumn(['data5', 0, 100, 200, 300]);
setTimeout(function(){
var data = chart.getDataById('data5');
for(var i = 0; i < data.length; i++){
expect(data[i].value).toBe(i*100);
}
done();
}, 500);
});
});
describe("popFromColumn", function(){
it("should pop values from column", function(done){
chart.loadColumns([['data1', 0, 100, 200, 300]]);
chart.loadColumns([['data2', 0, -100, -200, -300]]);
chart.popFromColumn('data1', 1);
chart.popFromColumn('data2', 3);
setTimeout(function(){
var data1 = chart.getDataById('data1');
var data2 = chart.getDataById('data2');
expect(data1.length).toBe(3);
expect(data2.length).toBe(1);
for(var i = 0; i < data1.length; i++){
expect(data1[i].value).toBe(i*100);
}
for(i = 0; i < data2.length; i++){
expect(data2[i].value).toBe(-i*100);
}
done();
}, 500);
});
it("should throw when non-existing sequence given", function(done){
expect(function(){
chart.popFromColumn('data2015', 2);
}).toThrow();
done();
});
it("shouldn't throw when popping more values than there is", function(done){
chart.loadColumns([['data1', 10, 20]]);
chart.popFromColumn('data1', 3);
expect(chart.getDataById('data1').length).toBe(0);
chart.popFromColumn('data1', 2);
expect(chart.getDataById('data1').length).toBe(0);
done();
});
});
describe("getValue", function(){
it("should get value", function(done){
chart.loadColumns([['data1', 100, 200], ['data2', 200, 300]]);
expect(chart.getValue('data1', 0)).toBe(100);
expect(chart.getValue('data1', 1)).toBe(200);
expect(chart.getValue('data2', 0)).toBe(200);
expect(chart.getValue('data2', 1)).toBe(300);
done();
});
it("should return undefined when not found", function(done){
chart.loadColumns([['data1', 100], ['data2', 200, 300]]);
expect(chart.getValue('data1', 1)).toBe(undefined);
expect(chart.getValue('data2', 2)).toBe(undefined);
done();
});
});
describe("setValue", function(){
it("should set value", function(done){
chart.loadColumns([['data1', 0, 100, 200], ['data2', 0, -100]]);
chart.setValue('data1', 0, 200);
chart.setValue('data2', 1, 100);
expect(chart.getValue('data1', 0)).toBe(200);
expect(chart.getValue('data2', 1)).toBe(100);
done();
});
it("should throw when setting to non-existing sequence", function(done){
expect(function(){
chart.setValue('not presented', 0, 1);
}).toThrow();
done();
});
it("should append value if set to higher point", function(done){
chart.loadColumns([['data1', 0]]);
chart.setValue('data1', 10, 100);
chart.setValue('data1', 2, 200);
var data = chart.getDataById('data1');
expect(data.length).toBe(3);
for(var i = 0; i < 3; i++){
expect(data[i].value).toBe(i*100);
}
done();
});
});
}); });
...@@ -41,3 +41,10 @@ function initChart(chart, args, done) { ...@@ -41,3 +41,10 @@ function initChart(chart, args, done) {
return chart; return chart;
} }
typeof initChart !== 'undefined'; typeof initChart !== 'undefined';
function wait(f){
'use strict';
setTimeout(f, 500);
}
typeof wait !== 'undefined';
...@@ -5,6 +5,24 @@ c3_chart_fn.resize = function (size) { ...@@ -5,6 +5,24 @@ c3_chart_fn.resize = function (size) {
this.flush(); this.flush();
}; };
c3_chart_fn.width = function(width){
var $$ = this.internal;
if(isUndefined(width)){
return $$.getCurrentWidth();
}
$$.config.size_width = width;
this.flush();
};
c3_chart_fn.height = function(height){
var $$ = this.internal;
if(isUndefined(height)){
return $$.getCurrentHeight();
}
$$.config.size_height = height;
this.flush();
};
c3_chart_fn.flush = function () { c3_chart_fn.flush = function () {
var $$ = this.internal; var $$ = this.internal;
$$.updateAndRedraw({withLegend: true, withTransition: false, withTransitionForTransform: false}); $$.updateAndRedraw({withLegend: true, withTransition: false, withTransitionForTransform: false});
......
...@@ -25,3 +25,12 @@ c3_chart_fn.data.colors = function (colors) { ...@@ -25,3 +25,12 @@ c3_chart_fn.data.colors = function (colors) {
c3_chart_fn.data.axes = function (axes) { c3_chart_fn.data.axes = function (axes) {
return this.internal.updateDataAttributes('axes', axes); return this.internal.updateDataAttributes('axes', axes);
}; };
c3_chart_fn.getDataById = function(seqId){
var $$ = this.internal;
var t = $$.api.data(seqId)[0];
if(isUndefined(t)) {
return undefined;
}
return t.values;
}
...@@ -49,3 +49,71 @@ c3_chart_fn.unload = function (args) { ...@@ -49,3 +49,71 @@ c3_chart_fn.unload = function (args) {
if (args.done) { args.done(); } if (args.done) { args.done(); }
}); });
}; };
c3_chart_fn.appendToColumn = function(col) {
var $$ = this.internal;
var column = $$.api.getDataById(col[0]);
if(!isUndefined(column)){
for(var i = column.length - 1; i > -1; i--){
col.splice(1, 0, column[i].value);
}
}
$$.api.loadColumns([col]);
};
c3_chart_fn.popFromColumn = function(id, amount){
var $$ = this.internal;
var columns = $$.api.getDataById(id);
if(isUndefined(columns)){
throw new Error("Popping values from non-existing sequence");
}
for(var i = 0; i < amount; i++){
columns.pop();
}
$$.api.loadColumns(columns);
};
c3_chart_fn.loadColumns = function(cols){
var $$ = this.internal;
$$.api.load({
columns: cols
});
};
c3_chart_fn.setValue = function(id, i, value){
var $$ = this.internal;
var column = $$.api.getDataById(id);
if(isUndefined(column)){
throw new Error("Setting value to non-existing sequence " + id);
}
if(isUndefined(column[i])){
$$.api.appendToColumn([id, value]);
} else {
column[i] = value;
$$.api.loadColumns([[id].concat(column)]);
}
};
c3_chart_fn.getValue = function(id, i){
var $$ = this.internal;
var column = $$.api.getDataById(id);
if(isUndefined(column)){
return undefined;
}
var v = column[i];
if(isUndefined(v)){
return undefined;
}
return v.value;
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment