Browse Source

Fix flow and data load in d3.v4

pull/2246/head
Masayuki Tanaka 7 years ago
parent
commit
f4a163f712
  1. 2
      htdocs/samples/api_flow.html
  2. 3
      htdocs/samples/api_flow_timeseries.html
  3. 53
      src/api.flow.js
  4. 36
      src/axis.js
  5. 86
      src/core.js
  6. 20
      src/grid.js
  7. 4
      src/region.js
  8. 4
      src/shape.bar.js
  9. 25
      src/shape.line.js
  10. 8
      src/text.js

2
htdocs/samples/api_flow.html

@ -11,7 +11,7 @@
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="http://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>

3
htdocs/samples/api_flow_timeseries.html

@ -5,7 +5,7 @@
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="http://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
@ -85,7 +85,6 @@
}, 4000);
setTimeout(function () {
console.log("Flow 1");
chart.flow({
columns: [
['x', '2013-03-01', '2013-03-08'],

53
src/api.flow.js

@ -171,14 +171,14 @@ c3_chart_internal_fn.generateFlow = function (args) {
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([]);
var xgrid,
xgridLines,
mainRegion,
mainText,
mainBar,
mainLine,
mainArea,
mainCircle;
// set flag
$$.flowing = true;
@ -193,6 +193,15 @@ c3_chart_internal_fn.generateFlow = function (args) {
// update elements related to x scale
if ($$.updateXGrid) { $$.updateXGrid(true); }
xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid
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([]);
// generate transform to flow
if (!flow.orgDataCount) { // if empty
if ($$.data.targets[0].values.length !== 1) {
@ -220,18 +229,17 @@ c3_chart_internal_fn.generateFlow = function (args) {
$$.hideXGridFocus();
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 flowTransition = d3.transition().ease(d3.easeLinear).duration(durationForFlow);
wait.add($$.xAxis($$.axes.x, flowTransition));
wait.add(mainBar.transition(flowTransition).attr('transform', transform));
wait.add(mainLine.transition(flowTransition).attr('transform', transform));
wait.add(mainArea.transition(flowTransition).attr('transform', transform));
wait.add(mainCircle.transition(flowTransition).attr('transform', transform));
wait.add(mainText.transition(flowTransition).attr('transform', transform));
wait.add(mainRegion.filter($$.isRegionOnX).transition(flowTransition).attr('transform', transform));
wait.add(xgrid.transition(flowTransition).attr('transform', transform));
wait.add(xgridLines.transition(flowTransition).attr('transform', transform));
wait(function () {
var i, shapes = [], texts = [], eventRects = [];
// remove flowed elements
@ -253,7 +261,8 @@ c3_chart_internal_fn.generateFlow = function (args) {
.attr('x1', $$.xgridAttr.x1)
.attr('x2', $$.xgridAttr.x2)
.attr('y1', $$.xgridAttr.y1)
.attr('y2', $$.xgridAttr.y2);
.attr('y2', $$.xgridAttr.y2)
.style("opacity", $$.xgridAttr.opacity);
xgridLines
.attr('transform', null);
xgridLines.select('line')
@ -282,7 +291,7 @@ c3_chart_internal_fn.generateFlow = function (args) {
.style('fill-opacity', $$.opacityForText.bind($$));
mainRegion
.attr('transform', null);
mainRegion.select('rect').filter($$.isRegionOnX)
mainRegion.filter($$.isRegionOnX)
.attr("x", $$.regionX.bind($$))
.attr("width", $$.regionWidth.bind($$));

36
src/axis.js

@ -191,7 +191,8 @@ c3_axis_internal_fn.tspanDy = function (d, i) {
c3_axis_internal_fn.generateAxis = function () {
var internal = this, d3 = internal.d3, params = internal.params;
function axis(g) {
function axis(g, transition) {
var self;
g.each(function () {
var g = axis.g = d3.select(this);
@ -203,11 +204,9 @@ c3_axis_internal_fn.generateAxis = function () {
tickEnter = ticks.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 = ticks.exit().remove(),
tickUpdate = tickEnter.merge(ticks),
tickUpdate = ticks.merge(tickEnter),
tickTransform, tickX, tickY;
internal.transitionise(tickUpdate).style('opacity', 1);
if (params.isCategory) {
internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);
tickX = internal.tickCentered ? 0 : internal.tickOffset;
@ -216,15 +215,12 @@ c3_axis_internal_fn.generateAxis = function () {
internal.tickOffset = tickX = 0;
}
tickEnter.append("line");
tickEnter.append("text");
internal.updateRange();
internal.updateTickLength();
internal.updateTickTextCharSize(g.select('.tick'));
var lineUpdate = tickUpdate.select("line"),
textUpdate = tickUpdate.select("text");
var lineUpdate = tickUpdate.select("line").merge(tickEnter.append("line")),
textUpdate = tickUpdate.select("text").merge(tickEnter.append("text"));
var tspans = tickUpdate.selectAll('text').selectAll('tspan').data(function (d, i) {
return internal.tspanData(d, i, ticks, scale1);
@ -307,8 +303,11 @@ c3_axis_internal_fn.generateAxis = function () {
tickExit.call(tickTransform, scale1, internal.tickOffset);
}
tickEnter.call(tickTransform, scale0, internal.tickOffset);
tickUpdate.call(tickTransform, scale1, internal.tickOffset);
self = (transition ? tickUpdate.transition(transition) : tickUpdate)
.style('opacity', 1)
.call(tickTransform, scale1, internal.tickOffset);
});
return self;
}
axis.scale = function (x) {
if (!arguments.length) { return internal.scale; }
@ -749,14 +748,11 @@ c3_axis_fn.generateTransitions = function generateTransitions(duration) {
axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx
};
};
c3_axis_fn.redraw = function redraw(transitions, isHidden) {
var $$ = this.owner;
$$.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);
c3_axis_fn.redraw = function redraw(duration, isHidden) {
var $$ = this.owner,
transition = duration ? $$.d3.transition().duration(duration) : null;
$$.axes.x.style("opacity", isHidden ? 0 : 1).call($$.xAxis, transition);
$$.axes.y.style("opacity", isHidden ? 0 : 1).call($$.yAxis, transition);
$$.axes.y2.style("opacity", isHidden ? 0 : 1).call($$.y2Axis, transition);
$$.axes.subx.style("opacity", isHidden ? 0 : 1).call($$.subXAxis, transition);
};

86
src/core.js

@ -446,7 +446,7 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
var hideAxis = $$.hasArcType();
var drawArea, drawBar, drawLine, xForText, yForText;
var duration, durationForExit, durationForAxis;
var waitForDraw, flow;
var transitionsToWait, waitForDraw, flow, transition;
var targetsToShow = $$.filterTargetsToShow($$.data.targets), tickValues, i, intervalForCulling, xDomainForZoom;
var xv = $$.xv.bind($$), cx, cy;
@ -510,7 +510,7 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
}
// axes
$$.axis.redraw(transitions, hideAxis);
$$.axis.redraw(durationForAxis, hideAxis);
// Update axis label
$$.axis.updateLabels(withTransition);
@ -542,6 +542,12 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);
yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false);
// update circleY based on updated parameters
$$.updateCircleY();
// generate circle x/y functions depending on updated params
cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);
cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$);
// Update sub domain
if (withY) {
$$.subY.domain($$.getYDomain(targetsToShow, 'y'));
@ -571,11 +577,11 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
// lines, areas and cricles
$$.updateLine(durationForExit);
$$.updateArea(durationForExit);
$$.updateCircle();
$$.updateCircle(cx, cy);
// text
if ($$.hasDataLabel()) {
$$.updateText(durationForExit);
$$.updateText(xForText, yForText, durationForExit);
}
// title
@ -600,13 +606,6 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
$$.updateEventRect();
}
// update circleY based on updated parameters
$$.updateCircleY();
// generate circle x/y functions depending on updated params
cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);
cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$);
if (options.flow) {
flow = $$.generateFlow({
targets: targetsToShow,
@ -623,51 +622,44 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
});
}
if ((duration || flow) && $$.isTabVisible()) { // Only use transition if tab visible. See #938.
// transition should be derived from one transition
d3.transition().duration(duration).each(function () {
var transitionsToWait = [];
// redraw and gather transitions
if ($$.isTabVisible()) { // Only use transition if tab visible. See #938.
if (duration) {
// transition should be derived from one transition
transition = d3.transition().duration(duration);
transitionsToWait = [];
[
$$.redrawBar(drawBar, true),
$$.redrawLine(drawLine, true),
$$.redrawArea(drawArea, true),
$$.redrawCircle(cx, cy, true),
$$.redrawText(xForText, yForText, options.flow, true),
$$.redrawRegion(true),
$$.redrawGrid(true),
$$.redrawBar(drawBar, true, transition),
$$.redrawLine(drawLine, true, transition),
$$.redrawArea(drawArea, true, transition),
$$.redrawCircle(cx, cy, true, transition),
$$.redrawText(xForText, yForText, options.flow, true, transition),
$$.redrawRegion(true, transition),
$$.redrawGrid(true, transition),
].forEach(function (transitions) {
transitions.forEach(function (transition) {
transitionsToWait.push(transition);
});
});
// Wait for end of transitions to call flow and onrendered callback
waitForDraw = $$.generateWait();
transitionsToWait.forEach(function (t) {
waitForDraw.add(t);
});
})
.call(waitForDraw, function () {
if (flow) {
flow();
}
if (config.onrendered) {
config.onrendered.call($$);
}
});
}
else {
$$.redrawBar(drawBar);
$$.redrawLine(drawLine);
$$.redrawArea(drawArea);
$$.redrawCircle(cx, cy);
$$.redrawText(xForText, yForText, options.flow);
$$.redrawRegion();
$$.redrawGrid();
if (config.onrendered) {
config.onrendered.call($$);
waitForDraw(function () {
if (flow) { flow(); }
if (config.onrendered) { config.onrendered.call($$); }
});
}
else {
$$.redrawBar(drawBar);
$$.redrawLine(drawLine);
$$.redrawArea(drawArea);
$$.redrawCircle(cx, cy);
$$.redrawText(xForText, yForText, options.flow);
$$.redrawRegion();
$$.redrawGrid();
if (flow) { flow(); }
if (config.onrendered) { config.onrendered.call($$); }
}
}
@ -1001,7 +993,7 @@ c3_chart_internal_fn.endall = function (transition, callback) {
};
c3_chart_internal_fn.generateWait = function () {
var transitionsToWait = [],
f = function (transition, callback) {
f = function (callback) {
var timer = setInterval(function () {
var done = 0;
transitionsToWait.forEach(function (t) {
@ -1019,7 +1011,7 @@ c3_chart_internal_fn.generateWait = function () {
clearInterval(timer);
if (callback) { callback(); }
}
}, 10);
}, 50);
};
f.add = function (transition) {
transitionsToWait.push(transition);

20
src/grid.js

@ -47,11 +47,20 @@ c3_chart_internal_fn.updateXGrid = function (withoutUpdate) {
'y1': 0,
'y2': $$.height
};
$$.xgridAttr.opacity = function () {
var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1');
return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1;
};
var xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid)
.data(xgridData);
var xgridEnter = xgrid.enter().append('line')
.attr("class", CLASS.xgrid);
.attr("class", CLASS.xgrid)
.attr('x1', $$.xgridAttr.x1)
.attr('x2', $$.xgridAttr.x2)
.attr('y1', $$.xgridAttr.y1)
.attr('y2', $$.xgridAttr.y2)
.style("opacity", 0);
$$.xgrid = xgridEnter.merge(xgrid);
if (!withoutUpdate) {
$$.xgrid
@ -59,7 +68,7 @@ c3_chart_internal_fn.updateXGrid = function (withoutUpdate) {
.attr('x2', $$.xgridAttr.x2)
.attr('y1', $$.xgridAttr.y1)
.attr('y2', $$.xgridAttr.y2)
.style("opacity", function () { return +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1') === (config.axis_rotated ? $$.height : 0) ? 0 : 1; });
.style("opacity", $$.xgridAttr.opacity);
}
xgrid.exit().remove();
};
@ -70,6 +79,7 @@ c3_chart_internal_fn.updateYGrid = function () {
var ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid)
.data(gridValues);
var ygridEnter = ygrid.enter().append('line')
// TODO: x1, x2, y1, y2, opacity need to be set here maybe
.attr('class', CLASS.ygrid);
$$.ygrid = ygridEnter.merge(ygrid);
$$.ygrid
@ -176,18 +186,18 @@ c3_chart_internal_fn.updateGrid = function (duration) {
.style("opacity", 0)
.remove();
};
c3_chart_internal_fn.redrawGrid = function (withTransition) {
c3_chart_internal_fn.redrawGrid = function (withTransition, transition) {
var $$ = this, config = $$.config, xv = $$.xv.bind($$),
lines = $$.xgridLines.select('line'),
texts = $$.xgridLines.select('text');
return [
(withTransition ? lines.transition() : lines)
(withTransition ? lines.transition(transition) : lines)
.attr("x1", config.axis_rotated ? 0 : xv)
.attr("x2", config.axis_rotated ? $$.width : xv)
.attr("y1", config.axis_rotated ? xv : 0)
.attr("y2", config.axis_rotated ? xv : $$.height)
.style("opacity", 1),
(withTransition ? texts.transition() : texts)
(withTransition ? texts.transition(transition) : texts)
.attr("x", config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$))
.attr("y", xv)
.text(function (d) { return d.text; })

4
src/region.js

@ -29,9 +29,9 @@ c3_chart_internal_fn.updateRegion = function (duration) {
.style("opacity", 0)
.remove();
};
c3_chart_internal_fn.redrawRegion = function (withTransition) {
c3_chart_internal_fn.redrawRegion = function (withTransition, transition) {
var $$ = this, regions = $$.mainRegion;
return [(withTransition ? regions.transition() : regions)
return [(withTransition ? regions.transition(transition) : regions)
.attr("x", $$.regionX.bind($$))
.attr("y", $$.regionY.bind($$))
.attr("width", $$.regionWidth.bind($$))

4
src/shape.bar.js

@ -42,9 +42,9 @@ c3_chart_internal_fn.updateBar = function (durationForExit) {
mainBar.exit().transition().duration(durationForExit)
.style("opacity", 0);
};
c3_chart_internal_fn.redrawBar = function (drawBar, withTransition) {
c3_chart_internal_fn.redrawBar = function (drawBar, withTransition, transition) {
return [
(withTransition ? this.mainBar.transition(Math.random().toString()) : this.mainBar)
(withTransition ? this.mainBar.transition(transition) : this.mainBar)
.attr('d', drawBar)
.style("stroke", this.color)
.style("fill", this.color)

25
src/shape.line.js

@ -57,9 +57,9 @@ c3_chart_internal_fn.updateLine = function (durationForExit) {
mainLine.exit().transition().duration(durationForExit)
.style('opacity', 0);
};
c3_chart_internal_fn.redrawLine = function (drawLine, withTransition) {
c3_chart_internal_fn.redrawLine = function (drawLine, withTransition, transition) {
return [
(withTransition ? this.mainLine.transition(Math.random().toString()) : this.mainLine)
(withTransition ? this.mainLine.transition(transition) : this.mainLine)
.attr("d", drawLine)
.style("stroke", this.color)
.style("opacity", 1)
@ -232,9 +232,9 @@ c3_chart_internal_fn.updateArea = function (durationForExit) {
mainArea.exit().transition().duration(durationForExit)
.style('opacity', 0);
};
c3_chart_internal_fn.redrawArea = function (drawArea, withTransition) {
c3_chart_internal_fn.redrawArea = function (drawArea, withTransition, transition) {
return [
(withTransition ? this.mainArea.transition(Math.random().toString()) : this.mainArea)
(withTransition ? this.mainArea.transition(transition) : this.mainArea)
.attr("d", drawArea)
.style("fill", this.color)
.style("opacity", this.orgAreaOpacity)
@ -302,12 +302,14 @@ c3_chart_internal_fn.generateGetAreaPoints = function (areaIndices, isSub) { //
};
c3_chart_internal_fn.updateCircle = function () {
c3_chart_internal_fn.updateCircle = function (cx, cy) {
var $$ = this;
var mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle)
.data($$.lineOrScatterData.bind($$));
var mainCircleEnter = mainCircle.enter().append("circle")
.attr("class", $$.classCircle.bind($$))
.attr("cx", cx)
.attr("cy", cy)
.attr("r", $$.pointR.bind($$))
.style("fill", $$.color);
$$.mainCircle = mainCircleEnter.merge(mainCircle)
@ -315,15 +317,16 @@ c3_chart_internal_fn.updateCircle = function () {
mainCircle.exit()
.style("opacity", 0);
};
c3_chart_internal_fn.redrawCircle = function (cx, cy, withTransition) {
var selectedCircles = this.main.selectAll('.' + CLASS.selectedCircle);
c3_chart_internal_fn.redrawCircle = function (cx, cy, withTransition, transition) {
var $$ = this,
selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle);
return [
(withTransition ? this.mainCircle.transition(Math.random().toString()) : this.mainCircle)
.style('opacity', this.opacityForCircle.bind(this))
.style("fill", this.color)
(withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle)
.style('opacity', this.opacityForCircle.bind($$))
.style("fill", $$.color)
.attr("cx", cx)
.attr("cy", cy),
(withTransition ? selectedCircles.transition(Math.random().toString()) : selectedCircles)
(withTransition ? selectedCircles.transition(transition) : selectedCircles)
.attr("cx", cx)
.attr("cy", cy)
];

8
src/text.js

@ -23,7 +23,7 @@ c3_chart_internal_fn.updateTargetsForText = function (targets) {
var mainTextUpdate = mainTextEnter.merge(mainText)
.attr('class', function (d) { return classChartText(d) + classFocus(d); });
};
c3_chart_internal_fn.updateText = function (durationForExit) {
c3_chart_internal_fn.updateText = function (xForText, yForText, durationForExit) {
var $$ = this, config = $$.config,
barOrLineData = $$.barOrLineData.bind($$),
classText = $$.classText.bind($$);
@ -33,6 +33,8 @@ c3_chart_internal_fn.updateText = function (durationForExit) {
.attr("class", classText)
.attr('text-anchor', function (d) { return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle'; })
.style("stroke", 'none')
.attr('x', xForText)
.attr('y', yForText)
.style("fill", function (d) { return $$.color(d); })
.style("fill-opacity", 0);
$$.mainText = mainTextEnter.merge(mainText)
@ -42,9 +44,9 @@ c3_chart_internal_fn.updateText = function (durationForExit) {
.style('fill-opacity', 0)
.remove();
};
c3_chart_internal_fn.redrawText = function (xForText, yForText, forFlow, withTransition) {
c3_chart_internal_fn.redrawText = function (xForText, yForText, forFlow, withTransition, transition) {
return [
(withTransition ? this.mainText.transition() : this.mainText)
(withTransition ? this.mainText.transition(transition) : this.mainText)
.attr('x', xForText)
.attr('y', yForText)
.style("fill", this.color)

Loading…
Cancel
Save