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