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
d3.min.js
components
build
# vim
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist
*~
......@@ -22,7 +22,9 @@
"describe": false,
"beforeEach": false,
"it": false,
"expect": false
"expect": false,
"d3": false,
"wait": false
}
}
module.exports = (grunt) ->
require('load-grunt-tasks') grunt, pattern: 'grunt-contrib-*'
require('load-grunt-tasks') grunt, pattern: ['grunt-contrib-*', 'grunt-sass']
grunt.initConfig
watch:
concat:
tasks: 'concat'
files: ['src/*.js']
sass:
tasks: 'sass'
files: ['src/scss/*.scss']
concat:
dist:
......@@ -37,6 +40,7 @@ module.exports = (grunt) ->
'src/grid.js',
'src/tooltip.js',
'src/legend.js',
'src/title.js',
'src/axis.js',
'src/clip.js',
'src/arc.js',
......@@ -69,6 +73,7 @@ module.exports = (grunt) ->
'src/api.chart.js',
'src/api.tooltip.js',
'src/c3.axis.js',
'src/ua.js',
'src/polyfill.js',
'src/tail.js'
]
......@@ -87,7 +92,7 @@ module.exports = (grunt) ->
specs: 'spec/*-spec.js'
helpers: 'spec/*-helper.js'
styles: 'c3.css'
vendor: 'http://d3js.org/d3.v3.min.js'
vendor: 'bower_components/d3/d3.js'
uglify:
c3:
......@@ -99,4 +104,7 @@ module.exports = (grunt) ->
src: 'c3.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 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/)
## 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)
+ [Examples](http://c3js.org/examples.html)
## How is this differ?
Additional samples can be found in this repository:
+ [https://github.com/masayuki0812/c3/tree/master/htdocs/samples](https://github.com/masayuki0812/c3/tree/master/htdocs/samples)
Our current improvements
You can run these samples as:
```
$ cd c3/htdocs
$ python -m SimpleHTTPServer 8080
```
#### Working with data
**chart.loadColumns([[id, values...], [...]])**
Loads given columns. Alias to chart.load({columns: [[id, values...], ...]});
## Google Group
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).
**chart.appendToColumn(column)**
## Using the issue queue
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!
Append given values to sequence
Before reporting an issue, please do the following:
1. [Search for existing issues](https://github.com/masayuki0812/c3/issues) to ensure you're not posting a duplicate.
Usage:
```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
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!
**chart.setValue(id, index, value)**
## Playground
Please fork this fiddle:
+ [http://jsfiddle.net/masayuki0812/7kYJu/](http://jsfiddle.net/masayuki0812/7kYJu/)
Sets value for given sequence and index. If no value is presented in index, new value is appended to sequence.
```js
// Say data was [0, 100, 200, 300]
chart.setValue('data', 2, 400);
// Now data is [0, 100, 400, 300]
## Dependency
+ [D3.js](https://github.com/mbostock/d3) `<=3.5.0`
// Set non-existing value
chart.setValue('data', 10, 20);
// Now data is [0, 100, 400, 300, 20]
```
## License
MIT
**chart.getValue(id, index)**
[![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 @@
});
};
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) {
var $$ = this.internal,
targets, data, notfoundIds = [], orgDataCount = $$.getMaxDataCount(),
......@@ -6428,6 +6496,15 @@
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) {
var $$ = this.internal, config = $$.config;
if (arguments.length > 1) {
......@@ -6547,6 +6624,24 @@
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 () {
var $$ = this.internal;
$$.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 () {
done();
}, 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 () {
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) {
var main = chart.internal.main,
legend = chart.internal.legend;
......
describe('c3 api load', function () {
'use strict';
var chart, d3;
var args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 5000, 2000, 1000, 4000, 1500, 2500]
]
}
};
var chart, args;
beforeEach(function (done) {
chart = window.initChart(chart, args, done);
d3 = chart.internal.d3;
});
describe('indexed data', 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) {
var main = chart.internal.main,
legend = chart.internal.legend;
......@@ -71,29 +72,6 @@ describe('c3 api load', function () {
legend = chart.internal.legend;
chart.load({
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'],
['data3', 800, 500, 900, 500, 1000, 700]
]
......@@ -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) {
return chart;
}
typeof initChart !== 'undefined';
function wait(f){
'use strict';
setTimeout(f, 500);
}
typeof wait !== 'undefined';
......@@ -5,6 +5,24 @@ c3_chart_fn.resize = function (size) {
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 () {
var $$ = this.internal;
$$.updateAndRedraw({withLegend: true, withTransition: false, withTransitionForTransform: false});
......
......@@ -25,3 +25,12 @@ c3_chart_fn.data.colors = function (colors) {
c3_chart_fn.data.axes = function (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) {
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