Transitions - 🐠

from IPython.display import HTML, Javascript, display

def configure_d3():
    display(Javascript("""
    require.config({
      paths: {
        d3: "https://d3js.org/d3.v6.min"
      }
    })"""))


configure_d3()

Starting Graph

%%html
<div id="gohere1"></div>

<script type="text/javascript">   
require(['d3'], function (d3) {
    const width = 300
    const height = 100
    margin = 40 
    const dataset = [3, 5, 5, 6, 15, 18]
    
    const svg = d3.select("div#gohere1").append("svg")
        .attr("width", width)
        .attr("height", height)
    
    const x = d3.scaleLinear().range([margin,width-margin]).domain(d3.extent(dataset,(d,i)=> i))
    
    svg.selectAll("circle")
    .data(dataset)
    .join("circle")
    .attr("cx", (d,i)=> x(i))
    .attr("cy", height/2)
    .attr("r", (d,i)=> d)
});
</script>

Transition

%%html
<div id="gohere2"></div>

<script type="text/javascript">   
require(['d3'], function (d3) {
    const width = 300
    const height = 100
    margin = 40 
    const dataset = [3, 5, 5, 6, 15, 18]
    
    const svg = d3.select("div#gohere2").append("svg")
        .attr("width", width)
        .attr("height", height)
    
    const x = d3.scaleLinear().range([margin,width-margin]).domain(d3.extent(dataset,(d,i)=> i))
    
    svg.selectAll("circle")
    .data(dataset)
    .join("circle")
    .attr("cx", (d,i)=> x(i))
    .attr("cy", height/2)
    .attr("r", 0)
    .transition()
    .attr("r", (d,i)=> d)
});
</script>

Duration

Amount of time the transition takes in ms (1000 ms = 1 second)

%%html
<div id="gohere3"></div>

<script type="text/javascript">   
require(['d3'], function (d3) {
    const width = 300
    const height = 100
    margin = 40 
    const dataset = [3, 5, 5, 6, 15, 18]
    
    const svg = d3.select("div#gohere3").append("svg")
        .attr("width", width)
        .attr("height", height)
    
    const x = d3.scaleLinear().range([margin,width-margin]).domain(d3.extent(dataset,(d,i)=> i))
    
    svg.selectAll("circle")
    .data(dataset)
    .join("circle")
    .attr("cx", (d,i)=> x(i))
    .attr("cy", height/2)
    .attr("r", 0)
    .transition()
    .duration(10000)
    .attr("r", (d,i)=> d)
});
</script>

Delay

Setting a specific delay on each element based on an amount of time.

%%html
<div id="gohere4"></div>

<script type="text/javascript">   
require(['d3'], function (d3) {
    const width = 300
    const height = 100
    margin = 40 
    const dataset = [3, 5, 5, 6, 15, 18]
    
    const svg = d3.select("div#gohere4").append("svg")
        .attr("width", width)
        .attr("height", height)
    
    const x = d3.scaleLinear().range([margin,width-margin]).domain(d3.extent(dataset,(d,i)=> i))
    
    svg.selectAll("circle")
    .data(dataset)
    .join("circle")
    .attr("cx", (d,i)=> x(i))
    .attr("cy", height/2)
    .attr("r", 0)
    .transition()
    .duration(1000)
    .delay((d,i)=> i*100)
    .attr("r", (d,i)=> d)
});
</script>

Easing

The pattern the transition use. https://observablehq.com/@d3/easing-animations

%%html
<div id="gohere5"></div>

<script type="text/javascript">   
require(['d3'], function (d3) {
    const width = 300
    const height = 100
    margin = 40 
    const dataset = [3, 5, 5, 6, 15, 18]
    
    const svg = d3.select("div#gohere5").append("svg")
        .attr("width", width)
        .attr("height", height)
    
    const x = d3.scaleLinear().range([margin,width-margin]).domain(d3.extent(dataset,(d,i)=> i))
    
    svg.selectAll("circle")
        .data(dataset)
        .join("circle")
        .attr("cx", (d,i)=> x(i))
        .attr("cy", height/2)
        .attr("r", 2)
        .transition()
        .duration(1000)
        .attr("cy", height/3)
        .transition()
        .duration(1000) 
        .attr("r", (d,i)=> d)
});
</script>

Using inputs for transitions.

There are a number of different types of inputs, but we will be covering the following:

  • Buttons

  • Radio buttons

  • Checkboxes

  • Range

Buttons

%%html
<input type="button" id="button1" onclick="console.log('Hello, Everyone!')" value="Click the button">

Radio buttons

%%html   
<input type="radio" id="vanilla" name="iceCream" value="vanilla">
<label for="vanilla">Vanilla</label><br>
<input type="radio" id="chocolate" name="iceCream" value="chocolate">
<label for="chocolate">Chocolate</label><br>
<input type="radio" id="other" name="iceCream" value="other" checked>
<label for="other">Other</label>


%%html   
<input type="radio" id="vanilla" name="iceCream" value="vanilla" checked>
<label for="vanilla">Vanilla</label><br>
<input type="radio" id="chocolate" name="iceCream" value="chocolate">
<label for="chocolate">Chocolate</label><br>
<input type="radio" id="other" name="iceCream" value="other">
<label for="other">Other</label>


Checkbox

%%html
<input type="checkbox" id="toppings1" name="toppings1" value="sprinkles" checked>
<label for="toppings1">Sprinkles</label><br>
<input type="checkbox" id="toppings2" name="toppings2" value="whippedCream" checked>
<label for="toppings2">Whipped Cream</label><br>
<input type="checkbox" id="toppings3" name="toppings3" value="cherry" checked>
<label for="toppings3">Cherry</label>


Sliders

%%html
<input type="range" id="orders" name="orders" min="0" max="10" value="5" step="5" style="width:200px">
<label for="orders">Number of Orders</label>

Adding a button

%%html
<div id="gohere6"></div>
<input type="button" id="button2" value="Run the Transition!">
<script type="text/javascript">   
require(['d3'], function (d3) {
    const width = 300
    const height = 100
    margin = 40 
    const dataset = [3, 5, 5, 6, 15, 18]
    
    const svg = d3.select("div#gohere6").append("svg")
        .attr("width", width)
        .attr("height", height)
    
    const x = d3.scaleLinear().range([margin,width-margin]).domain(d3.extent(dataset,(d,i)=> i))
    
    svg.selectAll("circle")
        .data(dataset)
        .join("circle")
        .attr("cx", (d,i)=> x(i))
        .attr("cy", height/2)
        .attr("r", 1)
    
    // d3.select can select any element on our page
    d3.select("input#button2")
        .on("click",function() {
            console.log("button pushed!")
        })


});
</script>
%%html
<div id="gohere7"></div>
<input type="button" id="button3" value="Run the Transition!">
<script type="text/javascript">   
require(['d3'], function (d3) {
    const width = 300
    const height = 100
    margin = 40 
    const dataset = [3, 5, 5, 6, 15, 18]
    
    const svg = d3.select("div#gohere7").append("svg")
        .attr("width", width)
        .attr("height", height)
    
    const x = d3.scaleLinear().range([margin,width-margin]).domain(d3.extent(dataset,(d,i)=> i))
    
    svg.selectAll("circle")
        .data(dataset)
        .join("circle")
        .attr("cx", (d,i)=> x(i))
        .attr("cy", height/2)
        .attr("r", 1)
    
    // d3.select can select any element on our page
    d3.select("input#button3")
        .on("click",function() {
            // svg.select selects things in the given graph
            svg.selectAll("circle")
                .transition()
                .duration(1000)
                .delay((d,i)=> i*100)
                .attr("r", (d,i)=> d)
        })

});
</script>
%%html
<div id="gohere8"></div>
<input type="button" id="button4" value="Run the Transition!">
<script type="text/javascript">   
require(['d3'], function (d3) {
    const width = 300
    const height = 100
    margin = 40 
    const dataset = [3, 5, 5, 6, 15, 18]
    
    const svg = d3.select("div#gohere8").append("svg")
        .attr("width", width)
        .attr("height", height)
    
    const x = d3.scaleLinear().range([margin,width-margin]).domain(d3.extent(dataset,(d,i)=> i))
    
    svg.selectAll("circle")
        .data(dataset)
        .join("circle")
        .attr("cx", (d,i)=> x(i))
        .attr("cy", height/2)
        .attr("r", 1)
    
    var selected = 1;
    
    // d3.select can select any element on our page
    d3.select("input#button4")
        .on("click",function() {
            // svg.select selects things in the given graph
            if (selected) {
                svg.selectAll("circle")
                    .transition()
                    .duration(1000)
                    .delay((d,i)=> i*100)
                    .attr("r", (d,i)=> d)  
                selected = 0;
            }
            else {
                svg.selectAll("circle")
                    .transition()
                    .duration(1000)
                    .delay((d,i)=> i*100)
                    .attr("r", (d,i)=> 1)  
                selected = 1;
            }

        })

});
</script>