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.
164 lines
4.9 KiB
164 lines
4.9 KiB
import { |
|
CLASS, |
|
isValue, |
|
isFunction, |
|
isString, |
|
isUndefined, |
|
isDefined, |
|
ceil10, |
|
asHalfPixel, |
|
diffDomain, |
|
isEmpty, |
|
notEmpty, |
|
getOption, |
|
hasValue, |
|
sanitise, |
|
getPathBox, |
|
ChartInternal |
|
} from '../chartinternal.js'; |
|
|
|
const flow = function (args) { |
|
let $$ = 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((t) => { |
|
let 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((t) => { |
|
let 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((t) => { |
|
let 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((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((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, |
|
duration: isValue(args.duration) ? args.duration : $$.config.transition_duration, |
|
done: args.done, |
|
orgDataCount, |
|
}, |
|
withLegend: true, |
|
withTransition: orgDataCount > 1, |
|
withTrimXDomain: false, |
|
withUpdateXAxis: true, |
|
}); |
|
}; |
|
|
|
export { flow };
|
|
|