|
|
@ -1,6 +1,8 @@ |
|
|
|
(function (window) { |
|
|
|
(function (window) { |
|
|
|
|
|
|
|
'use strict'; |
|
|
|
|
|
|
|
|
|
|
|
window.c3 = {}; |
|
|
|
var c3 = window.c3 = {}; |
|
|
|
|
|
|
|
var d3 = window.d3; |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
/* |
|
|
|
* Generate chart according to config |
|
|
|
* Generate chart according to config |
|
|
@ -15,13 +17,13 @@ |
|
|
|
/*-- Handle Config --*/ |
|
|
|
/*-- Handle Config --*/ |
|
|
|
|
|
|
|
|
|
|
|
function checkConfig(key, message) { |
|
|
|
function checkConfig(key, message) { |
|
|
|
if ( ! (key in config)) throw Error(message); |
|
|
|
if (! (key in config)) { throw Error(message); } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function getConfig(keys, defaultValue) { |
|
|
|
function getConfig(keys, defaultValue) { |
|
|
|
var target = config; |
|
|
|
var target = config; |
|
|
|
for (var i = 0; i < keys.length; i++) { |
|
|
|
for (var i = 0; i < keys.length; i++) { |
|
|
|
if ( ! (keys[i] in target)) return defaultValue; |
|
|
|
if (! (keys[i] in target)) { return defaultValue; } |
|
|
|
target = target[keys[i]]; |
|
|
|
target = target[keys[i]]; |
|
|
|
} |
|
|
|
} |
|
|
|
return target; |
|
|
|
return target; |
|
|
@ -54,7 +56,7 @@ |
|
|
|
__data_colors = getConfig(['data', 'colors'], {}), |
|
|
|
__data_colors = getConfig(['data', 'colors'], {}), |
|
|
|
__data_selection_enabled = getConfig(['data', 'selection', 'enabled'], false), |
|
|
|
__data_selection_enabled = getConfig(['data', 'selection', 'enabled'], false), |
|
|
|
__data_selection_grouped = getConfig(['data', 'selection', 'grouped'], false), |
|
|
|
__data_selection_grouped = getConfig(['data', 'selection', 'grouped'], false), |
|
|
|
__data_selection_isselectable = getConfig(['data','selection','isselectable'], function(d){return true}); |
|
|
|
__data_selection_isselectable = getConfig(['data', 'selection', 'isselectable'], function () { return true; }); |
|
|
|
|
|
|
|
|
|
|
|
// subchart
|
|
|
|
// subchart
|
|
|
|
var __subchart_show = getConfig(['subchart', 'show'], false), |
|
|
|
var __subchart_show = getConfig(['subchart', 'show'], false), |
|
|
@ -77,7 +79,8 @@ |
|
|
|
__axis_y_min = getConfig(['axis', 'y', 'min'], null), |
|
|
|
__axis_y_min = getConfig(['axis', 'y', 'min'], null), |
|
|
|
__axis_y_center = getConfig(['axis', 'y', 'center'], null), |
|
|
|
__axis_y_center = getConfig(['axis', 'y', 'center'], null), |
|
|
|
__axis_y_text = getConfig(['axis', 'y', 'text'], null), |
|
|
|
__axis_y_text = getConfig(['axis', 'y', 'text'], null), |
|
|
|
__axis_y_rescale = getConfig(['axis','y','rescale'], true), |
|
|
|
// not used
|
|
|
|
|
|
|
|
//__axis_y_rescale = getConfig(['axis', 'y', 'rescale'], true),
|
|
|
|
__axis_y_inner = getConfig(['axis', 'y', 'inner'], false), |
|
|
|
__axis_y_inner = getConfig(['axis', 'y', 'inner'], false), |
|
|
|
__axis_y_format = getConfig(['axis', 'y', 'format'], function (d) { return d; }), |
|
|
|
__axis_y_format = getConfig(['axis', 'y', 'format'], function (d) { return d; }), |
|
|
|
__axis_y_padding = getConfig(['axis', 'y', 'padding'], null), |
|
|
|
__axis_y_padding = getConfig(['axis', 'y', 'padding'], null), |
|
|
@ -86,8 +89,9 @@ |
|
|
|
__axis_y2_max = getConfig(['axis', 'y2', 'max'], null), |
|
|
|
__axis_y2_max = getConfig(['axis', 'y2', 'max'], null), |
|
|
|
__axis_y2_min = getConfig(['axis', 'y2', 'min'], null), |
|
|
|
__axis_y2_min = getConfig(['axis', 'y2', 'min'], null), |
|
|
|
__axis_y2_center = getConfig(['axis', 'y2', 'center'], null), |
|
|
|
__axis_y2_center = getConfig(['axis', 'y2', 'center'], null), |
|
|
|
__axis_y2_text = getConfig(['axis','y2','text'], null), |
|
|
|
// not used
|
|
|
|
__axis_y2_rescale = getConfig(['axis','y2','rescale'], true), |
|
|
|
// __axis_y2_text = getConfig(['axis', 'y2', 'text'], null),
|
|
|
|
|
|
|
|
// __axis_y2_rescale = getConfig(['axis', 'y2', 'rescale'], true),
|
|
|
|
__axis_y2_inner = getConfig(['axis', 'y2', 'inner'], false), |
|
|
|
__axis_y2_inner = getConfig(['axis', 'y2', 'inner'], false), |
|
|
|
__axis_y2_format = getConfig(['axis', 'y2', 'format'], function (d) { return d; }), |
|
|
|
__axis_y2_format = getConfig(['axis', 'y2', 'format'], function (d) { return d; }), |
|
|
|
__axis_y2_padding = getConfig(['axis', 'y2', 'padding'], null), |
|
|
|
__axis_y2_padding = getConfig(['axis', 'y2', 'padding'], null), |
|
|
@ -99,7 +103,8 @@ |
|
|
|
__grid_x_type = getConfig(['grid', 'x', 'type'], 'tick'), |
|
|
|
__grid_x_type = getConfig(['grid', 'x', 'type'], 'tick'), |
|
|
|
__grid_x_lines = getConfig(['grid', 'x', 'lines'], null), |
|
|
|
__grid_x_lines = getConfig(['grid', 'x', 'lines'], null), |
|
|
|
__grid_y_show = getConfig(['grid', 'y', 'show'], false), |
|
|
|
__grid_y_show = getConfig(['grid', 'y', 'show'], false), |
|
|
|
__grid_y_type = getConfig(['grid','y','type'], 'tick'), |
|
|
|
// not used
|
|
|
|
|
|
|
|
// __grid_y_type = getConfig(['grid', 'y', 'type'], 'tick'),
|
|
|
|
__grid_y_lines = getConfig(['grid', 'y', 'lines'], null); |
|
|
|
__grid_y_lines = getConfig(['grid', 'y', 'lines'], null); |
|
|
|
|
|
|
|
|
|
|
|
// point - point of each data
|
|
|
|
// point - point of each data
|
|
|
@ -154,18 +159,18 @@ |
|
|
|
|
|
|
|
|
|
|
|
var customTimeFormat = (function () { |
|
|
|
var customTimeFormat = (function () { |
|
|
|
var formats = [ |
|
|
|
var formats = [ |
|
|
|
[d3.time.format("%Y/%-m/%-d"), function() { return true }], |
|
|
|
[d3.time.format("%Y/%-m/%-d"), function () { return true; }], |
|
|
|
[d3.time.format("%-m/%-d"), function(d) { return d.getMonth() }], |
|
|
|
[d3.time.format("%-m/%-d"), function (d) { return d.getMonth(); }], |
|
|
|
[d3.time.format("%-m/%-d"), function(d) { return d.getDate() != 1 }], |
|
|
|
[d3.time.format("%-m/%-d"), function (d) { return d.getDate() !== 1; }], |
|
|
|
[d3.time.format("%-m/%-d"), function(d) { return d.getDay() && d.getDate() != 1 }], |
|
|
|
[d3.time.format("%-m/%-d"), function (d) { return d.getDay() && d.getDate() !== 1; }], |
|
|
|
[d3.time.format("%I %p"), function(d) { return d.getHours() }], |
|
|
|
[d3.time.format("%I %p"), function (d) { return d.getHours(); }], |
|
|
|
[d3.time.format("%I:%M"), function(d) { return d.getMinutes() }], |
|
|
|
[d3.time.format("%I:%M"), function (d) { return d.getMinutes(); }], |
|
|
|
[d3.time.format(":%S"), function(d) { return d.getSeconds() }], |
|
|
|
[d3.time.format(":%S"), function (d) { return d.getSeconds(); }], |
|
|
|
[d3.time.format(".%L"), function(d) { return d.getMilliseconds() }] |
|
|
|
[d3.time.format(".%L"), function (d) { return d.getMilliseconds(); }] |
|
|
|
]; |
|
|
|
]; |
|
|
|
return function (date) { |
|
|
|
return function (date) { |
|
|
|
var i = formats.length - 1, f = formats[i]; |
|
|
|
var i = formats.length - 1, f = formats[i]; |
|
|
|
while (!f[1](date)) f = formats[--i]; |
|
|
|
while (!f[1](date)) { f = formats[--i]; } |
|
|
|
return f[0](date); |
|
|
|
return f[0](date); |
|
|
|
}; |
|
|
|
}; |
|
|
|
})(); |
|
|
|
})(); |
|
|
@ -181,13 +186,13 @@ |
|
|
|
subXOrient = "bottom"; |
|
|
|
subXOrient = "bottom"; |
|
|
|
|
|
|
|
|
|
|
|
var translate = { |
|
|
|
var translate = { |
|
|
|
main : function () { return "translate(" + margin.left + "," + margin.top + ")" }, |
|
|
|
main : function () { return "translate(" + margin.left + "," + margin.top + ")"; }, |
|
|
|
context : function () { return "translate(" + margin2.left + "," + margin2.top + ")" }, |
|
|
|
context : function () { return "translate(" + margin2.left + "," + margin2.top + ")"; }, |
|
|
|
legend : function () { return "translate(" + margin3.left + "," + margin3.top + ")" }, |
|
|
|
legend : function () { return "translate(" + margin3.left + "," + margin3.top + ")"; }, |
|
|
|
y2 : function () { return "translate(" + (__axis_rotated ? 0 : width) + "," + (__axis_rotated ? 10 : 0) + ")" }, |
|
|
|
y2 : function () { return "translate(" + (__axis_rotated ? 0 : width) + "," + (__axis_rotated ? 10 : 0) + ")"; }, |
|
|
|
x : function () { return "translate(0," + height + ")" }, |
|
|
|
x : function () { return "translate(0," + height + ")"; }, |
|
|
|
subx : function () { return "translate(0," + height2 + ")" } |
|
|
|
subx : function () { return "translate(0," + height2 + ")"; } |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/*-- Define Functions --*/ |
|
|
|
/*-- Define Functions --*/ |
|
|
|
|
|
|
|
|
|
|
@ -233,10 +238,10 @@ |
|
|
|
yMin = __axis_rotated ? 0 : height; |
|
|
|
yMin = __axis_rotated ? 0 : height; |
|
|
|
yMax = __axis_rotated ? width : 1; |
|
|
|
yMax = __axis_rotated ? width : 1; |
|
|
|
// update scales
|
|
|
|
// update scales
|
|
|
|
x = getX(xMin, xMax, isDefined(x) ? x.domain() : undefined, function(d){ return xAxis.tickOffset() }); |
|
|
|
x = getX(xMin, xMax, isDefined(x) ? x.domain() : undefined, function () { return xAxis.tickOffset(); }); |
|
|
|
y = getY(yMin, yMax, isDefined(y) ? y.domain() : undefined); |
|
|
|
y = getY(yMin, yMax, isDefined(y) ? y.domain() : undefined); |
|
|
|
y2 = getY(yMin, yMax, isDefined(y2) ? y2.domain() : undefined); |
|
|
|
y2 = getY(yMin, yMax, isDefined(y2) ? y2.domain() : undefined); |
|
|
|
subX = getX(0, width, isDefined(orgXDomain) ? orgXDomain : undefined, function(d){ return d % 1 === 0 ? subXAxis.tickOffset() : 0 }); |
|
|
|
subX = getX(0, width, isDefined(orgXDomain) ? orgXDomain : undefined, function (d) { return d % 1 === 0 ? subXAxis.tickOffset() : 0; }); |
|
|
|
subY = getY(height2, 10); |
|
|
|
subY = getY(height2, 10); |
|
|
|
subY2 = getY(height2, 10); |
|
|
|
subY2 = getY(height2, 10); |
|
|
|
// update axes
|
|
|
|
// update axes
|
|
|
@ -244,13 +249,14 @@ |
|
|
|
yAxis = getYAxis(y, yOrient); |
|
|
|
yAxis = getYAxis(y, yOrient); |
|
|
|
yAxis2 = getYAxis(y2, y2Orient); |
|
|
|
yAxis2 = getYAxis(y2, y2Orient); |
|
|
|
subXAxis = getXAxis(subX, subXOrient); |
|
|
|
subXAxis = getXAxis(subX, subXOrient); |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function getX(min, max, domain, offset) { |
|
|
|
function getX(min, max, domain, offset) { |
|
|
|
var scale = ((isTimeSeries) ? d3.time.scale() : d3.scale.linear()).range([min, max]); |
|
|
|
var scale = ((isTimeSeries) ? d3.time.scale() : d3.scale.linear()).range([min, max]); |
|
|
|
// Set function and values for c3
|
|
|
|
// Set function and values for c3
|
|
|
|
scale.orgDomain = function () { return scale.domain(); } |
|
|
|
scale.orgDomain = function () { return scale.domain(); }; |
|
|
|
if (isDefined(domain)) scale.domain(domain); |
|
|
|
if (isDefined(domain)) { scale.domain(domain); } |
|
|
|
if (isUndefined(offset)) offset = function(d){ return 0; }; |
|
|
|
if (isUndefined(offset)) { offset = function () { return 0; }; } |
|
|
|
// Define customized scale if categorized axis
|
|
|
|
// Define customized scale if categorized axis
|
|
|
|
if (isCategorized) { |
|
|
|
if (isCategorized) { |
|
|
|
var _scale = scale, key; |
|
|
|
var _scale = scale, key; |
|
|
@ -263,7 +269,7 @@ |
|
|
|
}; |
|
|
|
}; |
|
|
|
scale.domain = function (domain) { |
|
|
|
scale.domain = function (domain) { |
|
|
|
if (!arguments.length) { |
|
|
|
if (!arguments.length) { |
|
|
|
var domain = _scale.domain(); |
|
|
|
domain = _scale.domain(); |
|
|
|
return [domain[0], domain[1] + 1]; |
|
|
|
return [domain[0], domain[1] + 1]; |
|
|
|
} |
|
|
|
} |
|
|
|
_scale.domain(domain); |
|
|
|
_scale.domain(domain); |
|
|
@ -293,7 +299,7 @@ |
|
|
|
axis.categories(__axis_x_categories).tickCentered(__axis_x_tick_centered); |
|
|
|
axis.categories(__axis_x_categories).tickCentered(__axis_x_tick_centered); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// TODO: fix
|
|
|
|
// TODO: fix
|
|
|
|
axis.tickOffset = function () { return 0; } |
|
|
|
axis.tickOffset = function () { return 0; }; |
|
|
|
} |
|
|
|
} |
|
|
|
return axis; |
|
|
|
return axis; |
|
|
|
} |
|
|
|
} |
|
|
@ -320,8 +326,8 @@ |
|
|
|
}); |
|
|
|
}); |
|
|
|
for (j = 0; j < __data_groups.length; j++) { |
|
|
|
for (j = 0; j < __data_groups.length; j++) { |
|
|
|
for (k = 1; k < __data_groups[j].length; k++) { |
|
|
|
for (k = 1; k < __data_groups[j].length; k++) { |
|
|
|
if ( ! isBarType(__data_groups[j][k])) continue; |
|
|
|
if (! isBarType(__data_groups[j][k])) { continue; } |
|
|
|
if (isUndefined(ys[__data_groups[j][k]])) continue; |
|
|
|
if (isUndefined(ys[__data_groups[j][k]])) { continue; } |
|
|
|
ys[__data_groups[j][k]].forEach(function (v, i) { |
|
|
|
ys[__data_groups[j][k]].forEach(function (v, i) { |
|
|
|
if (getAxisId(__data_groups[j][k]) === getAxisId(__data_groups[j][0])) { |
|
|
|
if (getAxisId(__data_groups[j][k]) === getAxisId(__data_groups[j][0])) { |
|
|
|
ys[__data_groups[j][0]][i] += v * 1; |
|
|
|
ys[__data_groups[j][0]][i] += v * 1; |
|
|
@ -342,7 +348,7 @@ |
|
|
|
padding_top = padding, padding_bottom = padding, |
|
|
|
padding_top = padding, padding_bottom = padding, |
|
|
|
center = axisId === 'y2' ? __axis_y2_center : __axis_y_center; |
|
|
|
center = axisId === 'y2' ? __axis_y2_center : __axis_y_center; |
|
|
|
if (center !== null) { |
|
|
|
if (center !== null) { |
|
|
|
yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax)); |
|
|
|
var yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax)); |
|
|
|
yDomainMax = yDomainAbs - center; |
|
|
|
yDomainMax = yDomainAbs - center; |
|
|
|
yDomainMin = center - yDomainAbs; |
|
|
|
yDomainMin = center - yDomainAbs; |
|
|
|
} |
|
|
|
} |
|
|
@ -375,7 +381,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
function hasCaches(ids) { |
|
|
|
function hasCaches(ids) { |
|
|
|
for (var i = 0; i < ids.length; i++) { |
|
|
|
for (var i = 0; i < ids.length; i++) { |
|
|
|
if ( ! (ids[i] in cache)) return false; |
|
|
|
if (! (ids[i] in cache)) { return false; } |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
@ -385,7 +391,7 @@ |
|
|
|
function getCaches(ids) { |
|
|
|
function getCaches(ids) { |
|
|
|
var targets = []; |
|
|
|
var targets = []; |
|
|
|
for (var i = 0; i < ids.length; i++) { |
|
|
|
for (var i = 0; i < ids.length; i++) { |
|
|
|
if (ids[i] in cache) targets.push(cloneTarget(cache[ids[i]])); |
|
|
|
if (ids[i] in cache) { targets.push(cloneTarget(cache[ids[i]])); } |
|
|
|
} |
|
|
|
} |
|
|
|
return targets; |
|
|
|
return targets; |
|
|
|
} |
|
|
|
} |
|
|
@ -394,13 +400,14 @@ |
|
|
|
|
|
|
|
|
|
|
|
function regionStart(d) { |
|
|
|
function regionStart(d) { |
|
|
|
return ('start' in d) ? x(isTimeSeries ? parseDate(d.start) : d.start) : 0; |
|
|
|
return ('start' in d) ? x(isTimeSeries ? parseDate(d.start) : d.start) : 0; |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function regionWidth(d) { |
|
|
|
function regionWidth(d) { |
|
|
|
var start = regionStart(d), |
|
|
|
var start = regionStart(d), |
|
|
|
end = ('end' in d) ? x(isTimeSeries ? parseDate(d.end) : d.end) : width, |
|
|
|
end = ('end' in d) ? x(isTimeSeries ? parseDate(d.end) : d.end) : width, |
|
|
|
w = end - start; |
|
|
|
w = end - start; |
|
|
|
return (w < 0) ? 0 : w; |
|
|
|
return (w < 0) ? 0 : w; |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//-- Data --//
|
|
|
|
//-- Data --//
|
|
|
|
|
|
|
|
|
|
|
@ -409,6 +416,7 @@ |
|
|
|
data.name = isDefined(name) ? name : data.id; |
|
|
|
data.name = isDefined(name) ? name : data.id; |
|
|
|
return data; |
|
|
|
return data; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function convertRowsToData(rows) { |
|
|
|
function convertRowsToData(rows) { |
|
|
|
var keys = rows[0], new_row = {}, new_rows = [], i, j; |
|
|
|
var keys = rows[0], new_row = {}, new_rows = [], i, j; |
|
|
|
for (i = 1; i < rows.length; i++) { |
|
|
|
for (i = 1; i < rows.length; i++) { |
|
|
@ -420,6 +428,7 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
return new_rows; |
|
|
|
return new_rows; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function convertColumnsToData(columns) { |
|
|
|
function convertColumnsToData(columns) { |
|
|
|
var new_rows = [], i, j, key; |
|
|
|
var new_rows = [], i, j, key; |
|
|
|
for (i = 0; i < columns.length; i++) { |
|
|
|
for (i = 0; i < columns.length; i++) { |
|
|
@ -434,23 +443,23 @@ |
|
|
|
return new_rows; |
|
|
|
return new_rows; |
|
|
|
} |
|
|
|
} |
|
|
|
function convertDataToTargets(data) { |
|
|
|
function convertDataToTargets(data) { |
|
|
|
var ids = d3.keys(data[0]).filter(function(key){ return key !== __data_x }); |
|
|
|
var ids = d3.keys(data[0]).filter(function (key) { return key !== __data_x; }); |
|
|
|
var targets, i = 0, parsedDate; |
|
|
|
var targets, i = 0, parsedDate; |
|
|
|
|
|
|
|
|
|
|
|
data.forEach(function (d) { |
|
|
|
data.forEach(function (d) { |
|
|
|
if (isTimeSeries) { |
|
|
|
if (isTimeSeries) { |
|
|
|
if (!(__data_x in d)) throw Error("'" + __data_x + "' must be included in data"); |
|
|
|
if (!(__data_x in d)) { throw Error("'" + __data_x + "' must be included in data"); } |
|
|
|
parsedDate = parseDate(d[__data_x]); |
|
|
|
parsedDate = parseDate(d[__data_x]); |
|
|
|
if (parsedDate === null) throw Error("Failed to parse timeseries date in data"); |
|
|
|
if (parsedDate === null) { throw Error("Failed to parse timeseries date in data"); } |
|
|
|
d.x = parsedDate; |
|
|
|
d.x = parsedDate; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
d.x = i++; |
|
|
|
d.x = i++; |
|
|
|
} |
|
|
|
} |
|
|
|
if (firstDate === null) firstDate = new Date(d.x); |
|
|
|
if (firstDate === null) { firstDate = new Date(d.x); } |
|
|
|
lastDate = new Date(d.x); |
|
|
|
lastDate = new Date(d.x); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
targets = ids.map(function(id,i) { |
|
|
|
targets = ids.map(function (id) { |
|
|
|
var convertedId = __data_id_converter(id); |
|
|
|
var convertedId = __data_id_converter(id); |
|
|
|
return { |
|
|
|
return { |
|
|
|
id: convertedId, |
|
|
|
id: convertedId, |
|
|
@ -487,7 +496,9 @@ |
|
|
|
function hasTarget(id) { |
|
|
|
function hasTarget(id) { |
|
|
|
var ids = getTargetIds(), i; |
|
|
|
var ids = getTargetIds(), i; |
|
|
|
for (i = 0; i < ids.length; i++) { |
|
|
|
for (i = 0; i < ids.length; i++) { |
|
|
|
if (ids[i] === id) return true; |
|
|
|
if (ids[i] === id) { |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
@ -531,7 +542,7 @@ |
|
|
|
var indices = {}, i = 0, j, k; |
|
|
|
var indices = {}, i = 0, j, k; |
|
|
|
getTargets(isBarType).forEach(function (d) { |
|
|
|
getTargets(isBarType).forEach(function (d) { |
|
|
|
for (j = 0; j < __data_groups.length; j++) { |
|
|
|
for (j = 0; j < __data_groups.length; j++) { |
|
|
|
if (__data_groups[j].indexOf(d.id) < 0) continue; |
|
|
|
if (__data_groups[j].indexOf(d.id) < 0) { continue; } |
|
|
|
for (k = 0; k < __data_groups[j].length; k++) { |
|
|
|
for (k = 0; k < __data_groups[j].length; k++) { |
|
|
|
if (__data_groups[j][k] in indices) { |
|
|
|
if (__data_groups[j][k] in indices) { |
|
|
|
indices[d.id] = indices[__data_groups[j][k]]; |
|
|
|
indices[d.id] = indices[__data_groups[j][k]]; |
|
|
@ -539,8 +550,8 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (isUndefined(indices[d.id])) indices[d.id] = i++; |
|
|
|
if (isUndefined(indices[d.id])) { indices[d.id] = i++; } |
|
|
|
}) |
|
|
|
}); |
|
|
|
indices.__max__ = i - 1; |
|
|
|
indices.__max__ = i - 1; |
|
|
|
return indices; |
|
|
|
return indices; |
|
|
|
} |
|
|
|
} |
|
|
@ -557,7 +568,7 @@ |
|
|
|
var offset = 0; |
|
|
|
var offset = 0; |
|
|
|
var scale = isSub ? getSubYScale(d.id) : getYScale(d.id); |
|
|
|
var scale = isSub ? getSubYScale(d.id) : getYScale(d.id); |
|
|
|
getTargets(isBarType).forEach(function (t) { |
|
|
|
getTargets(isBarType).forEach(function (t) { |
|
|
|
if (t.id === d.id || barIndices[t.id] !== barIndices[d.id]) return; |
|
|
|
if (t.id === d.id || barIndices[t.id] !== barIndices[d.id]) { return; } |
|
|
|
if (indicesIds.indexOf(t.id) < indicesIds.indexOf(d.id)) { |
|
|
|
if (indicesIds.indexOf(t.id) < indicesIds.indexOf(d.id)) { |
|
|
|
offset += barH(t.values[i]); |
|
|
|
offset += barH(t.values[i]); |
|
|
|
} |
|
|
|
} |
|
|
@ -586,7 +597,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
function setTargetType(targets, type) { |
|
|
|
function setTargetType(targets, type) { |
|
|
|
var targetIds = isUndefined(targets) ? getTargetIds() : targets; |
|
|
|
var targetIds = isUndefined(targets) ? getTargetIds() : targets; |
|
|
|
if (typeof targetIds === 'string') targetIds = [targetIds]; |
|
|
|
if (typeof targetIds === 'string') { targetIds = [targetIds]; } |
|
|
|
for (var i = 0; i < targetIds.length; i++) { |
|
|
|
for (var i = 0; i < targetIds.length; i++) { |
|
|
|
__data_types[targetIds[i]] = type; |
|
|
|
__data_types[targetIds[i]] = type; |
|
|
|
} |
|
|
|
} |
|
|
@ -594,14 +605,16 @@ |
|
|
|
function hasType(targets, type) { |
|
|
|
function hasType(targets, type) { |
|
|
|
var has = false; |
|
|
|
var has = false; |
|
|
|
targets.forEach(function (t) { |
|
|
|
targets.forEach(function (t) { |
|
|
|
if (__data_types[t.id] === type) has = true; |
|
|
|
if (__data_types[t.id] === type) { has = true; } |
|
|
|
if (!(t.id in __data_types) && type === 'line') has = true; |
|
|
|
if (!(t.id in __data_types) && type === 'line') { has = true; } |
|
|
|
}); |
|
|
|
}); |
|
|
|
return has; |
|
|
|
return has; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* not used |
|
|
|
function hasLineType(targets) { |
|
|
|
function hasLineType(targets) { |
|
|
|
return hasType(targets, 'line'); |
|
|
|
return hasType(targets, 'line'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
*/ |
|
|
|
function hasBarType(targets) { |
|
|
|
function hasBarType(targets) { |
|
|
|
return hasType(targets, 'bar'); |
|
|
|
return hasType(targets, 'bar'); |
|
|
|
} |
|
|
|
} |
|
|
@ -633,10 +646,10 @@ |
|
|
|
|
|
|
|
|
|
|
|
return function (id) { |
|
|
|
return function (id) { |
|
|
|
// if specified, choose that color
|
|
|
|
// if specified, choose that color
|
|
|
|
if (id in colors) return _colors[id]; |
|
|
|
if (id in colors) { return _colors[id]; } |
|
|
|
|
|
|
|
|
|
|
|
// if not specified, choose from pattern
|
|
|
|
// if not specified, choose from pattern
|
|
|
|
if ( ! (ids.indexOf(id) >= 0)) { |
|
|
|
if (ids.indexOf(id) === -1) { |
|
|
|
ids.push(id); |
|
|
|
ids.push(id); |
|
|
|
} |
|
|
|
} |
|
|
|
return pattern[ids.indexOf(id) % pattern.length]; |
|
|
|
return pattern[ids.indexOf(id) % pattern.length]; |
|
|
@ -659,7 +672,7 @@ |
|
|
|
function isWithinRegions(x, regions) { |
|
|
|
function isWithinRegions(x, regions) { |
|
|
|
var i; |
|
|
|
var i; |
|
|
|
for (i = 0; i < regions.length; i++) { |
|
|
|
for (i = 0; i < regions.length; i++) { |
|
|
|
if (regions[i].start < x && x <= regions[i].end) return true; |
|
|
|
if (regions[i].start < x && x <= regions[i].end) { return true; } |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
@ -672,7 +685,7 @@ |
|
|
|
main.select(".selected-circles-" + d.id).selectAll('.selected-circle-' + i) |
|
|
|
main.select(".selected-circles-" + d.id).selectAll('.selected-circle-' + i) |
|
|
|
.data([d]) |
|
|
|
.data([d]) |
|
|
|
.enter().append('circle') |
|
|
|
.enter().append('circle') |
|
|
|
.attr("class", function(d){ return "selected-circle selected-circle-" + i; }) |
|
|
|
.attr("class", function () { return "selected-circle selected-circle-" + i; }) |
|
|
|
.attr("cx", __axis_rotated ? circleY : circleX) |
|
|
|
.attr("cx", __axis_rotated ? circleY : circleX) |
|
|
|
.attr("cy", __axis_rotated ? circleX : circleY) |
|
|
|
.attr("cy", __axis_rotated ? circleX : circleY) |
|
|
|
.attr("stroke", function () { return color(d.id); }) |
|
|
|
.attr("stroke", function () { return color(d.id); }) |
|
|
@ -691,9 +704,9 @@ |
|
|
|
(selected) ? selectPoint(target, d, i) : unselectPoint(target, d, i); |
|
|
|
(selected) ? selectPoint(target, d, i) : unselectPoint(target, d, i); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function selectBar (target, d, i) { |
|
|
|
function selectBar() { |
|
|
|
} |
|
|
|
} |
|
|
|
function unselectBar (target, d, i) { |
|
|
|
function unselectBar() { |
|
|
|
} |
|
|
|
} |
|
|
|
function toggleBar(selected, target, d, i) { |
|
|
|
function toggleBar(selected, target, d, i) { |
|
|
|
(selected) ? selectBar(target, d, i) : unselectBar(target, d, i); |
|
|
|
(selected) ? selectBar(target, d, i) : unselectBar(target, d, i); |
|
|
@ -722,8 +735,8 @@ |
|
|
|
// For brush region
|
|
|
|
// For brush region
|
|
|
|
var lineOnSub = (function () { |
|
|
|
var lineOnSub = (function () { |
|
|
|
var line = d3.svg.line() |
|
|
|
var line = d3.svg.line() |
|
|
|
.x(function(d){ return subX(d.x) }) |
|
|
|
.x(function (d) { return subX(d.x); }) |
|
|
|
.y(function(d){ return getSubYScale(d.id)(d.value) }); |
|
|
|
.y(function (d) { return getSubYScale(d.id)(d.value); }); |
|
|
|
return function (d) { |
|
|
|
return function (d) { |
|
|
|
return isLineType(d) ? line(d.values) : "M " + subX(d.values[0].x) + " " + getSubYScale(d.id)(d.values[0].value); |
|
|
|
return isLineType(d) ? line(d.values) : "M " + subX(d.values[0].x) + " " + getSubYScale(d.id)(d.values[0].value); |
|
|
|
}; |
|
|
|
}; |
|
|
@ -732,7 +745,7 @@ |
|
|
|
function lineWithRegions(d, x, y, _regions) { |
|
|
|
function lineWithRegions(d, x, y, _regions) { |
|
|
|
var prev = -1, i, j; |
|
|
|
var prev = -1, i, j; |
|
|
|
var s = "M", sWithRegion; |
|
|
|
var s = "M", sWithRegion; |
|
|
|
var xp, yp, dx, dy, dd, diff, diff2; |
|
|
|
var xp, yp, dx, dy, dd, diff; |
|
|
|
var xValue, yValue; |
|
|
|
var xValue, yValue; |
|
|
|
var regions = []; |
|
|
|
var regions = []; |
|
|
|
|
|
|
|
|
|
|
@ -764,11 +777,11 @@ |
|
|
|
xv0 = new Date(x0 + x_diff * j), |
|
|
|
xv0 = new Date(x0 + x_diff * j), |
|
|
|
xv1 = new Date(x0 + x_diff * (j + diff)); |
|
|
|
xv1 = new Date(x0 + x_diff * (j + diff)); |
|
|
|
return "M" + x(xv0) + " " + y(yp(j)) + " " + x(xv1) + " " + y(yp(j + diff)); |
|
|
|
return "M" + x(xv0) + " " + y(yp(j)) + " " + x(xv1) + " " + y(yp(j + diff)); |
|
|
|
} |
|
|
|
}; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
sWithRegion = function (d0, d1, j, diff) { |
|
|
|
sWithRegion = function (d0, d1, j, diff) { |
|
|
|
return "M" + x(xp(j)) + " " + y(yp(j)) + " " + x(xp(j + diff)) + " " + y(yp(j + diff)); |
|
|
|
return "M" + x(xp(j)) + " " + y(yp(j)) + " " + x(xp(j + diff)) + " " + y(yp(j + diff)); |
|
|
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Generate
|
|
|
|
// Generate
|
|
|
@ -786,7 +799,7 @@ |
|
|
|
dy = y(d[i].value) - y(d[i - 1].value); |
|
|
|
dy = y(d[i].value) - y(d[i - 1].value); |
|
|
|
dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); |
|
|
|
dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); |
|
|
|
diff = 2 / dd; |
|
|
|
diff = 2 / dd; |
|
|
|
diffx2 = diff*2; |
|
|
|
var diffx2 = diff * 2; |
|
|
|
|
|
|
|
|
|
|
|
for (j = diff; j <= 1; j += diffx2) { |
|
|
|
for (j = diff; j <= 1; j += diffx2) { |
|
|
|
s += sWithRegion(d[i - 1], d[i], j, diff); |
|
|
|
s += sWithRegion(d[i - 1], d[i], j, diff); |
|
|
@ -805,7 +818,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
// define functions for c3
|
|
|
|
// define functions for c3
|
|
|
|
brush.update = function () { |
|
|
|
brush.update = function () { |
|
|
|
if (context) context.select('.x.brush').call(this); |
|
|
|
if (context) { context.select('.x.brush').call(this); } |
|
|
|
return this; |
|
|
|
return this; |
|
|
|
}; |
|
|
|
}; |
|
|
|
zoom.orgScaleExtent = function () { |
|
|
|
zoom.orgScaleExtent = function () { |
|
|
@ -828,7 +841,6 @@ |
|
|
|
|
|
|
|
|
|
|
|
function init(data) { |
|
|
|
function init(data) { |
|
|
|
var targets = c3.data.targets = convertDataToTargets(data); |
|
|
|
var targets = c3.data.targets = convertDataToTargets(data); |
|
|
|
var rectX, rectW; |
|
|
|
|
|
|
|
var grid, xgridLine; |
|
|
|
var grid, xgridLine; |
|
|
|
var i; |
|
|
|
var i; |
|
|
|
|
|
|
|
|
|
|
@ -856,7 +868,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
// Set initialized scales to brush and zoom
|
|
|
|
// Set initialized scales to brush and zoom
|
|
|
|
brush.x(subX); |
|
|
|
brush.x(subX); |
|
|
|
if (__zoom_enabled) zoom.x(x); |
|
|
|
if (__zoom_enabled) { zoom.x(x); } |
|
|
|
|
|
|
|
|
|
|
|
/*-- Basic Elements --*/ |
|
|
|
/*-- Basic Elements --*/ |
|
|
|
|
|
|
|
|
|
|
@ -1001,7 +1013,7 @@ |
|
|
|
.attr("class", function (d, i) { return "event-rect event-rect-" + i; }) |
|
|
|
.attr("class", function (d, i) { return "event-rect event-rect-" + i; }) |
|
|
|
.style("cursor", __data_selection_enabled && __data_selection_grouped ? "pointer" : null) |
|
|
|
.style("cursor", __data_selection_enabled && __data_selection_grouped ? "pointer" : null) |
|
|
|
.on('mouseover', function (d, i) { |
|
|
|
.on('mouseover', function (d, i) { |
|
|
|
if (dragging) return; // do nothing if dragging
|
|
|
|
if (dragging) { return; } // do nothing if dragging
|
|
|
|
|
|
|
|
|
|
|
|
var selectedData = c3.data.targets.map(function (d) { return addName(d.values[i]); }); |
|
|
|
var selectedData = c3.data.targets.map(function (d) { return addName(d.values[i]); }); |
|
|
|
var j, newData; |
|
|
|
var j, newData; |
|
|
@ -1058,17 +1070,17 @@ |
|
|
|
.classed(EXPANDED, false); |
|
|
|
.classed(EXPANDED, false); |
|
|
|
}) |
|
|
|
}) |
|
|
|
.on('mousemove', function (d, i) { |
|
|
|
.on('mousemove', function (d, i) { |
|
|
|
if ( ! __data_selection_enabled || dragging) return; |
|
|
|
if (! __data_selection_enabled || dragging) { return; } |
|
|
|
if ( __data_selection_grouped) return; // nothing to do when grouped
|
|
|
|
if (__data_selection_grouped) { return; } // nothing to do when grouped
|
|
|
|
|
|
|
|
|
|
|
|
main.selectAll('.-shape-' + i) |
|
|
|
main.selectAll('.-shape-' + i) |
|
|
|
.filter(function (d) { return __data_selection_isselectable(d); }) |
|
|
|
.filter(function (d) { return __data_selection_isselectable(d); }) |
|
|
|
.each(function(d){ |
|
|
|
.each(function () { |
|
|
|
var _this = d3.select(this).classed(EXPANDED, true); |
|
|
|
var _this = d3.select(this).classed(EXPANDED, true); |
|
|
|
if (this.nodeName === 'circle') _this.attr('r', __point_focus_expand_r); |
|
|
|
if (this.nodeName === 'circle') { _this.attr('r', __point_focus_expand_r); } |
|
|
|
d3.select('.event-rect-' + i).style('cursor', null); |
|
|
|
d3.select('.event-rect-' + i).style('cursor', null); |
|
|
|
}) |
|
|
|
}) |
|
|
|
.filter(function(d){ |
|
|
|
.filter(function () { |
|
|
|
var _this = d3.select(this); |
|
|
|
var _this = d3.select(this); |
|
|
|
if (this.nodeName === 'circle') { |
|
|
|
if (this.nodeName === 'circle') { |
|
|
|
return isWithinCircle(this, __point_select_r); |
|
|
|
return isWithinCircle(this, __point_select_r); |
|
|
@ -1077,11 +1089,11 @@ |
|
|
|
return isWithinBar(this, _this.attr('x'), _this.attr('y')); |
|
|
|
return isWithinBar(this, _this.attr('x'), _this.attr('y')); |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
.each(function(d){ |
|
|
|
.each(function () { |
|
|
|
var _this = d3.select(this); |
|
|
|
var _this = d3.select(this); |
|
|
|
if (! _this.classed(EXPANDED)) { |
|
|
|
if (! _this.classed(EXPANDED)) { |
|
|
|
_this.classed(EXPANDED, true); |
|
|
|
_this.classed(EXPANDED, true); |
|
|
|
if (this.nodeName === 'circle') _this.attr('r', __point_select_r); |
|
|
|
if (this.nodeName === 'circle') { _this.attr('r', __point_select_r); } |
|
|
|
} |
|
|
|
} |
|
|
|
d3.select('.event-rect-' + i).style('cursor', 'pointer'); |
|
|
|
d3.select('.event-rect-' + i).style('cursor', 'pointer'); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -1113,9 +1125,9 @@ |
|
|
|
}); |
|
|
|
}); |
|
|
|
}) |
|
|
|
}) |
|
|
|
.call( |
|
|
|
.call( |
|
|
|
d3.behavior.drag().origin(Object).on('drag', function(d){ |
|
|
|
d3.behavior.drag().origin(Object).on('drag', function () { |
|
|
|
if ( ! __data_selection_enabled) return; // do nothing if not selectable
|
|
|
|
if (! __data_selection_enabled) { return; } // do nothing if not selectable
|
|
|
|
if (__zoom_enabled && ! zoom.altDomain) return; // skip if zoomable because of conflict drag dehavior
|
|
|
|
if (__zoom_enabled && ! zoom.altDomain) { return; } // skip if zoomable because of conflict drag dehavior
|
|
|
|
|
|
|
|
|
|
|
|
var sx = dragStart[0], sy = dragStart[1], |
|
|
|
var sx = dragStart[0], sy = dragStart[1], |
|
|
|
mouse = d3.mouse(this), |
|
|
|
mouse = d3.mouse(this), |
|
|
@ -1159,7 +1171,7 @@ |
|
|
|
}); |
|
|
|
}); |
|
|
|
}) |
|
|
|
}) |
|
|
|
.on('dragstart', function () { |
|
|
|
.on('dragstart', function () { |
|
|
|
if ( ! __data_selection_enabled) return; // do nothing if not selectable
|
|
|
|
if (! __data_selection_enabled) { return; } // do nothing if not selectable
|
|
|
|
dragStart = d3.mouse(this); |
|
|
|
dragStart = d3.mouse(this); |
|
|
|
main.select('.chart').append('rect') |
|
|
|
main.select('.chart').append('rect') |
|
|
|
.attr('class', 'dragarea') |
|
|
|
.attr('class', 'dragarea') |
|
|
@ -1168,7 +1180,7 @@ |
|
|
|
// TODO: add callback here
|
|
|
|
// TODO: add callback here
|
|
|
|
}) |
|
|
|
}) |
|
|
|
.on('dragend', function () { |
|
|
|
.on('dragend', function () { |
|
|
|
if ( ! __data_selection_enabled) return; // do nothing if not selectable
|
|
|
|
if (! __data_selection_enabled) { return; } // do nothing if not selectable
|
|
|
|
main.select('.dragarea') |
|
|
|
main.select('.dragarea') |
|
|
|
.transition().duration(100) |
|
|
|
.transition().duration(100) |
|
|
|
.style('opacity', 0) |
|
|
|
.style('opacity', 0) |
|
|
@ -1239,7 +1251,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
/*-- Legend Region --*/ |
|
|
|
/*-- Legend Region --*/ |
|
|
|
|
|
|
|
|
|
|
|
if (__legend_show) updateLegend(targets); |
|
|
|
if (__legend_show) { updateLegend(targets); } |
|
|
|
|
|
|
|
|
|
|
|
// Set targets
|
|
|
|
// Set targets
|
|
|
|
updateTargets(targets); |
|
|
|
updateTargets(targets); |
|
|
@ -1249,10 +1261,10 @@ |
|
|
|
|
|
|
|
|
|
|
|
// Show tooltip if needed
|
|
|
|
// Show tooltip if needed
|
|
|
|
if (__tooltip_init_show) { |
|
|
|
if (__tooltip_init_show) { |
|
|
|
if (isTimeSeries && typeof __tooltip_init_x == 'string') { |
|
|
|
if (isTimeSeries && typeof __tooltip_init_x === 'string') { |
|
|
|
__tooltip_init_x = parseDate(__tooltip_init_x); |
|
|
|
__tooltip_init_x = parseDate(__tooltip_init_x); |
|
|
|
for (i = 0; i < targets[0].values.length; i++) { |
|
|
|
for (i = 0; i < targets[0].values.length; i++) { |
|
|
|
if ((targets[0].values[i].x - __tooltip_init_x) == 0) break; |
|
|
|
if ((targets[0].values[i].x - __tooltip_init_x) === 0) { break; } |
|
|
|
} |
|
|
|
} |
|
|
|
__tooltip_init_x = i; |
|
|
|
__tooltip_init_x = i; |
|
|
|
} |
|
|
|
} |
|
|
@ -1267,7 +1279,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
function redraw(options) { |
|
|
|
function redraw(options) { |
|
|
|
var xgrid, xgridData, xgridLine; |
|
|
|
var xgrid, xgridData, xgridLine; |
|
|
|
var mainPath, mainCircle, mainBar, contextPath; |
|
|
|
var mainCircle, mainBar; |
|
|
|
var barIndices = getBarIndices(), barTargetsNum = barIndices.__max__ + 1; |
|
|
|
var barIndices = getBarIndices(), barTargetsNum = barIndices.__max__ + 1; |
|
|
|
var barX, barY, barW, barH; |
|
|
|
var barX, barY, barW, barH; |
|
|
|
var rectX, rectW; |
|
|
|
var rectX, rectW; |
|
|
@ -1285,7 +1297,7 @@ |
|
|
|
// ATTENTION: call here to update tickOffset
|
|
|
|
// ATTENTION: call here to update tickOffset
|
|
|
|
if (withUpdateXDomain) { |
|
|
|
if (withUpdateXDomain) { |
|
|
|
x.domain(brush.empty() ? orgXDomain : brush.extent()); |
|
|
|
x.domain(brush.empty() ? orgXDomain : brush.extent()); |
|
|
|
if (__zoom_enabled) zoom.x(x).updateScaleExtent(); |
|
|
|
if (__zoom_enabled) { zoom.x(x).updateScaleExtent(); } |
|
|
|
} |
|
|
|
} |
|
|
|
y.domain(getYDomain(c3.data.targets, 'y')); |
|
|
|
y.domain(getYDomain(c3.data.targets, 'y')); |
|
|
|
y2.domain(getYDomain(c3.data.targets, 'y2')); |
|
|
|
y2.domain(getYDomain(c3.data.targets, 'y2')); |
|
|
@ -1308,8 +1320,8 @@ |
|
|
|
if (__grid_x_show) { |
|
|
|
if (__grid_x_show) { |
|
|
|
if (__grid_x_type === 'year') { |
|
|
|
if (__grid_x_type === 'year') { |
|
|
|
xgridData = []; |
|
|
|
xgridData = []; |
|
|
|
firstYear = firstDate.getFullYear(); |
|
|
|
var firstYear = firstDate.getFullYear(); |
|
|
|
lastYear = lastDate.getFullYear(); |
|
|
|
var lastYear = lastDate.getFullYear(); |
|
|
|
for (var year = firstYear; year <= lastYear; year++) { |
|
|
|
for (var year = firstYear; year <= lastYear; year++) { |
|
|
|
xgridData.push(new Date(year + '-01-01 00:00:00')); |
|
|
|
xgridData.push(new Date(year + '-01-01 00:00:00')); |
|
|
|
} |
|
|
|
} |
|
|
@ -1340,7 +1352,7 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
// Y-Grid
|
|
|
|
// Y-Grid
|
|
|
|
if (withY && __grid_y_show) { |
|
|
|
if (withY && __grid_y_show) { |
|
|
|
ygrid = main.select('.ygrids').selectAll(".ygrid") |
|
|
|
var ygrid = main.select('.ygrids').selectAll(".ygrid") |
|
|
|
.data(y.ticks(10)); |
|
|
|
.data(y.ticks(10)); |
|
|
|
ygrid.enter().append('line') |
|
|
|
ygrid.enter().append('line') |
|
|
|
.attr('class', 'ygrid'); |
|
|
|
.attr('class', 'ygrid'); |
|
|
@ -1420,7 +1432,7 @@ |
|
|
|
barH = getBarH(height2, true); |
|
|
|
barH = getBarH(height2, true); |
|
|
|
barX = getBarX(barW, barTargetsNum, barIndices, true); |
|
|
|
barX = getBarX(barW, barTargetsNum, barIndices, true); |
|
|
|
barY = getBarY(barH, barIndices, false, true); |
|
|
|
barY = getBarY(barH, barIndices, false, true); |
|
|
|
contextBar = context.selectAll('.-bars').selectAll('.-bar') |
|
|
|
var contextBar = context.selectAll('.-bars').selectAll('.-bar') |
|
|
|
.data(barData); |
|
|
|
.data(barData); |
|
|
|
contextBar.transition().duration(duration) |
|
|
|
contextBar.transition().duration(duration) |
|
|
|
.attr("x", barX).attr("y", barY).attr("width", barW).attr("height", barH); |
|
|
|
.attr("x", barX).attr("y", barY).attr("width", barW).attr("height", barH); |
|
|
@ -1460,7 +1472,7 @@ |
|
|
|
.attr("height", __axis_rotated ? rectW : height); |
|
|
|
.attr("height", __axis_rotated ? rectW : height); |
|
|
|
|
|
|
|
|
|
|
|
// rect for regions
|
|
|
|
// rect for regions
|
|
|
|
mainRegion = main.select('.regions').selectAll('rect.region') |
|
|
|
var mainRegion = main.select('.regions').selectAll('rect.region') |
|
|
|
.data(__regions); |
|
|
|
.data(__regions); |
|
|
|
mainRegion.enter().append('rect'); |
|
|
|
mainRegion.enter().append('rect'); |
|
|
|
mainRegion |
|
|
|
mainRegion |
|
|
@ -1469,7 +1481,7 @@ |
|
|
|
.attr("y", __axis_rotated ? regionStart : margin.top) |
|
|
|
.attr("y", __axis_rotated ? regionStart : margin.top) |
|
|
|
.attr("width", __axis_rotated ? width : regionWidth) |
|
|
|
.attr("width", __axis_rotated ? width : regionWidth) |
|
|
|
.attr("height", __axis_rotated ? regionWidth : height) |
|
|
|
.attr("height", __axis_rotated ? regionWidth : height) |
|
|
|
.style("fill-opacity", function(d){ return isDefined(d.opacity) ? d.opacity : .1; }); |
|
|
|
.style("fill-opacity", function (d) { return isDefined(d.opacity) ? d.opacity : 0.1; }); |
|
|
|
mainRegion.exit().transition().duration(duration) |
|
|
|
mainRegion.exit().transition().duration(duration) |
|
|
|
.style("fill-opacity", 0) |
|
|
|
.style("fill-opacity", 0) |
|
|
|
.remove(); |
|
|
|
.remove(); |
|
|
@ -1508,7 +1520,7 @@ |
|
|
|
// Set x for brush again because of scale update
|
|
|
|
// Set x for brush again because of scale update
|
|
|
|
brush.x(subX); |
|
|
|
brush.x(subX); |
|
|
|
// Set x for zoom again because of scale update
|
|
|
|
// Set x for zoom again because of scale update
|
|
|
|
if (__zoom_enabled) zoom.x(x); |
|
|
|
if (__zoom_enabled) { zoom.x(x); } |
|
|
|
// Update sizes
|
|
|
|
// Update sizes
|
|
|
|
d3.select('svg').attr('width', currentWidth).attr('height', currentHeight); |
|
|
|
d3.select('svg').attr('width', currentWidth).attr('height', currentHeight); |
|
|
|
d3.select('#' + clipId).select('rect').attr('width', width).attr('height', height); |
|
|
|
d3.select('#' + clipId).select('rect').attr('width', width).attr('height', height); |
|
|
@ -1670,7 +1682,7 @@ |
|
|
|
.style('opacity', 0.3); |
|
|
|
.style('opacity', 0.3); |
|
|
|
c3.focus(d); |
|
|
|
c3.focus(d); |
|
|
|
}) |
|
|
|
}) |
|
|
|
.on('mouseout', function(d){ |
|
|
|
.on('mouseout', function () { |
|
|
|
d3.selectAll('.legend-item') |
|
|
|
d3.selectAll('.legend-item') |
|
|
|
.transition().duration(100) |
|
|
|
.transition().duration(100) |
|
|
|
.style('opacity', 1); |
|
|
|
.style('opacity', 1); |
|
|
@ -1693,7 +1705,7 @@ |
|
|
|
l.append('text') |
|
|
|
l.append('text') |
|
|
|
.text(function (d) { return isDefined(__data_names[d]) ? __data_names[d] : d; }) |
|
|
|
.text(function (d) { return isDefined(__data_names[d]) ? __data_names[d] : d; }) |
|
|
|
.attr('x', -200) |
|
|
|
.attr('x', -200) |
|
|
|
.attr('y', function(d,i){ return legendHeight/2; }); |
|
|
|
.attr('y', function () { return legendHeight / 2; }); |
|
|
|
|
|
|
|
|
|
|
|
legend.selectAll('rect.legend-item-event') |
|
|
|
legend.selectAll('rect.legend-item-event') |
|
|
|
.data(ids) |
|
|
|
.data(ids) |
|
|
@ -1757,7 +1769,7 @@ |
|
|
|
c3.unzoom = function () { |
|
|
|
c3.unzoom = function () { |
|
|
|
brush.clear().update(); |
|
|
|
brush.clear().update(); |
|
|
|
redraw({withUpdateXDomain: true}); |
|
|
|
redraw({withUpdateXDomain: true}); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
c3.load = function (args) { |
|
|
|
c3.load = function (args) { |
|
|
|
// check args
|
|
|
|
// check args
|
|
|
@ -1771,7 +1783,7 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
// load data
|
|
|
|
// load data
|
|
|
|
if ('data' in args) { |
|
|
|
if ('data' in args) { |
|
|
|
load(convertDataToTargets(data), args.done); |
|
|
|
load(convertDataToTargets(args.data), args.done); |
|
|
|
} |
|
|
|
} |
|
|
|
else if ('url' in args) { |
|
|
|
else if ('url' in args) { |
|
|
|
d3.csv(args.url, function (error, data) { |
|
|
|
d3.csv(args.url, function (error, data) { |
|
|
@ -1791,7 +1803,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
c3.unload = function (target) { |
|
|
|
c3.unload = function (target) { |
|
|
|
c3.data.targets = c3.data.targets.filter(function (d) { |
|
|
|
c3.data.targets = c3.data.targets.filter(function (d) { |
|
|
|
return d.id != target; |
|
|
|
return d.id !== target; |
|
|
|
}); |
|
|
|
}); |
|
|
|
d3.selectAll('.target-' + target) |
|
|
|
d3.selectAll('.target-' + target) |
|
|
|
.transition() |
|
|
|
.transition() |
|
|
@ -1803,7 +1815,7 @@ |
|
|
|
updateLegend(c3.data.targets); |
|
|
|
updateLegend(c3.data.targets); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (c3.data.targets.length > 0) redraw(); |
|
|
|
if (c3.data.targets.length > 0) { redraw(); } |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
c3.selected = function (target) { |
|
|
|
c3.selected = function (target) { |
|
|
@ -1816,7 +1828,7 @@ |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
c3.select = function (ids, indices, resetOther) { |
|
|
|
c3.select = function (ids, indices, resetOther) { |
|
|
|
if ( ! __data_selection_enabled) return; |
|
|
|
if (! __data_selection_enabled) { return; } |
|
|
|
main.selectAll('.-shapes').selectAll('.-shape').each(function (d, i) { |
|
|
|
main.selectAll('.-shapes').selectAll('.-shape').each(function (d, i) { |
|
|
|
var selectShape = (this.nodeName === 'circle') ? selectPoint : selectBar, |
|
|
|
var selectShape = (this.nodeName === 'circle') ? selectPoint : selectBar, |
|
|
|
unselectShape = (this.nodeName === 'circle') ? unselectPoint : unselectBar; |
|
|
|
unselectShape = (this.nodeName === 'circle') ? unselectPoint : unselectBar; |
|
|
@ -1831,7 +1843,7 @@ |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
c3.unselect = function (ids, indices) { |
|
|
|
c3.unselect = function (ids, indices) { |
|
|
|
if ( ! __data_selection_enabled) return; |
|
|
|
if (! __data_selection_enabled) { return; } |
|
|
|
main.selectAll('.-shapes').selectAll('.-shape').each(function (d, i) { |
|
|
|
main.selectAll('.-shapes').selectAll('.-shape').each(function (d, i) { |
|
|
|
var unselectShape = (this.nodeName === 'circle') ? unselectPoint : unselectBar; |
|
|
|
var unselectShape = (this.nodeName === 'circle') ? unselectPoint : unselectBar; |
|
|
|
if (isUndefined(indices) || indices.indexOf(i) >= 0) { |
|
|
|
if (isUndefined(indices) || indices.indexOf(i) >= 0) { |
|
|
@ -1858,26 +1870,26 @@ |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
c3.groups = function (groups) { |
|
|
|
c3.groups = function (groups) { |
|
|
|
if (isUndefined(groups)) return __data_groups; |
|
|
|
if (isUndefined(groups)) { return __data_groups; } |
|
|
|
__data_groups = groups; |
|
|
|
__data_groups = groups; |
|
|
|
redraw(); |
|
|
|
redraw(); |
|
|
|
return __data_groups; |
|
|
|
return __data_groups; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
c3.regions = function (regions) { |
|
|
|
c3.regions = function (regions) { |
|
|
|
if (isUndefined(regions)) return __regions; |
|
|
|
if (isUndefined(regions)) { return __regions; } |
|
|
|
__regions = regions; |
|
|
|
__regions = regions; |
|
|
|
redraw(); |
|
|
|
redraw(); |
|
|
|
return __regions; |
|
|
|
return __regions; |
|
|
|
}; |
|
|
|
}; |
|
|
|
c3.regions.add = function (regions) { |
|
|
|
c3.regions.add = function (regions) { |
|
|
|
if (isUndefined(regions)) return __regions; |
|
|
|
if (isUndefined(regions)) { return __regions; } |
|
|
|
__regions = __regions.concat(regions); |
|
|
|
__regions = __regions.concat(regions); |
|
|
|
redraw(); |
|
|
|
redraw(); |
|
|
|
return __regions; |
|
|
|
return __regions; |
|
|
|
}; |
|
|
|
}; |
|
|
|
c3.regions.remove = function (classes, options) { |
|
|
|
c3.regions.remove = function (classes, options) { |
|
|
|
var regionClasses = [].concat(classes), |
|
|
|
var regionClasses = [].concat(classes); |
|
|
|
options = isDefined(options) ? options : {}; |
|
|
|
options = isDefined(options) ? options : {}; |
|
|
|
regionClasses.forEach(function (cls) { |
|
|
|
regionClasses.forEach(function (cls) { |
|
|
|
var regions = d3.selectAll('.' + cls); |
|
|
|
var regions = d3.selectAll('.' + cls); |
|
|
@ -1897,14 +1909,14 @@ |
|
|
|
return isDefined(target) ? target.values.map(function (d) { return d.value; }) : undefined; |
|
|
|
return isDefined(target) ? target.values.map(function (d) { return d.value; }) : undefined; |
|
|
|
}; |
|
|
|
}; |
|
|
|
c3.data.getAsTarget = function (id) { |
|
|
|
c3.data.getAsTarget = function (id) { |
|
|
|
var targets = getTargets(function(d){ return d.id == id; }); |
|
|
|
var targets = getTargets(function (d) { return d.id === id; }); |
|
|
|
return targets.length > 0 ? targets[0] : undefined; |
|
|
|
return targets.length > 0 ? targets[0] : undefined; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/*-- Load data and init chart with defined functions --*/ |
|
|
|
/*-- Load data and init chart with defined functions --*/ |
|
|
|
|
|
|
|
|
|
|
|
if ('url' in config.data) { |
|
|
|
if ('url' in config.data) { |
|
|
|
d3.csv(config.data.url, function(error, data) { init(data) }); |
|
|
|
d3.csv(config.data.url, function (error, data) { init(data); }); |
|
|
|
} |
|
|
|
} |
|
|
|
else if ('rows' in config.data) { |
|
|
|
else if ('rows' in config.data) { |
|
|
|
init(convertRowsToData(config.data.rows)); |
|
|
|
init(convertRowsToData(config.data.rows)); |
|
|
@ -1920,10 +1932,10 @@ |
|
|
|
window.onresize = resize; |
|
|
|
window.onresize = resize; |
|
|
|
|
|
|
|
|
|
|
|
return c3; |
|
|
|
return c3; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
function categoryAxis() { |
|
|
|
function categoryAxis() { |
|
|
|
var scale = d3.scale.linear(), orient = "bottom", tickMajorSize = 6, tickMinorSize = 6, tickEndSize = 6, tickPadding = 3, tickCentered = false, tickTextNum = 10, tickOffset = 0, categories = []; |
|
|
|
var scale = d3.scale.linear(), orient = "bottom", tickMajorSize = 6, /*tickMinorSize = 6,*/ tickEndSize = 6, tickPadding = 3, tickCentered = false, tickTextNum = 10, tickOffset = 0, categories = []; |
|
|
|
function axisX(selection, x) { |
|
|
|
function axisX(selection, x) { |
|
|
|
selection.attr("transform", function (d) { |
|
|
|
selection.attr("transform", function (d) { |
|
|
|
return "translate(" + (x(d) + tickOffset) + ", 0)"; |
|
|
|
return "translate(" + (x(d) + tickOffset) + ", 0)"; |
|
|
@ -1949,7 +1961,7 @@ |
|
|
|
return ticks; |
|
|
|
return ticks; |
|
|
|
} |
|
|
|
} |
|
|
|
function shouldShowTickText(ticks, i) { |
|
|
|
function shouldShowTickText(ticks, i) { |
|
|
|
return ticks.length < tickTextNum || i % Math.ceil(ticks.length / tickTextNum) == 0; |
|
|
|
return ticks.length < tickTextNum || i % Math.ceil(ticks.length / tickTextNum) === 0; |
|
|
|
} |
|
|
|
} |
|
|
|
function category(i) { |
|
|
|
function category(i) { |
|
|
|
return i < categories.length ? categories[i] : i; |
|
|
|
return i < categories.length ? categories[i] : i; |
|
|
@ -1958,8 +1970,19 @@ |
|
|
|
g.each(function () { |
|
|
|
g.each(function () { |
|
|
|
var g = d3.select(this); |
|
|
|
var g = d3.select(this); |
|
|
|
var ticks = generateTicks(scale.domain()); |
|
|
|
var ticks = generateTicks(scale.domain()); |
|
|
|
var tick = g.selectAll(".tick.major").data(ticks, String), tickEnter = tick.enter().insert("g", "path").attr("class", "tick major").style("opacity", 1e-6), tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(), tickUpdate = d3.transition(tick).style("opacity", 1), tickTransform, tickX; |
|
|
|
var tick = g.selectAll(".tick.major").data(ticks, String), |
|
|
|
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 = tick.enter().insert("g", "path").attr("class", "tick major").style("opacity", 1e-6), |
|
|
|
|
|
|
|
tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).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 ]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
path.enter().append("path").attr("class", "domain"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var pathUpdate = d3.transition(path); |
|
|
|
|
|
|
|
|
|
|
|
var scale1 = scale.copy(), scale0 = this.__chart__ || scale1; |
|
|
|
var scale1 = scale.copy(), scale0 = this.__chart__ || scale1; |
|
|
|
this.__chart__ = scale1; |
|
|
|
this.__chart__ = scale1; |
|
|
|
tickEnter.append("line"); |
|
|
|
tickEnter.append("line"); |
|
|
@ -1980,8 +2003,9 @@ |
|
|
|
text.attr("dy", ".71em").style("text-anchor", "middle"); |
|
|
|
text.attr("dy", ".71em").style("text-anchor", "middle"); |
|
|
|
text.text(function (i) { return shouldShowTickText(ticks, i) ? category(i) : ""; }); |
|
|
|
text.text(function (i) { return shouldShowTickText(ticks, i) ? category(i) : ""; }); |
|
|
|
pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize); |
|
|
|
pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize); |
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
/* TODO: implement |
|
|
|
/* TODO: implement |
|
|
|
case "top": |
|
|
|
case "top": |
|
|
|
{ |
|
|
|
{ |
|
|
@ -2035,36 +2059,36 @@ |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
axis.scale = function (x) { |
|
|
|
axis.scale = function (x) { |
|
|
|
if (!arguments.length) return scale; |
|
|
|
if (!arguments.length) { return scale; } |
|
|
|
scale = x; |
|
|
|
scale = x; |
|
|
|
return axis; |
|
|
|
return axis; |
|
|
|
} |
|
|
|
}; |
|
|
|
axis.orient = function (x) { |
|
|
|
axis.orient = function (x) { |
|
|
|
if (!arguments.length) return orient; |
|
|
|
if (!arguments.length) { return orient; } |
|
|
|
orient = x in {top: 1, right: 1, bottom: 1, left: 1} ? x + "" : "bottom"; |
|
|
|
orient = x in {top: 1, right: 1, bottom: 1, left: 1} ? x + "" : "bottom"; |
|
|
|
return axis; |
|
|
|
return axis; |
|
|
|
} |
|
|
|
}; |
|
|
|
axis.categories = function (x) { |
|
|
|
axis.categories = function (x) { |
|
|
|
if (!arguments.length) return categories; |
|
|
|
if (!arguments.length) { return categories; } |
|
|
|
categories = x; |
|
|
|
categories = x; |
|
|
|
return axis; |
|
|
|
return axis; |
|
|
|
} |
|
|
|
}; |
|
|
|
axis.tickCentered = function (x) { |
|
|
|
axis.tickCentered = function (x) { |
|
|
|
if (!arguments.length) return tickCentered; |
|
|
|
if (!arguments.length) { return tickCentered; } |
|
|
|
tickCentered = x; |
|
|
|
tickCentered = x; |
|
|
|
return axis; |
|
|
|
return axis; |
|
|
|
} |
|
|
|
}; |
|
|
|
axis.tickTextNum = function (x) { |
|
|
|
axis.tickTextNum = function (x) { |
|
|
|
if (!arguments.length) return tickTextNum; |
|
|
|
if (!arguments.length) { return tickTextNum; } |
|
|
|
tickTextNum = x; |
|
|
|
tickTextNum = x; |
|
|
|
return axis; |
|
|
|
return axis; |
|
|
|
} |
|
|
|
}; |
|
|
|
axis.tickOffset = function () { |
|
|
|
axis.tickOffset = function () { |
|
|
|
return tickOffset; |
|
|
|
return tickOffset; |
|
|
|
} |
|
|
|
}; |
|
|
|
axis.ticks = function () { |
|
|
|
axis.ticks = function () { |
|
|
|
return; // TODO: implement
|
|
|
|
return; // TODO: implement
|
|
|
|
} |
|
|
|
}; |
|
|
|
return axis; |
|
|
|
return axis; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|