score:0
The problem is that onrendered
is called when all the svg
manipulations are done. But the transitions still have to be started. You have to wait till the transitions are finished.
The naive way is to get the transition
after a call to c.hide
or c.show
but it is not attached yet. You have to wait till the first idle processing is done and the first transition tick is processed. You can do that by using a timeout of a few milisecond, then use the attached transition
and hook a follow-up on to it and wait for the start of it to call a function to be handled when transition ends. This is done with the following function.
function atEndOf(dataN, action) {
setTimeout(function() {
var transition = d3.active(d3.select(".bb-chart-line.bb-target.bb-target-"+dataN).node());
if (!transition) { return; } // no transition running
transition.transition().on("start", action);
}, 10);
}
To know when the hide and show transitions are done you can build an atEndOf
chain
// wait till main animation is finished
setTimeout(function() {
c.hide('data1');
atEndOf('data1', function () {
console.log('should be d1=0,d2=1');
showOpacity();
c.hide('data2');
atEndOf('data2', function () {
console.log('should be d1=0,d2=0');
showOpacity();
});
});
}, 6000);
I don't know why but this trick does not work for the main start up draw transition. I get the error "too late: already started"
This uses the following function
function showOpacity() {
var data1op = d3.select(".bb-chart-line.bb-target.bb-target-data1").style("opacity");
var data2op = d3.select(".bb-chart-line.bb-target.bb-target-data2").style("opacity");
console.log(`data1 op: ${data1op} --- data2 op: ${data2op}`);
}
Because the show
and hide
transitions use the default 1s duration it is hard to see that we wait till the end of the transition. To change the duration of these transitions we need to decorate the ChartInternal.endAll()
method. Here I set a duration of 5000ms to all transitions.
var bb_endall = bb.chart.internal.fn.endall;
bb.chart.internal.fn.endall = function (transition, callback) {
transition.duration(5000);
bb_endall(transition, callback);
};
I tried to use another decoration that uses the atEndOf
technique to call a user defined function but I could not get it to work.
A complete example with all transitions set to a duration of 5000ms
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://d3js.org/d3.v4.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/billboard.js/dist/billboard.min.css" />
<script src="https://cdn.jsdelivr.net/npm/billboard.js/dist/billboard.pkgd.min.js"></script>
<title>JS Bin</title>
</head>
<body>
<div id="chart"></div>
<script>
var bb_endall = bb.chart.internal.fn.endall;
bb.chart.internal.fn.endall = function (transition, callback) {
transition.duration(5000);
bb_endall(transition, callback);
};
//console.log('should be d1=1,d2=1');
var c = bb.generate({
bindto: "#chart",
size: {
width: 500,
height: 250
},
// transition: 0,
transition: {duration: 5000},
data: {
x: "x",
columns: [
["x", "2013-01-01", "2013-01-02", "2013-01-03", "2013-01-04", "2013-01-05", "2013-01-06"],
["data1", 30, 200, 100, 400, 150, 250],
["data2", 130, 340, 200, 500, 250, 350],
]
},
axis: {
x: {
type: "timeseries",
tick: {
format: "%Y-%m-%d"
}
}
},
onrendered: function() {
// not usefull for end of transition
}
});
function showOpacity() {
var data1op = d3.select(".bb-chart-line.bb-target.bb-target-data1").style("opacity");
var data2op = d3.select(".bb-chart-line.bb-target.bb-target-data2").style("opacity");
console.log(`data1 op: ${data1op} --- data2 op: ${data2op}`);
}
function atEndOf(dataN, action) {
setTimeout(function() {
var transition = d3.active(d3.select(".bb-chart-line.bb-target.bb-target-"+dataN).node());
if (!transition) { return; } // no transition running
transition.transition().on("start", action);
}, 10);
}
// wait till main animation is finished
setTimeout(function() {
c.hide('data1');
atEndOf('data1', function () {
console.log('should be d1=0,d2=1');
showOpacity();
c.hide('data2');
atEndOf('data2', function () {
console.log('should be d1=0,d2=0');
showOpacity();
});
});
}, 6000);
// setTimeout(function(){console.log('should be d1=0,d2=1');c.hide('data1')},500);
// setTimeout(function(){console.log('should be d1=0,d2=0');c.hide('data2')},1000);
// setTimeout(function(){console.log('should be d1=1,d2=0');c.show('data1')},1500);
// setTimeout(function(){console.log('should be d1=1,d2=1');c.show('data2')},2000);
// setTimeout(function(){console.log('more waiting between hide/show')},3500);
// setTimeout(function(){console.log('should be d1=0,d2=1');c.hide('data1')},5000);
// setTimeout(function(){console.log('should be d1=0,d2=0');c.hide('data2')},6000);
// setTimeout(function(){console.log('should be d1=1,d2=0');c.show('data1')},7000);
// setTimeout(function(){console.log('should be d1=1,d2=1');c.show('data2')},8000);
</script>
</body>
</html>
There is some code in billboard.js
that calls onrendered
when there is a TabVisible. It will be postponed to when the transition has finished. I have no clue yet when that is the case.
Source: stackoverflow.com
Related Query
- How to make sure billboard.js series have ended all transitions in onrendered?
- D3.js: After setting xAxis labels text-orientation vertical, how to make sure all the texts are placed below the horizontal line
- How to make sure that all data are pushed to the array before resolving promise?
- Nvd3: How prevent to display chart between -1 and 1 if have all y values 0?
- d3.js How to make all the nodes collapsed in Collapsible indented Tree
- How to have 2 rect overlap in d3 to make progress bar?
- How to make all the nodes circle the center node?
- How to make React Recharts tooltip modal over all charts?
- How to make d3 concurrent transitions work?
- How to make sure text in treemap cell do not overflow?
- How to make a mouseover interactive line graph with multiple data series and 2 y axes?
- How do I make sure the zoom doesn't go below zero and avoid the zoomed points touching the y and z axis? d3.zoom v4
- How can I make multiple D3.js transitions that repeat at an unchanging rate?
- How can I make 2 different elements in a SVG group have different drag behaviours?
- How to make axis have a top tick
- D3 - How to make visualization with a partition layout have equally divided sectors?
- how to make this D3js sunburst chart display all layers of data?
- how to make smooth transitions with d3 + socket.io
- How to make bars have different patterns in d3.js?
- How to make bars have different colors in d3?
- How do I make sure that data is passed correctly in d3 on drag?
- How do I make sure a function will be called before another in a deeply modularized Backbone, Require.js and D3 app?
- How to make webglcandlestick series respect the bandwidth function?
- How do I make all my graphs show up on my html page?
- How to make d3-tip appear at all times?
- Line-Bar Chart: how to set the xAxis ticks when I have 2 series of 2 different frequencies?
- D3 how to make dynamic sequential transitions work using transform/translate and offset coordinates?
- How to Make True Zero Duration Instant Transitions in D3
- How do I remove all children elements from a node and then apply them again with different color and size?
- How to make force layout graph in D3.js responsive to screen/browser size
More Query from same tag
- Add space above x-caption on D3js multiline chart
- How to Use D3 to Angular Project from Bower Install D3
- D3.js: Starting animations when a section is in view
- How can I find the translated co-ordinates of an SVG element?
- FileAttachment in ObservableHQ - different behaviour if within 2 cells or 1: TypeError: reading.map is not a function
- How do I tell D3 to make the dendrogram vertical (top down) instead of left to right?
- D3: Translating two identical paths so that they run parallel
- d3 bound metadata vs closure accessor
- "Property _ does not exist on _ type" D3.js typescript errors in Ionic 2 project
- Major issue with running d3.v3.js
- d3.js Combining the draggable network with a force directed graph
- Replace old content d3
- How to place an image in D3 node?
- Vertically center a label consisting of multiple lines over a node in D3 force directed graph
- d3.timeParse() Issue with date, month & year
- D3 how to change a circle to rectangle on a mouseover
- Error when generating line Chart, Uncaught TypeError: Cannot read property 'each' of undefined
- In NV D3 horizontal bar chart how to use Json as a data?
- Is there a better approach to using transitions within timer functions in d3js
- dc.js heatmap how to rotate text ?
- Animate position of svg rect on transition
- D3 empty placeholders in scaleBand?
- D3js - change line color based on dataset
- d3.js Overlay Graph
- d3 geo - Map projection
- Onion Ring Chart with nested elements
- custom datamap of the Netherlands in D3
- How to snap svg element to grid while dragging in force layout
- D3 Sankey diagram with dynamic height\width
- Y-Axis not updating at drop down filter change