Commit 8f35f9db authored by Kyle Campbell's avatar Kyle Campbell

resolved conflicts with upstream

parents 12310757 bab6c75f
......@@ -2,6 +2,77 @@ module.exports = (grunt) ->
require('load-grunt-tasks') grunt, pattern: 'grunt-contrib-*'
grunt.initConfig
watch:
concat:
tasks: 'concat'
files: ['src/*.js']
concat:
dist:
options:
process: (src, filepath) ->
if filepath != 'src/head.js' && filepath != 'src/tail.js'
lines = []
src.split('\n').forEach (line) ->
lines.push( (if line.length > 0 then ' ' else '') + line)
src = lines.join('\n')
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/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/tail.js'
]
dest: 'c3.js'
jshint:
c3: 'c3.js'
spec: 'spec/*.js'
......@@ -19,4 +90,4 @@ module.exports = (grunt) ->
files:
'c3.min.js': 'c3.js'
grunt.registerTask 'default', ['jshint', 'jasmine', 'uglify']
grunt.registerTask 'default', ['concat', 'jshint', 'jasmine', 'uglify']
c3 [![Build Status](https://travis-ci.org/masayuki0812/c3.png?branch=master)](https://travis-ci.org/masayuki0812/c3)
==
c3 is a D3-based chart library that allows you to integrate charts into web applications more deeply.
c3 is a D3-based reusable chart library that enables deeper integration of charts into web applications.
More information in [the wiki](https://github.com/masayuki0812/c3/wiki).
More information is here: [http://c3js.org](http://c3js.org/)
Samples in [c3js.org](http://c3js.org/#basic)
## Tutorial and Examples
+ [Getting Started](http://c3js.org/gettingstarted.html)
+ [Examples](http://c3js.org/examples.html)
Another samples are included in this repository:
+ [https://github.com/masayuki0812/c3/tree/master/htdocs/samples](https://github.com/masayuki0812/c3/tree/master/htdocs/samples)
And you can run these samples as:
```
$ cd c3/htdocs
$ python -m SimpleHTTPServer 8080
```
## Forum
Now you can ask anything in this forum:
+ [https://groups.google.com/forum/#!forum/c3js](https://groups.google.com/forum/#!forum/c3js)
## Playground
Please fork this fiddle:
+ [http://jsfiddle.net/masayuki0812/7kYJu/](http://jsfiddle.net/masayuki0812/7kYJu/)
## License
MIT
{
"name": "c3",
"main": "c3.min.js",
"version": "0.1.31",
"main": [
"c3.css",
"c3.js"
],
"version": "0.3.0",
"homepage": "https://github.com/masayuki0812/c3",
"authors": [
"Masayuki Tanaka <masayuki0812@mac.com>"
......
......@@ -13,6 +13,14 @@
user-select: none;
}
.c3-legend-item-tile,
.c3-xgrid-focus,
.c3-ygrid,
.c3-event-rect,
.c3-bars path {
shape-rendering: crispEdges;
}
.c3-chart-arc path {
stroke: #fff;
......@@ -58,6 +66,11 @@
.c3-text {
}
.c3-text.c3-empty {
fill: #808080;
font-size: 2em;
}
/*-- Line --*/
.c3-line {
......@@ -76,6 +89,9 @@
/*-- Bar --*/
.c3-bar {
stroke-width: 0;
}
.c3-bar._expanded_ {
fill-opacity: 0.75;
}
......@@ -88,7 +104,7 @@
/*-- Focus --*/
.c3-target.c3-focused path.c3-line {
.c3-target.c3-focused path.c3-line, .c3-target.c3-focused path.c3-step {
stroke-width: 2px;
}
......@@ -115,8 +131,12 @@
.c3-legend-item {
font-size: 12px;
}
.c3-legend-item-hidden {
opacity: 0.1;
.c3-legend-background {
opacity: 0.75;
fill: white;
stroke: lightgray;
stroke-width: 1
}
/*-- Tooltip --*/
......@@ -161,3 +181,23 @@
stroke-width: 0;
opacity: 0.2;
}
.c3-chart-arcs .c3-chart-arcs-background {
fill: #e0e0e0;
stroke: none;
}
.c3-chart-arcs .c3-chart-arcs-gauge-unit {
fill: #000;
font-size: 16px;
}
.c3-chart-arcs .c3-chart-arcs-gauge-max {
fill: #777;
}
.c3-chart-arcs .c3-chart-arcs-gauge-min {
fill: #777;
}
.c3-chart-arc .c3-gauge-value {
fill: #000;
font-size: 28px;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -2,7 +2,7 @@
"name": "c3",
"repo": "masayuki0812/c3",
"description": "A D3-based reusable chart library",
"version": "0.0.1",
"version": "0.3.0",
"keywords": [],
"dependencies": {
"mbostock/d3": "3.4.4"
......
var c3ext = {};
c3ext.generate = function (options) {
if (options.zoom2 != null) {
zoom2_reducers = options.zoom2.reducers || {};
zoom2_enabled = options.zoom2.enabled;
_zoom2_factor = options.zoom2.factor || 1;
_zoom2_maxItems = options.zoom2.maxItems;
}
if (!zoom2_enabled) {
return c3.generate(options);
}
var originalData = Q.copy(options.data);
var zoom2_reducers;
var zoom2_enabled;
var _zoom2_maxItems;
if (_zoom2_maxItems == null) {
var el = d3.select(options.bindto)[0][0];
if (el != null) {
var availWidth = el.clientWidth;
var pointSize = 20;
_zoom2_maxItems = Math.ceil(availWidth / pointSize);
}
if (_zoom2_maxItems == null || _zoom2_maxItems < 10) {
_zoom2_maxItems = 10;
}
}
function onZoomChanged(e) {
refresh();
}
var zoom2 = c3ext.ZoomBehavior({ changed: onZoomChanged, bindto: options.bindto });
zoom2.enhance = function () {
_zoom2_maxItems *= 2;
var totalItems = zoom2.getZoom().totalItems;
if (_zoom2_maxItems > totalItems)
_zoom2_maxItems = totalItems;
refresh();
}
zoom2.dehance = function () {
_zoom2_maxItems = Math.ceil(_zoom2_maxItems / 2) + 1;
refresh();
}
zoom2.maxItems = function () { return _zoom2_maxItems; };
function zoomAndReduceData(list, zoomRange, func, maxItems) {
//var maxItems = 10;//Math.ceil(10 * zoomFactor);
var list2 = list.slice(zoomRange[0], zoomRange[1]);
var chunkSize = 1;
var list3 = list2;
if (list3.length > maxItems) {
var chunkSize = Math.ceil(list2.length / maxItems);
list3 = list3.splitIntoChunksOf(chunkSize).map(func);
}
//console.log("x" + getCurrentZoomLevel() + ", maxItems=" + maxItems + " chunkSize=" + chunkSize + " totalBefore=" + list2.length + ", totalAfter=" + list3.length);
return list3;
}
function first(t) { return t[0]; }
var getDataForZoom = function (data) {
if (data.columns == null || data.columns.length == 0)
return;
var zoomInfo = zoom2.getZoom();
if (zoomInfo.totalItems != data.columns[0].length - 1) {
zoom2.setOptions({ totalItems: data.columns[0].length - 1 });
zoomInfo = zoom2.getZoom();
}
data.columns = originalData.columns.map(function (column) {
var name = column[0];
var reducer = zoom2_reducers[name] || first; //by default take the first
var values = column.slice(1);
var newValues = zoomAndReduceData(values, zoomInfo.currentZoom, reducer, _zoom2_maxItems);
return [name].concat(newValues);
});
return data;
};
getDataForZoom(options.data);
var chart = c3.generate(options);
var _chart_load_org = chart.load.bind(chart);
chart.zoom2 = zoom2;
chart.load = function (data) {
if (data.unload) {
unload(data.unload);
delete data.unload;
}
Q.copy(data, originalData);
refresh();
}
chart.unload = function (names) {
unload(names);
refresh();
}
function unload(names) {
originalData.columns.removeAll(function (t) { names.contains(t); });
}
function refresh() {
var data = Q.copy(originalData)
getDataForZoom(data);
_chart_load_org(data);
};
return chart;
}
c3ext.ZoomBehavior = function (options) {
var zoom = { __type: "ZoomBehavior" };
var _zoom2_factor;
var _left;
var totalItems;
var currentZoom;
var bindto = options.bindto;
var _zoomChanged = options.changed || function () { };
var element;
var mousewheelTimer;
var deltaY = 0;
var leftRatio = 0;
zoom.setOptions = function (options) {
if (options == null)
options = {};
_zoom2_factor = options.factor || 1;
_left = 0;
totalItems = options.totalItems || 0;
currentZoom = [0, totalItems];
_zoomChanged = options.changed || _zoomChanged;
}
zoom.setOptions(options);
function verifyZoom(newZoom) {
//newZoom.sort();
if (newZoom[1] > totalItems) {
var diff = newZoom[1] - totalItems;
newZoom[0] -= diff;
newZoom[1] -= diff;
}
if (newZoom[0] < 0) {
var diff = newZoom[0] * -1;
newZoom[0] += diff;
newZoom[1] += diff;
}
if (newZoom[1] > totalItems)
newZoom[1] = totalItems;
if (newZoom[0] < 0)
newZoom[0] = 0;
}
function zoomAndPan(zoomFactor, left) {
var itemsToShow = Math.ceil(totalItems / zoomFactor);
var newZoom = [left, left + itemsToShow];
verifyZoom(newZoom);
currentZoom = newZoom;
onZoomChanged();
}
function onZoomChanged() {
if (_zoomChanged != null)
_zoomChanged(zoom.getZoom());
}
function applyZoomAndPan() {
zoomAndPan(_zoom2_factor, _left);
}
function getItemsToShow() {
var itemsToShow = Math.ceil(totalItems / _zoom2_factor);
return itemsToShow;
}
zoom.getZoom = function () {
return { totalItems: totalItems, currentZoom: currentZoom.slice() };
}
zoom.factor = function (factor, skipDraw) {
if (arguments.length == 0)
return _zoom2_factor;
_zoom2_factor = factor;
if (_zoom2_factor < 1)
_zoom2_factor = 1;
if (skipDraw)
return;
applyZoomAndPan();
}
zoom.left = function (left, skipDraw) {
if (arguments.length == 0)
return _left;
_left = left;
if (_left < 0)
_left = 0;
var pageSize = getItemsToShow();
//_left += pageSize;
if (_left + pageSize > totalItems)
_left = totalItems - pageSize;
console.log({ left: _left, pageSize: pageSize });
if (skipDraw)
return;
applyZoomAndPan();
}
zoom.zoomAndPanByRatio = function (zoomRatio, panRatio) {
var pageSize = getItemsToShow();
var leftOffset = Math.round(pageSize * panRatio);
var mouseLeft = _left + leftOffset;
zoom.factor(zoom.factor() * zoomRatio, true);
var finalLeft = mouseLeft;
if (zoomRatio != 1) {
var pageSize2 = getItemsToShow();
var leftOffset2 = Math.round(pageSize2 * panRatio);
finalLeft = mouseLeft - leftOffset2;
}
zoom.left(finalLeft, true);
applyZoomAndPan();
}
zoom.zoomIn = function () {
zoom.zoomAndPanByRatio(2, 0);
}
zoom.zoomOut = function () {
zoom.zoomAndPanByRatio(0.5, 0);
}
zoom.panLeft = function () {
zoom.zoomAndPanByRatio(1, -1);
}
zoom.panRight = function () {
zoom.zoomAndPanByRatio(1, 1);
}
zoom.reset = function () {
_left = 0;
_zoom2_factor = 1;
applyZoomAndPan();
}
function doZoom() {
if (deltaY != 0) {
var maxDelta = 10;
var multiply = (maxDelta + deltaY) / maxDelta;
//var factor = chart.zoom2.factor()*multiply;
//factor= Math.ceil(factor*100) / 100;
console.log({ deltaY: deltaY, multiply: multiply });
zoom.zoomAndPanByRatio(multiply, leftRatio);//0.5);//leftRatio);
deltaY = 0;
}
}
function element_mousewheel(e) {
deltaY += e.deltaY;
leftRatio = (e.offsetX - 70) / (e.currentTarget.offsetWidth - 70);
//console.log({ "e.offsetX": e.offsetX, "e.currentTarget.offsetWidth": e.currentTarget.offsetWidth, leftRatio: leftRatio });
mousewheelTimer.set(150);
e.preventDefault();
}
if (bindto != null) {
element = $(options.bindto);
if (element.mousewheel) {
mousewheelTimer = new Timer(doZoom);
element.mousewheel(element_mousewheel);
}
}
return zoom;
}
if (typeof (Q) == "undefined") {
var Q = function () {
};
Q.copy = function (src, target, options, depth) {
///<summary>Copies an object into a target object, recursively cloning any object or array in the way, overwrite=true will overwrite a primitive field value even if exists</summary>
///<param name="src" />
///<param name="target" />
///<param name="options" type="Object">{ overwrite:false }</param>
///<returns type="Object">The copied object</returns>
if (depth == null)
depth = 0;
if (depth == 100) {
console.warn("Q.copy is in depth of 100 - possible circular reference")
}
options = options || { overwrite: false };
if (src == target || src == null)
return target;
if (typeof (src) != "object") {
if (options.overwrite || target == null)
return src;
return target;
}
if (typeof (src.clone) == "function") {
if (options.overwrite || target == null)
return src.clone();
return target;
}
if (target == null) {
if (src instanceof Array)
target = [];
else
target = {};
}
if (src instanceof Array) {
for (var i = 0; i < src.length; i++) {
var item = src[i];
var item2 = target[i];
item2 = Q.copy(item, item2, options, depth + 1);
target[i] = item2;
}
target.splice(src.length, target.length - src.length);
return target;
}
for (var p in src) {
var value = src[p];
var value2 = target[p];
value2 = Q.copy(value, value2, options, depth + 1);
target[p] = value2;
}
return target;
}
}
if (typeof (Timer) == "undefined") {
var Timer = function (action, ms) {
this.action = action;
if (ms != null)
this.set(ms);
}
Timer.prototype.set = function (ms) {
if (ms == null)
ms = this._ms;
else
this._ms = ms;
this.clear();
if (ms == null)
return;
this.timeout = window.setTimeout(this.onTick.bind(this), ms);
}
Timer.prototype.onTick = function () {
this.clear();
this.action();
}
Timer.prototype.clear = function (ms) {
if (this.timeout == null)
return;
window.clearTimeout(this.timeout);
this.timeout = null;
}
}
if (typeof(Array.prototype.splitIntoChunksOf)=="undefined") {
Array.prototype.splitIntoChunksOf = function (countInEachChunk) {
var chunks = Math.ceil(this.length / countInEachChunk);
var list = [];
for (var i = 0; i < this.length; i += countInEachChunk) {
list.push(this.slice(i, i + countInEachChunk));
}
return list;
}
}
\ No newline at end of file
.row {
margin-left: 8px;
}
.row a {
display: block;
text-align: left;
font-size: 1.2em;
line-height: 1.8;
}
.row h3 {
color: #777;
}
\ No newline at end of file
{
"data1": [120, 140, 170, 150, 180],
"data2": [80, 50, 100, 70, 120],
"data3": [200, 210, 250, 300, 280]
}
x,data1,data2,data3
2013-04-01,20,180,400
2013-04-02,40,150,310
2013-04-03,70,120,470
2013-04-04,50,170,400
2013-04-05,80,200,380
\ No newline at end of file
{
"data1": [20, 40, 70, 50, 80, 30],
"data2": [180, 150, 200, 170, 220, 400],
"data3": [1200, 1210, 1250, 1300, 1280, 1000]
}
[
{ "id": 1, "name": "abc", "data1": 1200, "data2": 500 },
{ "id": 2, "name": "efg", "data1": 900, "data2": 600 },
{ "id": 3, "name": "pqr", "data1": 1150, "data2": 300 },
{ "id": 4, "name": "xyz", "data1": 1020, "data2": 900 }
]
x,data1,data2,data3
2012-12-31,120,80,200
2013-01-01,140,50,210
2013-01-02,170,100,250
2013-01-03,150,70,300
2013-01-04,180,120,280
\ No newline at end of file
<html>
<head>
<link href="./css/bootstrap.min.css" rel="stylesheet">
<link href="./css/index.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="section">
<a href="#basic" name="basic"><h2># <span>Basic</span></h2></a>
<h2># <span>Chart Type</span></h2>
<div>
<div class="row">
<div class="col-md-4">
<h3>Simple Line Chart</h3>
<p>Simple line chart for getting started.</p>
<p><a class="btn btn-default" href="./samples/simple.html" role="button">View details &raquo;</a></p>
<h3>Line Chart</h3>
<a href="./samples/simple.html">
Line chart with ordinary data
</a>
<a href="./samples/chart_spline.html">
Spline chart with ordinary data
</a>
<a href="./samples/chart_step.html">
Step chart with ordinary data
</a>
</div>
<div class="col-md-4">
<h3>Multiple Line Chart</h3>
<p>Multiple line chart with multiple data.</p>
<p><a class="btn btn-default" href="./samples/simple_multiple.html" role="button">View details &raquo;</a></p>
<h3>Area Chart</h3>
<a href="./samples/chart_area.html">
Area chart with ordinary data
</a>
<a href="./samples/chart_area_spline.html">
Area-spline chart with ordinary data
</a>
<a href="./samples/chart_area_step.html">
Area-step chart with ordinary data
</a>
<a href="./samples/chart_area_stacked.html">
Stacked Area chart with ordinary data
</a>
<a href="./samples/chart_area_spline_stacked.html">
Stacked Area-spline chart with ordinary data
</a>
<a href="./samples/chart_area_step_stacked.html">
Stacked Area-step chart with ordinary data
</a>
</div>
<div class="col-md-4">
<h3>Bar Chart</h3>
<a href="./samples/chart_bar.html">
Bar chart with ordinary data
</a>
<a href="./samples/chart_bar_stacked.html">
Stacked Bar chart with ordinary data
</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Pie Chart</h3>
<a href="./samples/chart_pie.html">
Pie chart with ordinary data
</a>
<a href="./samples/chart_pie_sort.html">
Pie chart with/without sort
</a>
</div>
<div class="col-md-4">
<h3>Donut Chart</h3>
<a href="./samples/chart_donut.html">
Donut chart with ordinary data
</a>
</div>
<div class="col-md-4">
<h3>Timeseries Chart</h3>
<p>Simple line chart with timeseries data.</p>
<p><a class="btn btn-default" href="./samples/timeseries.html" role="button">View details &raquo;</a></p>
<h3>Gauge Chart</h3>
<a href="./samples/chart_gauge.html">
Gauge chart with ordinary data
</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Scatter Chart</h3>
<a href="./samples/chart_scatter.html">
Scatter chart with ordinary data
</a>
</div>
<div class="col-md-4">
<h3>Combination Chart</h3>
<a href="./samples/chart_combination.html">
Combination chart with ordinary data
</a>
</div>
</div>
</div>
</div>
<div class="section">
<a href="#axes" name="axes"><h2># <span>Axes</span></h2></a>
<h2># <span>Axes</span></h2>
<div>
<div class="row">
<div class="col-md-4">
<h3>Categorized Axis</h3>
<p>Axis with ticks categorizing each data.</p>
<p><a class="btn btn-default" href="./samples/categorized.html" role="button">View details &raquo;</a></p>
<h3>Timeseries Axis</h3>
<a href="./samples/timeseries.html">
Line chart with timeseries data
</a>
<a href="./samples/timeseries_descendent.html">
Line chart with descendent timeseries data
</a>
<a href="./samples/timeseries_raw.html">
Line chart with timeseries data as Number
</a>
<a href="./samples/timeseries_date.html">
Line chart with timeseries data as Date object
</a>
</div>
<div class="col-md-4">
<h3>Category Axis</h3>
<a href="./samples/categorized.html">
Chart with category axis
</a>
<a href="./samples/custom_x_categorized.html">
Chart with category data on category axis
</a>
</div>
<div class="col-md-4">
<h3>Additional Axis</h3>
<p>Additional y axis can be added.</p>
<p><a class="btn btn-default" href="./samples/axes_y2.html" role="button">View details &raquo;</a></p>
<a href="./samples/axes_y2.html">
Add y2 axis
</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Axis Range</h3>
<a href="./samples/axes_range.html">
Set range of axis
</a>
</div>
<div class="col-md-4">
<h3>Axis Padding</h3>
<a href="./samples/axes_padding.html">
Set padding of axis
</a>
</div>
<div class="col-md-4">
<h3>X Axis Tick</h3>
<a href="./samples/axes_x_tick_values.html">
Set values for x axis
</a>
<a href="./samples/axes_x_tick_culling.html">
Set culling for x axis
</a>
<a href="./samples/axes_x_tick_fit.html">
Set fitting for x axis
</a>
<a href="./samples/axes_x_tick_rotate.html">
Set rotation for x axis
</a>
<a href="./samples/axes_x_range_timeseries.html">
Set range in timeseries for x axis
</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Default Y Domain</h3>
<a href="./samples/axes_y_default.html">
Set default y domain
</a>
</div>
<div class="col-md-4">
<h3>Y Domain</h3>
<a href="./samples/domain_y.html">
Update y domain automatically
</a>
</div>
</div>
</div>
</div>
<div class="section">
<a href="#data" name="data"><h2># <span>Data</span></h2></a>
<h2># <span>Data</span></h2>
<div>
<div class="row">
<div class="col-md-4">
<h3>Column Oriented Data</h3>
<p>Column-oriented data can be used as input.</p>
<p><a class="btn btn-default" href="./samples/data_columned.html" role="button">View details &raquo;</a></p>
<h3>Input Data</h3>
<a href="./samples/data_columned.html">
Columned data
</a>
<a href="./samples/data_rowed.html">
Rowed data
</a>
<a href="./samples/data_json.html">
JSON data
</a>
<a href="./samples/data_url.html">
Data from URL
</a>
<a href="./samples/data_hide.html">
Hide data when init
</a>
</div>
<div class="col-md-4">
<h3>Row Oriented Data</h3>
<p>Row-oriented data can be used as input.</p>
<p><a class="btn btn-default" href="./samples/data_rowed.html" role="button">View details &raquo;</a></p>
<h3>Load Data</h3>
<a href="./samples/data_load.html">
Load ordinary data
</a>
<a href="./samples/data_load_timeseries.html">
Load timeseries data
</a>
</div>
<div class="col-md-4">
<h3>Data from URL</h3>
<p>Data from URL can be used as input.</p>
<p><a class="btn btn-default" href="./samples/data_url.html" role="button">View details &raquo;</a></p>
<h3>Custom X</h3>
<a href="./samples/custom_x_scale.html">
Custom x for all data
</a>
<a href="./samples/custom_xs_scale.html">
Custom x for each data
</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Load Data</h3>
<p>Load data dynamically.</p>
<p><a class="btn btn-default" href="./samples/data_load.html" role="button">View details &raquo;</a></p>
<h3>Data Label</h3>
<a href="./samples/data_label.html">
Show label on data
</a>
<a href="./samples/data_label_format.html">
Show label on data with format
</a>
</div>
<div class="col-md-4">
<h3>Data Region</h3>
<a href="./samples/data_region.html">
Set region of data
</a>
<a href="./samples/data_region_timeseries.html">
Set region of timeseries data
</a>
</div>
</div>
</div>
</div>
<div class="section">
<a href="#chart_type" name="chart_type"><h2># <span>Chart Type</span></h2></a>
<h2># <span>Components</span></h2>
<div>
<div class="row">
<div class="col-md-4">
<h3>Bar Chart</h3>
<p>Display as Bar Chart</p>
<p><a class="btn btn-default" href="./samples/chart_bar.html" role="button">View details &raquo;</a></p>
<h3>Grid</h3>
<a href="./samples/grids.html">
Show x/y grids
</a>
<a href="./samples/grids_timeseries.html">
Show x/y grids with timeseries
</a>
<a href="./samples/grid_x_lines.html">
Show optional x grids
</a>
<a href="./samples/grid_x_lines_timeseries.html">
Show optional x grids with timeseries
</a>
<a href="./samples/grid_focus.html">
Hide focus grid
</a>
</div>
<div class="col-md-4">
<h3>Stacked Bar Chart</h3>
<p>Display as Stacked Bar Chart</p>
<p><a class="btn btn-default" href="./samples/chart_bar_stacked.html" role="button">View details &raquo;</a></p>
<h3>Region</h3>
<a href="./samples/regions.html">
Show regions
</a>
</div>
<div class="col-md-4">
<h3>Spline Chart</h3>
<p>Display as Spline Chart</p>
<p><a class="btn btn-default" href="./samples/chart_spline.html" role="button">View details &raquo;</a></p>
<h3>Legend</h3>
<a href="./samples/legend.html">
Show legend
</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Area Chart</h3>
<p>Display as Filled Area Chart</p>
<p><a class="btn btn-default" href="./samples/chart_area.html" role="button">View details &raquo;</a></p>
<h3>Tooltip</h3>
<a href="./samples/tooltip_show.html">
Show tooltip
</a>
<a href="./samples/tooltip_grouped.html">
Show tooltip as each data
</a>
</div>
</div>
</div>
</div>
<div class="section">
<h2># <span>Chart Option</span></h2>
<div>
<div class="row">
<div class="col-md-4">
<h3>Combination Chart</h3>
<p>Display as Bar Chart</p>
<p><a class="btn btn-default" href="./samples/chart_combination.html" role="button">View details &raquo;</a></p>
<h3>Bind</h3>
<a href="./samples/bindto.html">
Specify the element binded
</a>
</div>
<div class="col-md-4">
<h3>Padding</h3>
<a href="./samples/padding.html">
Change padding of chart
</a>
<a href="./samples/padding_update.html">
Auto padding when chart updated
</a>
</div>
<div class="col-md-4">
<h3>Empty Data</h3>
<a href="./samples/emptydata.html">
Show text when empty data
</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Point</h3>
<a href="./samples/point_r.html">
Change radius of data point
</a>
</div>
<div class="col-md-4">
<h3>Bar</h3>
<a href="./samples/bar_zerobased.html">
Disable zero-based y domain
</a>
</div>
<div class="col-md-4">
<h3>Area</h3>
<a href="./samples/area_zerobased.html">
Disable zero-based y domain
</a>
</div>
</div>
</div>
</div>
<div class="section">
<a href="#interaction" name="interaction"><h2># <span>Interaction</span></h2></a>
<h2># <span>Interaction</span></h2>
<div>
<div class="row">
<div class="col-md-4">
<h3>Zoom</h3>
<p>Zoom by mouse wheel event and slide by drag.</p>
<p><a class="btn btn-default" href="./samples/interaction_zoom.html" role="button">View details &raquo;</a></p>
<a href="./samples/zoom.html">
Enable zoom
</a>
<a href="./samples/zoom.html">
Zoom on category axis
</a>
<a href="./samples/zoom_reduction.html">
Zoom with reduction
</a>
<a href="./samples/zoom_onzoom.html">
Callback on zoom
</a>
</div>
<div class="col-md-4">
<h3>Subchart</h3>
<a href="./samples/subchart.html">
Show subchart
</a>
<a href="./samples/subchart_onbrush.html">
Callback on brush
</a>
</div>
<div class="col-md-4">
<h3>Selection</h3>
<a href="./samples/selection.html">
Select data
</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Disable Interaction</h3>
<a href="./samples/interaction_enabled.html">
Disable interaction
</a>
</div>
</div>
</div>
</div>
<div class="section">
<h2># <span>API</span></h2>
<div>
<div class="row">
<div class="col-md-4">
<h3>Flow</h3>
<a href="./samples/api_flow.html">
Flow ordinary data
</a>
<a href="./samples/api_flow_timeseries.html">
Flow timeseries data
</a>
</div>
<div class="col-md-4">
<h3>Axis</h3>
<a href="./samples/api_axis_range.html">
Update axis range
</a>
<a href="./samples/api_axis_label.html">
Update axis label
</a>
</div>
<div class="col-md-4">
<h3>Grid</h3>
<a href="./samples/api_xgrid_lines.html">
Update x grid lines
</a>
<a href="./samples/api_ygrid_lines.html">
Update y grid lines
</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Legend</h3>
<a href="./samples/api_legend.html">
Update legend
</a>
</div>
<div class="col-md-4">
<h3>Transform</h3>
<a href="./samples/api_transform.html">
Transform chart
</a>
</div>
<div class="col-md-4">
<h3>Element</h3>
<a href="./samples/element.html">
Access svg element of chart
</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Data</h3>
<a href="./samples/api_data_colors.html">
Update data color
</a>
</div>
<div class="col-md-4">
<h3>Tooltip</h3>
<a href="./samples/api_tooltip_show.html">
Show tooltip programmatically
</a>
</div>
</div>
</div>
</div>
<div class="section">
<h2># <span>Other Library</span></h2>
<div>
<div class="row">
<div class="col-md-4">
<h3>RequireJS</h3>
<a href="./samples/requirejs.html">
Load by RequireJS
</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
../../extensions/js
\ No newline at end of file
c3.chart.internal.fn.isTimeSeries = function () {
console.log('custom isTimeSeries');
return false;
};
c3.chart.internal.fn.additionalConfig.test1 = undefined;
c3.chart.internal.fn.additionalConfig.test2 = undefined;
c3.chart.fn.hoge = function () {
console.log("hoge()", this.internal.isTimeSeries());
};
c3.chart.fn.test = function () {
console.log('test()', this.internal.config.test1);
};
......@@ -7,7 +7,7 @@ require.config({
require(["d3", "c3"], function(d3, c3) {
var chart = c3.generate({
window.chart = c3.generate({
data: {
columns: [
['sample', 30, 200, 100, 400, 150, 250]
......@@ -15,4 +15,4 @@ require(["d3", "c3"], function(d3, c3) {
}
});
});
\ No newline at end of file
});
var chart;
function refresh() {
if (suspendRefresh)
return;
chart.load({
columns: [
["Value"].concat(zoom(column, currentZoom, "t=>Math.round(t.avg())".toLambda())),
["xColumn"].concat(zoom(xColumn, currentZoom, "t=>t[0]".toLambda())),
]
});
}
function getChart() {
return chart;
}
function main() {
var last = 0;
var max = 10000;
var column = Array.generate(max, function (i) {
return last += Math.randomInt(-10, 10);
});
var xColumn = Array.generateNumbers(0, max);
var options = {
bindto: "#divChart",
data: {
columns: [
["Value"].concat(column),
["x"].concat(xColumn),
],
type: "line",
x: "x"
},
zoom2: {
enabled: true,
}
};
chart = c3ext.generate(options);
window.setInterval(refreshStatus, 1000);
function refreshStatus() {
var zoomInfo = chart.zoom2.getZoom();
var info = {
reduced: chart.zoom2.maxItems(),
actual: (zoomInfo.currentZoom[1] - zoomInfo.currentZoom[0]),
range: zoomInfo.currentZoom[0] + "-" + zoomInfo.currentZoom[1],
total: zoomInfo.totalItems
};
$("#status").text(JSON.stringify(info, null, " "));
}
};
if (typeof (Array.generate) == "undefined") {
Array.generate = function (length, generator) {
var list = new Array(length);
for (var i = 0; i < length; i++) {
list[i] = generator(i);
}
return list;
}
}
if (typeof (Math.randomInt) == "undefined") {
Math.randomInt = function (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}
if (typeof (Array.generateNumbers) == "undefined") {
Array.generateNumbers = function (from, until) {
if (arguments.length == 1) {
until = from;
from = 0;
}
var length = until - from;
var list = new Array(length);
for (var i = 0; i < length; i++) {
list[i] = i + from;
}
return list;
}
}
\ No newline at end of file
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
axes: {
data1: 'y',
data2: 'y2',
}
},
axis: {
x: {
label: 'X Label'
},
y: {
label: {
text: 'Y Axis Label',
position: 'outer-middle'
}
},
y2: {
show: true,
label: {
text: 'Y2 Axis Label',
position: 'outer-middle'
}
}
},
tooltip: {
// enabled: false
},
zoom: {
// enabled: true
},
subchart: {
// show: true
}
});
setTimeout(function () {
chart.axis.max(500);
}, 1000);
setTimeout(function () {
chart.axis.min(-500);
}, 2000);
setTimeout(function () {
chart.axis.max({y: 600, y2: 100});
}, 3000);
setTimeout(function () {
chart.axis.min({y: -600, y2: -100});
}, 4000);
setTimeout(function () {
chart.axis.range({max: 1000, min: -1000});
}, 5000);
setTimeout(function () {
chart.axis.range({min: {y: 1000}, max: {y: 2000}});
}, 6000);
setTimeout(function () {
chart.axis.range({max: {y: 600, y2: 100}, min: {y: -100, y2: 0}});
}, 7000);
</script>
</body>
</html>
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<div id="message"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
x: 'x',
columns: [
['x', '1e-3', '1e-2', '1'],
['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250]
]
},
axis: {
x: {
type: 'categorized'
}
}
});
setTimeout(function () {
d3.select('#message').node().innerHTML = "chart.categories() =>" + chart.categories();
}, 1000);
setTimeout(function () {
chart.categories(['updated 1', 'updated 2', 'updated 3', 'updated 4']);
d3.select('#message').node().innerHTML = "";
}, 2000);
setTimeout(function () {
d3.select('#message').node().innerHTML = "chart.category(1) =>" + chart.category(1);
}, 3000);
setTimeout(function () {
chart.category(1, 'UPDATED 1');
d3.select('#message').node().innerHTML = "";
}, 4000);
</script>
</body>
</html>
......@@ -6,25 +6,28 @@
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
columns: [
['sample', 30, 200, 100, 400, 150, 250]
]
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
},
grid: {
axis: {
x: {
lines: [{
value: 3,
text: '3',
class: 'lineFor3'
}]
type: 'category'
}
}
});
setTimeout(function () {
chart.data.colors({data1: '#000'});
}, 1000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
<style>
.c3-region-1 {
fill: #dd3333;
fill-opacity: 0.8
}
</style>
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var padding = {}, types = {}, chart, generate = function () { return c3.generate({
data: {
columns: [
['data1'],
['data2'],
],
types: types,
labels: true
},
bar: {
width: 10
},
axis: {
x: {
padding: padding
},
y: {
/*
min: -100,
max: 1000
*/
}
},
grid: {
x: {
show: true,
lines: [{value: 3, text:'Label 3'}, {value: 4.5, text: 'Label 4.5'}]
},
y: {
show: true
}
},
regions: [
{start:2, end:4, class:'region1'},
{start:100, end:200, axis:'y'},
],
});
};
function run() {
chart = generate();
setTimeout(function () {
// Load only one data
chart.flow({
rows: [
['data1', 'data2', 'data3'],
[500, 100, 200],
[200, null, null],
[100, 50, null]
],
duration: 1500,
done: function () {
// Load 2 data without data2 and remove 1 data
chart.flow({
columns: [
['data1', 200, 300],
['data3', 100, 100]
],
length: 0,
duration: 1500,
done: function () {
chart.flow({
columns: [
['data1', 200, 300],
['data2', 200, 300],
['data3', 100, 100]
],
length: 2,
duration: 1500,
done: function () {
chart.flow({
columns: [
['data1', 500],
['data2', 100],
['data3', 200]
],
length: 1,
duration: 1500,
});
}
});
}// done
});
},
});
}, 1000);
setTimeout(function () {
chart.flow({
columns: [
['data1', 250],
['data2', 350],
['data3', 150]
],
length: 0
});
}, 9000);
setTimeout(function () {
chart.flow({
columns: [
['data1', 100],
['data2', 50],
['data3', 300]
],
length: 2
});
}, 10000);
setTimeout(function () {
chart.flow({
columns: [
['data1', 600],
['data2', 400],
['data3', 500]
],
to: 2,
});
}, 11000);
setTimeout(function () {
chart.flow({
columns: [
['data1', 100],
['data2', 200],
['data3', 300]
]
});
}, 12000);
setTimeout(function () {
chart = generate();
}, 13000);
setTimeout(function () {
chart.flow({
columns: [
['data1', 500, 100],
['data2', 100, 200],
['data3', 200, 300],
],
duration: 1500,
done: function () {
chart.flow({
columns: [
['data1', 200],
['data3', 100]
],
// duration: 1000,
length: 1
});
},
});
}, 14000);
setTimeout(function () {
chart.flow({
columns: [
['data1', 200],
['data2', 300],
['data3', 100]
],
to: 1,
});
}, 18000);
setTimeout(function () {
chart.flow({
columns: [
['data1', 200],
['data2', 300],
['data3', 400]
]
});
}, 19000);
}
run();
// Test for no padding
setTimeout(function () {
padding = {left: 0, right: 0};
run();
}, 22000);
// Test for other chart types
setTimeout(function () {
types = {
data2: 'area',
data3: 'bar',
};
run();
}, 45000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var padding = {}, types = {};
var generate = function () { return c3.generate({
data: {
x: 'x',
columns: [
['x', ],
['data1', ],
['data2', ],
// ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-10', '2013-01-11', '2013-01-12'],
// ['data1', 30, 200, 100, 400, 150, 250],
// ['data2', 310, 400, 200, 100, 450, 150],
// ['data3', 310, 400, 200, 100, null, 150],
],
types: types,
// labels: true
},
bar: {
width: 10
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%m/%d',
},
padding: padding
},
y: {
/*
min: -100,
max: 1000
*/
}
},
/* not supported yet
grid: {
x: {
show: true
},
y: {
show: true
}
}
*/
}); }, chart;
function run() {
chart = generate();
setTimeout(function () {
chart.flow({
columns: [
['x', '2013-01-21'],
['data1', 500],
['data3', 200],
],
duration: 1500
});
}, 1000);
setTimeout(function () {
chart.flow({
columns: [
['x', '2013-02-01', '2013-02-08', '2013-02-15'],
['data1', 200, 400, 300],
['data2', 100, 300, 200],
['data3', 100, 200, 50]
],
length: 1,
duration: 1500
});
}, 4000);
setTimeout(function () {
console.log("Flow 1");
chart.flow({
columns: [
['x', '2013-03-01', '2013-03-08'],
['data1', 200, 500],
['data2', 300, 400],
['data3', 400, 200]
],
to: '2013-02-08',
duration: 1500
});
}, 7000);
setTimeout(function () {
chart.flow({
columns: [
['x', '2013-03-15', '2013-05-01'],
['data1', 200, 500],
['data2', 300, 400],
['data3', 400, 200]
],
length: 0,
duration: 1500
});
}, 10000);
setTimeout(function () {
chart = generate();
}, 14000);
setTimeout(function () {
chart.flow({
columns: [
['x', '2013-01-21', '2013-01-25', '2013-01-26'],
['data1', 500, 300, 100],
['data3', 200, 150, null],
],
duration: 1500
});
}, 15000);
setTimeout(function () {
chart.flow({
columns: [
['x', '2013-02-01'],
['data1', 200],
['data2', 100],
['data3', 100]
],
length: 0,
duration: 1500
});
}, 18000);
setTimeout(function () {
chart.flow({
columns: [
['x', '2013-03-01'],
['data1', 200],
['data2', 300],
['data3', 400]
],
to: '2013-02-01',
duration: 1500
});
}, 21000);
};
run();
setTimeout(function () {
padding = {left: 0, right: 0};
run();
}, 25000);
setTimeout(function () {
types = {
data2: 'area',
data3: 'bar',
}
run();
}, 50000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var columns = [];
for (var i = 0; i < 5; i++ ) {
columns[i] = ['datahogehogeohgeohoge' + i, 10 * i, 20 * i, 30 * i];
}
var chart = c3.generate({
data: {
columns: columns,
},
axis: {
x: {
type: 'category'
}
}
});
setTimeout(function () {
chart.legend.hide();
}, 1000);
setTimeout(function () {
chart = c3.generate({
data: {
columns: columns,
},
axis: {
x: {
type: 'category'
}
},
legend: {
position: 'right'
}
});
}, 2000);
setTimeout(function () {
chart.legend.hide();
}, 3000);
setTimeout(function () {
chart = c3.generate({
data: {
columns: columns,
},
axis: {
rotated: true
}
});
}, 4000);
setTimeout(function () {
chart.legend.hide();
}, 5000);
setTimeout(function () {
chart = c3.generate({
data: {
columns: columns,
},
legend: {
position: 'right'
},
axis: {
rotated: true
}
});
}, 6000);
setTimeout(function () {
chart.legend.hide();
}, 7000);
setTimeout(function () {
chart = c3.generate({
data: {
columns: columns,
},
legend: {
show: false
}
});
}, 8000);
setTimeout(function () {
chart.legend.show();
}, 9000);
setTimeout(function () {
chart = c3.generate({
data: {
columns: columns,
},
legend: {
show: false
},
axis: {
rotated: true
}
});
}, 10000);
setTimeout(function () {
chart.legend.show();
}, 11000);
setTimeout(function () {
chart = c3.generate({
data: {
columns: columns,
},
legend: {
position: 'right',
show: false
}
});
}, 12000);
setTimeout(function () {
chart.legend.show();
}, 13000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
}
});
setTimeout(function () {
chart.tooltip.show({ x: 1 });
}, 1000);
setTimeout(function () {
chart.tooltip.show({ index: 3 });
}, 2000);
setTimeout(function () {
chart.tooltip.show({ data: {x: 2} });
}, 3000);
setTimeout(function () {
chart.tooltip.hide();
}, 4000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
},
});
setTimeout(function () {
chart.transform('bar');
}, 1000);
setTimeout(function () {
chart.transform('pie');
}, 2000);
setTimeout(function () {
chart.transform('donut');
}, 3000);
setTimeout(function () {
chart.transform('area');
}, 4000);
setTimeout(function () {
chart.transform('spline');
}, 5000);
setTimeout(function () {
chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25],
['data1_x', 50, 20, 10, 40, 15, 25],
['data2_x', 30, 200, 100, 400, 150, 250],
],
xs: {
data1: 'data1_x',
data2: 'data2_x',
},
type: 'scatter'
},
});
}, 7000);
setTimeout(function () {
chart.transform('pie');
}, 8000);
setTimeout(function () {
chart.transform('scatter');
}, 9000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var axis_rotated = false, axis_x_type = "";
var generate = function () { return c3.generate({
bindto: '#chart',
data: {
columns: [
['sample', 30, 200, 100, 400, 150, 250]
]
},
axis: {
rotated: axis_rotated,
x: {
type: axis_x_type
}
},
grid: {
x: {
// lines: [{value: 3, text:'Label 3'}, {value: 4.5, text: 'Label 4.5'}]
}
}
}); }, chart = generate();
var queue = [
function () {
chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);
},
function () {
chart.xgrids([{value: 2, text:'Label 2'}]);
},
function () {
chart.xgrids.add([{value: 3, text:'Label 3', class:'hoge'}]);
},
function () {
chart.xgrids.remove({value:2});
},
function () {
chart.xgrids.remove({class:'hoge'});
},
function () {
chart.xgrids.remove([{value: 1}, {value: 4}]);
},
function () {
chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);
},
function () {
chart.xgrids.remove();
},
function () {
axis_rotated = true;
chart = generate();
},
function () {
chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);
},
function () {
chart.xgrids([{value: 2, text:'Label 2'}]);
},
function () {
chart.xgrids.add([{value: 3, text:'Label 3', class:'hoge'}]);
},
function () {
chart.xgrids.remove({value:2});
},
function () {
chart.xgrids.remove({class:'hoge'});
},
function () {
chart.xgrids.remove([{value: 1}, {value: 4}]);
},
function () {
chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);
},
function () {
chart.xgrids.remove();
},
function () {
axis_rotated = false;
axis_x_type = 'category';
chart = generate();
},
function () {
chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);
},
function () {
chart.xgrids([{value: 2, text:'Label 2'}]);
},
function () {
chart.xgrids.add([{value: 3, text:'Label 3', class:'hoge'}]);
},
function () {
chart.xgrids.remove({value:2});
},
function () {
chart.xgrids.remove({class:'hoge'});
},
function () {
chart.xgrids.remove([{value: 1}, {value: 4}]);
},
function () {
chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);
},
function () {
chart.xgrids.remove();
},
];
var i = 0;
queue.forEach(function (f) {
setTimeout(f, 1000 * i++);
});
</script>
</body>
</html>
......@@ -20,21 +20,21 @@
},
grid: {
y: {
lines: [{value: 30, text:'Lable 30'}, {value: 250, text: 'Lable 250'}]
// lines: [{value: 30, text:'Label 30'}, {value: 250, text: 'Label 250'}]
}
}
});
setTimeout(function () {
chart.ygrids([{value: 130, text:'Lable 130'}, {value: 50, text: 'Lable 50'}]);
chart.ygrids([{value: 130, text:'Label 130'}, {value: 50, text: 'Label 50'}]);
}, 1000);
setTimeout(function () {
chart.ygrids([{value: 130, text:'Lable 130', class: 'hoge'}]);
chart.ygrids([{value: 130, text:'Label 130', class: 'hoge'}]);
}, 2000);
setTimeout(function () {
chart.ygrids.add([{value: 230, text:'Lable 230'}]);
chart.ygrids.add([{value: 230, text:'Label 230', class: 'hoge'}]);
}, 3000);
setTimeout(function () {
......
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 1030, 1200, 1100, 1400, 1150, 1250],
['data2', 2130, 2100, 2140, 2200, 2150, 1850]
],
type: 'area',
},
area: {
zerobased: false
}
});
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 300, 2000, 1000, 4000, 1500, 2500],
],
axes: {
data2: 'y2'
}
},
axis: {
y: {
padding: {
top: 0.1,
bottom: 0.1,
unit: 'ratio'
}
},
y2: {
show: true,
padding: {
top: 200,
bottom: 200,
}
}
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['data1', 3000, 20000, 10000, 40000, 15000, 25000],
],
},
axis: {
y: {
padding: {
top: 0.1,
bottom: 0.1,
unit: 'ratio'
}
}
}
});
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['sample', 100, 200, 100, 400, 150, 250]
],
},
axis: {
x: {
min: -10,
max: 10,
}
},
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
x: 'x',
columns: [
['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
['sample', 100, 200, 100, 400, 150, 250]
],
},
axis: {
x: {
type: 'timeseries',
min: new Date('2012-12-20'),
max: '2013-03-01',
tick : {
format : "%Y-%m-%d %H:%M:%S" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format
}
}
}
});
setTimeout(function () {
chart1.axis.max({x: 20});
}, 1000);
setTimeout(function () {
chart1.axis.min({x: -5});
}, 2000);
setTimeout(function () {
chart1.axis.range({max: {x: 5}, min: {x: 0}});
}, 3000);
setTimeout(function () {
chart2.axis.max({x: new Date('2013-02-01')});
}, 1000);
setTimeout(function () {
chart2.axis.min({x: new Date('2012-12-01')});
}, 2000);
setTimeout(function () {
chart2.axis.range({max: {x: '2013-01-06'}, min: {x: '2013-01-01'}});
}, 3000);
setTimeout(function () {
chart2.axis.max({y: 1000});
}, 4000);
setTimeout(function () {
chart2.axis.min({y: -1000});
}, 5000);
setTimeout(function () {
chart2.axis.range({max: {y: 400}, min: {y: 0}});
}, 6000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var data, axis_x_localtime;
var data1 = {
x : 'date',
columns: [
['date', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05'],
['sample', 30, 200, 100, 400, 150],
['sample2', 130, 300, 200, 450, 250]
]
};
var data2 = {
x : 'date',
columns: [
['date', 1356966000000, 1357052400000, 1357138800000, 1357225200000, 1357311600000],
['sample', 30, 200, 100, 400, 150],
['sample2', 130, 300, 200, 450, 250]
]
};
var data3 = {
x : 'date',
columns: [
['date', new Date(1356966000000), new Date(1357052400000), new Date(1357138800000), new Date(1357225200000), new Date(1357311600000)],
['sample', 30, 200, 100, 400, 150],
['sample2', 130, 300, 200, 450, 250]
]
};
var data4 = {
x : 'date',
x_format : '%Y%m%d',
columns: [
['date', '20130101', '20130102', '20130103', '20130104', '20130105'],
['sample', 1030, 1200, 1100, 1400, 1150],
['sample2', 130, 300, 200, 450, 250]
]
};
var data5 = {
x : 'date',
x_format : '%Y%m%d %H:%M:%S',
columns: [
['date', '20130101 00:00:00', '20130102 00:00:00', '20130103 00:00:00', '20130104 00:00:00', '20130105 00:00:00'],
['sample', 30, 200, 100, 400, 150],
['sample2', 1130, 1300, 1200, 1450, 1250]
]
};
var generate = function () { return c3.generate({
bindto: '#chart',
data: data,
axis : {
x : {
type : 'timeseries',
tick : {
format : "%Y-%m-%d %H:%M:%S" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format
},
localtime: axis_x_localtime
}
}
}); };
setTimeout(function () {
data = data1;
axis_x_localtime = true;
chart = generate();
}, 1000);
setTimeout(function () {
data = data1;
axis_x_localtime = false;
chart = generate();
}, 2000);
setTimeout(function () {
data = data2;
axis_x_localtime = true;
chart = generate();
}, 3000);
setTimeout(function () {
data = data2;
axis_x_localtime = false;
chart = generate();
}, 4000);
setTimeout(function () {
data = data3;
axis_x_localtime = true;
chart = generate();
}, 5000);
setTimeout(function () {
data = data3;
axis_x_localtime = false;
chart = generate();
}, 6000);
setTimeout(function () {
data = data4;
axis_x_localtime = true;
chart = generate();
}, 7000);
setTimeout(function () {
data = data4;
axis_x_localtime = false;
chart = generate();
}, 8000);
setTimeout(function () {
data = data5;
axis_x_localtime = true;
chart = generate();
}, 9000);
setTimeout(function () {
data = data5;
axis_x_localtime = false;
chart = generate();
}, 10000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
"bindto": "#chart1",
"axis": {
"x": {
"type": "timeseries",
"min": 1401879600000,
"max": 1401969600000,
}
},
"data": {
"type": "line",
"columns": [
["epoch", 1401879600000, 1401883200000, 1401886800000],
["y", 1955, 2419, 2262]
],
"xs": {
"y": "epoch"
}
}
});
var chart2 = c3.generate({
"bindto": "#chart2",
"axis": {
"x": {
"type": "timeseries",
"min": new Date(1401879600000),
"max": new Date(1401969600000),
}
},
"data": {
"type": "line",
"columns": [
["epoch", 1401879600000, 1401883200000, 1401886800000],
["y", 1955, 2419, 2262]
],
"xs": {
"y": "epoch"
}
}
});
</script>
</body>
</html>
......@@ -15,6 +15,15 @@
['data2', 50, 20, 10, 40, 15, 25]
]
},
axis: {
x: {
tick: {
culling: {
max: 2
}
}
}
},
tooltip: {
// enabled: false
},
......
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250, 100, 600],
['data2', 50, 20, 10, 40, 15, 25],
]
},
axis: {
// rotated: true,
x: {
tick: {
format: function () { return "hogehogehogehogehoge"; },
rotate: 30,
},
label: {
text: 'Hogehoge',
position: 'outer-middle'
},
height: 90,
},
y: {
label: {
text: 'Y Label',
position: 'outer-center'
}
}
},
subchart: {
show: true
}
});
setTimeout(function () {
chart.load({
columns: [
// ['data1', 30, 200, 100, 400, 150, 250, 100, 400],
['data1', 1030, 2000, 1000, 1400, 1500, 1250, 1100, 140000],
]
})
}, 1000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
},
axis: {
x : {
tick: {
values: [2, 4]
}
}
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
x : 'date',
xFormat : '%Y%m%d',
columns: [
['date', '20130101', '20130102', '20130103', '20130104', '20130105', '20130106'],
['sample', 30, 200, 100, 400, 150, 250],
['sample2', 130, 300, 200, 450, 250, 350]
]
},
axis : {
x : {
type : 'timeseries',
tick : {
format : "%e %b %y", // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format
values: ['20130103', '20130104']
}
}
}
});
</script>
</body>
</html>
......@@ -9,17 +9,15 @@
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
columns: [
['sample1', 30, 200, 100, 400, 150, 250],
['sample2', 130, 300, 200, 500, 250, 350],
['sample3', 230, 400, 300, 600, 350, 450]
['data1'],
['data2'],
],
selection: {
enabled: true,
grouped: true,
multiple: false
},
axis: {
y: {
default: [-100, 100]
}
}
});
......
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 1030, 1200, 1100, 1400, 1150, 1250],
['data2', 2130, 2100, 2140, 2200, 2150, 1850]
],
type: 'bar',
},
bar: {
zerobased: false
}
});
</script>
</body>
</html>
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart1" style="height:300px;"></div>
<div class="chart2" style="height:150px;"></div>
<div class="chart3" style="height:150px;"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['data1', 130, 210, 120, 440, 250, 350]
]
}
});
var chart2 = c3.generate({
bindto: '.chart2',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250]
]
}
});
var chart3 = c3.generate({
bindto: document.getElementsByClassName('chart3')[0],
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250]
]
}
});
</script>
</body>
</html>
......@@ -3,14 +3,19 @@
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<div id="chart1"></div>
<div id="chart2"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
var chart1 = c3.generate({
bindto: '#chart1',
data: {
x: 'x',
columns: [
['x', '1e-3', '1e-2', '1'],
['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250]
]
},
......@@ -21,9 +26,28 @@
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250]
]
},
axis: {
x: {
categories: ['1e-3', '1e-2', '1e-1', '0', 'hoge'],
type: 'categorized'
}
}
});
setTimeout(function () {
chart1.load({columns:[['data2', 30, 20, 50, 40, 60, 50, 100, 200, 300,100]]});
}, 1000);
setTimeout(function () {
chart.load({columns:[['data2', 30, 20, 50, 40, 60, 50, 100, 200, 300,100]]});
}, 500);
chart2.load({columns:[['data2', 30, 20, 50, 40, 60, 50, 100, 200, 300,100]]});
}, 2000);
</script>
</body>
......
......@@ -3,23 +3,86 @@
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<h3>Zerobased</h3>
<div id="chart1"></div>
<h3>Not zerobased because of axis.y.min</h3>
<div id="chart2"></div>
<h3>Zerobased</h3>
<div id="chart3"></div>
<h3>Not zerobased because of axis.y.min</h3>
<div id="chart4"></div>
<h3>+/- vaulues</h3>
<div id="chart5"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['data1', 300, 350, 300, 0, 0, 0],
['data2', 130, 100, 140, 200, 150, 50]
],
type: 'area'
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['data1', 300, 350, 300, 0, 0, 0],
['data2', 130, 100, 140, 200, 150, 50]
],
types: {
data1: 'area',
data2: 'area-spline'
type: 'area'
},
axis: {
y: {
min: 100,
}
},
});
var chart3 = c3.generate({
bindto: '#chart3',
data: {
columns: [
['data1', -300, -350, -300, 0, 0, 0],
['data2', -130, -100, -140, -200, -150, -50]
],
type: 'area'
}
});
var chart4 = c3.generate({
bindto: '#chart4',
data: {
columns: [
['data1', -300, -350, -300, 0, 0, 0],
['data2', -130, -100, -140, -200, -150, -50]
],
type: 'area'
},
axis: {
y: {
max: -100,
}
}
});
var chart5 = c3.generate({
bindto: '#chart5',
data: {
columns: [
['data1', -300, 350, -300, 0, 0, 0],
['data2', -130, -100, 140, -200, 150, -50]
],
type: 'area'
}
});
</script>
</body>
</html>
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['data1', 300, 350, 300, 0, 0, 0],
['data2', 130, 100, 140, 200, 150, 50]
],
type: 'area-spline'
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['data1', -300, -350, -300, 0, 0, 0],
['data2', -130, -100, -140, -200, -150, -50]
],
type: 'area-spline'
}
});
var chart3 = c3.generate({
bindto: '#chart3',
data: {
columns: [
['data1', -300, 350, -300, 0, 0, 0],
['data2', -130, -100, 140, -200, 150, -50]
],
type: 'area-spline'
}
});
</script>
</body>
</html>
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['data1', 300, 350, 300, 0, 0, 100],
['data2', 130, 0, 140, 200, 0, 50],
],
type: 'area-spline',
groups: [['data1', 'data2']],
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['data1', -300, -350, -300, 0, 0, -100],
['data2', -130, 0, -140, -200, 0, -50]
],
type: 'area-spline',
groups: [['data1', 'data2']],
}
});
var chart3 = c3.generate({
bindto: '#chart3',
data: {
columns: [
['data1', -300, 350, -300, 0, 0, 100],
['data2', -130, 0, 140, -200, 150, -50]
],
type: 'area-spline',
groups: [['data1', 'data2']],
}
});
</script>
</body>
</html>
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['data1', 300, 350, 300, 0, 0, 100],
['data2', 130, 0, 140, 200, 0, 50],
],
type: 'area',
groups: [['data1', 'data2']],
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['data1', -300, -350, -300, 0, 0, -100],
['data2', -130, 0, -140, -200, 0, -50]
],
type: 'area',
groups: [['data1', 'data2']],
}
});
var chart3 = c3.generate({
bindto: '#chart3',
data: {
columns: [
['data1', -300, 350, -300, 0, 0, 100],
['data2', -130, 0, 140, -200, 150, -50]
],
type: 'area',
groups: [['data1', 'data2']],
}
});
</script>
</body>
</html>
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['data1', 300, 350, 300, 0, 0, 0],
['data2', 130, 100, 140, 200, 150, 50]
],
type: 'area-step'
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['data1', -300, -350, -300, 0, 0, 0],
['data2', -130, -100, -140, -200, -150, -50]
],
type: 'area-step'
}
});
var chart3 = c3.generate({
bindto: '#chart3',
data: {
columns: [
['data1', -300, 350, -300, 0, 0, 0],
['data2', -130, -100, 140, -200, 150, -50]
],
type: 'area-step'
}
});
</script>
</body>
</html>
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['data1', 300, 350, 300, 0, 0, 0],
['data2', 130, 100, 140, 200, 150, 50]
],
type: 'area-step',
groups: [['data1', 'data2']],
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['data1', -300, -350, -300, 0, 0, 0],
['data2', -130, -100, -140, -200, -150, -50]
],
type: 'area-step',
groups: [['data1', 'data2']],
}
});
var chart3 = c3.generate({
bindto: '#chart3',
data: {
columns: [
['data1', -300, 350, -300, 0, 0, 0],
['data2', -130, -100, 140, -200, 150, -50]
],
type: 'area-step',
groups: [['data1', 'data2']],
}
});
</script>
</body>
</html>
......@@ -11,13 +11,15 @@
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 130, 100, 140, 200, 150, 50]
['data1', 1030, 1200, 1100, 1400, 1150, 1250],
['data2', 2130, 2100, 2140, 2200, 2150, 1850]
// ['data1', 30, 200, 100, 400, 150, 250],
// ['data2', 130, 100, 140, 200, 150, 50]
],
type: 'bar',
onclick: function (d, element) { console.log("onclick", d, element); },
onenter: function (d) { console.log("onenter", d); },
onleave: function (d) { console.log("onleave", d); }
onmouseover: function (d) { console.log("onmouseover", d); },
onmouseout: function (d) { console.log("onmouseout", d); }
},
axis: {
x: {
......@@ -26,8 +28,9 @@
},
bar: {
width: {
ratio: 0.3
}
ratio: 0.3,
// max: 30
},
}
});
</script>
......
......@@ -8,12 +8,16 @@
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
var axis_x_type = 'category',
axis_rotated = false;
var generate = function () { return c3.generate({
data: {
columns: [
['data1', 30, 200, 200, 400, 150, -250],
['data2', 130, -100, 100, 200, 150, 50],
['data3', 230, -200, 200, 300, 250, 250]
['data3', 230, -200, 200, 0, 250, 250]
],
type: 'bar',
groups: [
......@@ -22,39 +26,65 @@
},
axis: {
x: {
type: 'categorized'
type: axis_x_type
},
// rotated: true
rotated: axis_rotated
},
grid: {
y: {
lines: [{value:0}]
}
},
zoom: {
// enabled: true
},
subchart: {
// show: true
},
tooltip: {
// enabled: false
}
});
}); }, chart = generate();
setTimeout(function () {
function update1() {
chart.groups([['data1', 'data2', 'data3']])
}, 500);
}
setTimeout(function () {
function update2() {
chart.load({
columns: [['data4', 100, 50, 150, -200, 300, -100]]
});
}, 1000);
}
setTimeout(function () {
function update3() {
chart.groups([['data1', 'data2', 'data3', 'data4']])
}, 1500);
}
setTimeout(update1, 1000);
setTimeout(update2, 2000);
setTimeout(update3, 3000);
setTimeout(function () {
axis_rotated = true;
chart = generate();
}, 4000);
setTimeout(update1, 5000);
setTimeout(update2, 6000);
setTimeout(update3, 7000);
setTimeout(function () {
axis_x_type = '';
axis_rotated = false;
chart = generate();
}, 8000);
setTimeout(update1, 9000);
setTimeout(update2, 10000);
setTimeout(update3, 11000);
setTimeout(function () {
axis_x_type = '';
axis_rotated = true;
chart = generate();
}, 12000);
setTimeout(update1, 13000);
setTimeout(update2, 14000);
setTimeout(update3, 15000);
</script>
</body>
......
......@@ -10,24 +10,19 @@
<script>
var chart = c3.generate({
data: {
xs: {
setosa: 'setosa_x',
versicolor: 'versicolor_x',
virginica: 'virginica_x'
},
columns: [
["setosa_x", 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3.0, 3.0, 4.0, 4.4, 3.9, 3.5, 3.8, 3.8, 3.4, 3.7, 3.6, 3.3, 3.4, 3.0, 3.4, 3.5, 3.4, 3.2, 3.1, 3.4, 4.1, 4.2, 3.1, 3.2, 3.5, 3.6, 3.0, 3.4, 3.5, 2.3, 3.2, 3.5, 3.8, 3.0, 3.8, 3.2, 3.7, 3.3],
["versicolor_x", 3.2, 3.2, 3.1, 2.3, 2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 2.0, 3.0, 2.2, 2.9, 2.9, 3.1, 3.0, 2.7, 2.2, 2.5, 3.2, 2.8, 2.5, 2.8, 2.9, 3.0, 2.8, 3.0, 2.9, 2.6, 2.4, 2.4, 2.7, 2.7, 3.0, 3.4, 3.1, 2.3, 3.0, 2.5, 2.6, 3.0, 2.6, 2.3, 2.7, 3.0, 2.9, 2.9, 2.5, 2.8],
["virginica_x", 3.3, 2.7, 3.0, 2.9, 3.0, 3.0, 2.5, 2.9, 2.5, 3.6, 3.2, 2.7, 3.0, 2.5, 2.8, 3.2, 3.0, 3.8, 2.6, 2.2, 3.2, 2.8, 2.8, 2.7, 3.3, 3.2, 2.8, 3.0, 2.8, 3.0, 2.8, 3.8, 2.8, 2.8, 2.6, 3.0, 3.4, 3.1, 3.0, 3.1, 3.1, 3.1, 2.7, 3.2, 3.3, 3.0, 2.5, 3.0, 3.4, 3.0],
["setosa", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],
// ["setosa", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],
["versicolor", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],
["virginica", 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8],
// ["setosa", 30],
["setosa", 30],
// ["versicolor", 40],
// ["virginica", 50],
],
type : 'donut',
// type : 'pie',
onmouseover: function (d, i) { console.log("onmouseover", d, i, this); },
onmouseout: function (d, i) { console.log("onmouseout", d, i, this); },
onclick: function (d, i) { console.log("onclick", d, i, this); },
order: null // set null to disable sort of data. desc is the default.
},
axis: {
x: {
......@@ -42,9 +37,7 @@
// format: function (d, ratio) { return ""; }
},
title: "Iris Petal Width",
onmouseover: function (d, i) { console.log(d, i); },
onmouseout: function (d, i) { console.log(d, i); },
onclick: function (d, i) { console.log(d, i); },
width: 70
}
});
......@@ -57,7 +50,9 @@
}, 1000);
setTimeout(function () {
chart.unload('virginica');
chart.unload({
ids: 'virginica'
});
}, 2000);
</script>
......
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
[ 'data', 91.4 ]
],
type: 'gauge',
onmouseover: function (d, i) { console.log("onmouseover", d, i, this); },
onmouseout: function (d, i) { console.log("onmouseout", d, i, this); },
onclick: function (d, i) { console.log("onclick", d, i, this); },
},
gauge: {
label: {
// format: function(value, ratio) {
// return value;
// },
// show: false // to turn off the min/max labels.
},
// min: 0, // 0 is default, //can handle negative min e.g. vacuum / voltage / current flow / rate of change
// max: 100, // 100 is default
// units: ' %',
// width: 39 // for adjusting arc thickness
},
color: {
pattern: ['#FF0000', '#F6C600', '#60B044'], // the three color levels for the percentage values.
threshold: {
// unit: 'value', // percentage is default
// max: 200, // 100 is default
values: [30, 60, 90] // alternate first value is 'value'
}
}
});
var cycleDemo = function () {
setTimeout(function () {
d3.select('#chart .c3-chart-arcs-background')
.transition()
.style('fill', '#333');
}, 1000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 10 ]]
});
}, 2000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 50 ]]
});
}, 3000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 91.4 ]]
});
}, 4000);
setTimeout(function () {
d3.select('#chart .c3-chart-arcs-background')
.transition()
.style('fill', '#e0e0e0');
}, 5000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 0 ]]
});
}, 6000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 50 ]]
});
}, 7000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 91.4 ]]
});
}, 8000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 0 ]]
});
}, 9000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 50 ]]
});
}, 10000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 91.4 ]]
});
}, 11000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 0 ]]
});
}, 12000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 50 ]]
});
}, 13000);
setTimeout(function () {
chart.load({
columns: [[ 'data', 91.4 ]]
});
}, 14000);
}
cycleDemo();
// setInterval(cycleDemo, 30000);
</script>
</body>
</html>
......@@ -10,23 +10,18 @@
<script>
var chart = c3.generate({
data: {
xs: {
setosa: 'setosa_x',
versicolor: 'versicolor_x',
virginica: 'virginica_x'
},
columns: [
["setosa_x", 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3.0, 3.0, 4.0, 4.4, 3.9, 3.5, 3.8, 3.8, 3.4, 3.7, 3.6, 3.3, 3.4, 3.0, 3.4, 3.5, 3.4, 3.2, 3.1, 3.4, 4.1, 4.2, 3.1, 3.2, 3.5, 3.6, 3.0, 3.4, 3.5, 2.3, 3.2, 3.5, 3.8, 3.0, 3.8, 3.2, 3.7, 3.3],
["versicolor_x", 3.2, 3.2, 3.1, 2.3, 2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 2.0, 3.0, 2.2, 2.9, 2.9, 3.1, 3.0, 2.7, 2.2, 2.5, 3.2, 2.8, 2.5, 2.8, 2.9, 3.0, 2.8, 3.0, 2.9, 2.6, 2.4, 2.4, 2.7, 2.7, 3.0, 3.4, 3.1, 2.3, 3.0, 2.5, 2.6, 3.0, 2.6, 2.3, 2.7, 3.0, 2.9, 2.9, 2.5, 2.8],
["virginica_x", 3.3, 2.7, 3.0, 2.9, 3.0, 3.0, 2.5, 2.9, 2.5, 3.6, 3.2, 2.7, 3.0, 2.5, 2.8, 3.2, 3.0, 3.8, 2.6, 2.2, 3.2, 2.8, 2.8, 2.7, 3.3, 3.2, 2.8, 3.0, 2.8, 3.0, 2.8, 3.8, 2.8, 2.8, 2.6, 3.0, 3.4, 3.1, 3.0, 3.1, 3.1, 3.1, 2.7, 3.2, 3.3, 3.0, 2.5, 3.0, 3.4, 3.0],
["setosa", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],
// ["setosa", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],
["versicolor", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],
["virginica", 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8],
// ["setosa", 30],
["setosa", 30],
// ["versicolor", 40],
// ["virginica", 50],
],
type : 'pie',
onmouseover: function (d, i) { console.log("onmouseover", d, i, this); },
onmouseout: function (d, i) { console.log("onmouseout", d, i, this); },
onclick: function (d, i) { console.log("onclick", d, i, this); },
},
axis: {
x: {
......@@ -35,26 +30,21 @@
y: {
label: 'Petal.Width'
}
},
pie: {
onmouseover: function (d, i) { console.log(d, i); },
onmouseout: function (d, i) { console.log(d, i); },
onclick: function (d, i) { console.log(d, i); },
}
});
setTimeout(function () {
console.log("== LOAD ==");
chart.load({
columns: [
["setosa", 30],
["setosa", 130],
]
});
}, 1000);
setTimeout(function () {
console.log("== UNLOAD ==");
chart.unload('virginica');
chart.unload({
ids: 'virginica'
});
}, 2000);
</script>
......
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var sort = true;
var generate = function () { return c3.generate({
data: {
columns: [
// ["setosa", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],
["versicolor", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],
["virginica", 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8],
["setosa", 30],
// ["versicolor", 40],
// ["virginica", 50],
],
type : 'pie',
},
axis: {
x: {
label: 'Sepal.Width'
},
y: {
label: 'Petal.Width'
}
},
pie: {
sort: sort,
onmouseover: function (d, i) { console.log(d, i); },
onmouseout: function (d, i) { console.log(d, i); },
onclick: function (d, i) { console.log(d, i); },
}
}); }, chart = generate();
setTimeout(function () {
chart.load({
columns: [
["setosa", 130],
]
});
}, 1000);
setTimeout(function () {
chart.unload({
ids: 'virginica'
});
}, 2000);
setTimeout(function () {
chart.load({
columns: [
["new data", 300],
]
});
}, 3000);
setTimeout(function () {
sort = false;
chart = generate();
}, 4000);
setTimeout(function () {
chart.load({
columns: [
["setosa", 130],
]
});
}, 5000);
setTimeout(function () {
chart.unload({
ids: 'virginica'
});
}, 6000);
setTimeout(function () {
chart.load({
columns: [
["new data", 300],
]
});
}, 7000);
</script>
</body>
</html>
......@@ -27,7 +27,10 @@
},
axis: {
x: {
label: 'Sepal.Width'
label: 'Sepal.Width',
tick: {
fit: false
}
},
y: {
label: 'Petal.Width'
......
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 300, 350, 300, 0, 0, 0],
// ['data2', 130, 100, 140, 200, 150, 50]
],
types: {
data1: 'step',
data2: 'area-step'
},
onclick: function (d) { console.log('clicked', d); }
},
subchart: {
show: true
},
});
setTimeout(function () {
chart.load({
columns: [
['data2', 130, 100, 140, 200, 150, 50]
]
});
}, 1000);
</script>
</body>
</html>
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
x: 'x',
columns: [
['x', 'hogehoge', 'aaa', 'aaaaaa', 'a', 'b'],
['data1', 300, 350, 300, 0, 0, 0],
// ['data2', 130, 100, 140, 200, 150, 50]
],
types: {
data1: 'step',
data2: 'area-step'
},
empty: {
abort: false,
label: {
text: 'hoge'
}
}
},
axis: {
x: {
type: 'categorized'
}
},
subchart: {
show: true
},
});
setTimeout(function () {
chart.load({
columns: [
['data2', 130, 100, 140, 200, 150, 50]
]
});
}, 1000);
</script>
</body>
</html>
......@@ -20,8 +20,8 @@
selection: {
enabled: true
},
onenter: function (d) { console.log("onenter", d); },
onleave: function (d) { console.log("onleave", d); }
onmouseover: function (d) { console.log("onmouseover", d); },
onmouseout: function (d) { console.log("onmouseout", d); }
},
});
......@@ -36,6 +36,24 @@
setTimeout(function () {
chart.x([200, 210, 350, 400, 550, 750]);
}, 2000);
setTimeout(function () {
chart.load({
columns: [
['data3', 300, 410, 350, 400, 500, 350],
]
});
}, 3000);
setTimeout(function () {
chart.load({
columns: [
['x', 130, 140, 200, 300, 450, 550],
['sample', 200, 350, 100, 200, 50, 100]
]
})
}, 4000);
</script>
</body>
</html>
......@@ -24,26 +24,41 @@
selection: {
enabled: true
},
onenter: function (d) { console.log("onenter", d); },
onleave: function (d) { console.log("onleave", d); }
},
onclick: function (d) { console.log("onclick", d); },
onmouseover: function (d) { console.log("onmouseover", d); },
onmouseout: function (d) { console.log("onmouseout", d); }
}
});
setTimeout(function () {
chart.load({
columns: [
['data1', 100, 210, 150, 200, null, 150],
['data1', 100, 210, 150, null, 200, 150],
['data2', 200, 310, 50, 400, 120, 250, 10],
]
});
}, 1000);
setTimeout(function () {
chart.xs({
'data1': [200, 210, 350, 400, 600, 750]
// 'data2': [200, 210, 350, 400, 550, 750, 900]
chart.load({
columns: [
['x2', 150, 220, 230, 400, 540, 600, 800],
['data2', 200, 310, 50, 400, 120, 250, 10],
['data3', 300, 410, 350, 600, 420, 550, 310],
],
xs: {
data3: 'x2'
}
});
}, 2000);
setTimeout(function () {
chart.xs({
'data1': [200, 210, 350, 400, 600, 750],
'data2': [200, 210, 350, 400, 550, 750, 900]
});
}, 3000);
</script>
</body>
</html>
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 30, 20, 50, 40, 60, 50],
['data2', 200, 130, 90, 240, 130, 220],
['data3', 300, 200, 160, 400, 250, 250]
],
// hide: ['data1', 'data3']
hide: true // hide all data
}
});
</script>
</body>
</html>
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
json: {
data1: [30, 20, 50, 40, 60, 50],
data2: [200, 130, 90, 240, 130, 220],
data3: [300, 200, 160, 400, 250, 250]
}
}
});
setTimeout(function () {
chart = c3.generate({
data: {
json: [{
"date": "2014-06-03",
"443": "3000",
"995": "500"
}, {
"date": "2014-06-04",
"443": "1000",
}, {
"date": "2014-06-05",
"443": "5000",
"995": "1000"
}],
keys: {
x: 'date',
value: [ "443", "995" ]
}
},
axis: {
x: {
type: "category"
}
}
});
}, 1000);
setTimeout(function () {
chart = c3.generate({
data: {
// x: 'name',
json: [
{ id: 1, name: 'abc', visits: 200 },
{ id: 2, name: 'efg', visits: 400 },
{ id: 3, name: 'pqr', visits: 150 },
{ id: 4, name: 'xyz', visits: 420 },
],
keys: {
x: 'name',
value: ['visits'],
}
},
axis: {
x: {
type: 'categorized'
}
}
});
}, 2000);
setTimeout(function () {
chart.load({
json: [
{ id: 1, name: 'abc', visits: 1200 },
{ id: 2, name: 'efg', visits: 900 },
{ id: 3, name: 'pqr', visits: 1150 },
{ id: 4, name: 'xyz', visits: 1020 },
],
keys: {
x: 'name',
value: ['visits'],
}
});
}, 3000);
</script>
</body>
</html>
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
<div id="chart4"></div>
<div id="chart5"></div>
<div id="chart6"></div>
<div id="chart7"></div>
<div id="chart8"></div>
<div id="chart9" style="width:33%;"></div>
<div id="chart10"></div>
<div id="chart11"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['data1', 190, 200, 190, null],
],
type: 'bar',
labels: {
format: function (v, id) {
if (v === null) {
return 'Not Applicable';
}
return d3.format('$')(v);
}
}
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['data1', -190, -200, -190, null],
],
type: 'bar',
labels: {
format: function (v, id) {
if (v === null) {
return 'Not Applicable';
}
return d3.format('$')(v);
}
}
}
});
var chart3 = c3.generate({
bindto: '#chart3',
data: {
columns: [
['data1', -190, 200, 190, null],
],
type: 'bar',
labels: {
format: function (v, id) {
if (v === null) {
return 'Not Applicable';
}
return d3.format('$')(v);
}
}
}
});
var chart4 = c3.generate({
bindto: '#chart4',
data: {
columns: [
['data1', 190, 200, 190, null],
],
type: 'bar',
labels: {
format: function (v, id) {
if (v === null) {
return 'Not Applicable';
}
return d3.format('$')(v);
}
}
},
axis: {
rotated: true
}
});
var chart5 = c3.generate({
bindto: '#chart5',
data: {
columns: [
['data1', -190, -200, -190, null],
],
type: 'bar',
labels: {
format: function (v, id) {
if (v === null) {
return 'Not Applicable';
}
return d3.format('$')(v);
}
}
},
axis: {
rotated: true
}
});
var chart6 = c3.generate({
bindto: '#chart6',
data: {
columns: [
['data1', -190, 200, 190, null],
],
type: 'bar',
labels: {
format: function (v, id) {
if (v === null) {
return 'Not Applicable';
}
return d3.format('$')(v);
}
}
},
axis: {
rotated: true
}
});
var chart7 = c3.generate({
bindto: '#chart7',
data: {
columns: [
['data1', 30, 200, 100, 500, 150, 250],
['data2', 50, 20, 10, 40, 15, 25],
['data3', 250, 220, 210, 240, 215, 225]
],
groups: [['data1', 'data2', 'data3']],
labels: true,
type: 'bar',
},
axis: {
rotated: true
}
});
var chart8 = c3.generate({
bindto: '#chart8',
data: {
columns: [
['data1', -30, -200, -100, -500, -150, -250],
['data2', -50, -20, -10, -40, -15, -25],
['data3', -250, -220, -210, -240, -215, -225]
],
groups: [['data1', 'data2', 'data3']],
labels: true,
type: 'bar',
},
axis: {
rotated: true
}
});
var chart9 = c3.generate({
bindto: '#chart9',
data: {
columns: [
['data1', -19000000000000, 200, 19000000000000, null],
],
type: 'bar',
labels: {
format: function (v, id) {
if (v === null) {
return 'Not Applicable';
}
return d3.format('$')(v);
}
}
},
axis: {
rotated: true
}
});
var chart10 = c3.generate({
bindto: '#chart10',
data: {
columns: [
['data1', 300, 350, 300, 0, 0, 100],
['data2', 130, 0, 140, 200, 0, 50],
['data3', 130, 0, 140, 200, 0, 50],
['data4', 130, 0, 140, 200, 0, 50],
],
type: 'area',
groups: [['data1', 'data2', 'data3', 'data4']],
labels: true
}
});
var chart11 = c3.generate({
bindto: '#chart11',
data: {
columns: [
['data1', 300, 350, 300, 0, 0, 100],
['data2', 130, 0, 140, 200, 0, 50],
['data3', 130, 0, 140, 200, 0, 50],
['data4', 130, 0, 140, 200, 0, 50],
],
groups: [['data1', 'data2', 'data3', 'data4']],
labels: true
}
});
</script>
</body>
</html>
......@@ -15,10 +15,10 @@
['data2', 50, 20, 10, 40, 15, 25]
],
labels: {
// format: function (v) { return "Default Format"; },
// format: function (v, id) { return "Default Format on " + id; },
format: {
y: function (v) { return "Y Format"; },
y2: function (v) { return "Y2 Format"; }
y: function (v, id) { return "Y Format on " + id; },
y2: function (v, id) { return "Y2 Format on " + id; }
}
},
axes: {
......
......@@ -8,10 +8,14 @@
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
url: '/data/c3_test.csv',
labels: true
labels: true,
filter: function (t) {
return t.id !== 'data1';
}
},
subchart: {
show: true
......@@ -20,75 +24,87 @@
enabled: true
},
transition: {
duration: 200
duration: 500
}
});
setTimeout(function () {
var queue = [
function () {
chart.load({
url: '/data/c3_test2.csv'
url: '/data/c3_test2.csv',
filter: function (t) {
return t.id !== 'data1';
}
});
}, 1000);
setTimeout(function () {
// chart.unload(['data1', 'data2']);
// chart.unload('data1');
chart.unload('data2');
}, 2000);
setTimeout(function () {
chart.load({
columns: [
['data1@test', 30, 20, 50, 40, 60, 50],
],
unload: true,
// unload: ['data2', 'data3'],
// unload: ['data2']
});
}, 3000);
setTimeout(function () {
},
function () {
chart.load({
rows: [
['data1@test', 'data2', 'data3'],
['data4', 'data5', 'data6'],
[90, 120, 300],
[40, 160, 240],
[50, 200, 290],
[120, 160, 230],
[80, 130, 300],
[90, 220, 320],
[1090, 1220, 1320],
]
});
}, 4000);
setTimeout(function () {
},
function () {
chart.unload({
ids: ['data4', 'data5']
});
},
function () {
chart.unload({
ids: 'data6'
});
},
function () {
chart.load({
columns:[
['data1', 30, 20, 50, 40, 60, 50,100,200]
['data1', 30, 20, 50, 40, 60, 50, 100, 200],
['data7', 230, 220, 250, 240, 260, 250, 300, 400]
]
});
}, 5000);
setTimeout(function () {
chart.unload('data1@test');
}, 6000);
setTimeout(function () {
},
function () {
chart.load({
columns:[
['data2', null, 30, 20, 50, 40, 60, 50]
]
json: {
data1: [1030, 1020, 1050, 1040, 1060, 1050, 1100, 1200],
data7: [430, 420, 450, 440, 460, 550, 400, 200]
}
});
}, 7000);
setTimeout(function () {
},
function () {
chart.load({
columns: [
['data8', 30, 20, 50, 40, 60, 50],
],
unload: true,
});
},
function () {
chart.load({
columns: [
['data9', 130, 120, 150, 140, 160, 150],
],
unload: ['data7', 'data8'],
});
},
function () {
chart.load({
unload: ['data1', 'data2'],
});
},
function () {
chart.unload();
}, 8000);
setTimeout(function () {
},
function () {
chart.load({
rows: [
['data1@test', 'data2', 'data3'],
['data1', 'data2', 'data3'],
[90, 120, 300],
[40, 160, 240],
[50, 200, 290],
......@@ -97,11 +113,18 @@
[90, 220, 320],
]
});
}, 9000);
},
function () {
chart.unload({
ids: ['data2', 'data3']
});
},
];
setTimeout(function () {
chart.unload(['data2', 'data3']);
}, 10000);
var i = 0;
queue.forEach(function (f) {
setTimeout(f, 1500 * i++);
});
</script>
</body>
......
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
x: 'x',
url: '/data/c3_test_ts.csv',
labels: true
},
axis: {
x: {
type: 'timeseries'
}
},
subchart: {
show: true
},
zoom: {
enabled: true
},
});
setTimeout(function () {
chart.load({
url: '/data/c3_test2_ts.csv'
});
}, 1000);
setTimeout(function () {
chart.unload({
ids: 'data2'
});
}, 2000);
setTimeout(function () {
chart.load({
columns: [
['data1', 30, 20, 50, 40, 60, 50],
],
unload: true,
// unload: ['data2', 'data3'],
// unload: ['data2']
});
}, 3000);
</script>
</body>
</html>
......@@ -6,7 +6,7 @@
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
......
......@@ -6,13 +6,13 @@
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
x : 'date',
x_format : '%Y%m%d',
xFormat : '%Y%m%d',
columns: [
// ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
['date', '20130101', '20130102', '20130103', '20130104', '20130105', '20130106'],
......
......@@ -6,13 +6,47 @@
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
url: '/data/c3_test.csv'
}
});
setTimeout(function () {
chart.load({
url: '/data/c3_test2.csv',
});
}, 1000);
setTimeout(function () {
chart = c3.generate({
data: {
url: '/data/c3_test.json',
mimeType: 'json'
}
});
}, 2000);
setTimeout(function () {
chart.load({
url: '/data/c3_test_2.json',
mimeType: 'json'
});
}, 3000);
setTimeout(function () {
chart.load({
url: '/data/c3_test_3.json',
mimeType: 'json',
keys: {
value: ['data1', 'data2']
}
});
}, 4000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<button id="btn1">Bar</button>
<button id="btn2">Line</button>
<button id="btn3">Area</button>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var normalData = {
columns: [
['data1', -1030, -1200, 1000],
['data2', -1150, -220, -1110]
],
labels: true,
},
allPositiveData = {
columns: [
['data1', 1030, 1200, 1100],
['data2', 2050, 2020, 2010]
],
labels: true,
},
allNegativeData = {
columns: [
['data1', -1030, -2200, -2100],
['data2', -1150, -2010, -1200]
],
labels: true,
}
var chart1 = c3.generate({
bindto: '#chart1',
data: normalData
});
var chart2 = c3.generate({
bindto: '#chart2',
data: allPositiveData
});
var chart3 = c3.generate({
bindto: '#chart3',
data: allNegativeData
});
d3.select('#btn1').on('click', function () {
chart1.transform('bar');
chart2.transform('bar');
chart3.transform('bar');
});
d3.select('#btn2').on('click', function () {
chart1.transform('line');
chart2.transform('line');
chart3.transform('line');
});
d3.select('#btn3').on('click', function () {
chart1.transform('area');
chart2.transform('area');
chart3.transform('area');
});
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
data: {
columns: [
['sample', 30, 200, 100, null, 150, 250]
],
},
});
var chart2 = c3.generate({
data: {
columns: [
['sample', 30, 200, 100, null, 150, 250]
],
type: 'bar'
}
});
document.getElementById('chart1').appendChild(chart1.element);
$('#chart2').append(chart2.element);
</script>
</body>
</html>
......@@ -6,35 +6,32 @@
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
x: 'x',
columns: [
['x', 30, 40, 100, 200, 250, 350],
['sample', 30, 200, 100, 400, 150, 250]
]
// ['data1', 100, 200],
],
empty: {
label: {
text: 'No Data'
}
}
},
subchart: {
show: true
}
});
setTimeout(function () {
chart.load({
columns: [
['sample', 100, 300, 200, 300, 150, 300]
]
})
['data1', 100, 200],
],
});
}, 1000);
setTimeout(function () {
chart.load({
columns: [
['x', 130, 140, 200, 300, 450, 550],
['sample', 200, 350, 100, 200, 50, 100]
]
})
}, 1500);
</script>
</body>
</html>
......@@ -3,37 +3,27 @@
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<div id="chart1"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
var chart1 = c3.generate({
bindto: '#chart1',
data: {
x : 'date',
x_format : '%Y%m%d',
columns: [
// ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
['date', '20130101', '20130102', '20130103', '20130104', '20130105', '20130106'],
['sample', 30, 200, 100, 400, 150, 250]
['data1', 30, 200, 100, 400, 150, 250],
['data2', 130, 300, 200, 300, 250, 150]
]
},
axis : {
x : {
type : 'timeseries'
}
},
grid: {
x: {
lines: [{
value: '20130104',
text: '2013/01/04',
class: 'lineFor20130104'
}]
focus: {
show: false
}
}
});
</script>
</body>
</html>
......@@ -3,47 +3,64 @@
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<div id="chart1"></div>
<div id="chart2"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
bindto: '#chart1',
data: {
columns: [
['sample', 30, 200, 100, 400, 150, 250]
]
},
axis: {
// rotated: true,
['data1', 30, 200, 100, 400, 150, 250]
],
type: 'bar'
},
grid: {
x: {
lines: [{value: 3, text:'Lable 3'}, {value: 4.5, text: 'Lable 4.5'}]
show: true,
lines: [{
value: 2,
text: 'Label 2',
class: 'lineFor2'
}]
},
y: {
show: true,
}
}
});
setTimeout(function () {
chart.xgrids([{value: 1, text:'Lable 1'}, {value: 4, text: 'Lable 4'}]);
}, 1000);
setTimeout(function () {
chart.xgrids([{value: 2, text:'Lable 2'}]);
}, 2000);
setTimeout(function () {
chart.xgrids.add([{value: 3, text:'Lable 3', class:'hoge'}]);
}, 3000);
setTimeout(function () {
chart.xgrids.remove({value:2});
}, 4000);
var chart2 = c3.generate({
bindto: '#chart2',
data: {
x : 'x',
columns: [
['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05'],
['sample', 30, 200, 100, 400, 150]
],
},
axis : {
x : {
type : 'timeseries'
}
},
grid: {
x: {
lines: [{
value: '2013-01-04',
text: '2013/01/04',
class: 'lineFor20130104'
}]
},
lines: {
front: false
}
}
});
setTimeout(function () {
chart.xgrids.remove({class:'hoge'});
}, 5000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
"bindto": "#chart1",
"axis": {
"x": {
"type": "timeseries",
"tick": {
format: '%Y-%m-%d %H:%M:%S'
}
}
},
"grid": {
"x": {
"lines": [
{ "value": 1401883200000, "text": new Date(1401883200000), "color": "#f00" },
]
}
},
"data": {
"type": "line",
"columns": [
["epoch", 1401879600000, 1401883200000, 1401886800000],
["y", 1955, 2419, 2262]
],
"xs": {
"y": "epoch"
}
}
});
var chart2 = c3.generate({
"bindto": "#chart2",
"axis": {
"x": {
"type": "timeseries",
"tick": {
format: '%Y-%m-%d %H:%M:%S'
}
}
},
"grid": {
"x": {
"lines": [
{ "value": new Date(1401883200000), "text": new Date(1401883200000), "color": "#f00" },
]
}
},
"data": {
"type": "line",
"columns": [
["epoch", 1401879600000, 1401883200000, 1401886800000],
["y", 1955, 2419, 2262]
],
"xs": {
"y": "epoch"
}
}
});
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
<div id="chart4"></div>
<div id="chart5"></div>
<div id="chart6"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var smallData = [['sample', 30, 200, 100, 400, 150, 250]],
bigData = [['sample', 30, 200, 100, 400, 150, 250, 30, 200, 100, 400, 150, 250]];
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: smallData
},
grid: {
x: {
show: true
},
}
});
c3.generate({
bindto: '#chart2',
data: {
columns: smallData
},
grid: {
y: {
show: true
}
}
});
c3.generate({
bindto: '#chart3',
data: {
columns: smallData
},
axis: {
rotated: true,
},
grid: {
x: {
show: true
},
}
});
c3.generate({
bindto: '#chart4',
data: {
columns: smallData
},
axis: {
rotated: true,
},
grid: {
y: {
show: true
}
}
});
c3.generate({
bindto: '#chart5',
data: {
columns: bigData
},
grid: {
x: {
show: true
},
y: {
show: true
}
}
});
c3.generate({
bindto: '#chart6',
data: {
columns: bigData
},
axis: {
x: {
type: 'category'
}
},
grid: {
x: {
show: true
},
y: {
show: true
}
}
});
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var smallData = [
['x', '2014-01-01', '2014-02-01', '2014-03-01', '2014-04-01', '2014-05-01', '2014-06-01'],
['sample', 30, 200, 100, 400, 150, 250]
],
bigData = [
['x', '2014-01-01', '2014-02-01', '2014-03-01', '2014-04-01', '2014-05-01', '2014-06-01', '2014-07-01', '2014-08-01', '2014-09-01', '2014-10-01', '2014-11-01', '2014-12-01'],
['sample', 30, 200, 100, 400, 150, 250, 30, 200, 100, 400, 150, 250]
];
c3.generate({
bindto: '#chart1',
data: {
x: 'x',
columns: smallData
},
axis: {
x: {
type: 'timeseries',
tick: {
format: "%Y-%m-%d %H:%M:%S"
}
}
},
grid: {
x: {
show: true,
},
}
});
c3.generate({
bindto: '#chart2',
data: {
x: 'x',
columns: smallData
},
axis: {
rotated: true,
x: {
type: 'timeseries',
tick: {
format: "%Y-%m-%d %H:%M:%S"
}
}
},
grid: {
x: {
show: true,
},
}
});
c3.generate({
bindto: '#chart3',
data: {
x: 'x',
columns: bigData
},
axis: {
x: {
type: 'timeseries',
tick: {
format: "%Y-%m-%d %H:%M:%S"
}
}
},
grid: {
x: {
show: true
}
}
});
</script>
</body>
</html>
......@@ -6,19 +6,18 @@
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
zoom: {
enabled: true
},
data: {
columns: [
['sample', 30, 200, 100, 400, 150, 250]
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
]
},
subchart: {
show: true
interaction: {
enabled: false
}
});
</script>
......
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
<div id="chart4"></div>
<div id="chart5"></div>
<div id="chart6"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var columns = [];
for (var i = 0; i < 28; i++ ) {
columns[i] = ['datahogehogeohgeohoge' + i, 10 * i, 20 * i];
}
c3.generate({
bindto: '#chart1',
data: {
columns: columns,
},
});
c3.generate({
bindto: '#chart2',
data: {
columns: columns,
},
legend: {
position: 'right'
},
});
c3.generate({
bindto: '#chart3',
data: {
columns: columns,
},
legend: {
position: 'inset',
},
});
c3.generate({
bindto: '#chart4',
data: {
columns: columns,
},
axis: {
rotated: true,
},
});
c3.generate({
bindto: '#chart5',
data: {
columns: columns,
},
legend: {
position: 'right'
},
axis: {
rotated: true,
},
});
c3.generate({
bindto: '#chart6',
data: {
columns: columns,
},
legend: {
position: 'inset'
},
axis: {
rotated: true,
},
});
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
<style type="text/css">
<!--
.c3 svg {
/* font-size: 13px;*/
}
-->
</style>
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
<div id="chart4"></div>
<div id="chart5"></div>
<div id="chart6"></div>
<div id="chart7"></div>
<div id="chart8"></div>
<div id="chart9"></div>
<div id="chart10"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var option = {
padding: {
top: 50,
right: 200,
bottom: 50,
left: 200,
},
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 130, 100, 200, 100, 150, 150]
],
axes: {
data2: 'y2'
},
},
axis: {
rotated: true,
y: {
label: {
text: 'Y Label',
position: 'outer-center'
}
},
y2: {
show: true,
label: {
text: 'Y2 Label',
position: 'outer-center'
}
}
},
legend: {
position: 'bottom'
},
subchart: {
show: false
},
grid: {
x: {
show: true,
},
y: {
show: true,
}
}
};
option.bindto = '#chart1';
var chart1 = c3.generate(option);
option.bindto = '#chart2';
option.legend.position = 'right'
var chart2 = c3.generate(option);
option.bindto = '#chart3';
option.legend.position = 'bottom';
option.subchart.show = true;
var chart3 = c3.generate(option);
option.bindto = '#chart4';
option.legend.position = 'right';
option.subchart.show = true;
var chart4 = c3.generate(option);
option.bindto = '#chart5';
option.padding = {
top: 0,
right: 0,
bottom: 0,
left: 0,
};
option.subchart.show = false;
option.legend.position = 'bottom';
var chart5 = c3.generate(option);
option.axis.rotated = false;
option.bindto = '#chart6';
var chart6 = c3.generate(option);
option.bindto = '#chart7';
option.legend.position = 'right'
var chart7 = c3.generate(option);
option.bindto = '#chart8';
option.legend.position = 'bottom';
option.subchart.show = true;
var chart8 = c3.generate(option);
option.bindto = '#chart9';
option.legend.position = 'right';
option.subchart.show = true;
var chart9 = c3.generate(option);
option.bindto = '#chart10';
option.padding = {
top: 0,
right: 0,
bottom: 0,
left: 0,
};
option.subchart.show = false;
option.legend.position = 'bottom';
var chart10 = c3.generate(option);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var axis_rotated = true;
var generate = function () { return c3.generate({
data: {
x: 'x',
columns: [
['x', '2014-01-01', '2014-02-01', '2014-03-01', '2014-04-01'],
['data1', 190, 200, 190, null],
],
type: 'bar',
labels: {
format: function (v, id) {
if (v === null) {
return 'Not Applicable';
}
return d3.format('$')(v);
}
}
},
axis: {
x: {
type: 'categorized'
},
rotated: axis_rotated
},
}); }, chart = generate();
setTimeout(function () {
chart.hide();
}, 1000);
setTimeout(function () {
chart.show();
}, 2000);
setTimeout(function () {
chart.load({
columns: [
['data1', 300, 350, 100]
],
categories: ['2014-01-01 10:10:10', '2014-02-01 12:30:00', '2014-03-01 16:30:00']
});
}, 3000);
setTimeout(function () {
chart.load({
columns: [
['data1', 50, 100, 150]
],
categories: ['2014', '2015', '2016']
});
}, 4000);
setTimeout(function () {
axis_rotated = false;
chart = generate();
}, 5000);
setTimeout(function () {
chart.load({
columns: [
['data1', 300, 350, 100000]
],
});
}, 6000);
setTimeout(function () {
chart.load({
columns: [
['data1', 50, 100, 150]
],
});
}, 7000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<!-- <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>-->
<script src="/js/d3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script src="/js/samples/plugin.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
onclick: function (d, element) { console.log("onclick", d, element); },
onmouseover: function (d) { console.log("onmouseover", d); },
onmouseout: function (d) { console.log("onmouseout", d); },
},
test1: 'TEST1',
});
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/style.css">
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
......@@ -13,10 +12,14 @@
bindto: '#chart',
data: {
columns: [
['sample', 30, 200, 100, 400, 150, 250]
['data1', 30, 200, 100, 400, 150, 250],
['data2', 130, 300, 200, 600, 250, 150]
],
types: {
'sample': 'bar'
},
point: {
// r: 10
r: function (d) {
return d.id === 'data2' ? 10 : 2.5;
}
}
});
......
......@@ -11,13 +11,77 @@
var chart = c3.generate({
data: {
columns: [
['sample', 30, 200, 100, 400, 150, 250]
['sample', 30, 200, 100, 400, 150, 250, 300]
]
},
axis: {
rotated: true,
y2: {
// show: true,
}
},
regions: [
{start:2,end:4,class:'region1'}
]
{end:1,class:'region1'},
{start:2,end:4,class:'region1'},
{start:5,class:'region1'},
{end:50,axis:'y'},
{start:100,end:200,axis:'y'},
{start:300,axis:'y'},
],
zoom: {
// enabled: true
}
});
setTimeout(function () {
chart.load({
columns: [
['sample', -100, 200, 50, 100, 400, 299]
]
});
}, 1000);
setTimeout(function () {
chart.regions([]);
}, 2000);
setTimeout(function () {
chart.regions([{start:0.5,end:2.5}]);
}, 3000);
setTimeout(function () {
chart.regions.add([{start:4.5}]);
}, 4000);
setTimeout(function () {
chart.regions.add([{start:3,end:3.5,class:"region1"}, {start:4,end:4.5,class:"region2"}]);
}, 5000);
setTimeout(function () {
chart.regions.remove({classes:['region1', 'region2'], duration: 0});
}, 6000);
setTimeout(function () {
chart.regions.add([
{start:3,end:3.5,class:"region3 hoge"},
{start:4,end:4.5,class:"region4 hoge"},
{start:0,end:0.5,class:"region5 hogehoge"},
]);
}, 7000);
setTimeout(function () {
chart.regions.remove({classes:['hoge'], duration: 500});
}, 8000);
setTimeout(function () {
chart.regions.remove({classes:['hogehoge']});
}, 9000);
setTimeout(function () {
chart.regions.remove({});
}, 10000);
</script>
</body>
</html>
......@@ -3,12 +3,36 @@
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
grouped => true, multiple => true
<div id="chart1"></div>
grouped => true, multiple => true, tooltip.grouped = false
<div id="chart1-1"></div>
grouped => true, multiple => false
<div id="chart2"></div>
grouped => true, multiple => false, tooltip.grouped = false
<div id="chart2-1"></div>
grouped => false, multiple => true
<div id="chart3"></div>
grouped => false, multiple => true, tooltip.grouped = false
<div id="chart3-1"></div>
grouped => false, multiple => false
<div id="chart4"></div>
grouped => false, multiple => false, tooltip.grouped = false
<div id="chart4-1"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
var chart1 = c3.generate({
bindto: '#chart1',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
......@@ -17,7 +41,7 @@
selection: {
enabled: true,
grouped: true,
multiple: false,
multiple: true,
},
onclick: function (d, element) { console.log("onclick", d, element); },
onselected: function (d, element) { console.log("onselected", d, element); },
......@@ -26,6 +50,124 @@
ondragend: function () { console.log("ondragend"); },
},
});
var chart11 = c3.generate({
bindto: '#chart1-1',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
selection: {
enabled: true,
grouped: true,
multiple: true,
},
},
tooltip: {
grouped: false
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
selection: {
enabled: true,
grouped: true,
multiple: false,
}
}
});
var chart21 = c3.generate({
bindto: '#chart2-1',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
selection: {
enabled: true,
grouped: true,
multiple: false,
}
},
tooltip: {
grouped: false
}
});
var chart3 = c3.generate({
bindto: '#chart3',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
selection: {
enabled: true,
grouped: false,
multiple: true,
}
}
});
var chart31 = c3.generate({
bindto: '#chart3-1',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
selection: {
enabled: true,
grouped: false,
multiple: true,
}
},
tooltip: {
grouped: false
}
});
var chart4 = c3.generate({
bindto: '#chart4',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
selection: {
enabled: true,
grouped: false,
multiple: false,
}
}
});
var chart41 = c3.generate({
bindto: '#chart4-1',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
selection: {
enabled: true,
grouped: false,
multiple: false,
}
},
tooltip: {
grouped: false
}
});
</script>
</body>
</html>
......@@ -6,17 +6,17 @@
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
columns: [
['sample', 30, 200, 100, 400, 150, 250]
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
onclick: function (d, element) { console.log("onclick", d, element); },
onenter: function (d) { console.log("onenter", d); },
onleave: function (d) { console.log("onleave", d); },
onmouseover: function (d) { console.log("onmouseover", d); },
onmouseout: function (d) { console.log("onmouseout", d); },
}
});
</script>
......
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1" style="height:300px;"></div>
<div id="chart2" style="height:150px;"></div>
<div id="chart3" style="height:150px;"></div>
<div id="chart1"></div>
<div id="chart2"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
// xs: {
// 'data2': 'data1',
// },
columns: [
['data1', 130, 210, 120, 440, 250, 350],
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
// type: 'scatter'
// type: 'pie'
selection: {
enabled: true
}
labels: true
},
zoom: {
enabled: true
},
subchart : {
subchart: {
show: true
}
},
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 150, 120, 210, 240, 215, 125]
['data2', 50, 20, 10, 40, 15, 25]
],
// type: 'scatter'
// type: 'pie'
labels: true
},
});
var chart3 = c3.generate({
bindto: '#chart3',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 550, 520, 510, 540, 515, 525]
],
// type: 'scatter'
// type: 'pie'
subchart: {
show: true
},
axis: {
rotated: true
}
});
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
x : 'x',
columns: [
['x', '2013-01-01', '2013-02-01', '2013-03-01', '2013-04-01', '2013-05-01'],
['sample', 30, 200, 100, 400, 150],
['sample2', 130, 300, 200, 450, 250]
]
},
axis : {
x : {
type : 'timeseries',
tick : {
format : "%Y-%m-%d"
}
}
},
subchart: {
show: true,
onbrush: function (domain) {
console.log(this, domain);
}
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['sample', 30, 200, 100, 400, 150],
['sample2', 130, 300, 200, 450, 250]
]
},
subchart: {
show: true,
onbrush: function (domain) {
console.log(this, domain);
}
}
});
</script>
</body>
</html>
......@@ -12,7 +12,7 @@
bindto: '#chart',
data: {
x : 'date',
x_format : '%Y%m%d',
xFormat : '%Y%m%d',
columns: [
// ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
['date', '20130101', '20130102', '20130103', '20130104', '20130105', '20130106'],
......
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
x : 'x',
xFormat : '%Y%m%d',
columns: [
['x', new Date('2013-01-01 00:00:00'), new Date('2013-01-02 00:00:00'), new Date('2013-01-03 00:00:00'), new Date('2013-01-04 00:00:00'), new Date('2013-01-05 00:00:00'), new Date('2013-01-06 00:00:00')],
['sample', 30, 200, 100, 400, 150, 250],
['sample2', 130, 300, 200, 450, 250, 350]
]
},
axis : {
x : {
type : 'timeseries',
tick : {
// format : "%m/%d" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format
format : "%e %b %y" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format
}
}
}
});
setTimeout(function () {
chart.load({
columns: [
['sample', 200, 130, 90, 240, 130, 100],
['sample2', 300, 200, 160, 400, 250, 250]
]
});
}, 1000);
setTimeout(function () {
chart.load({
columns: [
['x', '20140101', '20140201', '20140301', '20140401', '20140501', '20140601'],
['sample', 500, 630, 690, 440, 630, 900],
['sample2', 400, 600, 460, 200, 350, 450]
]
});
}, 2000);
setTimeout(function () {
chart.load({
columns: [
['x', new Date('2014-01-02 00:00:00'), new Date('2014-02-02 00:00:00'), new Date('2014-03-02 00:00:00'), new Date('2014-04-02 00:00:00'), new Date('2014-05-02 00:00:00'), new Date('2014-06-02 00:00:00')],
['sample', 500, 630, 690, 440, 630, 900],
['sample2', 400, 600, 460, 200, 350, 450]
]
});
}, 3000);
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<!-- <script src="/js/c3.min.0.1.35.js"></script>-->
<script>
var dates = ['date',
1401908040000,
1401907980000,
1401907920000,
1401907860000,
1401907800000,
1401907740000,
1401907680000,
1401907620000,
1401907560000,
1401907500000
];
var chart = c3.generate({
bindto: '#chart',
data: {
x : 'date',
columns: [
dates,
['data1', 30, 200, 100, 400, 150, 250, 30, 200, 100, 400],
['data2', 130, 300, 200, 450, 250, 350, 130, 300, 200, 450]
],
types: {
data1: 'bar',
}
},
axis : {
x : {
type : 'timeseries',
tick : {
format : "%Y-%m-%d %H:%M:%S"
}
}
}
});
/*
setTimeout(function () {
chart.load({
columns: [
['sample', 200, 130, 90, 240, 130, 100],
['sample2', 300, 200, 160, 400, 250, 250]
]
});
}, 1000);
setTimeout(function () {
chart.load({
columns: [
['date', '20140101', '20140201', '20140301', '20140401', '20140501', '20140601'],
['sample', 500, 630, 690, 440, 630, 900],
['sample2', 400, 600, 460, 200, 350, 450]
]
});
}, 2000);
*/
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var rows = [["x","Views","GMV"]];
rows = rows.concat([[1398709800000,780,136],
[1398450600000,812,134],
[1399401000000,784,154],
[1399228200000,786,135],
[1399573800000,802,131],
[1399487400000,773,166],
[1399314600000,787,146],
[1399919400000,1496,309],
[1399833000000,767,138],
[1399746600000,797,141],
[1399660200000,796,146],
[1398623400000,779,143],
[1399055400000,794,140],
[1398969000000,791,140],
[1398882600000,825,107],
[1399141800000,786,136],
[1398537000000,773,143],
[1398796200000,783,154],
[1400005800000,1754,284]].sort(function (a, b) {
return a[0] - b[0];
}));
var chart = c3.generate({
bindto: '#chart',
data: {
x : 'x',
rows: rows
},
axis : {
x : {
type : 'timeseries',
tick : {
format : "%Y-%m-%d" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format
}
}
}
});
</script>
</body>
</html>
......@@ -6,18 +6,21 @@
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['sample', 30, 200, 100, 400, 150, 250, 150, 200, 170, 240, 350, 150, 100, 400, 150, 250, 150, 200, 170, 240, 100, 150, 250, 150, 200, 170, 240, 30, 200, 100, 400, 150, 250, 150, 200, 170, 240, 350, 150, 100, 400, 350, 220, 250, 300, 270, 140, 150, 90, 150, 50, 120, 70, 40]
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
]
},
zoom: {
enabled: true
tooltip: {
grouped: false
}
});
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<button onclick="load()">Load</button>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
columns: [
generateData(100)
],
},
zoom: { enabled: true },
subchart: { show: true }
});
function load() {
chart.load({
columns: [
generateData(Math.random() * 1000)
],
});
}
function generateData(n) {
var column = ['sample'];
for (var i = 0; i < n; i++) {
column.push(Math.random() * 500);
}
return column;
}
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<button onclick="load()">Load</button>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
columns: [
generateData(100)
],
},
axis: {
x: {
type: 'category'
}
},
zoom: { enabled: true },
subchart: { show: true }
});
function load() {
chart.load({
columns: [
generateData(Math.random() * 1000)
],
});
}
function generateData(n) {
var column = ['sample'];
for (var i = 0; i < n; i++) {
column.push(Math.random() * 500);
}
return column;
}
</script>
</body>
</html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart1 = c3.generate({
bindto: '#chart1',
data: {
x : 'x',
columns: [
['x', '2013-01-01', '2013-02-01', '2013-03-01', '2013-04-01', '2013-05-01'],
['sample', 30, 200, 100, 400, 150],
['sample2', 130, 300, 200, 450, 250]
]
},
axis : {
x : {
type : 'timeseries',
tick : {
format : "%Y-%m-%d"
}
}
},
zoom: {
enabled: true,
onzoom: function (domain) {
console.log(this, domain);
}
}
});
var chart2 = c3.generate({
bindto: '#chart2',
data: {
columns: [
['sample', 30, 200, 100, 400, 150],
['sample2', 130, 300, 200, 450, 250]
]
},
zoom: {
enabled: true,
onzoom: function (domain) {
console.log(this, domain);
}
}
});
</script>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>c3ext</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="/images/logo_128.ico" />
<link href="/css/c3.css" rel="stylesheet" />
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="https://rawgithub.com/brandonaaron/jquery-mousewheel/master/jquery.mousewheel.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script src="/js/extensions/c3ext.js"></script>
<script src="/js/samples/zoom_reduction.js"></script>
</head>
<body onload="main()">
<div class="container-fluid">
<h1>C3 DataSet Reduction by Zoom Level</h1>
<h2>Hackathon May 2014</h2>
<h4>By Dan-el Khen</h4>
<p>Rendering graphs in the browser has many advantages, the downside is that takes a long time to render when having large datasets. </p>
<p>This feature allows you reduces the dataset according to your current zoom level.
It allows the developer to implement the reduction algorithm in a simple function that accepts an array of values, and returns a reduced single value.
The default reducer will take the first item, but avg/sum/first/last or any other algorithm is simple to implement.
</p>
<h3>Example</h3>
<p>
In the following example, we'll render 10K data points, each time we'll reduce those to about 100 items (depending on available size on your screen),
when zooming in, the resolution of the data will be better and more accurate. This would help in showing the big picture, even when the amount of data is bigger than the numbers of pixels on the screen.
</p>
<p>Click on the buttons or scroll with your mouse wheel inside the graph to zoom and/or pan.</p>
<pre id="status"></pre>
<div>
<button onclick="chart.zoom2.zoomIn()">zoomIn</button>
<button onclick="chart.zoom2.zoomOut()">zoomOut</button>
<button onclick="chart.zoom2.panLeft()">panLeft</button>
<button onclick="chart.zoom2.panRight()">panRight</button>
<button onclick="chart.zoom2.enhance()">enhance</button>
<button onclick="chart.zoom2.dehance()">dehance</button>
<button onclick="chart.zoom2.reset()">reset</button>
</div>
<div id="divChart" style="height:300px"></div>
<h3>Notes</h3>
<p>Only 'columns' data format is supported for now.</p>
</div>
</body>
</html>
{
"name": "c3",
"version": "0.1.31",
"version": "0.3.0",
"description": "D3-based reusable chart library",
"main": "c3.js",
"scripts": {
......@@ -21,9 +21,11 @@
"readmeFilename": "README.md",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.7.1",
"grunt-contrib-concat": "~0.5.0",
"grunt-contrib-jasmine": "~0.5.2",
"load-grunt-tasks": "~0.2.0",
"grunt-contrib-uglify": "~0.4.0"
"grunt-contrib-jshint": "~0.7.1",
"grunt-contrib-uglify": "~0.4.0",
"grunt-contrib-watch": "^0.6.1",
"load-grunt-tasks": "~0.2.0"
}
}
c3_chart_fn.axis = function () {};
c3_chart_fn.axis.labels = function (labels) {
var $$ = this.internal;
if (arguments.length) {
Object.keys(labels).forEach(function (axisId) {
$$.setAxisLabelText(axisId, labels[axisId]);
});
$$.updateAxisLabels();
}
// 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});
}
};
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});
}
};
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); }
}
};
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;
};
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;
$$.data.targets = undefined;
$$.data.xs = {};
$$.selectChart.classed('c3', false).html("");
window.onresize = null;
};
// TODO: fix
c3_chart_fn.color = function (id) {
var $$ = this.internal;
return $$.color(id); // more patterns
};
c3_chart_fn.data = function () {};
c3_chart_fn.data.get = function (targetId) {
var target = this.data.getAsTarget(targetId);
return isDefined(target) ? target.values.map(function (d) { return d.value; }) : undefined;
};
c3_chart_fn.data.getAsTarget = function (targetId) {
var targets = this.data.targets.filter(function (t) { return t.id === targetId; });
return targets.length > 0 ? targets[0] : undefined;
};
c3_chart_fn.data.names = function (names) {
var $$ = this.internal, config = $$.config;
if (!arguments.length) { return config.data_names; }
Object.keys(names).forEach(function (id) {
config.data_names[id] = names[id];
});
$$.redraw({withLegend: true});
return config.data_names;
};
c3_chart_fn.data.colors = function (colors) {
var $$ = this.internal, config = $$.config;
if (!arguments.length) { return config.data_colors; }
Object.keys(colors).forEach(function (id) {
config.data_colors[id] = colors[id];
});
$$.redraw({withLegend: true});
return config.data_colors;
};
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, 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, 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,
});
};
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([]);
// 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.x === 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)';
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($$));
$$.updateEventRect();
// callback for end of flow
done();
});
};
};
c3_chart_fn.focus = function (targetId) {
var $$ = this.internal,
candidates = $$.svg.selectAll($$.selectorTarget(targetId)),
candidatesForNoneArc = candidates.filter($$.isNoneArc.bind($$)),
candidatesForArc = candidates.filter($$.isArc.bind($$));
function focus(targets) {
$$.filterTargetsToShow(targets).transition().duration(100).style('opacity', 1);
}
this.revert();
this.defocus();
focus(candidatesForNoneArc.classed(CLASS.focused, true));
focus(candidatesForArc);
if ($$.hasArcType()) {
$$.expandArc(targetId, true);
}
$$.toggleFocusLegend(targetId, true);
};
c3_chart_fn.defocus = function (targetId) {
var $$ = this.internal,
candidates = $$.svg.selectAll($$.selectorTarget(targetId)),
candidatesForNoneArc = candidates.filter($$.isNoneArc.bind($$)),
candidatesForArc = candidates.filter($$.isArc.bind($$));
function defocus(targets) {
$$.filterTargetsToShow(targets).transition().duration(100).style('opacity', 0.3);
}
this.revert();
defocus(candidatesForNoneArc.classed(CLASS.focused, false));
defocus(candidatesForArc);
if ($$.hasArcType()) {
$$.unexpandArc(targetId);
}
$$.toggleFocusLegend(targetId, false);
};
c3_chart_fn.revert = function (targetId) {
var $$ = this.internal,
candidates = $$.svg.selectAll($$.selectorTarget(targetId)),
candidatesForNoneArc = candidates.filter($$.isNoneArc.bind($$)),
candidatesForArc = candidates.filter($$.isArc.bind($$));
function revert(targets) {
$$.filterTargetsToShow(targets).transition().duration(100).style('opacity', 1);
}
revert(candidatesForNoneArc.classed(CLASS.focused, false));
revert(candidatesForArc);
if ($$.hasArcType()) {
$$.unexpandArc(targetId);
}
$$.revertLegend();
};
c3_chart_fn.xgrids = function (grids) {
var $$ = this.internal, config = $$.config;
if (! grids) { return config.grid_x_lines; }
config.grid_x_lines = grids;
$$.redraw();
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;
$$.redraw();
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.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.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.load = function (args) {
var $$ = this.internal, config = $$.config;
// update xs if specified
if (args.xs) {
$$.addXs(args.xs);
}
// 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;
}
// 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 || {};
$$.unload($$.mapToTargetIds(args.ids), function () {
$$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true});
if (args.done) { args.done(); }
});
};
c3_chart_fn.regions = function (regions) {
var $$ = this.internal, config = $$.config;
if (!regions) { return config.regions; }
config.regions = regions;
$$.redraw();
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);
$$.redraw();
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.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).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).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.show = function (targetIds, options) {
var $$ = this.internal;
targetIds = $$.mapToTargetIds(targetIds);
options = options || {};
$$.removeHiddenTargetIds(targetIds);
$$.svg.selectAll($$.selectorTargets(targetIds))
.transition()
.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;
targetIds = $$.mapToTargetIds(targetIds);
options = options || {};
$$.addHiddenTargetIds(targetIds);
$$.svg.selectAll($$.selectorTargets(targetIds))
.transition()
.style('opacity', 0);
if (options.withLegend) {
$$.hideLegend(targetIds);
}
$$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true});
};
c3_chart_fn.toggle = function (targetId) {
var $$ = this.internal;
$$.isTargetToShow(targetId) ? this.hide(targetId) : this.show(targetId);
};
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 (args.x) {
index = $$.getIndexByX(args.x);
}
else if (args.index) {
index = args.index;
}
// emulate mouse events to show
$$.dispatchEvent('mouseover', index, mouse);
$$.dispatchEvent('mousemove', index, mouse);
};
c3_chart_fn.tooltip.hide = function () {
// TODO: get target data by checking the state of focus
this.internal.dispatchEvent('mouseout', 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);
$$.updateAndRedraw(options);
};
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.zoom = function () {
};
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_internal_fn.initPie = function () {
var $$ = this, d3 = $$.d3, config = $$.config;
$$.pie = d3.layout.pie().value(function (d) {
return d.values.reduce(function (a, b) { return a + b.value; }, 0);
});
if (!config.data_order || !config.pie_sort || !config.donut_sort) {
$$.pie.sort(null);
}
};
c3_chart_internal_fn.updateRadius = function () {
var $$ = this, config = $$.config,
w = config.gauge_width || config.donut_width;
$$.radiusExpanded = Math.min($$.arcWidth, $$.arcHeight) / 2;
$$.radius = $$.radiusExpanded * 0.95;
$$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6;
$$.innerRadius = $$.hasType('donut') || $$.hasType('gauge') ? $$.radius * $$.innerRadiusRatio : 0;
};
c3_chart_internal_fn.updateArc = function () {
var $$ = this;
$$.svgArc = $$.getSvgArc();
$$.svgArcExpanded = $$.getSvgArcExpanded();
$$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98);
};
c3_chart_internal_fn.updateAngle = function (d) {
var $$ = this, config = $$.config,
found = false, index = 0;
$$.pie($$.filterTargetsToShow($$.data.targets)).sort($$.descByStartAngle).forEach(function (t) {
if (! found && t.data.id === d.data.id) {
found = true;
d = t;
d.index = index;
}
index++;
});
if (isNaN(d.endAngle)) {
d.endAngle = d.startAngle;
}
if ($$.isGaugeType(d.data)) {
var gMin = config.gauge_min, gMax = config.gauge_max,
gF = Math.abs(gMin) + gMax,
aTic = (Math.PI) / gF;
d.startAngle = (-1 * (Math.PI / 2)) + (aTic * Math.abs(gMin));
d.endAngle = d.startAngle + (aTic * ((d.value > gMax) ? gMax : d.value));
}
return found ? d : null;
};
c3_chart_internal_fn.getSvgArc = function () {
var $$ = this,
arc = $$.d3.svg.arc().outerRadius($$.radius).innerRadius($$.innerRadius),
newArc = function (d, withoutUpdate) {
var updated;
if (withoutUpdate) { return arc(d); } // for interpolate
updated = $$.updateAngle(d);
return updated ? arc(updated) : "M 0 0";
};
// TODO: extends all function
newArc.centroid = arc.centroid;
return newArc;
};
c3_chart_internal_fn.getSvgArcExpanded = function (rate) {
var $$ = this,
arc = $$.d3.svg.arc().outerRadius($$.radiusExpanded * (rate ? rate : 1)).innerRadius($$.innerRadius);
return function (d) {
var updated = $$.updateAngle(d);
return updated ? arc(updated) : "M 0 0";
};
};
c3_chart_internal_fn.getArc = function (d, withoutUpdate, force) {
return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : "M 0 0";
};
c3_chart_internal_fn.transformForArcLabel = function (d) {
var $$ = this,
updated = $$.updateAngle(d), c, x, y, h, ratio, translate = "";
if (updated && !$$.hasType('gauge')) {
c = this.svgArc.centroid(updated);
x = isNaN(c[0]) ? 0 : c[0];
y = isNaN(c[1]) ? 0 : c[1];
h = Math.sqrt(x * x + y * y);
// TODO: ratio should be an option?
ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0;
translate = "translate(" + (x * ratio) + ',' + (y * ratio) + ")";
}
return translate;
};
c3_chart_internal_fn.getArcRatio = function (d) {
var $$ = this,
whole = $$.hasType('gauge') ? Math.PI : (Math.PI * 2);
return d ? (d.endAngle - d.startAngle) / whole : null;
};
c3_chart_internal_fn.convertToArcData = function (d) {
return this.addName({
id: d.data.id,
value: d.value,
ratio: this.getArcRatio(d),
index: d.index
});
};
c3_chart_internal_fn.textForArcLabel = function (d) {
var $$ = this,
updated, value, ratio, format;
if (! $$.shouldShowArcLabel()) { return ""; }
updated = $$.updateAngle(d);
value = updated ? updated.value : null;
ratio = $$.getArcRatio(updated);
if (! $$.hasType('gauge') && ! $$.meetsArcLabelThreshold(ratio)) { return ""; }
format = $$.getArcLabelFormat();
return format ? format(value, ratio) : $$.defaultArcValueFormat(value, ratio);
};
c3_chart_internal_fn.expandArc = function (id, withoutFadeOut) {
var $$ = this,
target = $$.svg.selectAll('.' + CLASS.chartArc + $$.selectorTarget(id)),
noneTargets = $$.svg.selectAll('.' + CLASS.arc).filter(function (data) { return data.data.id !== id; });
if ($$.shouldExpand(id)) {
target.selectAll('path')
.transition().duration(50)
.attr("d", $$.svgArcExpanded)
.transition().duration(100)
.attr("d", $$.svgArcExpandedSub)
.each(function (d) {
if ($$.isDonutType(d.data)) {
// callback here
}
});
}
if (!withoutFadeOut) {
noneTargets.style("opacity", 0.3);
}
};
c3_chart_internal_fn.unexpandArc = function (id) {
var $$ = this,
target = $$.svg.selectAll('.' + CLASS.chartArc + $$.selectorTarget(id));
target.selectAll('path.' + CLASS.arc)
.transition().duration(50)
.attr("d", $$.svgArc);
$$.svg.selectAll('.' + CLASS.arc)
.style("opacity", 1);
};
c3_chart_internal_fn.shouldExpand = function (id) {
var $$ = this, config = $$.config;
return ($$.isDonutType(id) && config.donut_expand) || ($$.isGaugeType(id) && config.gauge_expand) || ($$.isPieType(id) && config.pie_expand);
};
c3_chart_internal_fn.shouldShowArcLabel = function () {
var $$ = this, config = $$.config, shouldShow = true;
if ($$.hasType('donut')) {
shouldShow = config.donut_label_show;
} else if ($$.hasType('pie')) {
shouldShow = config.pie_label_show;
}
// when gauge, always true
return shouldShow;
};
c3_chart_internal_fn.meetsArcLabelThreshold = function (ratio) {
var $$ = this, config = $$.config,
threshold = $$.hasType('donut') ? config.donut_label_threshold : config.pie_label_threshold;
return ratio >= threshold;
};
c3_chart_internal_fn.getArcLabelFormat = function () {
var $$ = this, config = $$.config,
format = config.pie_label_format;
if ($$.hasType('gauge')) {
format = config.gauge_label_format;
} else if ($$.hasType('donut')) {
format = config.donut_label_format;
}
return format;
};
c3_chart_internal_fn.getArcTitle = function () {
var $$ = this;
return $$.hasType('donut') ? $$.config.donut_title : "";
};
c3_chart_internal_fn.descByStartAngle = function (a, b) {
return a.startAngle - b.startAngle;
};
c3_chart_internal_fn.updateTargetsForArc = function (targets) {
var $$ = this, main = $$.main,
mainPieUpdate, mainPieEnter,
classChartArc = $$.classChartArc.bind($$),
classArcs = $$.classArcs.bind($$);
mainPieUpdate = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc)
.data($$.pie(targets))
.attr("class", classChartArc);
mainPieEnter = mainPieUpdate.enter().append("g")
.attr("class", classChartArc);
mainPieEnter.append('g')
.attr('class', classArcs);
mainPieEnter.append("text")
.attr("dy", $$.hasType('gauge') ? "-0.35em" : ".35em")
.style("opacity", 0)
.style("text-anchor", "middle")
.style("pointer-events", "none");
// MEMO: can not keep same color..., but not bad to update color in redraw
//mainPieUpdate.exit().remove();
};
c3_chart_internal_fn.initArc = function () {
var $$ = this;
$$.arcs = $$.main.select('.' + CLASS.chart).append("g")
.attr("class", CLASS.chartArcs)
.attr("transform", $$.getTranslate('arc'));
$$.arcs.append('text')
.attr('class', CLASS.chartArcsTitle)
.style("text-anchor", "middle")
.text($$.getArcTitle());
};
c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransform) {
var $$ = this, d3 = $$.d3, config = $$.config, main = $$.main,
mainArc;
mainArc = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc)
.data($$.arcData.bind($$));
mainArc.enter().append('path')
.attr("class", $$.classArc.bind($$))
.style("fill", function (d) { return $$.color(d.data); })
.style("cursor", function (d) { return config.data_selection_isselectable(d) ? "pointer" : null; })
.style("opacity", 0)
.each(function (d) {
if ($$.isGaugeType(d.data)) {
d.startAngle = d.endAngle = -1 * (Math.PI / 2);
}
this._current = d;
})
.on('mouseover', function (d) {
var updated, arcData;
if ($$.transiting) { // skip while transiting
return;
}
updated = $$.updateAngle(d);
arcData = $$.convertToArcData(updated);
// transitions
$$.expandArc(updated.data.id);
$$.toggleFocusLegend(updated.data.id, true);
$$.config.data_onmouseover(arcData, this);
})
.on('mousemove', function (d) {
var updated = $$.updateAngle(d),
arcData = $$.convertToArcData(updated),
selectedData = [arcData];
$$.showTooltip(selectedData, d3.mouse(this));
})
.on('mouseout', function (d) {
var updated, arcData;
if ($$.transiting) { // skip while transiting
return;
}
updated = $$.updateAngle(d);
arcData = $$.convertToArcData(updated);
// transitions
$$.unexpandArc(updated.data.id);
$$.revertLegend();
$$.hideTooltip();
$$.config.data_onmouseout(arcData, this);
})
.on('click', function (d, i) {
var updated, arcData;
if (!$$.toggleShape) {
return;
}
updated = $$.updateAngle(d);
arcData = $$.convertToArcData(updated);
$$.toggleShape(this, arcData, i); // onclick called in toogleShape()
});
mainArc
.attr("transform", function (d) { return !$$.isGaugeType(d.data) && withTransform ? "scale(0)" : ""; })
.style("opacity", function (d) { return d === this._current ? 0 : 1; })
.each(function () { $$.transiting = true; })
.transition().duration(duration)
.attrTween("d", function (d) {
var updated = $$.updateAngle(d), interpolate;
if (! updated) {
return function () { return "M 0 0"; };
}
// if (this._current === d) {
// this._current = {
// startAngle: Math.PI*2,
// endAngle: Math.PI*2,
// };
// }
if (isNaN(this._current.endAngle)) {
this._current.endAngle = this._current.startAngle;
}
interpolate = d3.interpolate(this._current, updated);
this._current = interpolate(0);
return function (t) { return $$.getArc(interpolate(t), true); };
})
.attr("transform", withTransform ? "scale(1)" : "")
.style("fill", function (d) {
return $$.levelColor ? $$.levelColor(d.data.values[0].value) : $$.color(d.data.id);
}) // Where gauge reading color would receive customization.
.style("opacity", 1)
.call($$.endall, function () {
$$.transiting = false;
});
mainArc.exit().transition().duration(durationForExit)
.style('opacity', 0)
.remove();
main.selectAll('.' + CLASS.chartArc).select('text')
.style("opacity", 0)
.attr('class', function (d) { return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''; })
.text($$.textForArcLabel.bind($$))
.attr("transform", $$.transformForArcLabel.bind($$))
.transition().duration(duration)
.style("opacity", function (d) { return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0; });
main.select('.' + CLASS.chartArcsTitle)
.style("opacity", $$.hasType('donut') || $$.hasType('gauge') ? 1 : 0);
};
c3_chart_internal_fn.initGauge = function () {
var $$ = this, config = $$.config, arcs = $$.arcs;
if ($$.hasType('gauge')) {
arcs.append('path')
.attr("class", CLASS.chartArcsBackground)
.attr("d", function () {
var d = {
data: [{value: config.gauge_max}],
startAngle: -1 * (Math.PI / 2),
endAngle: Math.PI / 2
};
return $$.getArc(d, true, true);
});
arcs.append("text")
.attr("dy", ".75em")
.attr("class", CLASS.chartArcsGaugeUnit)
.style("text-anchor", "middle")
.style("pointer-events", "none")
.text(config.gauge_label_show ? config.gauge_units : '');
arcs.append("text")
.attr("dx", -1 * ($$.innerRadius + (($$.radius - $$.innerRadius) / 2)) + "px")
.attr("dy", "1.2em")
.attr("class", CLASS.chartArcsGaugeMin)
.style("text-anchor", "middle")
.style("pointer-events", "none")
.text(config.gauge_label_show ? config.gauge_min : '');
arcs.append("text")
.attr("dx", $$.innerRadius + (($$.radius - $$.innerRadius) / 2) + "px")
.attr("dy", "1.2em")
.attr("class", CLASS.chartArcsGaugeMax)
.style("text-anchor", "middle")
.style("pointer-events", "none")
.text(config.gauge_label_show ? config.gauge_max : '');
}
};
c3_chart_internal_fn.getGaugeLabelHeight = function () {
return this.config.gauge_label_show ? 20 : 0;
};
c3_chart_internal_fn.initAxis = function () {
var $$ = this, 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", $$.textAnchorForXAxisLabel.bind($$));
$$.axes.y = main.append("g")
.attr("class", CLASS.axis + ' ' + CLASS.axisY)
.attr("clip-path", $$.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", $$.textAnchorForYAxisLabel.bind($$));
$$.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", $$.textAnchorForY2AxisLabel.bind($$));
};
c3_chart_internal_fn.getXAxis = function (scale, orient, tickFormat, tickValues) {
var $$ = this, config = $$.config,
axis = c3_axis($$.d3, $$.isCategorized()).scale(scale).orient(orient);
if ($$.isTimeSeries() && tickValues) {
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;
}
} else {
// TODO: move this to c3_axis
axis.tickOffset = function () {
var edgeX = $$.getEdgeX($$.data.targets), diff = $$.x(edgeX[1]) - $$.x(edgeX[0]),
base = diff ? diff : (config.axis_rotated ? $$.height : $$.width);
return (base / $$.getMaxDataCount()) / 2;
};
}
return axis;
};
c3_chart_internal_fn.getYAxis = function (scale, orient, tickFormat, ticks) {
return c3_axis(this.d3).scale(scale).orient(orient).tickFormat(tickFormat).ticks(ticks);
};
c3_chart_internal_fn.getAxisId = function (id) {
var config = this.config;
return id in config.data_axes ? config.data_axes[id] : 'y';
};
c3_chart_internal_fn.getXAxisTickFormat = function () {
var $$ = this, 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;
};
c3_chart_internal_fn.getAxisLabelOptionByAxisId = function (axisId) {
var $$ = this, 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;
};
c3_chart_internal_fn.getAxisLabelText = function (axisId) {
var option = this.getAxisLabelOptionByAxisId(axisId);
return isString(option) ? option : option ? option.text : null;
};
c3_chart_internal_fn.setAxisLabelText = function (axisId, text) {
var $$ = this, config = $$.config,
option = $$.getAxisLabelOptionByAxisId(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;
}
};
c3_chart_internal_fn.getAxisLabelPosition = function (axisId, defaultPosition) {
var option = this.getAxisLabelOptionByAxisId(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
};
};
c3_chart_internal_fn.getXAxisLabelPosition = function () {
return this.getAxisLabelPosition('x', this.config.axis_rotated ? 'inner-top' : 'inner-right');
};
c3_chart_internal_fn.getYAxisLabelPosition = function () {
return this.getAxisLabelPosition('y', this.config.axis_rotated ? 'inner-right' : 'inner-top');
};
c3_chart_internal_fn.getY2AxisLabelPosition = function () {
return this.getAxisLabelPosition('y2', this.config.axis_rotated ? 'inner-right' : 'inner-top');
};
c3_chart_internal_fn.getAxisLabelPositionById = function (id) {
return id === 'y2' ? this.getY2AxisLabelPosition() : id === 'y' ? this.getYAxisLabelPosition() : this.getXAxisLabelPosition();
};
c3_chart_internal_fn.textForXAxisLabel = function () {
return this.getAxisLabelText('x');
};
c3_chart_internal_fn.textForYAxisLabel = function () {
return this.getAxisLabelText('y');
};
c3_chart_internal_fn.textForY2AxisLabel = function () {
return this.getAxisLabelText('y2');
};
c3_chart_internal_fn.xForAxisLabel = function (forHorizontal, position) {
var $$ = this;
if (forHorizontal) {
return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width;
} else {
return position.isBottom ? -$$.height : position.isMiddle ? -$$.height / 2 : 0;
}
};
c3_chart_internal_fn.dxForAxisLabel = function (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";
}
};
c3_chart_internal_fn.textAnchorForAxisLabel = function (forHorizontal, position) {
if (forHorizontal) {
return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end';
} else {
return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end';
}
};
c3_chart_internal_fn.xForXAxisLabel = function () {
return this.xForAxisLabel(!this.config.axis_rotated, this.getXAxisLabelPosition());
};
c3_chart_internal_fn.xForYAxisLabel = function () {
return this.xForAxisLabel(this.config.axis_rotated, this.getYAxisLabelPosition());
};
c3_chart_internal_fn.xForY2AxisLabel = function () {
return this.xForAxisLabel(this.config.axis_rotated, this.getY2AxisLabelPosition());
};
c3_chart_internal_fn.dxForXAxisLabel = function () {
return this.dxForAxisLabel(!this.config.axis_rotated, this.getXAxisLabelPosition());
};
c3_chart_internal_fn.dxForYAxisLabel = function () {
return this.dxForAxisLabel(this.config.axis_rotated, this.getYAxisLabelPosition());
};
c3_chart_internal_fn.dxForY2AxisLabel = function () {
return this.dxForAxisLabel(this.config.axis_rotated, this.getY2AxisLabelPosition());
};
c3_chart_internal_fn.dyForXAxisLabel = function () {
var $$ = this, config = $$.config,
position = $$.getXAxisLabelPosition();
if (config.axis_rotated) {
return position.isInner ? "1.2em" : -25 - $$.getMaxTickWidth('x');
} else {
return position.isInner ? "-0.5em" : config.axis_x_height ? config.axis_x_height - 10 : "3em";
}
};
c3_chart_internal_fn.dyForYAxisLabel = function () {
var $$ = this,
position = $$.getYAxisLabelPosition();
if ($$.config.axis_rotated) {
return position.isInner ? "-0.5em" : "3em";
} else {
return position.isInner ? "1.2em" : -20 - $$.getMaxTickWidth('y');
}
};
c3_chart_internal_fn.dyForY2AxisLabel = function () {
var $$ = this,
position = $$.getY2AxisLabelPosition();
if ($$.config.axis_rotated) {
return position.isInner ? "1.2em" : "-2.2em";
} else {
return position.isInner ? "-0.5em" : 30 + this.getMaxTickWidth('y2');
}
};
c3_chart_internal_fn.textAnchorForXAxisLabel = function () {
var $$ = this;
return $$.textAnchorForAxisLabel(!$$.config.axis_rotated, $$.getXAxisLabelPosition());
};
c3_chart_internal_fn.textAnchorForYAxisLabel = function () {
var $$ = this;
return $$.textAnchorForAxisLabel($$.config.axis_rotated, $$.getYAxisLabelPosition());
};
c3_chart_internal_fn.textAnchorForY2AxisLabel = function () {
var $$ = this;
return $$.textAnchorForAxisLabel($$.config.axis_rotated, $$.getY2AxisLabelPosition());
};
c3_chart_internal_fn.xForRotatedTickText = function (r) {
return 10 * Math.sin(Math.PI * (r / 180));
};
c3_chart_internal_fn.yForRotatedTickText = function (r) {
return 11.5 - 2.5 * (r / 15);
};
c3_chart_internal_fn.rotateTickText = function (axis, transition, rotate) {
axis.selectAll('.tick text')
.style("text-anchor", "start");
transition.selectAll('.tick text')
.attr("y", this.yForRotatedTickText(rotate))
.attr("x", this.xForRotatedTickText(rotate))
.attr("transform", "rotate(" + rotate + ")");
};
c3_chart_internal_fn.getMaxTickWidth = function (id) {
var $$ = this, config = $$.config,
maxWidth = 0, targetsToShow, scale, axis;
if ($$.svg) {
targetsToShow = $$.filterTargetsToShow($$.data.targets);
if (id === 'y') {
scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));
axis = $$.getYAxis(scale, $$.yOrient, config.axis_y_tick_format, config.axis_y_ticks);
} else if (id === 'y2') {
scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));
axis = $$.getYAxis(scale, $$.y2Orient, config.axis_y2_tick_format, config.axis_y2_ticks);
} else {
scale = $$.x.copy().domain($$.getXDomain(targetsToShow));
axis = $$.getXAxis(scale, $$.xOrient, $$.getXAxisTickFormat(), config.axis_x_tick_values ? config.axis_x_tick_values : $$.xAxis.tickValues());
}
$$.d3.select('body').append("g").style('visibility', 'hidden').call(axis).each(function () {
$$.d3.select(this).selectAll('text').each(function () {
var box = this.getBoundingClientRect();
if (maxWidth < box.width) { maxWidth = box.width; }
});
}).remove();
}
$$.currentMaxTickWidth = maxWidth <= 0 ? $$.currentMaxTickWidth : maxWidth;
return $$.currentMaxTickWidth;
};
c3_chart_internal_fn.updateAxisLabels = function (withTransition) {
var $$ = this;
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", $$.xForXAxisLabel.bind($$))
.attr("dx", $$.dxForXAxisLabel.bind($$))
.attr("dy", $$.dyForXAxisLabel.bind($$))
.text($$.textForXAxisLabel.bind($$));
(withTransition ? axisYLabel.transition() : axisYLabel)
.attr("x", $$.xForYAxisLabel.bind($$))
.attr("dx", $$.dxForYAxisLabel.bind($$))
.attr("dy", $$.dyForYAxisLabel.bind($$))
.text($$.textForYAxisLabel.bind($$));
(withTransition ? axisY2Label.transition() : axisY2Label)
.attr("x", $$.xForY2AxisLabel.bind($$))
.attr("dx", $$.dxForY2AxisLabel.bind($$))
.attr("dy", $$.dyForY2AxisLabel.bind($$))
.text($$.textForY2AxisLabel.bind($$));
};
c3_chart_internal_fn.getAxisPadding = function (padding, key, defaultValue, all) {
var ratio = padding.unit === 'ratio' ? all : 1;
return isValue(padding[key]) ? padding[key] * ratio : defaultValue;
};
c3_chart_internal_fn.generateTickValues = function (xs, tickCount) {
var $$ = this;
var tickValues = xs, targetCount, start, end, count, interval, i, tickValue;
if (tickCount) {
targetCount = isFunction(tickCount) ? tickCount() : tickCount;
// compute ticks according to $$.config.axis_x_tick_count
if (targetCount === 1) {
tickValues = [xs[0]];
} else if (targetCount === 2) {
tickValues = [xs[0], xs[xs.length - 1]];
} else if (targetCount > 2) {
count = targetCount - 2;
start = xs[0];
end = xs[xs.length - 1];
interval = (end - start) / (count + 1);
// re-construct uniqueXs
tickValues = [start];
for (i = 0; i < count; i++) {
tickValue = +start + interval * (i + 1);
tickValues.push($$.isTimeSeries() ? new Date(tickValue) : tickValue);
}
tickValues.push(end);
}
}
if (!$$.isTimeSeries()) { tickValues = tickValues.sort(function (a, b) { return a - b; }); }
return tickValues;
};
c3_chart_internal_fn.generateAxisTransitions = function (duration) {
var $$ = this, 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
};
};
c3_chart_internal_fn.redrawAxis = function (transitions, isHidden) {
var $$ = this;
$$.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);
};
// Features:
// 1. category axis
// 2. ceil values of translate/x/y to int for half pixel antialiasing
function c3_axis(d3, isCategory) {
var scale = d3.scale.linear(), orient = "bottom", innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickValues = null, tickFormat, tickArguments;
var tickOffset = 0, tickCulling = true, tickCentered;
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 (isCategory) {
domain = scale.domain();
newScale.domain([domain[0], domain[1] - 1]);
}
return newScale;
}
function textFormatted(v) {
return tickFormat ? tickFormat(v) : v;
}
function axis(g) {
g.each(function () {
var 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 = d3.transition(tick).style("opacity", 1),
tickTransform, tickX;
var range = scale.rangeExtent ? scale.rangeExtent() : scaleExtent(scale.range()),
path = g.selectAll(".domain").data([ 0 ]),
pathUpdate = (path.enter().append("path").attr("class", "domain"), d3.transition(path));
tickEnter.append("line");
tickEnter.append("text");
var lineEnter = tickEnter.select("line"),
lineUpdate = tickUpdate.select("line"),
text = tick.select("text").text(textFormatted),
textEnter = tickEnter.select("text"),
textUpdate = tickUpdate.select("text");
if (isCategory) {
tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);
tickX = tickCentered ? 0 : tickOffset;
} else {
tickOffset = tickX = 0;
}
function tickSize(d) {
var tickPosition = scale(d) + tickOffset;
return range[0] < tickPosition && tickPosition < range[1] ? innerTickSize : 0;
}
switch (orient) {
case "bottom":
{
tickTransform = axisX;
lineEnter.attr("y2", innerTickSize);
textEnter.attr("y", Math.max(innerTickSize, 0) + tickPadding);
lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", tickSize);
textUpdate.attr("x", 0).attr("y", Math.max(innerTickSize, 0) + tickPadding);
text.attr("dy", ".71em").style("text-anchor", "middle");
pathUpdate.attr("d", "M" + range[0] + "," + outerTickSize + "V0H" + range[1] + "V" + outerTickSize);
break;
}
case "top":
{
tickTransform = axisX;
lineEnter.attr("y2", -innerTickSize);
textEnter.attr("y", -(Math.max(innerTickSize, 0) + tickPadding));
lineUpdate.attr("x2", 0).attr("y2", -innerTickSize);
textUpdate.attr("x", 0).attr("y", -(Math.max(innerTickSize, 0) + tickPadding));
text.attr("dy", "0em").style("text-anchor", "middle");
pathUpdate.attr("d", "M" + range[0] + "," + -outerTickSize + "V0H" + range[1] + "V" + -outerTickSize);
break;
}
case "left":
{
tickTransform = axisY;
lineEnter.attr("x2", -innerTickSize);
textEnter.attr("x", -(Math.max(innerTickSize, 0) + tickPadding));
lineUpdate.attr("x2", -innerTickSize).attr("y2", 0);
textUpdate.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)).attr("y", tickOffset);
text.attr("dy", ".32em").style("text-anchor", "end");
pathUpdate.attr("d", "M" + -outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + -outerTickSize);
break;
}
case "right":
{
tickTransform = axisY;
lineEnter.attr("x2", innerTickSize);
textEnter.attr("x", Math.max(innerTickSize, 0) + tickPadding);
lineUpdate.attr("x2", innerTickSize).attr("y2", 0);
textUpdate.attr("x", Math.max(innerTickSize, 0) + tickPadding).attr("y", 0);
text.attr("dy", ".32em").style("text-anchor", "start");
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 () { // This will be overwritten when normal x axis
return tickOffset;
};
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;
}
c3_chart_internal_fn.hasCaches = function (ids) {
for (var i = 0; i < ids.length; i++) {
if (! (ids[i] in this.cache)) { return false; }
}
return true;
};
c3_chart_internal_fn.addCache = function (id, target) {
this.cache[id] = this.cloneTarget(target);
};
c3_chart_internal_fn.getCaches = function (ids) {
var targets = [], i;
for (i = 0; i < ids.length; i++) {
if (ids[i] in this.cache) { targets.push(this.cloneTarget(this.cache[ids[i]])); }
}
return targets;
};
c3_chart_internal_fn.categoryName = function (i) {
var config = this.config;
return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i;
};
var CLASS = c3_chart_internal_fn.CLASS = {
target: 'c3-target',
chart: 'c3-chart',
chartLine: 'c3-chart-line',
chartLines: 'c3-chart-lines',
chartBar: 'c3-chart-bar',
chartBars: 'c3-chart-bars',
chartText: 'c3-chart-text',
chartTexts: 'c3-chart-texts',
chartArc: 'c3-chart-arc',
chartArcs: 'c3-chart-arcs',
chartArcsTitle: 'c3-chart-arcs-title',
chartArcsBackground: 'c3-chart-arcs-background',
chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit',
chartArcsGaugeMax: 'c3-chart-arcs-gauge-max',
chartArcsGaugeMin: 'c3-chart-arcs-gauge-min',
selectedCircle: 'c3-selected-circle',
selectedCircles: 'c3-selected-circles',
eventRect: 'c3-event-rect',
eventRects: 'c3-event-rects',
eventRectsSingle: 'c3-event-rects-single',
eventRectsMultiple: 'c3-event-rects-multiple',
zoomRect: 'c3-zoom-rect',
brush: 'c3-brush',
focused: 'c3-focused',
region: 'c3-region',
regions: 'c3-regions',
tooltip: 'c3-tooltip',
tooltipName: 'c3-tooltip-name',
shape: 'c3-shape',
shapes: 'c3-shapes',
line: 'c3-line',
lines: 'c3-lines',
bar: 'c3-bar',
bars: 'c3-bars',
circle: 'c3-circle',
circles: 'c3-circles',
arc: 'c3-arc',
arcs: 'c3-arcs',
area: 'c3-area',
areas: 'c3-areas',
empty: 'c3-empty',
text: 'c3-text',
texts: 'c3-texts',
gaugeValue: 'c3-gauge-value',
grid: 'c3-grid',
gridLines: 'c3-grid-lines',
xgrid: 'c3-xgrid',
xgrids: 'c3-xgrids',
xgridLine: 'c3-xgrid-line',
xgridLines: 'c3-xgrid-lines',
xgridFocus: 'c3-xgrid-focus',
ygrid: 'c3-ygrid',
ygrids: 'c3-ygrids',
ygridLine: 'c3-ygrid-line',
ygridLines: 'c3-ygrid-lines',
axis: 'c3-axis',
axisX: 'c3-axis-x',
axisXLabel: 'c3-axis-x-label',
axisY: 'c3-axis-y',
axisYLabel: 'c3-axis-y-label',
axisY2: 'c3-axis-y2',
axisY2Label: 'c3-axis-y2-label',
legendBackground: 'c3-legend-background',
legendItem: 'c3-legend-item',
legendItemEvent: 'c3-legend-item-event',
legendItemTile: 'c3-legend-item-tile',
legendItemHidden: 'c3-legend-item-hidden',
legendItemFocused: 'c3-legend-item-focused',
dragarea: 'c3-dragarea',
EXPANDED: '_expanded_',
SELECTED: '_selected_',
INCLUDED: '_included_'
};
c3_chart_internal_fn.generateClass = function (prefix, targetId) {
return " " + prefix + " " + prefix + this.getTargetSelectorSuffix(targetId);
};
c3_chart_internal_fn.classText = function (d) {
return this.generateClass(CLASS.text, d.index);
};
c3_chart_internal_fn.classTexts = function (d) {
return this.generateClass(CLASS.texts, d.id);
};
c3_chart_internal_fn.classShape = function (d) {
return this.generateClass(CLASS.shape, d.index);
};
c3_chart_internal_fn.classShapes = function (d) {
return this.generateClass(CLASS.shapes, d.id);
};
c3_chart_internal_fn.classLine = function (d) {
return this.classShape(d) + this.generateClass(CLASS.line, d.id);
};
c3_chart_internal_fn.classLines = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.lines, d.id);
};
c3_chart_internal_fn.classCircle = function (d) {
return this.classShape(d) + this.generateClass(CLASS.circle, d.index);
};
c3_chart_internal_fn.classCircles = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.circles, d.id);
};
c3_chart_internal_fn.classBar = function (d) {
return this.classShape(d) + this.generateClass(CLASS.bar, d.index);
};
c3_chart_internal_fn.classBars = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.bars, d.id);
};
c3_chart_internal_fn.classArc = function (d) {
return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id);
};
c3_chart_internal_fn.classArcs = function (d) {
return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id);
};
c3_chart_internal_fn.classArea = function (d) {
return this.classShape(d) + this.generateClass(CLASS.area, d.id);
};
c3_chart_internal_fn.classAreas = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.areas, d.id);
};
c3_chart_internal_fn.classRegion = function (d, i) {
return this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d.class : '');
};
c3_chart_internal_fn.classEvent = function (d) {
return this.generateClass(CLASS.eventRect, d.index);
};
c3_chart_internal_fn.classTarget = function (id) {
var $$ = this;
var additionalClassSuffix = $$.config.data_classes[id], additionalClass = '';
if (additionalClassSuffix) {
additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix;
}
return $$.generateClass(CLASS.target, id) + additionalClass;
};
c3_chart_internal_fn.classChartText = function (d) {
return CLASS.chartText + this.classTarget(d.id);
};
c3_chart_internal_fn.classChartLine = function (d) {
return CLASS.chartLine + this.classTarget(d.id);
};
c3_chart_internal_fn.classChartBar = function (d) {
return CLASS.chartBar + this.classTarget(d.id);
};
c3_chart_internal_fn.classChartArc = function (d) {
return CLASS.chartArc + this.classTarget(d.data.id);
};
c3_chart_internal_fn.getTargetSelectorSuffix = function (targetId) {
return targetId || targetId === 0 ? '-' + (targetId.replace ? targetId.replace(/([^a-zA-Z0-9-_])/g, '-') : targetId) : '';
};
c3_chart_internal_fn.selectorTarget = function (id) {
return '.' + CLASS.target + this.getTargetSelectorSuffix(id);
};
c3_chart_internal_fn.selectorTargets = function (ids) {
var $$ = this;
return ids.length ? ids.map(function (id) { return $$.selectorTarget(id); }) : null;
};
c3_chart_internal_fn.selectorLegend = function (id) {
return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id);
};
c3_chart_internal_fn.selectorLegends = function (ids) {
var $$ = this;
return ids.length ? ids.map(function (id) { return $$.selectorLegend(id); }) : null;
};
c3_chart_internal_fn.getClipPath = function (id) {
var isIE9 = window.navigator.appVersion.toLowerCase().indexOf("msie 9.") >= 0;
return "url(" + (isIE9 ? "" : document.URL.split('#')[0]) + "#" + id + ")";
};
c3_chart_internal_fn.getAxisClipX = function (forHorizontal) {
// axis line width + padding for left
return forHorizontal ? -(1 + 30) : -(this.margin.left - 1);
};
c3_chart_internal_fn.getAxisClipY = function (forHorizontal) {
return forHorizontal ? -20 : -4;
};
c3_chart_internal_fn.getXAxisClipX = function () {
var $$ = this;
return $$.getAxisClipX(!$$.config.axis_rotated);
};
c3_chart_internal_fn.getXAxisClipY = function () {
var $$ = this;
return $$.getAxisClipY(!$$.config.axis_rotated);
};
c3_chart_internal_fn.getYAxisClipX = function () {
var $$ = this;
return $$.getAxisClipX($$.config.axis_rotated);
};
c3_chart_internal_fn.getYAxisClipY = function () {
var $$ = this;
return $$.getAxisClipY($$.config.axis_rotated);
};
c3_chart_internal_fn.getAxisClipWidth = function (forHorizontal) {
var $$ = this;
// width + axis line width + padding for left/right
return forHorizontal ? $$.width + 2 + 30 + 30 : $$.margin.left + 20;
};
c3_chart_internal_fn.getAxisClipHeight = function (forHorizontal) {
var $$ = this, config = $$.config;
return forHorizontal ? (config.axis_x_height ? config.axis_x_height : 0) + 80 : $$.height + 8;
};
c3_chart_internal_fn.getXAxisClipWidth = function () {
var $$ = this;
return $$.getAxisClipWidth(!$$.config.axis_rotated);
};
c3_chart_internal_fn.getXAxisClipHeight = function () {
var $$ = this;
return $$.getAxisClipHeight(!$$.config.axis_rotated);
};
c3_chart_internal_fn.getYAxisClipWidth = function () {
var $$ = this;
return $$.getAxisClipWidth($$.config.axis_rotated);
};
c3_chart_internal_fn.getYAxisClipHeight = function () {
var $$ = this;
return $$.getAxisClipHeight($$.config.axis_rotated);
};
c3_chart_internal_fn.generateColor = function () {
var $$ = this, config = $$.config, d3 = $$.d3,
colors = config.data_colors,
pattern = notEmpty(config.color_pattern) ? config.color_pattern : d3.scale.category10().range(),
callback = config.data_color,
ids = [];
return function (d) {
var id = d.id || d, color;
// if callback function is provided
if (colors[id] instanceof Function) {
color = colors[id](d);
}
// if specified, choose that color
else if (colors[id]) {
color = colors[id];
}
// if not specified, choose from pattern
else {
if (ids.indexOf(id) < 0) { ids.push(id); }
color = pattern[ids.indexOf(id) % pattern.length];
colors[id] = color;
}
return callback instanceof Function ? callback(color, d) : color;
};
};
c3_chart_internal_fn.generateLevelColor = function () {
var $$ = this, config = $$.config,
colors = config.color_pattern,
threshold = config.color_threshold,
asValue = threshold.unit === 'value',
values = threshold.values && threshold.values.length ? threshold.values : [],
max = threshold.max || 100;
return notEmpty(config.color_threshold) ? function (value) {
var i, v, color = colors[colors.length - 1];
for (i = 0; i < values.length; i++) {
v = asValue ? value : (value * 100 / max);
if (v < values[i]) {
color = colors[i];
break;
}
}
return color;
} : null;
};
c3_chart_internal_fn.getDefaultConfig = function () {
var config = {
bindto: '#chart',
size_width: undefined,
size_height: undefined,
padding_left: undefined,
padding_right: undefined,
padding_top: undefined,
padding_bottom: undefined,
zoom_enabled: false,
zoom_extent: undefined,
zoom_privileged: false,
zoom_onzoom: function () {},
interaction_enabled: true,
onmouseover: function () {},
onmouseout: function () {},
onresize: function () {},
onresized: function () {},
transition_duration: 350,
data_x: undefined,
data_xs: {},
data_xFormat: '%Y-%m-%d',
data_xLocaltime: true,
data_idConverter: function (id) { return id; },
data_names: {},
data_classes: {},
data_groups: [],
data_axes: {},
data_type: undefined,
data_types: {},
data_labels: {},
data_order: 'desc',
data_regions: {},
data_color: undefined,
data_colors: {},
data_hide: false,
data_filter: undefined,
data_selection_enabled: false,
data_selection_grouped: false,
data_selection_isselectable: function () { return true; },
data_selection_multiple: true,
data_onclick: function () {},
data_onmouseover: function () {},
data_onmouseout: function () {},
data_onselected: function () {},
data_onunselected: function () {},
data_ondragstart: function () {},
data_ondragend: function () {},
data_url: undefined,
data_json: undefined,
data_rows: undefined,
data_columns: undefined,
data_mimeType: undefined,
data_keys: undefined,
// configuration for no plot-able data supplied.
data_empty_label_text: "",
// subchart
subchart_show: false,
subchart_size_height: 60,
subchart_onbrush: function () {},
// color
color_pattern: [],
color_threshold: {},
// legend
legend_show: true,
legend_position: 'bottom',
legend_inset_anchor: 'top-left',
legend_inset_x: 10,
legend_inset_y: 0,
legend_inset_step: undefined,
legend_item_onclick: undefined,
legend_item_onmouseover: undefined,
legend_item_onmouseout: undefined,
legend_equally: false,
// axis
axis_rotated: false,
axis_x_show: true,
axis_x_type: 'indexed',
axis_x_localtime: true,
axis_x_categories: [],
axis_x_tick_centered: false,
axis_x_tick_format: undefined,
axis_x_tick_culling: {},
axis_x_tick_culling_max: 10,
axis_x_tick_count: undefined,
axis_x_tick_fit: true,
axis_x_tick_values: null,
axis_x_tick_rotate: undefined,
axis_x_tick_outer: true,
axis_x_max: undefined,
axis_x_min: undefined,
axis_x_padding: {},
axis_x_height: undefined,
axis_x_default: undefined,
axis_x_label: {},
axis_y_show: true,
axis_y_max: undefined,
axis_y_min: undefined,
axis_y_center: undefined,
axis_y_label: {},
axis_y_tick_format: undefined,
axis_y_tick_outer: true,
axis_y_padding: {},
axis_y_ticks: 10,
axis_y_default: undefined,
axis_y2_show: false,
axis_y2_max: undefined,
axis_y2_min: undefined,
axis_y2_center: undefined,
axis_y2_label: {},
axis_y2_tick_format: undefined,
axis_y2_tick_outer: true,
axis_y2_padding: {},
axis_y2_ticks: 10,
axis_y2_default: undefined,
// grid
grid_x_show: false,
grid_x_type: 'tick',
grid_x_lines: [],
grid_y_show: false,
// not used
// grid_y_type: 'tick',
grid_y_lines: [],
grid_y_ticks: 10,
grid_focus_show: true,
grid_lines_front: true,
// point - point of each data
point_show: true,
point_r: 2.5,
point_focus_expand_enabled: true,
point_focus_expand_r: undefined,
point_select_r: undefined,
line_connect_null: false,
// bar
bar_width: undefined,
bar_width_ratio: 0.6,
bar_width_max: undefined,
bar_zerobased: true,
// area
area_zerobased: true,
// pie
pie_label_show: true,
pie_label_format: undefined,
pie_label_threshold: 0.05,
pie_sort: true,
pie_expand: true,
// gauge
gauge_label_show: true,
gauge_label_format: undefined,
gauge_expand: true,
gauge_min: 0,
gauge_max: 100,
gauge_units: undefined,
gauge_width: undefined,
// donut
donut_label_show: true,
donut_label_format: undefined,
donut_label_threshold: 0.05,
donut_width: undefined,
donut_sort: true,
donut_expand: true,
donut_title: "",
// region - region to change style
regions: [],
// tooltip - show when mouseover on each data
tooltip_show: true,
tooltip_grouped: true,
tooltip_format_title: undefined,
tooltip_format_name: undefined,
tooltip_format_value: undefined,
tooltip_contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : '';
},
tooltip_init_show: false,
tooltip_init_x: 0,
tooltip_init_position: {top: '0px', left: '50px'}
};
Object.keys(this.additionalConfig).forEach(function (key) {
config[key] = this.additionalConfig[key];
}, this);
return config;
};
c3_chart_internal_fn.additionalConfig = {};
c3_chart_internal_fn.loadConfig = function (config) {
var this_config = this.config, target, keys, read;
function find() {
var key = keys.shift();
// console.log("key =>", key, ", target =>", target);
if (key && target && typeof target === 'object' && key in target) {
target = target[key];
return find();
}
else if (!key) {
return target;
}
else {
return undefined;
}
}
Object.keys(this_config).forEach(function (key) {
target = config;
keys = key.split('_');
read = find();
// console.log("CONFIG : ", key, read);
if (isDefined(read)) {
this_config[key] = read;
}
});
};
var c3 = { version: "0.3.0" };
var c3_chart_fn, c3_chart_internal_fn;
function Chart(config) {
var $$ = this.internal = new ChartInternal(this);
$$.loadConfig(config);
$$.init();
// bind "this" to nested API
(function bindThis(fn, target, argThis) {
for (var key in fn) {
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;
c3_chart_internal_fn.init = function () {
var $$ = this, config = $$.config;
$$.initParams();
if (config.data_url) {
$$.convertUrlToData(config.data_url, config.data_mimeType, config.data_keys, $$.initWithData);
}
else if (config.data_json) {
$$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));
}
else if (config.data_rows) {
$$.initWithData($$.convertRowsToData(config.data_rows));
}
else if (config.data_columns) {
$$.initWithData($$.convertColumnsToData(config.data_columns));
}
else {
throw Error('url or json or rows or columns is required.');
}
};
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',
$$.clipPath = $$.getClipPath($$.clipId),
$$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis),
$$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);
$$.dragStart = null;
$$.dragging = false;
$$.cancelClick = false;
$$.mouseover = false;
$$.transiting = false;
$$.color = $$.generateColor();
$$.levelColor = $$.generateLevelColor();
$$.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; }]
]);
$$.hiddenTargetIds = [];
$$.hiddenLegendIds = [];
$$.xOrient = config.axis_rotated ? "left" : "bottom";
$$.yOrient = config.axis_rotated ? "bottom" : "left";
$$.y2Orient = config.axis_rotated ? "top" : "right";
$$.subXOrient = config.axis_rotated ? "left" : "bottom";
$$.isLegendRight = config.legend_position === 'right';
$$.isLegendInset = config.legend_position === 'inset';
$$.isLegendTop = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'top-right';
$$.isLegendLeft = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'bottom-left';
$$.legendStep = 0;
$$.legendItemWidth = 0;
$$.legendItemHeight = 0;
$$.legendOpacityForHidden = 0.15;
$$.currentMaxTickWidth = 0;
$$.rotated_padding_left = 30;
$$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30;
$$.rotated_padding_top = 5;
$$.withoutFadeIn = {};
$$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js
};
c3_chart_internal_fn.initWithData = function (data) {
var $$ = this, d3 = $$.d3, config = $$.config;
var main, binding = true;
if ($$.initPie) { $$.initPie(); }
if ($$.initBrush) { $$.initBrush(); }
if ($$.initZoom) { $$.initZoom(); }
$$.selectChart = d3.select(config.bindto);
if ($$.selectChart.empty()) {
$$.selectChart = d3.select(document.createElement('div')).style('opacity', 0);
$$.observeInserted($$.selectChart);
binding = false;
}
$$.selectChart.html("").classed("c3", true);
// Init data as targets
$$.data.xs = {};
$$.data.targets = $$.convertDataToTargets(data);
if (config.data_filter) {
$$.data.targets = $$.data.targets.filter(config.data_filter);
}
// Set targets to hide if needed
if (config.data_hide) {
$$.addHiddenTargetIds(config.data_hide === true ? $$.mapToIds($$.data.targets) : config.data_hide);
}
// when gauge, hide legend // TODO: fix
if ($$.hasType('gauge')) {
config.legend_show = false;
}
// Init sizes and scales
$$.updateSizes();
$$.updateScales();
// Set domains for each scale
$$.x.domain(d3.extent($$.getXDomain($$.data.targets)));
$$.y.domain($$.getYDomain($$.data.targets, 'y'));
$$.y2.domain($$.getYDomain($$.data.targets, 'y2'));
$$.subX.domain($$.x.domain());
$$.subY.domain($$.y.domain());
$$.subY2.domain($$.y2.domain());
// Save original x domain for zoom update
$$.orgXDomain = $$.x.domain();
// Set initialized scales to brush and zoom
if ($$.brush) { $$.brush.scale($$.subX); }
if (config.zoom_enabled) { $$.zoom.scale($$.x); }
/*-- Basic Elements --*/
// Define svgs
$$.svg = $$.selectChart.append("svg")
.style("overflow", "hidden")
.on('mouseenter', function () { return config.onmouseover.call($$); })
.on('mouseleave', function () { return config.onmouseout.call($$); });
// Define defs
$$.defs = $$.svg.append("defs");
$$.defs.append("clipPath").attr("id", $$.clipId).append("rect");
$$.defs.append("clipPath").attr("id", $$.clipIdForXAxis).append("rect");
$$.defs.append("clipPath").attr("id", $$.clipIdForYAxis).append("rect");
$$.updateSvgSize();
// Define regions
main = $$.main = $$.svg.append("g").attr("transform", $$.getTranslate('main'));
if ($$.initSubchart) { $$.initSubchart(); }
if ($$.initTooltip) { $$.initTooltip(); }
if ($$.initLegend) { $$.initLegend(); }
/*-- Main Region --*/
// text when empty
main.append("text")
.attr("class", CLASS.text + ' ' + CLASS.empty)
.attr("text-anchor", "middle") // horizontal centering of text at x position in all browsers.
.attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE.
// Regions
$$.initRegion();
// Grids
$$.initGrid();
// Define g for chart area
main.append('g')
.attr("clip-path", $$.clipPath)
.attr('class', CLASS.chart);
// Grid lines
if (config.grid_lines_front) { $$.initGridLines(); }
// Cover whole with rects for events
$$.initEventRect();
// Define g for bar chart area
if ($$.initBar) { $$.initBar(); }
// Define g for line chart area
if ($$.initLine) { $$.initLine(); }
// Define g for arc chart area
if ($$.initArc) { $$.initArc(); }
if ($$.initGauge) { $$.initGauge(); }
// Define g for text area
if ($$.initText) { $$.initText(); }
// if zoom privileged, insert rect to forefront
// TODO: is this needed?
main.insert('rect', config.zoom_privileged ? null : 'g.' + CLASS.regions)
.attr('class', CLASS.zoomRect)
.attr('width', $$.width)
.attr('height', $$.height)
.style('opacity', 0)
.on("dblclick.zoom", null);
// Set default extent if defined
if (config.axis_x_default) {
$$.brush.extent(isFunction(config.axis_x_default) ? config.axis_x_default($$.getXDomain()) : config.axis_x_default);
}
// Add Axis
$$.initAxis();
// Set targets
$$.updateTargets($$.data.targets);
// Draw with targets
if (binding) {
$$.updateDimension();
$$.redraw({
withTransform: true,
withUpdateXDomain: true,
withUpdateOrgXDomain: true,
withTransitionForAxis: false
});
}
// Bind resize event
if (window.onresize == null) {
window.onresize = $$.generateResize();
}
if (window.onresize.add) {
window.onresize.add(function () {
config.onresize.call($$);
});
window.onresize.add(function () {
$$.api.flush();
});
window.onresize.add(function () {
config.onresized.call($$);
});
}
// export element of the chart
$$.api.element = $$.selectChart.node();
};
c3_chart_internal_fn.smoothLines = function (el, type) {
var $$ = this;
if (type === 'grid') {
el.each(function () {
var g = $$.d3.select(this),
x1 = g.attr('x1'),
x2 = g.attr('x2'),
y1 = g.attr('y1'),
y2 = g.attr('y2');
g.attr({
'x1': Math.ceil(x1),
'x2': Math.ceil(x2),
'y1': Math.ceil(y1),
'y2': Math.ceil(y2)
});
});
}
};
c3_chart_internal_fn.updateSizes = function () {
var $$ = this, config = $$.config;
var legendHeight = $$.legend ? $$.getLegendHeight() : 0,
legendWidth = $$.legend ? $$.getLegendWidth() : 0,
legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight,
hasArc = $$.hasArcType(),
xAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'),
subchartHeight = config.subchart_show && !hasArc ? (config.subchart_size_height + xAxisHeight) : 0;
$$.currentWidth = $$.getCurrentWidth();
$$.currentHeight = $$.getCurrentHeight();
// for main
$$.margin = config.axis_rotated ? {
top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),
right: hasArc ? 0 : $$.getCurrentPaddingRight(),
bottom: $$.getHorizontalAxisHeight('y') + legendHeightForBottom + $$.getCurrentPaddingBottom(),
left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())
} : {
top: 4 + $$.getCurrentPaddingTop(), // for top tick text
right: hasArc ? 0 : $$.getCurrentPaddingRight(),
bottom: xAxisHeight + subchartHeight + legendHeightForBottom + $$.getCurrentPaddingBottom(),
left: hasArc ? 0 : $$.getCurrentPaddingLeft()
};
// for subchart
$$.margin2 = config.axis_rotated ? {
top: $$.margin.top,
right: NaN,
bottom: 20 + legendHeightForBottom,
left: $$.rotated_padding_left
} : {
top: $$.currentHeight - subchartHeight - legendHeightForBottom,
right: NaN,
bottom: xAxisHeight + legendHeightForBottom,
left: $$.margin.left
};
// for legend
$$.margin3 = {
top: 0,
right: NaN,
bottom: 0,
left: 0
};
if ($$.updateSizeForLegend) { $$.updateSizeForLegend(legendHeight, legendWidth); }
$$.width = $$.currentWidth - $$.margin.left - $$.margin.right;
$$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom;
if ($$.width < 0) { $$.width = 0; }
if ($$.height < 0) { $$.height = 0; }
$$.width2 = config.axis_rotated ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right : $$.width;
$$.height2 = config.axis_rotated ? $$.height : $$.currentHeight - $$.margin2.top - $$.margin2.bottom;
if ($$.width2 < 0) { $$.width2 = 0; }
if ($$.height2 < 0) { $$.height2 = 0; }
// for arc
$$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);
$$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);
if ($$.hasType('gauge')) {
$$.arcHeight += $$.height - $$.getGaugeLabelHeight();
}
if ($$.updateRadius) { $$.updateRadius(); }
if ($$.isLegendRight && hasArc) {
$$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1;
}
};
c3_chart_internal_fn.updateTargets = function (targets) {
var $$ = this, config = $$.config;
/*-- Main --*/
//-- Text --//
$$.updateTargetsForText(targets);
//-- Bar --//
$$.updateTargetsForBar(targets);
//-- Line --//
$$.updateTargetsForLine(targets);
//-- Arc --//
if ($$.updateTargetsForArc) { $$.updateTargetsForArc(targets); }
if ($$.updateTargetsForSubchart) { $$.updateTargetsForSubchart(targets); }
/*-- Show --*/
// Fade-in each chart
$$.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);
var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, withTransform, withUpdateXDomain, withUpdateOrgXDomain, withLegend;
var hideAxis = $$.hasArcType();
var drawArea, drawBar, drawLine, xForText, yForText;
var duration, durationForExit, durationForAxis;
var waitForDraw, flow;
var targetsToShow = $$.filterTargetsToShow($$.data.targets), tickValues, i, intervalForCulling;
var xv = $$.xv.bind($$),
cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$),
cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$);
options = options || {};
withY = getOption(options, "withY", true);
withSubchart = getOption(options, "withSubchart", true);
withTransition = getOption(options, "withTransition", true);
withTransform = getOption(options, "withTransform", false);
withUpdateXDomain = getOption(options, "withUpdateXDomain", false);
withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", false);
withLegend = getOption(options, "withLegend", false);
withTransitionForExit = getOption(options, "withTransitionForExit", withTransition);
withTransitionForAxis = getOption(options, "withTransitionForAxis", withTransition);
duration = withTransition ? config.transition_duration : 0;
durationForExit = withTransitionForExit ? duration : 0;
durationForAxis = withTransitionForAxis ? duration : 0;
transitions = transitions || $$.generateAxisTransitions(durationForAxis);
// update legend and transform each g
if (withLegend && config.legend_show) {
$$.updateLegend($$.mapToIds($$.data.targets), options, transitions);
}
// MEMO: needed for grids calculation
if ($$.isCategorized() && targetsToShow.length === 0) {
$$.x.domain([0, $$.axes.x.selectAll('.tick').size()]);
}
if (targetsToShow.length) {
$$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain);
// update axis tick values according to options
if (!config.axis_x_tick_values && (config.axis_x_tick_fit || config.axis_x_tick_count)) {
tickValues = $$.generateTickValues($$.mapTargetsToUniqueXs(targetsToShow), config.axis_x_tick_count);
$$.xAxis.tickValues(tickValues);
$$.subXAxis.tickValues(tickValues);
}
} else {
$$.xAxis.tickValues([]);
$$.subXAxis.tickValues([]);
}
$$.y.domain($$.getYDomain(targetsToShow, 'y'));
$$.y2.domain($$.getYDomain(targetsToShow, 'y2'));
// axes
$$.redrawAxis(transitions, hideAxis);
// Update axis label
$$.updateAxisLabels(withTransition);
// show/hide if manual culling needed
if (withUpdateXDomain && targetsToShow.length) {
if (config.axis_x_tick_culling && tickValues) {
for (i = 1; i < tickValues.length; i++) {
if (tickValues.length / i < config.axis_x_tick_culling_max) {
intervalForCulling = i;
break;
}
}
$$.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');
}
});
} else {
$$.svg.selectAll('.' + CLASS.axisX + ' .tick text').style('display', 'block');
}
}
// rotate tick text if needed
if (!config.axis_rotated && config.axis_x_tick_rotate) {
$$.rotateTickText($$.axes.x, transitions.axisX, config.axis_x_tick_rotate);
}
// setup drawer - MEMO: these must be called after axis updated
drawArea = $$.generateDrawArea ? $$.generateDrawArea(areaIndices, false) : undefined;
drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined;
drawLine = $$.generateDrawLine ? $$.generateDrawLine(lineIndices, false) : undefined;
xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);
yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false);
// Update sub domain
$$.subY.domain($$.y.domain());
$$.subY2.domain($$.y2.domain());
// tooltip
$$.tooltip.style("display", "none");
// xgrid focus
$$.updateXgridFocus();
// Data empty label positioning and text.
main.select("text." + CLASS.text + '.' + CLASS.empty)
.attr("x", $$.width / 2)
.attr("y", $$.height / 2)
.text(config.data_empty_label_text)
.transition()
.style('opacity', targetsToShow.length ? 0 : 1);
// grid
$$.redrawGrid(duration, withY);
// rect for regions
$$.redrawRegion(duration);
// bars
$$.redrawBar(durationForExit);
// lines, areas and cricles
$$.redrawLine(durationForExit);
$$.redrawArea(durationForExit);
if (config.point_show) { $$.redrawCircle(); }
// text
if ($$.hasDataLabel()) {
$$.redrawText(durationForExit);
}
// arc
if ($$.redrawArc) { $$.redrawArc(duration, durationForExit, withTransform); }
// subchart
if ($$.redrawSubchart) {
$$.redrawSubchart(withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices);
}
// circles for select
main.selectAll('.' + CLASS.selectedCircles)
.filter($$.isBarType.bind($$))
.selectAll('circle')
.remove();
// event rect
if (config.interaction_enabled) {
$$.redrawEventRect();
}
// transition should be derived from one transition
d3.transition().duration(duration).each(function () {
var transitions = [];
$$.addTransitionForBar(transitions, drawBar);
$$.addTransitionForLine(transitions, drawLine);
$$.addTransitionForArea(transitions, drawArea);
if (config.point_show) { $$.addTransitionForCircle(transitions, cx, cy); }
$$.addTransitionForText(transitions, xForText, yForText, options.flow);
$$.addTransitionForRegion(transitions);
$$.addTransitionForGrid(transitions);
// Wait for end of transitions if called from flow API
if (options.flow) {
waitForDraw = $$.generateWait();
transitions.forEach(function (t) {
waitForDraw.add(t);
});
flow = $$.generateFlow({
targets: targetsToShow,
flow: options.flow,
duration: duration,
drawBar: drawBar,
drawLine: drawLine,
drawArea: drawArea,
cx: cx,
cy: cy,
xv: xv,
xForText: xForText,
yForText: yForText
});
}
})
.call(waitForDraw || function () {}, flow || function () {});
// update fadein condition
$$.mapToIds($$.data.targets).forEach(function (id) {
$$.withoutFadeIn[id] = true;
});
if ($$.updateZoom) { $$.updateZoom(); }
};
c3_chart_internal_fn.updateAndRedraw = function (options) {
var $$ = this, config = $$.config, transitions;
options = options || {};
// same with redraw
options.withTransition = getOption(options, "withTransition", true);
options.withTransform = getOption(options, "withTransform", false);
options.withLegend = getOption(options, "withLegend", false);
// NOT same with redraw
options.withUpdateXDomain = true;
options.withUpdateOrgXDomain = true;
options.withTransitionForExit = false;
options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition);
// MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)
$$.updateSizes();
// MEMO: called in updateLegend in redraw if withLegend
if (!(options.withLegend && config.legend_show)) {
transitions = $$.generateAxisTransitions(options.withTransitionForAxis ? config.transition_duration : 0);
// Update scales
$$.updateScales();
$$.updateSvgSize();
// Update g positions
$$.transformAll(options.withTransitionForTransform, transitions);
}
// Draw with new sizes & scales
$$.redraw(options, transitions);
};
c3_chart_internal_fn.isTimeSeries = function () {
return this.config.axis_x_type === 'timeseries';
};
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;
return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs));
};
c3_chart_internal_fn.getTranslate = function (target) {
var $$ = this, config = $$.config, x, y;
if (target === 'main') {
x = asHalfPixel($$.margin.left);
y = asHalfPixel($$.margin.top);
} else if (target === 'context') {
x = asHalfPixel($$.margin2.left);
y = asHalfPixel($$.margin2.top);
} else if (target === 'legend') {
x = $$.margin3.left;
y = $$.margin3.top;
} else if (target === 'x') {
x = 0;
y = config.axis_rotated ? 0 : $$.height;
} else if (target === 'y') {
x = 0;
y = config.axis_rotated ? $$.height : 0;
} else if (target === 'y2') {
x = config.axis_rotated ? 0 : $$.width;
y = config.axis_rotated ? 1 : 0;
} else if (target === 'subx') {
x = 0;
y = config.axis_rotated ? 0 : $$.height2;
} else if (target === 'arc') {
x = $$.arcWidth / 2;
y = $$.arcHeight / 2;
}
return "translate(" + x + "," + y + ")";
};
c3_chart_internal_fn.initialOpacity = function (d) {
return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0;
};
c3_chart_internal_fn.opacityForCircle = function (d) {
var $$ = this;
return isValue(d.value) ? $$.isScatterType(d) ? 0.5 : 1 : 0;
};
c3_chart_internal_fn.opacityForText = function () {
return this.hasDataLabel() ? 1 : 0;
};
c3_chart_internal_fn.xx = function (d) {
return d ? this.x(d.x) : null;
};
c3_chart_internal_fn.xv = function (d) {
var $$ = this;
return Math.ceil($$.x($$.isTimeSeries() ? $$.parseDate(d.value) : d.value));
};
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) {
return d ? this.subX(d.x) : null;
};
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);
if (withTransition) { xAxis = xAxis.transition(); }
}
if (transitions && transitions.axisY) {
yAxis = transitions.axisY;
} else {
yAxis = $$.main.select('.' + CLASS.axisY);
if (withTransition) { yAxis = yAxis.transition(); }
}
if (transitions && transitions.axisY2) {
y2Axis = transitions.axisY2;
} else {
y2Axis = $$.main.select('.' + CLASS.axisY2);
if (withTransition) { y2Axis = y2Axis.transition(); }
}
(withTransition ? $$.main.transition() : $$.main).attr("transform", $$.getTranslate('main'));
xAxis.attr("transform", $$.getTranslate('x'));
yAxis.attr("transform", $$.getTranslate('y'));
y2Axis.attr("transform", $$.getTranslate('y2'));
$$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc'));
};
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 () {
var $$ = this;
$$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);
$$.svg.select('#' + $$.clipId).select('rect')
.attr('width', $$.width)
.attr('height', $$.height);
$$.svg.select('#' + $$.clipIdForXAxis).select('rect')
.attr('x', $$.getXAxisClipX.bind($$))
.attr('y', $$.getXAxisClipY.bind($$))
.attr('width', $$.getXAxisClipWidth.bind($$))
.attr('height', $$.getXAxisClipHeight.bind($$));
$$.svg.select('#' + $$.clipIdForYAxis).select('rect')
.attr('x', $$.getYAxisClipX.bind($$))
.attr('y', $$.getYAxisClipY.bind($$))
.attr('width', $$.getYAxisClipWidth.bind($$))
.attr('height', $$.getYAxisClipHeight.bind($$));
$$.svg.select('.' + CLASS.zoomRect)
.attr('width', $$.width)
.attr('height', $$.height);
// MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>
$$.selectChart.style('max-height', $$.currentHeight + "px");
};
c3_chart_internal_fn.updateDimension = function () {
var $$ = this;
if ($$.config.axis_rotated) {
$$.axes.x.call($$.xAxis);
$$.axes.subx.call($$.subXAxis);
} else {
$$.axes.y.call($$.yAxis);
$$.axes.y2.call($$.y2Axis);
}
$$.updateSizes();
$$.updateScales();
$$.updateSvgSize();
$$.transformAll(false);
};
c3_chart_internal_fn.observeInserted = function (selection) {
var $$ = this, 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
var interval = window.setInterval(function () {
// parentNode will NOT be null when completed
if (selection.node().parentNode) {
window.clearInterval(interval);
$$.updateDimension();
$$.redraw({
withTransform: true,
withUpdateXDomain: true,
withUpdateOrgXDomain: true,
withTransition: false,
withTransitionForTransform: false,
withLegend: true
});
selection.transition().style('opacity', 1);
}
}, 10);
}
});
});
observer.observe(selection.node(), {attributes: true, childList: true, characterData: true});
};
c3_chart_internal_fn.generateResize = function () {
var resizeFunctions = [];
function callResizeFunctions() {
resizeFunctions.forEach(function (f) {
f();
});
}
callResizeFunctions.add = function (f) {
resizeFunctions.push(f);
};
return callResizeFunctions;
};
c3_chart_internal_fn.endall = function (transition, callback) {
var n = 0;
transition
.each(function () { ++n; })
.each("end", function () {
if (!--n) { callback.apply(this, arguments); }
});
};
c3_chart_internal_fn.generateWait = function () {
var transitionsToWait = [],
f = function (transition, callback) {
var timer = setInterval(function () {
var done = 0;
transitionsToWait.forEach(function (t) {
if (t.empty()) {
done += 1;
return;
}
try {
t.transition();
} catch (e) {
done += 1;
}
});
if (done === transitionsToWait.length) {
clearInterval(timer);
if (callback) { callback(); }
}
}, 10);
};
f.add = function (transition) {
transitionsToWait.push(transition);
};
return f;
};
c3_chart_internal_fn.parseDate = function (date) {
var $$ = this, parsedDate;
if (date instanceof Date) {
parsedDate = date;
} else if (typeof date === 'number') {
parsedDate = new Date(date);
} else {
parsedDate = $$.dataTimeFormat($$.config.data_xFormat).parse(date);
}
if (!parsedDate || isNaN(+parsedDate)) {
window.console.error("Failed to parse x '" + date + "' to Date object");
}
return parsedDate;
};
c3_chart_internal_fn.convertUrlToData = function (url, mimeType, keys, done) {
var $$ = this, type = mimeType ? mimeType : 'csv';
$$.d3.xhr(url, function (error, data) {
var d;
if (type === 'json') {
d = $$.convertJsonToData(JSON.parse(data.response), keys);
} else {
d = $$.convertCsvToData(data.response);
}
done.call($$, d);
});
};
c3_chart_internal_fn.convertCsvToData = function (csv) {
var d3 = this.d3, rows = d3.csv.parseRows(csv), d;
if (rows.length === 1) {
d = [{}];
rows[0].forEach(function (id) {
d[0][id] = null;
});
} else {
d = d3.csv.parse(csv);
}
return d;
};
c3_chart_internal_fn.convertJsonToData = function (json, keys) {
var $$ = this,
new_rows = [], targetKeys, data;
if (keys) { // when keys specified, json would be an array that includes objects
targetKeys = keys.value;
if (keys.x) {
targetKeys.push(keys.x);
$$.config.data_x = keys.x;
}
new_rows.push(targetKeys);
json.forEach(function (o) {
var new_row = [];
targetKeys.forEach(function (key) {
// convert undefined to null because undefined data will be removed in convertDataToTargets()
var v = isUndefined(o[key]) ? null : o[key];
new_row.push(v);
});
new_rows.push(new_row);
});
data = $$.convertRowsToData(new_rows);
} else {
Object.keys(json).forEach(function (key) {
new_rows.push([key].concat(json[key]));
});
data = $$.convertColumnsToData(new_rows);
}
return data;
};
c3_chart_internal_fn.convertRowsToData = function (rows) {
var keys = rows[0], new_row = {}, new_rows = [], i, j;
for (i = 1; i < rows.length; i++) {
new_row = {};
for (j = 0; j < rows[i].length; j++) {
if (isUndefined(rows[i][j])) {
throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
}
new_row[keys[j]] = rows[i][j];
}
new_rows.push(new_row);
}
return new_rows;
};
c3_chart_internal_fn.convertColumnsToData = function (columns) {
var new_rows = [], i, j, key;
for (i = 0; i < columns.length; i++) {
key = columns[i][0];
for (j = 1; j < columns[i].length; j++) {
if (isUndefined(new_rows[j - 1])) {
new_rows[j - 1] = {};
}
if (isUndefined(columns[i][j])) {
throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
}
new_rows[j - 1][key] = columns[i][j];
}
}
return new_rows;
};
c3_chart_internal_fn.convertDataToTargets = function (data, appendXs) {
var $$ = this, config = $$.config,
ids = $$.d3.keys(data[0]).filter($$.isNotX, $$),
xs = $$.d3.keys(data[0]).filter($$.isX, $$),
targets;
// save x for update data by load when custom x and c3.x API
ids.forEach(function (id) {
var xKey = $$.getXKey(id);
if ($$.isCustomX() || $$.isTimeSeries()) {
// if included in input data
if (xs.indexOf(xKey) >= 0) {
$$.data.xs[id] = (appendXs && $$.data.xs[id] ? $$.data.xs[id] : []).concat(
data.map(function (d) { return d[xKey]; })
.filter(isValue)
.map(function (rawX, i) { return $$.generateTargetX(rawX, id, i); })
);
}
// if not included in input data, find from preloaded data of other id's x
else if (config.data_x) {
$$.data.xs[id] = $$.getOtherTargetXs();
}
// if not included in input data, find from preloaded data
else if (notEmpty(config.data_xs)) {
$$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets);
}
// MEMO: if no x included, use same x of current will be used
} else {
$$.data.xs[id] = data.map(function (d, i) { return i; });
}
});
// check x is defined
ids.forEach(function (id) {
if (!$$.data.xs[id]) {
throw new Error('x is not defined for id = "' + id + '".');
}
});
// convert to target
targets = ids.map(function (id, index) {
var convertedId = config.data_idConverter(id);
return {
id: convertedId,
id_org: id,
values: data.map(function (d, i) {
var xKey = $$.getXKey(id), rawX = d[xKey], x = $$.generateTargetX(rawX, id, i);
// use x as categories if custom x and categorized
if ($$.isCustomX() && $$.isCategorized() && index === 0 && rawX) {
if (i === 0) { config.axis_x_categories = []; }
config.axis_x_categories.push(rawX);
}
// mark as x = undefined if value is undefined and filter to remove after mapped
if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {
x = undefined;
}
return {x: x, value: d[id] !== null && !isNaN(d[id]) ? +d[id] : null, id: convertedId};
}).filter(function (v) { return isDefined(v.x); })
};
});
// finish targets
targets.forEach(function (t) {
var i;
// sort values by its x
t.values = t.values.sort(function (v1, v2) {
var x1 = v1.x || v1.x === 0 ? v1.x : Infinity,
x2 = v2.x || v2.x === 0 ? v2.x : Infinity;
return x1 - x2;
});
// indexing each value
i = 0;
t.values.forEach(function (v) {
v.index = i++;
});
// this needs to be sorted because its index and value.index is identical
$$.data.xs[t.id].sort(function (v1, v2) {
return v1 - v2;
});
});
// set target types
if (config.data_type) {
$$.setTargetType($$.mapToIds(targets).filter(function (id) { return ! (id in config.data_types); }), config.data_type);
}
// cache as original id keyed
targets.forEach(function (d) {
$$.addCache(d.id_org, d);
});
return targets;
};
c3_chart_internal_fn.isX = function (key) {
var $$ = this, config = $$.config;
return (config.data_x && key === config.data_x) || (notEmpty(config.data_xs) && hasValue(config.data_xs, key));
};
c3_chart_internal_fn.isNotX = function (key) {
return !this.isX(key);
};
c3_chart_internal_fn.getXKey = function (id) {
var $$ = this, config = $$.config;
return config.data_x ? config.data_x : notEmpty(config.data_xs) ? config.data_xs[id] : null;
};
c3_chart_internal_fn.getXValuesOfXKey = function (key, targets) {
var $$ = this,
xValues, ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];
ids.forEach(function (id) {
if ($$.getXKey(id) === key) {
xValues = $$.data.xs[id];
}
});
return xValues;
};
c3_chart_internal_fn.getIndexByX = function (x) {
var $$ = this,
data = $$.filterByX($$.data.targets, x);
return data.length ? data[0].index : null;
};
c3_chart_internal_fn.getXValue = function (id, i) {
var $$ = this;
return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i;
};
c3_chart_internal_fn.getOtherTargetXs = function () {
var $$ = this,
idsForX = Object.keys($$.data.xs);
return idsForX.length ? $$.data.xs[idsForX[0]] : null;
};
c3_chart_internal_fn.getOtherTargetX = function (index) {
var xs = this.getOtherTargetXs();
return xs && index < xs.length ? xs[index] : null;
};
c3_chart_internal_fn.addXs = function (xs) {
var $$ = this;
Object.keys(xs).forEach(function (id) {
$$.config.data_xs[id] = xs[id];
});
};
c3_chart_internal_fn.hasMultipleX = function (xs) {
return this.d3.set(Object.keys(xs).map(function (id) { return xs[id]; })).size() > 1;
};
c3_chart_internal_fn.isMultipleX = function () {
var $$ = this, config = $$.config;
return notEmpty(config.data_xs) && $$.hasMultipleX(config.data_xs);
};
c3_chart_internal_fn.addName = function (data) {
var $$ = this, name;
if (data) {
name = $$.config.data_names[data.id];
data.name = name ? name : data.id;
}
return data;
};
c3_chart_internal_fn.getValueOnIndex = function (values, index) {
var valueOnIndex = values.filter(function (v) { return v.index === index; });
return valueOnIndex.length ? valueOnIndex[0] : null;
};
c3_chart_internal_fn.updateTargetX = function (targets, x) {
var $$ = this;
targets.forEach(function (t) {
t.values.forEach(function (v, i) {
v.x = $$.generateTargetX(x[i], t.id, i);
});
$$.data.xs[t.id] = x;
});
};
c3_chart_internal_fn.updateTargetXs = function (targets, xs) {
var $$ = this;
targets.forEach(function (t) {
if (xs[t.id]) {
$$.updateTargetX([t], xs[t.id]);
}
});
};
c3_chart_internal_fn.generateTargetX = function (rawX, id, index) {
var $$ = this, x;
if ($$.isTimeSeries()) {
x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index));
}
else if ($$.isCustomX() && !$$.isCategorized()) {
x = isValue(rawX) ? +rawX : $$.getXValue(id, index);
}
else {
x = index;
}
return x;
};
c3_chart_internal_fn.cloneTarget = function (target) {
return {
id : target.id,
id_org : target.id_org,
values : target.values.map(function (d) {
return {x: d.x, value: d.value, id: d.id};
})
};
};
c3_chart_internal_fn.getPrevX = function (i) {
var $$ = this, value = $$.getValueOnIndex($$.data.targets[0].values, i - 1);
return value ? value.x : null;
};
c3_chart_internal_fn.getNextX = function (i) {
var $$ = this, value = $$.getValueOnIndex($$.data.targets[0].values, i + 1);
return value ? value.x : null;
};
c3_chart_internal_fn.getMaxDataCount = function () {
var $$ = this;
return $$.d3.max($$.data.targets, function (t) { return t.values.length; });
};
c3_chart_internal_fn.getMaxDataCountTarget = function (targets) {
var length = targets.length, max = 0, maxTarget;
if (length > 1) {
targets.forEach(function (t) {
if (t.values.length > max) {
maxTarget = t;
max = t.values.length;
}
});
} else {
maxTarget = length ? targets[0] : null;
}
return maxTarget;
};
c3_chart_internal_fn.getEdgeX = function (targets) {
var $$ = this;
return !targets.length ? [0, 0] : [
$$.d3.min(targets, function (t) { return t.values[0].x; }),
$$.d3.max(targets, function (t) { return t.values[t.values.length - 1].x; })
];
};
c3_chart_internal_fn.mapToIds = function (targets) {
return targets.map(function (d) { return d.id; });
};
c3_chart_internal_fn.mapToTargetIds = function (ids) {
var $$ = this;
return ids ? (isString(ids) ? [ids] : ids) : $$.mapToIds($$.data.targets);
};
c3_chart_internal_fn.hasTarget = function (targets, id) {
var ids = this.mapToIds(targets), i;
for (i = 0; i < ids.length; i++) {
if (ids[i] === id) {
return true;
}
}
return false;
};
c3_chart_internal_fn.isTargetToShow = function (targetId) {
return this.hiddenTargetIds.indexOf(targetId) < 0;
};
c3_chart_internal_fn.isLegendToShow = function (targetId) {
return this.hiddenLegendIds.indexOf(targetId) < 0;
};
c3_chart_internal_fn.filterTargetsToShow = function (targets) {
var $$ = this;
return targets.filter(function (t) { return $$.isTargetToShow(t.id); });
};
c3_chart_internal_fn.mapTargetsToUniqueXs = function (targets) {
var $$ = this;
var xs = $$.d3.set($$.d3.merge(targets.map(function (t) { return t.values.map(function (v) { return v.x; }); }))).values();
return $$.isTimeSeries() ? xs.map(function (x) { return new Date(x); }) : xs.map(function (x) { return +x; });
};
c3_chart_internal_fn.addHiddenTargetIds = function (targetIds) {
this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds);
};
c3_chart_internal_fn.removeHiddenTargetIds = function (targetIds) {
this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) { return targetIds.indexOf(id) < 0; });
};
c3_chart_internal_fn.addHiddenLegendIds = function (targetIds) {
this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds);
};
c3_chart_internal_fn.removeHiddenLegendIds = function (targetIds) {
this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) { return targetIds.indexOf(id) < 0; });
};
c3_chart_internal_fn.getValuesAsIdKeyed = function (targets) {
var ys = {};
targets.forEach(function (t) {
ys[t.id] = [];
t.values.forEach(function (v) {
ys[t.id].push(v.value);
});
});
return ys;
};
c3_chart_internal_fn.checkValueInTargets = function (targets, checker) {
var ids = Object.keys(targets), i, j, values;
for (i = 0; i < ids.length; i++) {
values = targets[ids[i]].values;
for (j = 0; j < values.length; j++) {
if (checker(values[j].value)) {
return true;
}
}
}
return false;
};
c3_chart_internal_fn.hasNegativeValueInTargets = function (targets) {
return this.checkValueInTargets(targets, function (v) { return v < 0; });
};
c3_chart_internal_fn.hasPositiveValueInTargets = function (targets) {
return this.checkValueInTargets(targets, function (v) { return v > 0; });
};
c3_chart_internal_fn.isOrderDesc = function () {
var config = this.config;
return config.data_order && config.data_order.toLowerCase() === 'desc';
};
c3_chart_internal_fn.isOrderAsc = function () {
var config = this.config;
return config.data_order && config.data_order.toLowerCase() === 'asc';
};
c3_chart_internal_fn.orderTargets = function (targets) {
var $$ = this, config = $$.config, orderAsc = $$.isOrderAsc(), orderDesc = $$.isOrderDesc();
if (orderAsc || orderDesc) {
targets.sort(function (t1, t2) {
var reducer = function (p, c) { return p + Math.abs(c.value); };
var t1Sum = t1.values.reduce(reducer, 0),
t2Sum = t2.values.reduce(reducer, 0);
return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum;
});
} else if (isFunction(config.data_order)) {
targets.sort(config.data_order);
} // TODO: accept name array for order
return targets;
};
c3_chart_internal_fn.filterByX = function (targets, x) {
return this.d3.merge(targets.map(function (t) { return t.values; })).filter(function (v) { return v.x - x === 0; });
};
c3_chart_internal_fn.filterRemoveNull = function (data) {
return data.filter(function (d) { return isValue(d.value); });
};
c3_chart_internal_fn.hasDataLabel = function () {
var config = this.config;
if (typeof config.data_labels === 'boolean' && config.data_labels) {
return true;
} else if (typeof config.data_labels === 'object' && notEmpty(config.data_labels)) {
return true;
}
return false;
};
c3_chart_internal_fn.getDataLabelLength = function (min, max, axisId, key) {
var $$ = this,
lengths = [0, 0], paddingCoef = 1.3;
$$.selectChart.select('svg').selectAll('.dummy')
.data([min, max])
.enter().append('text')
.text(function (d) { return $$.formatByAxisId(axisId)(d); })
.each(function (d, i) {
lengths[i] = this.getBoundingClientRect()[key] * paddingCoef;
})
.remove();
return lengths;
};
c3_chart_internal_fn.isNoneArc = function (d) {
return this.hasTarget(this.data.targets, d.id);
},
c3_chart_internal_fn.isArc = function (d) {
return 'data' in d && this.hasTarget(this.data.targets, d.data.id);
};
c3_chart_internal_fn.findSameXOfValues = function (values, index) {
var i, targetX = values[index].x, sames = [];
for (i = index - 1; i >= 0; i--) {
if (targetX !== values[i].x) { break; }
sames.push(values[i]);
}
for (i = index; i < values.length; i++) {
if (targetX !== values[i].x) { break; }
sames.push(values[i]);
}
return sames;
};
c3_chart_internal_fn.findClosestOfValues = function (values, pos, _min, _max) { // MEMO: values must be sorted by x
var $$ = this,
min = _min ? _min : 0,
max = _max ? _max : values.length - 1,
med = Math.floor((max - min) / 2) + min,
value = values[med],
diff = $$.x(value.x) - pos[$$.config.axis_rotated ? 1 : 0],
candidates;
// Update range for search
diff > 0 ? max = med : min = med;
// if candidates are two closest min and max, stop recursive call
if ((max - min) === 1 || (min === 0 && max === 0)) {
// Get candidates that has same min and max index
candidates = [];
if (values[min].x || values[min].x === 0) {
candidates = candidates.concat($$.findSameXOfValues(values, min));
}
if (values[max].x || values[max].x === 0) {
candidates = candidates.concat($$.findSameXOfValues(values, max));
}
// Determine the closest and return
return $$.findClosest(candidates, pos);
}
return $$.findClosestOfValues(values, pos, min, max);
};
c3_chart_internal_fn.findClosestFromTargets = function (targets, pos) {
var $$ = this, candidates;
// map to array of closest points of each target
candidates = targets.map(function (target) {
return $$.findClosestOfValues(target.values, pos);
});
// decide closest point and return
return $$.findClosest(candidates, pos);
};
c3_chart_internal_fn.findClosest = function (values, pos) {
var $$ = this, minDist, closest;
values.forEach(function (v) {
var d = $$.dist(v, pos);
if (d < minDist || ! minDist) {
minDist = d;
closest = v;
}
});
return closest;
};
c3_chart_internal_fn.dist = function (data, pos) {
var $$ = this, config = $$.config,
yScale = $$.getAxisId(data.id) === 'y' ? $$.y : $$.y2,
xIndex = config.axis_rotated ? 1 : 0,
yIndex = config.axis_rotated ? 0 : 1;
return Math.pow($$.x(data.x) - pos[xIndex], 2) + Math.pow(yScale(data.value) - pos[yIndex], 2);
};
c3_chart_internal_fn.load = function (targets, args) {
var $$ = this;
if (targets) {
// filter loading targets if needed
if (args.filter) {
targets = targets.filter(args.filter);
}
// set type if args.types || args.type specified
if (args.type || args.types) {
targets.forEach(function (t) {
$$.setTargetType(t.id, args.types ? args.types[t.id] : args.type);
});
}
// Update/Add data
$$.data.targets.forEach(function (d) {
for (var i = 0; i < targets.length; i++) {
if (d.id === targets[i].id) {
d.values = targets[i].values;
targets.splice(i, 1);
break;
}
}
});
$$.data.targets = $$.data.targets.concat(targets); // add remained
}
// Set targets
$$.updateTargets($$.data.targets);
// Redraw with new targets
$$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true});
if (args.done) { args.done(); }
};
c3_chart_internal_fn.loadFromArgs = function (args) {
var $$ = this;
if (args.data) {
$$.load($$.convertDataToTargets(args.data), args);
}
else if (args.url) {
$$.convertUrlToData(args.url, args.mimeType, args.keys, function (data) {
$$.load($$.convertDataToTargets(data), args);
});
}
else if (args.json) {
$$.load($$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), args);
}
else if (args.rows) {
$$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args);
}
else if (args.columns) {
$$.load($$.convertDataToTargets($$.convertColumnsToData(args.columns)), args);
}
else {
$$.load(null, args);
}
};
c3_chart_internal_fn.unload = function (targetIds, done) {
var $$ = this;
if (!done) {
done = function () {};
}
// filter existing target
targetIds = targetIds.filter(function (id) { return $$.hasTarget($$.data.targets, id); });
// If no target, call done and return
if (!targetIds || targetIds.length === 0) {
done();
return;
}
$$.svg.selectAll(targetIds.map(function (id) { return $$.selectorTarget(id); }))
.transition()
.style('opacity', 0)
.remove()
.call($$.endall, done);
targetIds.forEach(function (id) {
// Reset fadein for future load
$$.withoutFadeIn[id] = false;
// Remove target's elements
if ($$.legend) {
$$.legend.selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id)).remove();
}
// Remove target
$$.data.targets = $$.data.targets.filter(function (t) {
return t.id !== id;
});
});
};
c3_chart_internal_fn.getYDomainMin = function (targets) {
var $$ = this, config = $$.config,
ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets),
j, k, baseId, idsInGroup, id, hasNegativeValue;
if (config.data_groups.length > 0) {
hasNegativeValue = $$.hasNegativeValueInTargets(targets);
for (j = 0; j < config.data_groups.length; j++) {
// Determine baseId
idsInGroup = config.data_groups[j].filter(function (id) { return ids.indexOf(id) >= 0; });
if (idsInGroup.length === 0) { continue; }
baseId = idsInGroup[0];
// Consider negative values
if (hasNegativeValue && ys[baseId]) {
ys[baseId].forEach(function (v, i) {
ys[baseId][i] = v < 0 ? v : 0;
});
}
// Compute min
for (k = 1; k < idsInGroup.length; k++) {
id = idsInGroup[k];
if (! ys[id]) { continue; }
ys[id].forEach(function (v, i) {
if ($$.getAxisId(id) === $$.getAxisId(baseId) && ys[baseId] && !(hasNegativeValue && +v > 0)) {
ys[baseId][i] += +v;
}
});
}
}
}
return $$.d3.min(Object.keys(ys).map(function (key) { return $$.d3.min(ys[key]); }));
};
c3_chart_internal_fn.getYDomainMax = function (targets) {
var $$ = this, config = $$.config,
ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets),
j, k, baseId, idsInGroup, id, hasPositiveValue;
if (config.data_groups.length > 0) {
hasPositiveValue = $$.hasPositiveValueInTargets(targets);
for (j = 0; j < config.data_groups.length; j++) {
// Determine baseId
idsInGroup = config.data_groups[j].filter(function (id) { return ids.indexOf(id) >= 0; });
if (idsInGroup.length === 0) { continue; }
baseId = idsInGroup[0];
// Consider positive values
if (hasPositiveValue && ys[baseId]) {
ys[baseId].forEach(function (v, i) {
ys[baseId][i] = v > 0 ? v : 0;
});
}
// Compute max
for (k = 1; k < idsInGroup.length; k++) {
id = idsInGroup[k];
if (! ys[id]) { continue; }
ys[id].forEach(function (v, i) {
if ($$.getAxisId(id) === $$.getAxisId(baseId) && ys[baseId] && !(hasPositiveValue && +v < 0)) {
ys[baseId][i] += +v;
}
});
}
}
}
return $$.d3.max(Object.keys(ys).map(function (key) { return $$.d3.max(ys[key]); }));
};
c3_chart_internal_fn.getYDomain = function (targets, axisId) {
var $$ = this, config = $$.config,
yTargets = targets.filter(function (d) { return $$.getAxisId(d.id) === axisId; }),
yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min,
yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max,
yDomainMin = isValue(yMin) ? yMin : $$.getYDomainMin(yTargets),
yDomainMax = isValue(yMax) ? yMax : $$.getYDomainMax(yTargets),
domainLength, padding, padding_top, padding_bottom,
center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center,
yDomainAbs, lengths, diff, ratio, isAllPositive, isAllNegative,
isZeroBased = ($$.hasType('bar', yTargets) && config.bar_zerobased) || ($$.hasType('area', yTargets) && config.area_zerobased),
showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated,
showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated;
if (yTargets.length === 0) { // use current domain if target of axisId is none
return axisId === 'y2' ? $$.y2.domain() : $$.y.domain();
}
if (isNaN(yDomainMin)) { // set minimum to zero when not number
yDomainMin = 0;
}
if (isNaN(yDomainMax)) { // set maximum to have same value as yDomainMin
yDomainMax = yDomainMin;
}
if (yDomainMin === yDomainMax) {
yDomainMin < 0 ? yDomainMax = 0 : yDomainMin = 0;
}
isAllPositive = yDomainMin >= 0 && yDomainMax >= 0;
isAllNegative = yDomainMin <= 0 && yDomainMax <= 0;
// Cancel zerobased if axis_*_min / axis_*_max specified
if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) {
isZeroBased = false;
}
// Bar/Area chart should be 0-based if all positive|negative
if (isZeroBased) {
if (isAllPositive) { yDomainMin = 0; }
if (isAllNegative) { yDomainMax = 0; }
}
domainLength = Math.abs(yDomainMax - yDomainMin);
padding = padding_top = padding_bottom = domainLength * 0.1;
if (center) {
yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));
yDomainMax = yDomainAbs - center;
yDomainMin = center - yDomainAbs;
}
// add padding for data label
if (showHorizontalDataLabel) {
lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, axisId, 'width');
diff = diffDomain($$.y.range());
ratio = [lengths[0] / diff, lengths[1] / diff];
padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1]));
padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1]));
} else if (showVerticalDataLabel) {
lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, axisId, 'height');
padding_top += lengths[1];
padding_bottom += lengths[0];
}
if (axisId === 'y' && notEmpty(config.axis_y_padding)) {
padding_top = $$.getAxisPadding(config.axis_y_padding, 'top', padding, domainLength);
padding_bottom = $$.getAxisPadding(config.axis_y_padding, 'bottom', padding, domainLength);
}
if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) {
padding_top = $$.getAxisPadding(config.axis_y2_padding, 'top', padding, domainLength);
padding_bottom = $$.getAxisPadding(config.axis_y2_padding, 'bottom', padding, domainLength);
}
// Bar/Area chart should be 0-based if all positive|negative
if (isZeroBased) {
if (isAllPositive) { padding_bottom = yDomainMin; }
if (isAllNegative) { padding_top = -yDomainMax; }
}
return [yDomainMin - padding_bottom, yDomainMax + padding_top];
};
c3_chart_internal_fn.getXDomainMin = function (targets) {
var $$ = this, config = $$.config;
return isDefined(config.axis_x_min) ?
($$.isTimeSeries() ? this.parseDate(config.axis_x_min) : config.axis_x_min) :
$$.d3.min(targets, function (t) { return $$.d3.min(t.values, function (v) { return v.x; }); });
};
c3_chart_internal_fn.getXDomainMax = function (targets) {
var $$ = this, config = $$.config;
return isDefined(config.axis_x_max) ?
($$.isTimeSeries() ? this.parseDate(config.axis_x_max) : config.axis_x_max) :
$$.d3.max(targets, function (t) { return $$.d3.max(t.values, function (v) { return v.x; }); });
};
c3_chart_internal_fn.getXDomainPadding = function (targets) {
var $$ = this, config = $$.config,
edgeX = this.getEdgeX(targets), diff = edgeX[1] - edgeX[0],
maxDataCount, padding, paddingLeft, paddingRight;
if ($$.isCategorized()) {
padding = 0;
} else if ($$.hasType('bar', targets)) {
maxDataCount = $$.getMaxDataCount();
padding = maxDataCount > 1 ? (diff / (maxDataCount - 1)) / 2 : 0.5;
} else {
padding = diff * 0.01;
}
if (typeof config.axis_x_padding === 'object' && notEmpty(config.axis_x_padding)) {
paddingLeft = isValue(config.axis_x_padding.left) ? config.axis_x_padding.left : padding;
paddingRight = isValue(config.axis_x_padding.right) ? config.axis_x_padding.right : padding;
} else if (typeof config.axis_x_padding === 'number') {
paddingLeft = paddingRight = config.axis_x_padding;
} else {
paddingLeft = paddingRight = padding;
}
return {left: paddingLeft, right: paddingRight};
};
c3_chart_internal_fn.getXDomain = function (targets) {
var $$ = this,
xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)],
firstX = xDomain[0], lastX = xDomain[1],
padding = $$.getXDomainPadding(targets),
min = 0, max = 0;
// show center of x domain if min and max are the same
if ((firstX - lastX) === 0 && !$$.isCategorized()) {
firstX = $$.isTimeSeries() ? new Date(firstX.getTime() * 0.5) : -0.5;
lastX = $$.isTimeSeries() ? new Date(lastX.getTime() * 1.5) : 0.5;
}
if (firstX || firstX === 0) {
min = $$.isTimeSeries() ? new Date(firstX.getTime() - padding.left) : firstX - padding.left;
}
if (lastX || lastX === 0) {
max = $$.isTimeSeries() ? new Date(lastX.getTime() + padding.right) : lastX + padding.right;
}
return [min, max];
};
c3_chart_internal_fn.updateXDomain = function (targets, withUpdateXDomain, withUpdateOrgXDomain, domain) {
var $$ = this, config = $$.config;
if (withUpdateOrgXDomain) {
$$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets)));
$$.orgXDomain = $$.x.domain();
if (config.zoom_enabled) { $$.zoom.scale($$.x).updateScaleExtent(); }
$$.subX.domain($$.x.domain());
if ($$.brush) { $$.brush.scale($$.subX); }
}
if (withUpdateXDomain) {
$$.x.domain(domain ? domain : (!$$.brush || $$.brush.empty()) ? $$.orgXDomain : $$.brush.extent());
if (config.zoom_enabled) { $$.zoom.scale($$.x).updateScaleExtent(); }
}
return $$.x.domain();
};
c3_chart_internal_fn.drag = function (mouse) {
var $$ = this, config = $$.config, main = $$.main, d3 = $$.d3;
var sx, sy, mx, my, minX, maxX, minY, maxY;
if ($$.hasArcType()) { return; }
if (! config.data_selection_enabled) { return; } // do nothing if not selectable
if (config.zoom_enabled && ! $$.zoom.altDomain) { return; } // skip if zoomable because of conflict drag dehavior
if (!config.data_selection_multiple) { return; } // skip when single selection because drag is used for multiple selection
sx = $$.dragStart[0];
sy = $$.dragStart[1];
mx = mouse[0];
my = mouse[1];
minX = Math.min(sx, mx);
maxX = Math.max(sx, mx);
minY = (config.data_selection_grouped) ? $$.margin.top : Math.min(sy, my);
maxY = (config.data_selection_grouped) ? $$.height : Math.max(sy, my);
main.select('.' + CLASS.dragarea)
.attr('x', minX)
.attr('y', minY)
.attr('width', maxX - minX)
.attr('height', maxY - minY);
// TODO: binary search when multiple xs
main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape)
.filter(function (d) { return config.data_selection_isselectable(d); })
.each(function (d, i) {
var shape = d3.select(this),
isSelected = shape.classed(CLASS.SELECTED),
isIncluded = shape.classed(CLASS.INCLUDED),
_x, _y, _w, _h, toggle, isWithin = false, box;
if (shape.classed(CLASS.circle)) {
_x = shape.attr("cx") * 1;
_y = shape.attr("cy") * 1;
toggle = $$.togglePoint;
isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY;
}
else if (shape.classed(CLASS.bar)) {
box = getPathBox(this);
_x = box.x;
_y = box.y;
_w = box.width;
_h = box.height;
toggle = $$.toggleBar;
isWithin = !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY);
} else {
// line/area selection not supported yet
return;
}
if (isWithin ^ isIncluded) {
shape.classed(CLASS.INCLUDED, !isIncluded);
// TODO: included/unincluded callback here
shape.classed(CLASS.SELECTED, !isSelected);
toggle.call($$, !isSelected, shape, d, i);
}
});
};
c3_chart_internal_fn.dragstart = function (mouse) {
var $$ = this, config = $$.config;
if ($$.hasArcType()) { return; }
if (! config.data_selection_enabled) { return; } // do nothing if not selectable
$$.dragStart = mouse;
$$.main.select('.' + CLASS.chart).append('rect')
.attr('class', CLASS.dragarea)
.style('opacity', 0.1);
$$.dragging = true;
$$.config.data_ondragstart();
};
c3_chart_internal_fn.dragend = function () {
var $$ = this, config = $$.config;
if ($$.hasArcType()) { return; }
if (! config.data_selection_enabled) { return; } // do nothing if not selectable
$$.main.select('.' + CLASS.dragarea)
.transition().duration(100)
.style('opacity', 0)
.remove();
$$.main.selectAll('.' + CLASS.shape)
.classed(CLASS.INCLUDED, false);
$$.dragging = false;
$$.config.data_ondragend();
};
c3_chart_internal_fn.getYFormat = function (forArc) {
var $$ = this,
formatForY = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat,
formatForY2 = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format;
return function (v, ratio, id) {
var format = $$.getAxisId(id) === 'y2' ? formatForY2 : formatForY;
return format.call($$, v, ratio);
};
};
c3_chart_internal_fn.yFormat = function (v) {
var $$ = this, config = $$.config,
format = config.axis_y_tick_format ? config.axis_y_tick_format : $$.defaultValueFormat;
return format(v);
};
c3_chart_internal_fn.y2Format = function (v) {
var $$ = this, config = $$.config,
format = config.axis_y2_tick_format ? config.axis_y2_tick_format : $$.defaultValueFormat;
return format(v);
};
c3_chart_internal_fn.defaultValueFormat = function (v) {
return isValue(v) ? +v : "";
};
c3_chart_internal_fn.defaultArcValueFormat = function (v, ratio) {
return (ratio * 100).toFixed(1) + '%';
};
c3_chart_internal_fn.formatByAxisId = function (axisId) {
var $$ = this, data_labels = $$.config.data_labels,
format = function (v) { return isValue(v) ? +v : ""; };
// find format according to axis id
if (typeof data_labels.format === 'function') {
format = data_labels.format;
} else if (typeof data_labels.format === 'object') {
if (data_labels.format[axisId]) {
format = data_labels.format[axisId];
}
}
return format;
};
c3_chart_internal_fn.initGrid = function () {
var $$ = this, config = $$.config, d3 = $$.d3;
$$.grid = $$.main.append('g')
.attr("clip-path", $$.clipPath)
.attr('class', CLASS.grid);
if (config.grid_x_show) {
$$.grid.append("g").attr("class", CLASS.xgrids);
}
if (config.grid_y_show) {
$$.grid.append('g').attr('class', CLASS.ygrids);
}
if (config.grid_focus_show) {
$$.grid.append('g')
.attr("class", CLASS.xgridFocus)
.append('line')
.attr('class', CLASS.xgridFocus);
}
$$.xgrid = d3.selectAll([]);
if (!config.grid_lines_front) { $$.initGridLines(); }
};
c3_chart_internal_fn.initGridLines = function () {
var $$ = this, d3 = $$.d3;
$$.gridLines = $$.main.append('g')
.attr("clip-path", $$.clipPath)
.attr('class', CLASS.grid + ' ' + CLASS.gridLines);
$$.gridLines.append('g').attr("class", CLASS.xgridLines);
$$.gridLines.append('g').attr('class', CLASS.ygridLines);
$$.xgridLines = d3.selectAll([]);
};
c3_chart_internal_fn.updateXGrid = function (withoutUpdate) {
var $$ = this, config = $$.config, d3 = $$.d3,
xgridData = $$.generateGridData(config.grid_x_type, $$.x),
tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0;
$$.xgridAttr = config.axis_rotated ? {
'x1': 0,
'x2': $$.width,
'y1': function (d) { return $$.x(d) - tickOffset; },
'y2': function (d) { return $$.x(d) - tickOffset; }
} : {
'x1': function (d) { return $$.x(d) + tickOffset; },
'x2': function (d) { return $$.x(d) + tickOffset; },
'y1': 0,
'y2': $$.height
};
$$.xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid)
.data(xgridData);
$$.xgrid.enter().append('line').attr("class", CLASS.xgrid);
if (!withoutUpdate) {
$$.xgrid.attr($$.xgridAttr)
.style("opacity", function () { return +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1') === (config.axis_rotated ? $$.height : 0) ? 0 : 1; });
}
$$.xgrid.exit().remove();
};
c3_chart_internal_fn.updateYGrid = function () {
var $$ = this, config = $$.config;
$$.ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid)
.data($$.y.ticks(config.grid_y_ticks));
$$.ygrid.enter().append('line')
.attr('class', CLASS.ygrid);
$$.ygrid.attr("x1", config.axis_rotated ? $$.y : 0)
.attr("x2", config.axis_rotated ? $$.y : $$.width)
.attr("y1", config.axis_rotated ? 0 : $$.y)
.attr("y2", config.axis_rotated ? $$.height : $$.y);
$$.ygrid.exit().remove();
$$.smoothLines($$.ygrid, 'grid');
};
c3_chart_internal_fn.redrawGrid = function (duration, withY) {
var $$ = this, main = $$.main, config = $$.config,
xgridLine, ygridLine, yv;
main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
if (config.grid_x_show) {
$$.updateXGrid();
}
$$.xgridLines = main.select('.' + CLASS.xgridLines).selectAll('.' + CLASS.xgridLine)
.data(config.grid_x_lines);
// enter
xgridLine = $$.xgridLines.enter().append('g')
.attr("class", function (d) { return CLASS.xgridLine + (d.class ? ' ' + d.class : ''); });
xgridLine.append('line')
.style("opacity", 0);
xgridLine.append('text')
.attr("text-anchor", "end")
.attr("transform", config.axis_rotated ? "" : "rotate(-90)")
.attr('dx', config.axis_rotated ? 0 : -$$.margin.top)
.attr('dy', -5)
.style("opacity", 0);
// udpate
// done in d3.transition() of the end of this function
// exit
$$.xgridLines.exit().transition().duration(duration)
.style("opacity", 0)
.remove();
// Y-Grid
if (withY && config.grid_y_show) {
$$.updateYGrid();
}
if (withY) {
$$.ygridLines = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine)
.data(config.grid_y_lines);
// enter
ygridLine = $$.ygridLines.enter().append('g')
.attr("class", function (d) { return CLASS.ygridLine + (d.class ? ' ' + d.class : ''); });
ygridLine.append('line')
.style("opacity", 0);
ygridLine.append('text')
.attr("text-anchor", "end")
.attr("transform", config.axis_rotated ? "rotate(-90)" : "")
.attr('dx', config.axis_rotated ? 0 : -$$.margin.top)
.attr('dy', -5)
.style("opacity", 0);
// update
yv = $$.yv.bind($$);
$$.ygridLines.select('line')
.transition().duration(duration)
.attr("x1", config.axis_rotated ? yv : 0)
.attr("x2", config.axis_rotated ? yv : $$.width)
.attr("y1", config.axis_rotated ? 0 : yv)
.attr("y2", config.axis_rotated ? $$.height : yv)
.style("opacity", 1);
$$.ygridLines.select('text')
.transition().duration(duration)
.attr("x", config.axis_rotated ? 0 : $$.width)
.attr("y", yv)
.text(function (d) { return d.text; })
.style("opacity", 1);
// exit
$$.ygridLines.exit().transition().duration(duration)
.style("opacity", 0)
.remove();
}
};
c3_chart_internal_fn.addTransitionForGrid = function (transitions) {
var $$ = this, config = $$.config, xv = $$.xv.bind($$);
transitions.push($$.xgridLines.select('line').transition()
.attr("x1", config.axis_rotated ? 0 : xv)
.attr("x2", config.axis_rotated ? $$.width : xv)
.attr("y1", config.axis_rotated ? xv : $$.margin.top)
.attr("y2", config.axis_rotated ? xv : $$.height)
.style("opacity", 1));
transitions.push($$.xgridLines.select('text').transition()
.attr("x", config.axis_rotated ? $$.width : 0)
.attr("y", xv)
.text(function (d) { return d.text; })
.style("opacity", 1));
};
c3_chart_internal_fn.showXGridFocus = function (selectedData) {
var $$ = this, config = $$.config,
dataToShow = selectedData.filter(function (d) { return d && isValue(d.value); }),
focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus),
xx = $$.xx.bind($$);
if (! config.tooltip_show) { return; }
// Hide when scatter plot exists
if ($$.hasType('scatter') || $$.hasArcType()) { return; }
focusEl
.style("visibility", "visible")
.data([dataToShow[0]])
.attr(config.axis_rotated ? 'y1' : 'x1', xx)
.attr(config.axis_rotated ? 'y2' : 'x2', xx);
$$.smoothLines(focusEl, 'grid');
};
c3_chart_internal_fn.hideXGridFocus = function () {
this.main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
};
c3_chart_internal_fn.updateXgridFocus = function () {
var $$ = this, config = $$.config;
$$.main.select('line.' + CLASS.xgridFocus)
.attr("x1", config.axis_rotated ? 0 : -10)
.attr("x2", config.axis_rotated ? $$.width : -10)
.attr("y1", config.axis_rotated ? -10 : 0)
.attr("y2", config.axis_rotated ? -10 : $$.height);
};
c3_chart_internal_fn.generateGridData = function (type, scale) {
var $$ = this,
gridData = [], xDomain, firstYear, lastYear, i,
tickNum = $$.main.select("." + CLASS.axisX).selectAll('.tick').size();
if (type === 'year') {
xDomain = $$.getXDomain();
firstYear = xDomain[0].getFullYear();
lastYear = xDomain[1].getFullYear();
for (i = firstYear; i <= lastYear; i++) {
gridData.push(new Date(i + '-01-01 00:00:00'));
}
} else {
gridData = scale.ticks(10);
if (gridData.length > tickNum) { // use only int
gridData = gridData.filter(function (d) { return ("" + d).indexOf('.') < 0; });
}
}
return gridData;
};
c3_chart_internal_fn.getGridFilterToRemove = function (params) {
return params ? function (line) {
var found = false;
[].concat(params).forEach(function (param) {
if ((('value' in param && line.value === params.value) || ('class' in param && line.class === params.class))) {
found = true;
}
});
return found;
} : function () { return true; };
};
c3_chart_internal_fn.removeGridLines = function (params, forX) {
var $$ = this, config = $$.config,
toRemove = $$.getGridFilterToRemove(params),
toShow = function (line) { return !toRemove(line); },
classLines = forX ? CLASS.xgridLines : CLASS.ygridLines,
classLine = forX ? CLASS.xgridLine : CLASS.ygridLine;
$$.main.select('.' + classLines).selectAll('.' + classLine).filter(toRemove)
.transition().duration(config.transition_duration)
.style('opacity', 0).remove();
if (forX) {
config.grid_x_lines = config.grid_x_lines.filter(toShow);
} else {
config.grid_y_lines = config.grid_y_lines.filter(toShow);
}
};
(function (window) {
'use strict';
/*global define, module, exports, require */
c3_chart_internal_fn.initEventRect = function () {
var $$ = this;
$$.main.select('.' + CLASS.chart).append("g")
.attr("class", CLASS.eventRects)
.style('fill-opacity', 0);
};
c3_chart_internal_fn.redrawEventRect = function () {
var $$ = this, config = $$.config,
eventRectUpdate, maxDataCountTarget,
isMultipleX = $$.isMultipleX();
// rects for mouseover
var eventRects = $$.main.select('.' + CLASS.eventRects)
.style('cursor', config.zoom_enabled ? config.axis_rotated ? 'ns-resize' : 'ew-resize' : null)
.classed(CLASS.eventRectsMultiple, isMultipleX)
.classed(CLASS.eventRectsSingle, !isMultipleX);
// clear old rects
eventRects.selectAll('.' + CLASS.eventRect).remove();
// open as public variable
$$.eventRect = eventRects.selectAll('.' + CLASS.eventRect);
if (isMultipleX) {
eventRectUpdate = $$.eventRect.data([0]);
// enter : only one rect will be added
$$.generateEventRectsForMultipleXs(eventRectUpdate.enter());
// update
$$.updateEventRect(eventRectUpdate);
// exit : not needed because always only one rect exists
}
else {
// Set data and update $$.eventRect
maxDataCountTarget = $$.getMaxDataCountTarget($$.data.targets);
eventRects.datum(maxDataCountTarget ? maxDataCountTarget.values : []);
$$.eventRect = eventRects.selectAll('.' + CLASS.eventRect);
eventRectUpdate = $$.eventRect.data(function (d) { return d; });
// enter
$$.generateEventRectsForSingleX(eventRectUpdate.enter());
// update
$$.updateEventRect(eventRectUpdate);
// exit
eventRectUpdate.exit().remove();
}
};
c3_chart_internal_fn.updateEventRect = function (eventRectUpdate) {
var $$ = this, config = $$.config,
x, y, w, h, rectW, rectX;
// set update selection if null
eventRectUpdate = eventRectUpdate || $$.eventRect.data(function (d) { return d; });
if ($$.isMultipleX()) {
// TODO: rotated not supported yet
x = 0;
y = 0;
w = $$.width;
h = $$.height;
}
else {
if (($$.isCustomX() || $$.isTimeSeries()) && !$$.isCategorized()) {
rectW = function (d) {
var prevX = $$.getPrevX(d.index), nextX = $$.getNextX(d.index), dx = $$.data.xs[d.id][d.index],
w = ($$.x(nextX ? nextX : dx) - $$.x(prevX ? prevX : dx)) / 2;
return w < 0 ? 0 : w;
};
rectX = function (d) {
var prevX = $$.getPrevX(d.index), dx = $$.data.xs[d.id][d.index];
return ($$.x(dx) + $$.x(prevX ? prevX : dx)) / 2;
};
} else {
rectW = $$.getEventRectWidth();
rectX = function (d) {
return $$.x(d.x) - (rectW / 2);
};
}
x = config.axis_rotated ? 0 : rectX;
y = config.axis_rotated ? rectX : 0;
w = config.axis_rotated ? $$.width : rectW;
h = config.axis_rotated ? rectW : $$.height;
}
eventRectUpdate
.attr('class', $$.classEvent.bind($$))
.attr("x", x)
.attr("y", y)
.attr("width", w)
.attr("height", h);
};
c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
var $$ = this, d3 = $$.d3, config = $$.config;
eventRectEnter.append("rect")
.attr("class", $$.classEvent.bind($$))
.style("cursor", config.data_selection_enabled && config.data_selection_grouped ? "pointer" : null)
.on('mouseover', function (d) {
var index = d.index, selectedData, newData;
if ($$.dragging) { return; } // do nothing if dragging
if ($$.hasArcType()) { return; }
selectedData = $$.data.targets.map(function (t) {
return $$.addName($$.getValueOnIndex(t.values, index));
});
// Sort selectedData as names order
newData = [];
Object.keys(config.data_names).forEach(function (id) {
for (var j = 0; j < selectedData.length; j++) {
if (selectedData[j] && selectedData[j].id === id) {
newData.push(selectedData[j]);
selectedData.shift(j);
break;
}
}
});
selectedData = newData.concat(selectedData); // Add remained
// Expand shapes for selection
if (config.point_focus_expand_enabled) { $$.expandCircles(index, null, true); }
$$.expandBars(index, null, true);
// Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
config.data_onmouseover.call($$, d);
});
})
.on('mouseout', function (d) {
var index = d.index;
if ($$.hasArcType()) { return; }
$$.hideXGridFocus();
$$.hideTooltip();
// Undo expanded shapes
$$.unexpandCircles();
$$.unexpandBars();
// Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
config.data_onmouseout.call($$, d);
});
})
.on('mousemove', function (d) {
var selectedData, index = d.index,
eventRect = $$.svg.select('.' + CLASS.eventRect + '-' + index);
if ($$.dragging) { return; } // do nothing when dragging
if ($$.hasArcType()) { return; }
if ($$.isStepType(d) && d3.mouse(this)[0] < $$.x($$.getXValue(d.id, index))) {
index -= 1;
}
// Show tooltip
selectedData = $$.filterTargetsToShow($$.data.targets).map(function (t) {
return $$.addName($$.getValueOnIndex(t.values, index));
});
if (config.tooltip_grouped) {
$$.showTooltip(selectedData, d3.mouse(this));
$$.showXGridFocus(selectedData);
}
if (config.tooltip_grouped && (!config.data_selection_enabled || config.data_selection_grouped)) {
return;
}
$$.main.selectAll('.' + CLASS.shape + '-' + index)
.each(function () {
d3.select(this).classed(CLASS.EXPANDED, true);
if (config.data_selection_enabled) {
eventRect.style('cursor', config.data_selection_grouped ? 'pointer' : null);
}
if (!config.tooltip_grouped) {
$$.hideXGridFocus();
$$.hideTooltip();
if (!config.data_selection_grouped) {
$$.unexpandCircles(index);
$$.unexpandBars(index);
}
}
})
.filter(function (d) {
if (this.nodeName === 'circle') {
return $$.isWithinCircle(this, $$.pointSelectR(d));
}
else if (this.nodeName === 'path') {
return $$.isWithinBar(this);
}
})
.each(function (d) {
if (config.data_selection_enabled && (config.data_selection_grouped || config.data_selection_isselectable(d))) {
eventRect.style('cursor', 'pointer');
}
if (!config.tooltip_grouped) {
$$.showTooltip([d], d3.mouse(this));
$$.showXGridFocus([d]);
if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id, true); }
$$.expandBars(index, d.id, true);
}
});
})
.on('click', function (d) {
var index = d.index;
if ($$.hasArcType() || !$$.toggleShape) { return; }
if ($$.cancelClick) {
$$.cancelClick = false;
return;
}
if ($$.isStepType(d) && d3.mouse(this)[0] < $$.x($$.getXValue(d.id, index))) {
index -= 1;
}
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
$$.toggleShape(this, d, index);
});
})
.call(
d3.behavior.drag().origin(Object)
.on('drag', function () { $$.drag(d3.mouse(this)); })
.on('dragstart', function () { $$.dragstart(d3.mouse(this)); })
.on('dragend', function () { $$.dragend(); })
)
.on("dblclick.zoom", null);
};
c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) {
var $$ = this, d3 = $$.d3, config = $$.config;
eventRectEnter.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', $$.width)
.attr('height', $$.height)
.attr('class', CLASS.eventRect)
.on('mouseout', function () {
if ($$.hasArcType()) { return; }
$$.hideXGridFocus();
$$.hideTooltip();
$$.unexpandCircles();
})
.on('mousemove', function () {
var targetsToShow = $$.filterTargetsToShow($$.data.targets);
var mouse, closest, sameXData, selectedData;
if ($$.dragging) { return; } // do nothing when dragging
if ($$.hasArcType(targetsToShow)) { return; }
mouse = d3.mouse(this);
closest = $$.findClosestFromTargets(targetsToShow, mouse);
if (! closest) { return; }
if ($$.isScatterType(closest)) {
sameXData = [closest];
} else {
sameXData = $$.filterByX(targetsToShow, closest.x);
}
// show tooltip when cursor is close to some point
selectedData = sameXData.map(function (d) {
return $$.addName(d);
});
$$.showTooltip(selectedData, mouse);
// expand points
if (config.point_focus_expand_enabled) {
$$.expandCircles(closest.index, closest.id, true);
}
// Show xgrid focus line
$$.showXGridFocus(selectedData);
// Show cursor as pointer if point is close to mouse position
if ($$.dist(closest, mouse) < 100) {
$$.svg.select('.' + CLASS.eventRect).style('cursor', 'pointer');
if (!$$.mouseover) {
config.data_onmouseover.call($$, closest);
$$.mouseover = true;
}
} else if ($$.mouseover) {
$$.svg.select('.' + CLASS.eventRect).style('cursor', null);
config.data_onmouseout.call($$, closest);
$$.mouseover = false;
}
})
.on('click', function () {
var targetsToShow = $$.filterTargetsToShow($$.data.targets);
var mouse, closest;
if ($$.hasArcType(targetsToShow)) { return; }
mouse = d3.mouse(this);
closest = $$.findClosestFromTargets(targetsToShow, mouse);
if (! closest) { return; }
// select if selection enabled
if ($$.dist(closest, mouse) < 100 && $$.toggleShape) {
$$.main.select('.' + CLASS.circles + $$.getTargetSelectorSuffix(closest.id)).select('.' + CLASS.circle + '-' + closest.index).each(function () {
$$.toggleShape(this, closest, closest.index);
});
}
})
.call(
d3.behavior.drag().origin(Object)
.on('drag', function () { $$.drag(d3.mouse(this)); })
.on('dragstart', function () { $$.dragstart(d3.mouse(this)); })
.on('dragend', function () { $$.dragend(); })
)
.on("dblclick.zoom", null);
};
c3_chart_internal_fn.dispatchEvent = function (type, index, mouse) {
var $$ = this,
selector = '.' + CLASS.eventRect + (!$$.isMultipleX() ? '-' + index : ''),
eventRect = $$.main.select(selector).node(),
box = eventRect.getBoundingClientRect(),
x = box.left + (mouse ? mouse[0] : 0),
y = box.top + (mouse ? mouse[1] : 0),
event = document.createEvent("MouseEvents");
event.initMouseEvent(type, true, true, window, 0, x, y, x, y,
false, false, false, false, 0, null);
eventRect.dispatchEvent(event);
};
c3_chart_internal_fn.initLegend = function () {
var $$ = this;
$$.legend = $$.svg.append("g").attr("transform", $$.getTranslate('legend'));
if (!$$.config.legend_show) {
$$.legend.style('visibility', 'hidden');
$$.hiddenLegendIds = $$.mapToIds($$.data.targets);
}
// MEMO: call here to update legend box and tranlate for all
// MEMO: translate will be upated by this, so transform not needed in updateLegend()
$$.updateLegend($$.mapToIds($$.data.targets), {withTransform: false, withTransitionForTransform: false, withTransition: false});
};
c3_chart_internal_fn.updateSizeForLegend = function (legendHeight, legendWidth) {
var $$ = this, config = $$.config, insetLegendPosition = {
top: $$.isLegendTop ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5 : $$.currentHeight - legendHeight - $$.getCurrentPaddingBottom() - config.legend_inset_y,
left: $$.isLegendLeft ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5 : $$.currentWidth - legendWidth - $$.getCurrentPaddingRight() - config.legend_inset_x + 0.5
};
$$.margin3 = {
top: $$.isLegendRight ? 0 : $$.isLegendInset ? insetLegendPosition.top : $$.currentHeight - legendHeight,
right: NaN,
bottom: 0,
left: $$.isLegendRight ? $$.currentWidth - legendWidth : $$.isLegendInset ? insetLegendPosition.left : 0
};
};
c3_chart_internal_fn.transformLegend = function (withTransition) {
var $$ = this;
(withTransition ? $$.legend.transition() : $$.legend).attr("transform", $$.getTranslate('legend'));
};
c3_chart_internal_fn.updateLegendStep = function (step) {
this.legendStep = step;
};
c3_chart_internal_fn.updateLegendItemWidth = function (w) {
this.legendItemWidth = w;
};
c3_chart_internal_fn.updateLegendItemHeight = function (h) {
this.legendItemHeight = h;
};
c3_chart_internal_fn.getLegendWidth = function () {
var $$ = this;
return $$.config.legend_show ? $$.isLegendRight || $$.isLegendInset ? $$.legendItemWidth * ($$.legendStep + 1) : $$.currentWidth : 0;
};
c3_chart_internal_fn.getLegendHeight = function () {
var $$ = this, config = $$.config, h = 0;
if (config.legend_show) {
if ($$.isLegendRight) {
h = $$.currentHeight;
} else if ($$.isLegendInset) {
h = config.legend_inset_step ? Math.max(20, $$.legendItemHeight) * (config.legend_inset_step + 1) : $$.height;
} else {
h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1);
}
}
return h;
};
c3_chart_internal_fn.opacityForLegend = function (legendItem) {
var $$ = this;
return legendItem.classed(CLASS.legendItemHidden) ? $$.legendOpacityForHidden : 1;
};
c3_chart_internal_fn.opacityForUnfocusedLegend = function (legendItem) {
var $$ = this;
return legendItem.classed(CLASS.legendItemHidden) ? $$.legendOpacityForHidden : 0.3;
};
c3_chart_internal_fn.toggleFocusLegend = function (id, focus) {
var $$ = this;
$$.legend.selectAll('.' + CLASS.legendItem)
.transition().duration(100)
.style('opacity', function (_id) {
var This = $$.d3.select(this);
if (id && _id !== id) {
return focus ? $$.opacityForUnfocusedLegend(This) : $$.opacityForLegend(This);
} else {
return focus ? $$.opacityForLegend(This) : $$.opacityForUnfocusedLegend(This);
}
});
};
c3_chart_internal_fn.revertLegend = function () {
var $$ = this, d3 = $$.d3;
$$.legend.selectAll('.' + CLASS.legendItem)
.transition().duration(100)
.style('opacity', function () { return $$.opacityForLegend(d3.select(this)); });
};
c3_chart_internal_fn.showLegend = function (targetIds) {
var $$ = this, config = $$.config;
if (!config.legend_show) {
config.legend_show = true;
$$.legend.style('visibility', 'visible');
}
$$.removeHiddenLegendIds(targetIds);
$$.legend.selectAll($$.selectorLegends(targetIds))
.style('visibility', 'visible')
.transition()
.style('opacity', function () { return $$.opacityForLegend($$.d3.select(this)); });
};
c3_chart_internal_fn.hideLegend = function (targetIds) {
var $$ = this, config = $$.config;
if (config.legend_show && isEmpty(targetIds)) {
config.legend_show = false;
$$.legend.style('visibility', 'hidden');
}
$$.addHiddenLegendIds(targetIds);
$$.legend.selectAll($$.selectorLegends(targetIds))
.style('opacity', 0)
.style('visibility', 'hidden');
};
c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) {
var $$ = this, config = $$.config;
var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect;
var paddingTop = 4, paddingRight = 36, maxWidth = 0, maxHeight = 0, posMin = 10;
var l, totalLength = 0, offsets = {}, widths = {}, heights = {}, margins = [0], steps = {}, step = 0;
var withTransition, withTransitionForTransform;
var hasFocused = $$.legend.selectAll('.' + CLASS.legendItemFocused).size();
var texts, rects, tiles;
options = options || {};
withTransition = getOption(options, "withTransition", true);
withTransitionForTransform = getOption(options, "withTransitionForTransform", true);
function updatePositions(textElement, id, reset) {
var box = $$.getTextRect(textElement.textContent, CLASS.legendItem),
itemWidth = Math.ceil((box.width + paddingRight) / 10) * 10,
itemHeight = Math.ceil((box.height + paddingTop) / 10) * 10,
itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth,
areaLength = $$.isLegendRight || $$.isLegendInset ? $$.getLegendHeight() : $$.getLegendWidth(),
margin, maxLength;
// MEMO: care about condifion of step, totalLength
function updateValues(id, withoutStep) {
if (!withoutStep) {
margin = (areaLength - totalLength - itemLength) / 2;
if (margin < posMin) {
margin = (areaLength - itemLength) / 2;
totalLength = 0;
step++;
}
}
steps[id] = step;
margins[step] = $$.isLegendInset ? 10 : margin;
offsets[id] = totalLength;
totalLength += itemLength;
}
if (reset) {
totalLength = 0;
step = 0;
maxWidth = 0;
maxHeight = 0;
}
if (config.legend_show && !$$.isLegendToShow(id)) {
widths[id] = heights[id] = steps[id] = offsets[id] = 0;
return;
}
widths[id] = itemWidth;
heights[id] = itemHeight;
if (!maxWidth || itemWidth >= maxWidth) { maxWidth = itemWidth; }
if (!maxHeight || itemHeight >= maxHeight) { maxHeight = itemHeight; }
maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth;
if (config.legend_equally) {
Object.keys(widths).forEach(function (id) { widths[id] = maxWidth; });
Object.keys(heights).forEach(function (id) { heights[id] = maxHeight; });
margin = (areaLength - maxLength * targetIds.length) / 2;
if (margin < posMin) {
totalLength = 0;
step = 0;
targetIds.forEach(function (id) { updateValues(id); });
}
else {
updateValues(id, true);
}
} else {
updateValues(id);
}
}
if ($$.isLegendRight) {
xForLegend = function (id) { return maxWidth * steps[id]; };
yForLegend = function (id) { return margins[steps[id]] + offsets[id]; };
} else if ($$.isLegendInset) {
xForLegend = function (id) { return maxWidth * steps[id] + 10; };
yForLegend = function (id) { return margins[steps[id]] + offsets[id]; };
} else {
xForLegend = function (id) { return margins[steps[id]] + offsets[id]; };
yForLegend = function (id) { return maxHeight * steps[id]; };
}
xForLegendText = function (id, i) { return xForLegend(id, i) + 14; };
yForLegendText = function (id, i) { return yForLegend(id, i) + 9; };
xForLegendRect = function (id, i) { return xForLegend(id, i) - 4; };
yForLegendRect = function (id, i) { return yForLegend(id, i) - 7; };
// Define g for legend area
l = $$.legend.selectAll('.' + CLASS.legendItem)
.data(targetIds)
.enter().append('g')
.attr('class', function (id) { return $$.generateClass(CLASS.legendItem, id); })
.style('visibility', function (id) { return $$.isLegendToShow(id) ? 'visible' : 'hidden'; })
.style('cursor', 'pointer')
.on('click', function (id) {
config.legend_item_onclick ? config.legend_item_onclick.call($$, id) : $$.api.toggle(id);
})
.on('mouseover', function (id) {
$$.d3.select(this).classed(CLASS.legendItemFocused, true);
if (!$$.transiting) {
$$.api.focus(id);
}
if (config.legend_item_onmouseover) {
config.legend_item_onmouseover.call($$, id);
}
})
.on('mouseout', function (id) {
$$.d3.select(this).classed(CLASS.legendItemFocused, false);
if (!$$.transiting) {
$$.api.revert();
}
if (config.legend_item_onmouseout) {
config.legend_item_onmouseout.call($$, id);
}
});
l.append('text')
.text(function (id) { return isDefined(config.data_names[id]) ? config.data_names[id] : id; })
.each(function (id, i) { updatePositions(this, id, i === 0); })
.style("pointer-events", "none")
.attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200)
.attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText);
l.append('rect')
.attr("class", CLASS.legendItemEvent)
.style('fill-opacity', 0)
.attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200)
.attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect);
l.append('rect')
.attr("class", CLASS.legendItemTile)
.style("pointer-events", "none")
.style('fill', $$.color)
.attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200)
.attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegend)
.attr('width', 10)
.attr('height', 10);
// Set background for inset legend
if ($$.isLegendInset && maxWidth !== 0) {
$$.legend.insert('g', '.' + CLASS.legendItem)
.attr("class", CLASS.legendBackground)
.append('rect')
.attr('height', $$.getLegendHeight() - 10)
.attr('width', maxWidth * (step + 1) + 10);
}
texts = $$.legend.selectAll('text')
.data(targetIds)
.text(function (id) { return isDefined(config.data_names[id]) ? config.data_names[id] : id; }) // MEMO: needed for update
.each(function (id, i) { updatePositions(this, id, i === 0); });
(withTransition ? texts.transition() : texts)
.attr('x', xForLegendText)
.attr('y', yForLegendText);
rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent)
.data(targetIds);
(withTransition ? rects.transition() : rects)
.attr('width', function (id) { return widths[id]; })
.attr('height', function (id) { return heights[id]; })
.attr('x', xForLegendRect)
.attr('y', yForLegendRect);
tiles = $$.legend.selectAll('rect.' + CLASS.legendItemTile)
.data(targetIds);
(withTransition ? tiles.transition() : tiles)
.style('fill', $$.color)
.attr('x', xForLegend)
.attr('y', yForLegend);
// toggle legend state
$$.legend.selectAll('.' + CLASS.legendItem)
.classed(CLASS.legendItemHidden, function (id) { return !$$.isTargetToShow(id); })
.transition()
.style('opacity', function (id) {
var This = $$.d3.select(this);
if ($$.isTargetToShow(id)) {
return !hasFocused || This.classed(CLASS.legendItemFocused) ? $$.opacityForLegend(This) : $$.opacityForUnfocusedLegend(This);
} else {
return $$.legendOpacityForHidden;
}
});
// Update all to reflect change of legend
$$.updateLegendItemWidth(maxWidth);
$$.updateLegendItemHeight(maxHeight);
$$.updateLegendStep(step);
// Update size and scale
$$.updateSizes();
$$.updateScales();
$$.updateSvgSize();
// Update g positions
$$.transformAll(withTransitionForTransform, transitions);
};
c3_chart_internal_fn.initRegion = function () {
var $$ = this;
$$.main.append('g')
.attr("clip-path", $$.clipPath)
.attr("class", CLASS.regions);
};
c3_chart_internal_fn.redrawRegion = function (duration) {
var $$ = this, config = $$.config;
$$.mainRegion = $$.main.select('.' + CLASS.regions).selectAll('.' + CLASS.region)
.data(config.regions);
$$.mainRegion.enter().append('g')
.attr('class', $$.classRegion.bind($$))
.append('rect')
.style("fill-opacity", 0);
$$.mainRegion.exit().transition().duration(duration)
.style("opacity", 0)
.remove();
};
c3_chart_internal_fn.addTransitionForRegion = function (transitions) {
var $$ = this,
x = $$.regionX.bind($$),
y = $$.regionY.bind($$),
w = $$.regionWidth.bind($$),
h = $$.regionHeight.bind($$);
transitions.push($$.mainRegion.selectAll('rect').transition()
.attr("x", x)
.attr("y", y)
.attr("width", w)
.attr("height", h)
.style("fill-opacity", function (d) { return isValue(d.opacity) ? d.opacity : 0.1; }));
};
c3_chart_internal_fn.regionX = function (d) {
var $$ = this, config = $$.config,
xPos, yScale = d.axis === 'y' ? $$.y : $$.y2;
if (d.axis === 'y' || d.axis === 'y2') {
xPos = config.axis_rotated ? ('start' in d ? yScale(d.start) : 0) : 0;
} else {
xPos = config.axis_rotated ? 0 : ('start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0);
}
return xPos;
};
c3_chart_internal_fn.regionY = function (d) {
var $$ = this, config = $$.config,
yPos, yScale = d.axis === 'y' ? $$.y : $$.y2;
if (d.axis === 'y' || d.axis === 'y2') {
yPos = config.axis_rotated ? 0 : ('end' in d ? yScale(d.end) : 0);
} else {
yPos = config.axis_rotated ? ('start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0) : 0;
}
return yPos;
};
c3_chart_internal_fn.regionWidth = function (d) {
var $$ = this, config = $$.config,
start = $$.regionX(d), end, yScale = d.axis === 'y' ? $$.y : $$.y2;
if (d.axis === 'y' || d.axis === 'y2') {
end = config.axis_rotated ? ('end' in d ? yScale(d.end) : $$.width) : $$.width;
} else {
end = config.axis_rotated ? $$.width : ('end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.width);
}
return end < start ? 0 : end - start;
};
c3_chart_internal_fn.regionHeight = function (d) {
var $$ = this, config = $$.config,
start = this.regionY(d), end, yScale = d.axis === 'y' ? $$.y : $$.y2;
if (d.axis === 'y' || d.axis === 'y2') {
end = config.axis_rotated ? $$.height : ('start' in d ? yScale(d.start) : $$.height);
} else {
end = config.axis_rotated ? ('end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.height) : $$.height;
}
return end < start ? 0 : end - start;
};
c3_chart_internal_fn.isRegionOnX = function (d) {
return !d.axis || d.axis === 'x';
};
c3_chart_internal_fn.getScale = function (min, max, forTimeseries) {
return (forTimeseries ? this.d3.time.scale() : this.d3.scale.linear()).range([min, max]);
};
c3_chart_internal_fn.getX = function (min, max, domain, offset) {
var $$ = this,
scale = $$.getScale(min, max, $$.isTimeSeries()),
_scale = domain ? scale.domain(domain) : scale, key;
// Define customized scale if categorized axis
if ($$.isCategorized()) {
offset = offset || function () { return 0; };
scale = function (d, raw) {
var v = _scale(d) + offset(d);
return raw ? v : Math.ceil(v);
};
} else {
scale = function (d, raw) {
var v = _scale(d);
return raw ? v : Math.ceil(v);
};
}
// define functions
for (key in _scale) {
scale[key] = _scale[key];
}
scale.orgDomain = function () {
return _scale.domain();
};
// define custom domain() for categorized axis
if ($$.isCategorized()) {
scale.domain = function (domain) {
if (!arguments.length) {
domain = this.orgDomain();
return [domain[0], domain[1] + 1];
}
_scale.domain(domain);
return scale;
};
}
return scale;
};
c3_chart_internal_fn.getY = function (min, max, domain) {
var scale = this.getScale(min, max);
if (domain) { scale.domain(domain); }
return scale;
};
c3_chart_internal_fn.getYScale = function (id) {
return this.getAxisId(id) === 'y2' ? this.y2 : this.y;
};
c3_chart_internal_fn.getSubYScale = function (id) {
return this.getAxisId(id) === 'y2' ? this.subY2 : this.subY;
};
c3_chart_internal_fn.updateScales = function () {
var $$ = this, config = $$.config,
forInit = !$$.x;
// update edges
$$.xMin = config.axis_rotated ? 1 : 0;
$$.xMax = config.axis_rotated ? $$.height : $$.width;
$$.yMin = config.axis_rotated ? 0 : $$.height;
$$.yMax = config.axis_rotated ? $$.width : 1;
$$.subXMin = $$.xMin;
$$.subXMax = $$.xMax;
$$.subYMin = config.axis_rotated ? 0 : $$.height2;
$$.subYMax = config.axis_rotated ? $$.width2 : 1;
// update scales
$$.x = $$.getX($$.xMin, $$.xMax, forInit ? undefined : $$.x.orgDomain(), function () { return $$.xAxis.tickOffset(); });
$$.y = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y_default : $$.y.domain());
$$.y2 = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y2_default : $$.y2.domain());
$$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function (d) { return d % 1 ? 0 : $$.subXAxis.tickOffset(); });
$$.subY = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y_default : $$.subY.domain());
$$.subY2 = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y2_default : $$.subY2.domain());
// update axes
$$.xAxisTickFormat = $$.getXAxisTickFormat();
$$.xAxisTickValues = config.axis_x_tick_values ? config.axis_x_tick_values : (forInit ? undefined : $$.xAxis.tickValues());
$$.xAxis = $$.getXAxis($$.x, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues);
$$.subXAxis = $$.getXAxis($$.subX, $$.subXOrient, $$.xAxisTickFormat, $$.xAxisTickValues);
$$.yAxis = $$.getYAxis($$.y, $$.yOrient, config.axis_y_tick_format, config.axis_y_ticks);
$$.y2Axis = $$.getYAxis($$.y2, $$.y2Orient, config.axis_y2_tick_format, config.axis_y2_ticks);
// Set initialized scales to brush and zoom
if (!forInit) {
if ($$.brush) { $$.brush.scale($$.subX); }
if (config.zoom_enabled) { $$.zoom.scale($$.x); }
}
// update for arc
if ($$.updateArc) { $$.updateArc(); }
};
c3_chart_internal_fn.selectPoint = function (target, d, i) {
var $$ = this, config = $$.config,
cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$),
cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$),
r = $$.pointSelectR.bind($$);
config.data_onselected.call($$.api, d, target.node());
// add selected-circle on low layer g
$$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i)
.data([d])
.enter().append('circle')
.attr("class", function () { return $$.generateClass(CLASS.selectedCircle, i); })
.attr("cx", cx)
.attr("cy", cy)
.attr("stroke", function () { return $$.color(d); })
.attr("r", function (d) { return $$.pointSelectR(d) * 1.4; })
.transition().duration(100)
.attr("r", r);
};
c3_chart_internal_fn.unselectPoint = function (target, d, i) {
var $$ = this;
$$.config.data_onunselected(d, target.node());
// remove selected-circle from low layer g
$$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i)
.transition().duration(100).attr('r', 0)
.remove();
};
c3_chart_internal_fn.togglePoint = function (selected, target, d, i) {
selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i);
};
c3_chart_internal_fn.selectBar = function (target, d) {
var $$ = this;
$$.config.data_onselected.call($$, d, target.node());
target.transition().duration(100)
.style("fill", function () { return $$.d3.rgb($$.color(d)).brighter(0.75); });
};
c3_chart_internal_fn.unselectBar = function (target, d) {
var $$ = this;
$$.config.data_onunselected.call($$, d, target.node());
target.transition().duration(100)
.style("fill", function () { return $$.color(d); });
};
c3_chart_internal_fn.toggleBar = function (selected, target, d, i) {
selected ? this.selectBar(target, d, i) : this.unselectBar(target, d, i);
};
c3_chart_internal_fn.toggleArc = function (selected, target, d, i) {
this.toggleBar(selected, target, d.data, i);
};
c3_chart_internal_fn.getToggle = function (that) {
var $$ = this;
// path selection not supported yet
return that.nodeName === 'circle' ? $$.togglePoint : ($$.d3.select(that).classed(CLASS.bar) ? $$.toggleBar : $$.toggleArc);
};
c3_chart_internal_fn.toggleShape = function (that, d, i) {
var $$ = this, d3 = $$.d3, config = $$.config,
shape = d3.select(that), isSelected = shape.classed(CLASS.SELECTED), isWithin, toggle;
if (that.nodeName === 'circle') {
if ($$.isStepType(d)) {
// circle is hidden in step chart, so treat as within the click area
isWithin = true;
toggle = function () {}; // TODO: how to select step chart?
} else {
isWithin = $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5);
toggle = $$.togglePoint;
}
}
else if (that.nodeName === 'path') {
if (shape.classed(CLASS.bar)) {
isWithin = $$.isWithinBar(that);
toggle = $$.toggleBar;
} else { // would be arc
isWithin = true;
toggle = $$.toggleArc;
}
}
if (config.data_selection_grouped || isWithin) {
if (config.data_selection_enabled && config.data_selection_isselectable(d)) {
if (!config.data_selection_multiple) {
$$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : "")).selectAll('.' + CLASS.shape).each(function (d, i) {
var shape = d3.select(this);
if (shape.classed(CLASS.SELECTED)) { toggle.call($$, false, shape.classed(CLASS.SELECTED, false), d, i); }
});
}
shape.classed(CLASS.SELECTED, !isSelected);
toggle.call($$, !isSelected, shape, d, i);
}
$$.config.data_onclick.call($$.api, d, that);
}
};
c3_chart_internal_fn.initBar = function () {
var $$ = this;
$$.main.select('.' + CLASS.chart).append("g")
.attr("class", CLASS.chartBars);
};
c3_chart_internal_fn.updateTargetsForBar = function (targets) {
var $$ = this, config = $$.config,
mainBarUpdate, mainBarEnter,
classChartBar = $$.classChartBar.bind($$),
classBars = $$.classBars.bind($$);
mainBarUpdate = $$.main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar)
.data(targets)
.attr('class', classChartBar);
mainBarEnter = mainBarUpdate.enter().append('g')
.attr('class', classChartBar)
.style('opacity', 0)
.style("pointer-events", "none");
// Bars for each data
mainBarEnter.append('g')
.attr("class", classBars)
.style("cursor", function (d) { return config.data_selection_isselectable(d) ? "pointer" : null; });
};
c3_chart_internal_fn.redrawBar = function (durationForExit) {
var $$ = this,
barData = $$.barData.bind($$),
classBar = $$.classBar.bind($$),
initialOpacity = $$.initialOpacity.bind($$),
color = function (d) { return $$.color(d.id); };
$$.mainBar = $$.main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar)
.data(barData);
$$.mainBar.enter().append('path')
.attr("class", classBar)
.style("stroke", color)
.style("fill", color);
$$.mainBar
.style("opacity", initialOpacity);
$$.mainBar.exit().transition().duration(durationForExit)
.style('opacity', 0)
.remove();
};
c3_chart_internal_fn.addTransitionForBar = function (transitions, drawBar) {
var $$ = this;
transitions.push($$.mainBar.transition()
.attr('d', drawBar)
.style("fill", $$.color)
.style("opacity", 1));
};
c3_chart_internal_fn.getBarW = function (axis, barTargetsNum) {
var $$ = this, config = $$.config,
w = typeof config.bar_width === 'number' ? config.bar_width : barTargetsNum ? (axis.tickOffset() * 2 * config.bar_width_ratio) / barTargetsNum : 0;
return config.bar_width_max && w > config.bar_width_max ? config.bar_width_max : w;
};
c3_chart_internal_fn.getBars = function (i) {
var $$ = this;
return $$.main.selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''));
};
c3_chart_internal_fn.expandBars = function (i, id, reset) {
var $$ = this;
if (reset) { $$.unexpandBars(); }
$$.getBars(i).classed(CLASS.EXPANDED, true);
};
c3_chart_internal_fn.unexpandBars = function (i) {
var $$ = this;
$$.getBars(i).classed(CLASS.EXPANDED, false);
};
c3_chart_internal_fn.generateDrawBar = function (barIndices, isSub) {
var $$ = this, config = $$.config,
getPoints = $$.generateGetBarPoints(barIndices, isSub);
return function (d, i) {
// 4 points that make a bar
var points = getPoints(d, i);
// switch points if axis is rotated, not applicable for sub chart
var indexX = config.axis_rotated ? 1 : 0;
var indexY = config.axis_rotated ? 0 : 1;
var path = 'M ' + points[0][indexX] + ',' + points[0][indexY] + ' ' +
'L' + points[1][indexX] + ',' + points[1][indexY] + ' ' +
'L' + points[2][indexX] + ',' + points[2][indexY] + ' ' +
'L' + points[3][indexX] + ',' + points[3][indexY] + ' ' +
'z';
return path;
};
};
c3_chart_internal_fn.generateGetBarPoints = function (barIndices, isSub) {
var $$ = this,
barTargetsNum = barIndices.__max__ + 1,
barW = $$.getBarW($$.xAxis, barTargetsNum),
barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub),
barY = $$.getShapeY(!!isSub),
barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub),
yScale = isSub ? $$.getSubYScale : $$.getYScale;
return function (d, i) {
var y0 = yScale.call($$, d.id)(0),
offset = barOffset(d, i) || y0, // offset is for stacked bar chart
posX = barX(d), posY = barY(d);
// fix posY not to overflow opposite quadrant
if ($$.config.axis_rotated) {
if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; }
}
// 4 points that make a bar
return [
[posX, offset],
[posX, posY - (y0 - offset)],
[posX + barW, posY - (y0 - offset)],
[posX + barW, offset]
];
};
};
c3_chart_internal_fn.isWithinBar = function (_this) {
var d3 = this.d3,
mouse = d3.mouse(_this), box = _this.getBoundingClientRect(),
seg0 = _this.pathSegList.getItem(0), seg1 = _this.pathSegList.getItem(1),
x = seg0.x, y = Math.min(seg0.y, seg1.y), w = box.width, h = box.height, offset = 2,
sx = x - offset, ex = x + w + offset, sy = y + h + offset, ey = y - offset;
return sx < mouse[0] && mouse[0] < ex && ey < mouse[1] && mouse[1] < sy;
};
c3_chart_internal_fn.getShapeIndices = function (typeFilter) {
var $$ = this, config = $$.config,
indices = {}, i = 0, j, k;
$$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) {
for (j = 0; j < config.data_groups.length; j++) {
if (config.data_groups[j].indexOf(d.id) < 0) { continue; }
for (k = 0; k < config.data_groups[j].length; k++) {
if (config.data_groups[j][k] in indices) {
indices[d.id] = indices[config.data_groups[j][k]];
break;
}
}
}
if (isUndefined(indices[d.id])) { indices[d.id] = i++; }
});
indices.__max__ = i - 1;
return indices;
};
c3_chart_internal_fn.getShapeX = function (offset, targetsNum, indices, isSub) {
var $$ = this, scale = isSub ? $$.subX : $$.x;
return function (d) {
var index = d.id in indices ? indices[d.id] : 0;
return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0;
};
};
c3_chart_internal_fn.getShapeY = function (isSub) {
var $$ = this;
return function (d) {
var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id);
return scale(d.value);
};
};
c3_chart_internal_fn.getShapeOffset = function (typeFilter, indices, isSub) {
var $$ = this,
targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))),
targetIds = targets.map(function (t) { return t.id; });
return function (d, i) {
var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id),
y0 = scale(0), offset = y0;
targets.forEach(function (t) {
if (t.id === d.id || indices[t.id] !== indices[d.id]) { return; }
if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id) && t.values[i].value * d.value >= 0) {
offset += scale(t.values[i].value) - y0;
}
});
return offset;
};
};
c3_chart_internal_fn.getInterpolate = function (d) {
var $$ = this;
return $$.isSplineType(d) ? "cardinal" : $$.isStepType(d) ? "step-after" : "linear";
};
c3_chart_internal_fn.initLine = function () {
var $$ = this;
$$.main.select('.' + CLASS.chart).append("g")
.attr("class", CLASS.chartLines);
};
c3_chart_internal_fn.updateTargetsForLine = function (targets) {
var $$ = this, config = $$.config,
mainLineUpdate, mainLineEnter,
classChartLine = $$.classChartLine.bind($$),
classLines = $$.classLines.bind($$),
classAreas = $$.classAreas.bind($$),
classCircles = $$.classCircles.bind($$);
mainLineUpdate = $$.main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine)
.data(targets)
.attr('class', classChartLine);
mainLineEnter = mainLineUpdate.enter().append('g')
.attr('class', classChartLine)
.style('opacity', 0)
.style("pointer-events", "none");
// Lines for each data
mainLineEnter.append('g')
.attr("class", classLines);
// Areas
mainLineEnter.append('g')
.attr('class', classAreas);
// Circles for each data point on lines
mainLineEnter.append('g')
.attr("class", function (d) { return $$.generateClass(CLASS.selectedCircles, d.id); });
mainLineEnter.append('g')
.attr("class", classCircles)
.style("cursor", function (d) { return config.data_selection_isselectable(d) ? "pointer" : null; });
// Update date for selected circles
targets.forEach(function (t) {
$$.main.selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id)).selectAll('.' + CLASS.selectedCircle).each(function (d) {
d.value = t.values[d.index].value;
});
});
// MEMO: can not keep same color...
//mainLineUpdate.exit().remove();
};
c3_chart_internal_fn.redrawLine = function (durationForExit) {
var $$ = this;
$$.mainLine = $$.main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line)
.data($$.lineData.bind($$));
$$.mainLine.enter().append('path')
.attr('class', $$.classLine.bind($$))
.style("stroke", $$.color);
$$.mainLine
.style("opacity", $$.initialOpacity.bind($$))
.attr('transform', null);
$$.mainLine.exit().transition().duration(durationForExit)
.style('opacity', 0)
.remove();
};
c3_chart_internal_fn.addTransitionForLine = function (transitions, drawLine) {
var $$ = this;
transitions.push($$.mainLine.transition()
.attr("d", drawLine)
.style("stroke", $$.color)
.style("opacity", 1));
};
c3_chart_internal_fn.generateDrawLine = function (lineIndices, isSub) {
var $$ = this, config = $$.config,
line = $$.d3.svg.line(),
getPoints = $$.generateGetLinePoints(lineIndices, isSub),
yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
xValue = function (d) { return (isSub ? $$.subxx : $$.xx).call($$, d); },
yValue = function (d, i) {
return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)(d.value);
};
line = config.axis_rotated ? line.x(yValue).y(xValue) : line.x(xValue).y(yValue);
if (!config.line_connect_null) { line = line.defined(function (d) { return d.value != null; }); }
return function (d) {
var data = config.line_connect_null ? $$.filterRemoveNull(d.values) : d.values,
x = isSub ? $$.x : $$.subX, y = yScaleGetter.call($$, d.id), x0 = 0, y0 = 0, path;
if ($$.isLineType(d)) {
if (config.data_regions[d.id]) {
path = $$.lineWithRegions(data, x, y, config.data_regions[d.id]);
} else {
path = line.interpolate($$.getInterpolate(d))(data);
}
} else {
if (data[0]) {
x0 = x(data[0].x);
y0 = y(data[0].value);
}
path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
}
return path ? path : "M 0 0";
};
};
c3_chart_internal_fn.generateGetLinePoints = function (lineIndices, isSub) { // partial duplication of generateGetBarPoints
var $$ = this, config = $$.config,
lineTargetsNum = lineIndices.__max__ + 1,
x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub),
y = $$.getShapeY(!!isSub),
lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub),
yScale = isSub ? $$.getSubYScale : $$.getYScale;
return function (d, i) {
var y0 = yScale.call($$, d.id)(0),
offset = lineOffset(d, i) || y0, // offset is for stacked area chart
posX = x(d), posY = y(d);
// fix posY not to overflow opposite quadrant
if (config.axis_rotated) {
if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; }
}
// 1 point that marks the line position
return [
[posX, posY - (y0 - offset)],
[posX, posY - (y0 - offset)], // needed for compatibility
[posX, posY - (y0 - offset)], // needed for compatibility
[posX, posY - (y0 - offset)] // needed for compatibility
];
};
};
c3_chart_internal_fn.lineWithRegions = function (d, x, y, _regions) {
var $$ = this, config = $$.config,
prev = -1, i, j,
s = "M", sWithRegion,
xp, yp, dx, dy, dd, diff, diffx2,
xValue, yValue,
regions = [];
function isWithinRegions(x, regions) {
var i;
for (i = 0; i < regions.length; i++) {
if (regions[i].start < x && x <= regions[i].end) { return true; }
}
return false;
}
// Check start/end of regions
if (isDefined(_regions)) {
for (i = 0; i < _regions.length; i++) {
regions[i] = {};
if (isUndefined(_regions[i].start)) {
regions[i].start = d[0].x;
} else {
regions[i].start = $$.isTimeSeries() ? $$.parseDate(_regions[i].start) : _regions[i].start;
}
if (isUndefined(_regions[i].end)) {
regions[i].end = d[d.length - 1].x;
} else {
regions[i].end = $$.isTimeSeries() ? $$.parseDate(_regions[i].end) : _regions[i].end;
}
}
}
// Set scales
xValue = config.axis_rotated ? function (d) { return y(d.value); } : function (d) { return x(d.x); };
yValue = config.axis_rotated ? function (d) { return x(d.x); } : function (d) { return y(d.value); };
// Define svg generator function for region
if ($$.isTimeSeries()) {
sWithRegion = function (d0, d1, j, diff) {
var x0 = d0.x.getTime(), x_diff = d1.x - d0.x,
xv0 = new Date(x0 + x_diff * j),
xv1 = new Date(x0 + x_diff * (j + diff));
return "M" + x(xv0) + " " + y(yp(j)) + " " + x(xv1) + " " + y(yp(j + diff));
};
} else {
sWithRegion = function (d0, d1, j, diff) {
return "M" + x(xp(j), true) + " " + y(yp(j)) + " " + x(xp(j + diff), true) + " " + y(yp(j + diff));
};
}
// Generate
for (i = 0; i < d.length; i++) {
// Draw as normal
if (isUndefined(regions) || ! isWithinRegions(d[i].x, regions)) {
s += " " + xValue(d[i]) + " " + yValue(d[i]);
}
// Draw with region // TODO: Fix for horizotal charts
else {
xp = $$.getScale(d[i - 1].x, d[i].x, $$.isTimeSeries());
yp = $$.getScale(d[i - 1].value, d[i].value);
dx = x(d[i].x) - x(d[i - 1].x);
dy = y(d[i].value) - y(d[i - 1].value);
dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
diff = 2 / dd;
diffx2 = diff * 2;
for (j = diff; j <= 1; j += diffx2) {
s += sWithRegion(d[i - 1], d[i], j, diff);
}
}
prev = d[i].x;
}
return s;
};
c3_chart_internal_fn.redrawArea = function (durationForExit) {
var $$ = this, d3 = $$.d3;
$$.mainArea = $$.main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area)
.data($$.lineData.bind($$));
$$.mainArea.enter().append('path')
.attr("class", $$.classArea.bind($$))
.style("fill", $$.color)
.style("opacity", function () { $$.orgAreaOpacity = +d3.select(this).style('opacity'); return 0; });
$$.mainArea
.style("opacity", $$.orgAreaOpacity);
$$.mainArea.exit().transition().duration(durationForExit)
.style('opacity', 0)
.remove();
};
c3_chart_internal_fn.addTransitionForArea = function (transitions, drawArea) {
var $$ = this;
transitions.push($$.mainArea.transition()
.attr("d", drawArea)
.style("fill", $$.color)
.style("opacity", $$.orgAreaOpacity));
};
c3_chart_internal_fn.generateDrawArea = function (areaIndices, isSub) {
var $$ = this, config = $$.config, area = $$.d3.svg.area(),
getPoints = $$.generateGetAreaPoints(areaIndices, isSub),
yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
xValue = function (d) { return (isSub ? $$.subxx : $$.xx).call($$, d); },
value0 = function (d, i) {
return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)(0);
},
value1 = function (d, i) {
return config.data_groups.length > 0 ? getPoints(d, i)[1][1] : yScaleGetter.call($$, d.id)(d.value);
};
area = config.axis_rotated ? area.x0(value0).x1(value1).y(xValue) : area.x(xValue).y0(value0).y1(value1);
if (!config.line_connect_null) {
area = area.defined(function (d) { return d.value !== null; });
}
return function (d) {
var data = config.line_connect_null ? $$.filterRemoveNull(d.values) : d.values, x0 = 0, y0 = 0, path;
if ($$.isAreaType(d)) {
path = area.interpolate($$.getInterpolate(d))(data);
} else {
if (data[0]) {
x0 = $$.x(data[0].x);
y0 = $$.getYScale(d.id)(data[0].value);
}
path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
}
return path ? path : "M 0 0";
};
};
c3_chart_internal_fn.generateGetAreaPoints = function (areaIndices, isSub) { // partial duplication of generateGetBarPoints
var $$ = this, config = $$.config,
areaTargetsNum = areaIndices.__max__ + 1,
x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub),
y = $$.getShapeY(!!isSub),
areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub),
yScale = isSub ? $$.getSubYScale : $$.getYScale;
return function (d, i) {
var y0 = yScale.call($$, d.id)(0),
offset = areaOffset(d, i) || y0, // offset is for stacked area chart
posX = x(d), posY = y(d);
// fix posY not to overflow opposite quadrant
if (config.axis_rotated) {
if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; }
}
// 1 point that marks the area position
return [
[posX, offset],
[posX, posY - (y0 - offset)],
[posX, posY - (y0 - offset)], // needed for compatibility
[posX, offset] // needed for compatibility
];
};
};
c3_chart_internal_fn.redrawCircle = function () {
var $$ = this;
$$.mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle)
.data($$.lineOrScatterData.bind($$));
$$.mainCircle.enter().append("circle")
.attr("class", $$.classCircle.bind($$))
.attr("r", $$.pointR.bind($$))
.style("fill", $$.color);
$$.mainCircle
.style("opacity", $$.initialOpacity.bind($$));
$$.mainCircle.exit().remove();
};
c3_chart_internal_fn.addTransitionForCircle = function (transitions, cx, cy) {
var $$ = this;
transitions.push($$.mainCircle.transition()
.style('opacity', $$.opacityForCircle.bind($$))
.style("fill", $$.color)
.attr("cx", cx)
.attr("cy", cy));
transitions.push($$.main.selectAll('.' + CLASS.selectedCircle).transition()
.attr("cx", cx)
.attr("cy", cy));
};
c3_chart_internal_fn.circleX = function (d) {
return d.x || d.x === 0 ? this.x(d.x) : null;
};
c3_chart_internal_fn.circleY = function (d, i) {
var $$ = this,
lineIndices = $$.getShapeIndices($$.isLineType), getPoints = $$.generateGetLinePoints(lineIndices);
return $$.config.data_groups.length > 0 ? getPoints(d, i)[0][1] : $$.getYScale(d.id)(d.value);
};
c3_chart_internal_fn.getCircles = function (i, id) {
var $$ = this;
return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''));
};
c3_chart_internal_fn.expandCircles = function (i, id, reset) {
var $$ = this,
r = $$.pointExpandedR.bind($$);
if (reset) { $$.unexpandCircles(); }
$$.getCircles(i, id)
.classed(CLASS.EXPANDED, true)
.attr('r', r);
};
c3_chart_internal_fn.unexpandCircles = function (i) {
var $$ = this,
r = $$.pointR.bind($$);
$$.getCircles(i)
.filter(function () { return $$.d3.select(this).classed(CLASS.EXPANDED); })
.classed(CLASS.EXPANDED, false)
.attr('r', r);
};
c3_chart_internal_fn.pointR = function (d) {
var $$ = this, config = $$.config;
return config.point_show && !$$.isStepType(d) ? (isFunction(config.point_r) ? config.point_r(d) : config.point_r) : 0;
};
c3_chart_internal_fn.pointExpandedR = function (d) {
var $$ = this, config = $$.config;
return config.point_focus_expand_enabled ? (config.point_focus_expand_r ? config.point_focus_expand_r : $$.pointR(d) * 1.75) : $$.pointR(d);
};
c3_chart_internal_fn.pointSelectR = function (d) {
var $$ = this, config = $$.config;
return config.point_select_r ? config.point_select_r : $$.pointR(d) * 4;
};
c3_chart_internal_fn.isWithinCircle = function (_this, _r) {
var d3 = this.d3,
mouse = d3.mouse(_this), d3_this = d3.select(_this),
cx = d3_this.attr("cx") * 1, cy = d3_this.attr("cy") * 1;
return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < _r;
};
c3_chart_internal_fn.getCurrentWidth = function () {
var $$ = this, config = $$.config;
return config.size_width ? config.size_width : $$.getParentWidth();
};
c3_chart_internal_fn.getCurrentHeight = function () {
var $$ = this, config = $$.config,
h = config.size_height ? config.size_height : $$.getParentHeight();
return h > 0 ? h : 320 / ($$.hasType('gauge') ? 2 : 1);
};
c3_chart_internal_fn.getCurrentPaddingTop = function () {
var config = this.config;
return isValue(config.padding_top) ? config.padding_top : 0;
};
c3_chart_internal_fn.getCurrentPaddingBottom = function () {
var config = this.config;
return isValue(config.padding_bottom) ? config.padding_bottom : 0;
};
c3_chart_internal_fn.getCurrentPaddingLeft = function () {
var $$ = this, config = $$.config;
if (isValue(config.padding_left)) {
return config.padding_left;
} else if (config.axis_rotated) {
return !config.axis_x_show ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x')), 40);
} else {
return !config.axis_y_show ? 1 : ceil10($$.getAxisWidthByAxisId('y'));
}
};
c3_chart_internal_fn.getCurrentPaddingRight = function () {
var $$ = this, config = $$.config,
defaultPadding = 10, legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0;
if (isValue(config.padding_right)) {
return config.padding_right + 1; // 1 is needed not to hide tick line
} else if (config.axis_rotated) {
return defaultPadding + legendWidthOnRight;
} else {
return (!config.axis_y2_show ? defaultPadding : ceil10($$.getAxisWidthByAxisId('y2'))) + legendWidthOnRight;
}
};
c3_chart_internal_fn.getParentRectValue = function (key) {
var parent = this.selectChart.node(), v;
while (parent && parent.tagName !== 'BODY') {
v = parent.getBoundingClientRect()[key];
if (v) {
break;
}
parent = parent.parentNode;
}
return v;
};
c3_chart_internal_fn.getParentWidth = function () {
return this.getParentRectValue('width');
};
c3_chart_internal_fn.getParentHeight = function () {
var h = this.selectChart.style('height');
return h.indexOf('px') > 0 ? +h.replace('px', '') : 0;
};
c3_chart_internal_fn.getSvgLeft = function () {
var $$ = this, config = $$.config,
leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY,
leftAxis = $$.main.select('.' + leftAxisClass).node(),
svgRect = leftAxis ? leftAxis.getBoundingClientRect() : {right: 0},
chartRect = $$.selectChart.node().getBoundingClientRect(),
hasArc = $$.hasArcType(),
svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft());
return svgLeft > 0 ? svgLeft : 0;
};
c3_chart_internal_fn.getAxisWidthByAxisId = function (id) {
var $$ = this, position = $$.getAxisLabelPositionById(id);
return position.isInner ? 20 + $$.getMaxTickWidth(id) : 40 + $$.getMaxTickWidth(id);
};
c3_chart_internal_fn.getHorizontalAxisHeight = function (axisId) {
var $$ = this, config = $$.config;
if (axisId === 'x' && !config.axis_x_show) { return 0; }
if (axisId === 'x' && config.axis_x_height) { return config.axis_x_height; }
if (axisId === 'y' && !config.axis_y_show) { return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1; }
if (axisId === 'y2' && !config.axis_y2_show) { return $$.rotated_padding_top; }
return ($$.getAxisLabelPositionById(axisId).isInner ? 30 : 40) + (axisId === 'y2' ? -10 : 0);
};
c3_chart_internal_fn.getEventRectWidth = function () {
var $$ = this;
var target = $$.getMaxDataCountTarget($$.data.targets),
firstData, lastData, base, maxDataCount, ratio, w;
if (!target) {
return 0;
}
firstData = target.values[0], lastData = target.values[target.values.length - 1];
base = $$.x(lastData.x) - $$.x(firstData.x);
if (base === 0) {
return $$.config.axis_rotated ? $$.height : $$.width;
}
maxDataCount = $$.getMaxDataCount();
ratio = ($$.hasType('bar') ? (maxDataCount - ($$.isCategorized() ? 0.25 : 1)) / maxDataCount : 1);
w = maxDataCount > 1 ? (base * ratio) / (maxDataCount - 1) : base;
return w < 1 ? 1 : w;
};
c3_chart_internal_fn.initBrush = function () {
var $$ = this, d3 = $$.d3;
$$.brush = d3.svg.brush().on("brush", function () { $$.redrawForBrush(); });
$$.brush.update = function () {
if ($$.context) { $$.context.select('.' + CLASS.brush).call(this); }
return this;
};
$$.brush.scale = function (scale) {
return $$.config.axis_rotated ? this.y(scale) : this.x(scale);
};
};
c3_chart_internal_fn.initSubchart = function () {
var $$ = this, config = $$.config,
context = $$.context = $$.svg.append("g").attr("transform", $$.getTranslate('context'));
if (!config.subchart_show) {
context.style('visibility', 'hidden');
}
// Define g for chart area
context.append('g')
.attr("clip-path", $$.clipPath)
.attr('class', CLASS.chart);
// Define g for bar chart area
context.select('.' + CLASS.chart).append("g")
.attr("class", CLASS.chartBars);
// Define g for line chart area
context.select('.' + CLASS.chart).append("g")
.attr("class", CLASS.chartLines);
// Add extent rect for Brush
context.append("g")
.attr("clip-path", $$.clipPath)
.attr("class", CLASS.brush)
.call($$.brush)
.selectAll("rect")
.attr(config.axis_rotated ? "width" : "height", config.axis_rotated ? $$.width2 : $$.height2);
// ATTENTION: This must be called AFTER chart added
// Add Axis
$$.axes.subx = context.append("g")
.attr("class", CLASS.axisX)
.attr("transform", $$.getTranslate('subx'))
.attr("clip-path", config.axis_rotated ? "" : $$.clipPathForXAxis);
};
c3_chart_internal_fn.updateTargetsForSubchart = function (targets) {
var $$ = this, context = $$.context, config = $$.config,
contextLineEnter, contextLineUpdate, contextBarEnter, contextBarUpdate,
classChartBar = $$.classChartBar.bind($$),
classBars = $$.classBars.bind($$),
classChartLine = $$.classChartLine.bind($$),
classLines = $$.classLines.bind($$),
classAreas = $$.classAreas.bind($$);
if (config.subchart_show) {
contextBarUpdate = context.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar)
.data(targets)
.attr('class', classChartBar);
contextBarEnter = contextBarUpdate.enter().append('g')
.style('opacity', 0)
.attr('class', classChartBar);
// Bars for each data
contextBarEnter.append('g')
.attr("class", classBars);
//-- Line --//
contextLineUpdate = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine)
.data(targets)
.attr('class', classChartLine);
contextLineEnter = contextLineUpdate.enter().append('g')
.style('opacity', 0)
.attr('class', classChartLine);
// Lines for each data
contextLineEnter.append("g")
.attr("class", classLines);
// Area
contextLineEnter.append("g")
.attr("class", classAreas);
}
};
c3_chart_internal_fn.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) {
var $$ = this, d3 = $$.d3, context = $$.context, config = $$.config,
contextLine, contextArea, contextBar, drawAreaOnSub, drawBarOnSub, drawLineOnSub,
barData = $$.barData.bind($$),
lineData = $$.lineData.bind($$),
classBar = $$.classBar.bind($$),
classLine = $$.classLine.bind($$),
classArea = $$.classArea.bind($$),
initialOpacity = $$.initialOpacity.bind($$);
// subchart
if (config.subchart_show) {
// reflect main chart to extent on subchart if zoomed
if (d3.event && d3.event.type === 'zoom') {
$$.brush.extent($$.x.orgDomain()).update();
}
// update subchart elements if needed
if (withSubchart) {
// rotate tick text if needed
if (!config.axis_rotated && config.axis_x_tick_rotate) {
$$.rotateTickText($$.axes.subx, transitions.axisSubX, config.axis_x_tick_rotate);
}
// extent rect
if (!$$.brush.empty()) {
$$.brush.extent($$.x.orgDomain()).update();
}
// setup drawer - MEMO: this must be called after axis updated
drawAreaOnSub = $$.generateDrawArea(areaIndices, true);
drawBarOnSub = $$.generateDrawBar(barIndices, true);
drawLineOnSub = $$.generateDrawLine(lineIndices, true);
// bars
contextBar = context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar)
.data(barData);
contextBar.enter().append('path')
.attr("class", classBar)
.style("stroke", 'none')
.style("fill", $$.color);
contextBar
.style("opacity", initialOpacity)
.transition().duration(duration)
.attr('d', drawBarOnSub)
.style('opacity', 1);
contextBar.exit().transition().duration(duration)
.style('opacity', 0)
.remove();
// lines
contextLine = context.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line)
.data(lineData);
contextLine.enter().append('path')
.attr('class', classLine)
.style('stroke', $$.color);
contextLine
.style("opacity", initialOpacity)
.transition().duration(duration)
.attr("d", drawLineOnSub)
.style('opacity', 1);
contextLine.exit().transition().duration(duration)
.style('opacity', 0)
.remove();
// area
contextArea = context.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area)
.data(lineData);
contextArea.enter().append('path')
.attr("class", classArea)
.style("fill", $$.color)
.style("opacity", function () { $$.orgAreaOpacity = +d3.select(this).style('opacity'); return 0; });
contextArea
.style("opacity", 0)
.transition().duration(duration)
.attr("d", drawAreaOnSub)
.style("fill", $$.color)
.style("opacity", $$.orgAreaOpacity);
contextArea.exit().transition().duration(durationForExit)
.style('opacity', 0)
.remove();
}
}
};
c3_chart_internal_fn.redrawForBrush = function () {
var $$ = this, x = $$.x;
$$.redraw({
withTransition: false,
withY: false,
withSubchart: false,
withUpdateXDomain: true
});
$$.config.subchart_onbrush.call($$.api, x.orgDomain());
};
c3_chart_internal_fn.transformContext = function (withTransition, transitions) {
var $$ = this, subXAxis;
if (transitions && transitions.axisSubX) {
subXAxis = transitions.axisSubX;
} else {
subXAxis = $$.context.select('.' + CLASS.axisX);
if (withTransition) { subXAxis = subXAxis.transition(); }
}
$$.context.attr("transform", $$.getTranslate('context'));
subXAxis.attr("transform", $$.getTranslate('subx'));
};
if (typeof define === 'function' && define.amd) {
define("c3", ["d3"], c3);
} else if ('undefined' !== typeof exports && 'undefined' !== typeof module) {
module.exports = c3;
} else {
window.c3 = c3;
}
})(window);
c3_chart_internal_fn.initText = function () {
var $$ = this;
$$.main.select('.' + CLASS.chart).append("g")
.attr("class", CLASS.chartTexts);
$$.mainText = $$.d3.selectAll([]);
};
c3_chart_internal_fn.updateTargetsForText = function (targets) {
var $$ = this, mainTextUpdate, mainTextEnter,
classChartText = $$.classChartText.bind($$),
classTexts = $$.classTexts.bind($$);
mainTextUpdate = $$.main.select('.' + CLASS.chartTexts).selectAll('.' + CLASS.chartText)
.data(targets)
.attr('class', classChartText);
mainTextEnter = mainTextUpdate.enter().append('g')
.attr('class', classChartText)
.style('opacity', 0)
.style("pointer-events", "none");
mainTextEnter.append('g')
.attr('class', classTexts);
};
c3_chart_internal_fn.redrawText = function (durationForExit) {
var $$ = this, config = $$.config,
barOrLineData = $$.barOrLineData.bind($$),
classText = $$.classText.bind($$);
$$.mainText = $$.main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text)
.data(barOrLineData);
$$.mainText.enter().append('text')
.attr("class", classText)
.attr('text-anchor', function (d) { return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle'; })
.style("stroke", 'none')
.style("fill", function (d) { return $$.color(d); })
.style("fill-opacity", 0);
$$.mainText
.text(function (d) { return $$.formatByAxisId($$.getAxisId(d.id))(d.value, d.id); });
$$.mainText.exit()
.transition().duration(durationForExit)
.style('fill-opacity', 0)
.remove();
};
c3_chart_internal_fn.addTransitionForText = function (transitions, xForText, yForText, forFlow) {
var $$ = this,
opacityForText = forFlow ? 0 : $$.opacityForText.bind($$);
transitions.push($$.mainText.transition()
.attr('x', xForText)
.attr('y', yForText)
.style("fill", $$.color)
.style("fill-opacity", opacityForText));
};
c3_chart_internal_fn.getTextRect = function (text, cls) {
var rect;
this.d3.select('body').selectAll('.dummy')
.data([text])
.enter().append('text')
.classed(cls ? cls : "", true)
.text(text)
.each(function () { rect = this.getBoundingClientRect(); })
.remove();
return rect;
};
c3_chart_internal_fn.generateXYForText = function (areaIndices, barIndices, lineIndices, forX) {
var $$ = this,
getAreaPoints = $$.generateGetAreaPoints(barIndices, false),
getBarPoints = $$.generateGetBarPoints(barIndices, false),
getLinePoints = $$.generateGetLinePoints(lineIndices, false),
getter = forX ? $$.getXForText : $$.getYForText;
return function (d, i) {
var getPoints = $$.isAreaType(d) ? getAreaPoints : $$.isBarType(d) ? getBarPoints : getLinePoints;
return getter.call($$, getPoints(d, i), d, this);
};
};
c3_chart_internal_fn.getXForText = function (points, d, textElement) {
var $$ = this,
box = textElement.getBoundingClientRect(), xPos, padding;
if ($$.config.axis_rotated) {
padding = $$.isBarType(d) ? 4 : 6;
xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1);
} else {
xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0];
}
return d.value !== null ? xPos : xPos > $$.width ? $$.width - box.width : xPos;
};
c3_chart_internal_fn.getYForText = function (points, d, textElement) {
var $$ = this,
box = textElement.getBoundingClientRect(), yPos;
if ($$.config.axis_rotated) {
yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2;
} else {
yPos = points[2][1] + (d.value < 0 ? box.height : $$.isBarType(d) ? -3 : -6);
}
return d.value !== null ? yPos : yPos < box.height ? box.height : yPos;
};
c3_chart_internal_fn.initTooltip = function () {
var $$ = this, config = $$.config, i;
$$.tooltip = $$.selectChart
.style("position", "relative")
.append("div")
.style("position", "absolute")
.style("pointer-events", "none")
.style("z-index", "10")
.style("display", "none");
// Show tooltip if needed
if (config.tooltip_init_show) {
if ($$.isTimeSeries() && isString(config.tooltip_init_x)) {
config.tooltip_init_x = $$.parseDate(config.tooltip_init_x);
for (i = 0; i < $$.data.targets[0].values.length; i++) {
if (($$.data.targets[0].values[i].x - config.tooltip_init_x) === 0) { break; }
}
config.tooltip_init_x = i;
}
$$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) {
return $$.addName(d.values[config.tooltip_init_x]);
}), $$.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color));
$$.tooltip.style("top", config.tooltip_init_position.top)
.style("left", config.tooltip_init_position.left)
.style("display", "block");
}
};
c3_chart_internal_fn.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) {
var $$ = this, config = $$.config,
titleFormat = config.tooltip_format_title || defaultTitleFormat,
nameFormat = config.tooltip_format_name || function (name) { return name; },
valueFormat = config.tooltip_format_value || defaultValueFormat,
text, i, title, value, name, bgcolor;
for (i = 0; i < d.length; i++) {
if (! (d[i] && (d[i].value || d[i].value === 0))) { continue; }
if (! text) {
title = titleFormat ? titleFormat(d[i].x) : d[i].x;
text = "<table class='" + CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
}
name = nameFormat(d[i].name);
value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
text += "<tr class='" + CLASS.tooltipName + "-" + d[i].id + "'>";
text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";
text += "<td class='value'>" + value + "</td>";
text += "</tr>";
}
return text + "</table>";
};
c3_chart_internal_fn.showTooltip = function (selectedData, mouse) {
var $$ = this, config = $$.config;
var tWidth, tHeight, svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;
var forArc = $$.hasArcType(),
dataToShow = selectedData.filter(function (d) { return d && isValue(d.value); });
if (dataToShow.length === 0 || !config.tooltip_show) {
return;
}
$$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block");
// Get tooltip dimensions
tWidth = $$.tooltip.property('offsetWidth');
tHeight = $$.tooltip.property('offsetHeight');
// Determin tooltip position
if (forArc) {
tooltipLeft = ($$.width / 2) + mouse[0];
tooltipTop = ($$.height / 2) + mouse[1] + 20;
} else {
if (config.axis_rotated) {
svgLeft = $$.getSvgLeft();
tooltipLeft = svgLeft + mouse[0] + 100;
tooltipRight = tooltipLeft + tWidth;
chartRight = $$.getCurrentWidth() - $$.getCurrentPaddingRight();
tooltipTop = $$.x(dataToShow[0].x) + 20;
} else {
svgLeft = $$.getSvgLeft();
tooltipLeft = svgLeft + $$.getCurrentPaddingLeft() + $$.x(dataToShow[0].x) + 20;
tooltipRight = tooltipLeft + tWidth;
chartRight = svgLeft + $$.getCurrentWidth() - $$.getCurrentPaddingRight();
tooltipTop = mouse[1] + 15;
}
if (tooltipRight > chartRight) {
tooltipLeft -= tooltipRight - chartRight;
}
if (tooltipTop + tHeight > $$.getCurrentHeight() && tooltipTop > tHeight + 30) {
tooltipTop -= tHeight + 30;
}
}
// Set tooltip
$$.tooltip
.style("top", tooltipTop + "px")
.style("left", tooltipLeft + 'px');
};
c3_chart_internal_fn.hideTooltip = function () {
this.tooltip.style("display", "none");
};
c3_chart_internal_fn.setTargetType = function (targetIds, type) {
var $$ = this, config = $$.config;
$$.mapToTargetIds(targetIds).forEach(function (id) {
$$.withoutFadeIn[id] = (type === config.data_types[id]);
config.data_types[id] = type;
});
if (!targetIds) {
config.data_type = type;
}
};
c3_chart_internal_fn.hasType = function (type, targets) {
var $$ = this, types = $$.config.data_types, has = false;
(targets || $$.data.targets).forEach(function (t) {
if ((types[t.id] && types[t.id].indexOf(type) >= 0) || (!(t.id in types) && type === 'line')) {
has = true;
}
});
return has;
};
c3_chart_internal_fn.hasArcType = function (targets) {
return this.hasType('pie', targets) || this.hasType('donut', targets) || this.hasType('gauge', targets);
};
c3_chart_internal_fn.isLineType = function (d) {
var config = this.config, id = isString(d) ? d : d.id;
return !config.data_types[id] || ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(config.data_types[id]) >= 0;
};
c3_chart_internal_fn.isStepType = function (d) {
var id = isString(d) ? d : d.id;
return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
};
c3_chart_internal_fn.isSplineType = function (d) {
var id = isString(d) ? d : d.id;
return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0;
};
c3_chart_internal_fn.isAreaType = function (d) {
var id = isString(d) ? d : d.id;
return ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
};
c3_chart_internal_fn.isBarType = function (d) {
var id = isString(d) ? d : d.id;
return this.config.data_types[id] === 'bar';
};
c3_chart_internal_fn.isScatterType = function (d) {
var id = isString(d) ? d : d.id;
return this.config.data_types[id] === 'scatter';
};
c3_chart_internal_fn.isPieType = function (d) {
var id = isString(d) ? d : d.id;
return this.config.data_types[id] === 'pie';
};
c3_chart_internal_fn.isGaugeType = function (d) {
var id = isString(d) ? d : d.id;
return this.config.data_types[id] === 'gauge';
};
c3_chart_internal_fn.isDonutType = function (d) {
var id = isString(d) ? d : d.id;
return this.config.data_types[id] === 'donut';
};
c3_chart_internal_fn.isArcType = function (d) {
return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d);
};
c3_chart_internal_fn.lineData = function (d) {
return this.isLineType(d) ? [d] : [];
};
c3_chart_internal_fn.arcData = function (d) {
return this.isArcType(d.data) ? [d] : [];
};
/* not used
function scatterData(d) {
return isScatterType(d) ? d.values : [];
}
*/
c3_chart_internal_fn.barData = function (d) {
return this.isBarType(d) ? d.values : [];
};
c3_chart_internal_fn.lineOrScatterData = function (d) {
return this.isLineType(d) || this.isScatterType(d) ? d.values : [];
};
c3_chart_internal_fn.barOrLineData = function (d) {
return this.isBarType(d) || this.isLineType(d) ? d.values : [];
};
var isValue = c3_chart_internal_fn.isValue = function (v) {
return v || v === 0;
},
isFunction = c3_chart_internal_fn.isFunction = function (o) {
return typeof o === 'function';
},
isString = c3_chart_internal_fn.isString = function (o) {
return typeof o === 'string';
},
isUndefined = c3_chart_internal_fn.isUndefined = function (v) {
return typeof v === 'undefined';
},
isDefined = c3_chart_internal_fn.isDefined = function (v) {
return typeof v !== 'undefined';
},
ceil10 = c3_chart_internal_fn.ceil10 = function (v) {
return Math.ceil(v / 10) * 10;
},
asHalfPixel = c3_chart_internal_fn.asHalfPixel = function (n) {
return Math.ceil(n) + 0.5;
},
diffDomain = c3_chart_internal_fn.diffDomain = function (d) {
return d[1] - d[0];
},
isEmpty = c3_chart_internal_fn.isEmpty = function (o) {
return !o || (isString(o) && o.length === 0) || (typeof o === 'object' && Object.keys(o).length === 0);
},
notEmpty = c3_chart_internal_fn.notEmpty = function (o) {
return Object.keys(o).length > 0;
},
getOption = c3_chart_internal_fn.getOption = function (options, key, defaultValue) {
return isDefined(options[key]) ? options[key] : defaultValue;
},
hasValue = c3_chart_internal_fn.hasValue = function (dict, value) {
var found = false;
Object.keys(dict).forEach(function (key) {
if (dict[key] === value) { found = true; }
});
return found;
},
getPathBox = c3_chart_internal_fn.getPathBox = function (path) {
var box = path.getBoundingClientRect(),
items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)],
minX = items[0].x, minY = Math.min(items[0].y, items[1].y);
return {x: minX, y: minY, width: box.width, height: box.height};
};
c3_chart_internal_fn.initZoom = function () {
var $$ = this, d3 = $$.d3, config = $$.config;
$$.zoom = d3.behavior.zoom()
.on("zoomstart", function () {
$$.zoom.altDomain = d3.event.sourceEvent.altKey ? $$.x.orgDomain() : null;
})
.on("zoom", function () { $$.redrawForZoom.call($$); });
$$.zoom.scale = function (scale) {
return config.axis_rotated ? this.y(scale) : this.x(scale);
};
$$.zoom.orgScaleExtent = function () {
var extent = config.zoom_extent ? config.zoom_extent : [1, 10];
return [extent[0], Math.max($$.getMaxDataCount() / extent[1], extent[1])];
};
$$.zoom.updateScaleExtent = function () {
var ratio = diffDomain($$.x.orgDomain()) / diffDomain($$.orgXDomain),
extent = this.orgScaleExtent();
this.scaleExtent([extent[0] * ratio, extent[1] * ratio]);
return this;
};
};
c3_chart_internal_fn.updateZoom = function () {
var $$ = this, z = $$.config.zoom_enabled ? $$.zoom : function () {};
$$.main.select('.' + CLASS.zoomRect).call(z);
$$.main.selectAll('.' + CLASS.eventRect).call(z);
};
c3_chart_internal_fn.redrawForZoom = function () {
var $$ = this, d3 = $$.d3, config = $$.config, zoom = $$.zoom, x = $$.x, orgXDomain = $$.orgXDomain;
if (!config.zoom_enabled) {
return;
}
if ($$.filterTargetsToShow($$.data.targets).length === 0) {
return;
}
if (d3.event.sourceEvent.type === 'mousemove' && zoom.altDomain) {
x.domain(zoom.altDomain);
zoom.scale(x).updateScaleExtent();
return;
}
if ($$.isCategorized() && x.orgDomain()[0] === orgXDomain[0]) {
x.domain([orgXDomain[0] - 1e-10, x.orgDomain()[1]]);
}
$$.redraw({
withTransition: false,
withY: false,
withSubchart: false
});
if (d3.event.sourceEvent.type === 'mousemove') {
$$.cancelClick = true;
}
config.zoom_onzoom.call($$.api, x.orgDomain());
};
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