<jupyter_start><jupyter_text>[![img/pythonista.png](img/pythonista.png)](https://www.pythonista.io)  Stacks en *D3.js*.  Inicialización de *D3.js* en la *notebook*. La siguiente celda permite habilitar *D3.js* dentro de esta *notebook* y debe de ser ejecutada siempre antes que cualquier otra celda. **Advertencia:**En caso de no inicializar *D3.js* como primera acción, es probable que el código de las siguientes celdas no funcione aún cuando se haga una inicialización posteriormente. En ese caso, es necesario limpiar todas las salidas de las celdas, guardar y recargar la *notebook*. Un *stack* no espota cosa que una serie de datos apilados.  La función ```d3.select.stack()```. De forma similar a los *pie charts* la función ```d3.select.stack()``` genera un arreglo de *javascript* que a su vez contiene arreglos con coordenadas. Las coordenadas son construidas a partir de ```data```.<jupyter_code>%%javascript

require.config({
        paths: {
            "d3": "https://d3js.org/d3.v7"
        }
    });<jupyter_output><empty_output><jupyter_text>https://github.com/d3/d3-shapestacks<jupyter_code>%%javascript

require(["d3"], function(d3){ 
    d3.csv("data/covid-2021.csv").then(function(data){
        console.log(data)
        ;
    })
})
%%javascript

require(["d3"], function(d3){ 
    d3.csv("data/covid-2021.csv").then(function(data){
        
        const pila = d3.stack().
        keys(["DISTRITO FEDERAL", "MEXICO", "JALISCO", "NUEVO LEON"]).
        order(d3.stackOrderNone).
        offset(d3.stackOffsetNone);

        const serie = pila(data);
        console.log(serie);
        
        
    })
})
%%svg
<svg width="500" height="300" id="svg-1">
</svg>
%%javascript

require(["d3"], function(d3){
    
    /* Obtiene los datos de documento data/covid-2021.csv,
      los guarda en data y a partir de ellos crea serie */
    d3.csv("data/covid-2021.csv").then(function(data){    
        
        /* Se genera la función de creación de stacks */
        const pila = d3.stack().
        keys(["<NAME>", "MEXICO", "JALISCO", "<NAME>"]).
        order(d3.stackOrderNone).
        offset(d3.stackOffsetNone);
        
        /* Se generan las coordenadas del stack para cada dato */
        const serie = pila(data);

            
        /* Se crea la escala lineal para el eje x. */
        const escalaX = d3.scaleLinear().
            domain([0, 364]).
            range([0, 450]);
    
        /* Se define la función del eje x a partir de d3.axisBottom. */ 
        const ejeX = d3.axisBottom(escalaX);
    
        /* Se construye el eje x insertando un elemento <g>. */
        d3.select("#svg-1").
        append("g").
        attr("transform", "translate(60, 255)").
        call(ejeX);
       
        /* Se crea la escala lineal. */
        const escalaY = d3.scaleLinear().
            domain([0, 12000]).
            range([250, 0]);
    
        /* Se define la función del eje y a partir de d3.axisBottom. */ 
        const ejeY = d3.axisLeft(escalaY);
    
    
        /* Se construye el eje y insertando un elemento <g>. */
        d3.select("#svg-1").
            append("g").
            attr("transform", "translate(60, 5)").
            call(ejeY);
    
        /* Se define la función de área */
        let area = d3.area().
            x((d, i) => escalaX(i)).
            y0(d => escalaY(d[0])).
            y1(d => escalaY(d[1]));
            
        for (let i = 0; i < serie.length; i++){
            d3.select("#svg-1").
                append("g").
                attr("transform", "translate(60, 5)").
                append("path").
                attr("d", area(serie[i])).
                attr("fill", "none").
                attr("stroke", "purple").
                attr("stroke-width", "0.3");
        }
    })
})<jupyter_output><empty_output><jupyter_text>* La siguiente celda creará una gráfica de áreas en pila en las que:   * Se utilizará la función [```d3.timeParse()```](https://github.com/d3/d3-time-formattimeParse) para convertir cadenas que representan fechas en objetos ```Date```.   * Se utilizará la función [```d3.scaleTime()```](https://github.com/d3/d3-scalescaleTime) para crear una escala en función de fechas.   * Se utilizará la función ```d3.scaleLinear()``` para definir colores.<jupyter_code>%%svg
<svg width="500" height="300" id="svg-2">
</svg>
%%javascript

require(["d3"], function(d3){
    
    /* Obtiene los datos de documento data/covid-2021.csv,
      los guarda en data y a partir de ellos crea serie */
    d3.csv("data/covid-2021.csv").then(function(data){    
        
        const pila = d3.stack().
        keys(["DISTRITO FEDERAL", "MEXICO", "JALISCO", "<NAME>"]).
        order(d3.stackOrderNone).
        offset(d3.stackOffsetNone);
        
        const serie = pila(data);
        
        /* La función d3.timeParse() permite crear 
          elementos de tiempo a partir de cadenas de
          caracteres que utilizan un formato particular */
        let parseTime = d3.timeParse("%Y-%m-%d");
            
        /* Se crea la escala den rango de tiempo para el eje x. */
        const escalaX = d3.scaleTime().
            domain([parseTime("2021-01-01"), parseTime("2021-12-31")]).
            range([0, 450]);
    
        /* Se define la función del eje x a partir de d3.axisBottom. */ 
        const ejeX = d3.axisBottom(escalaX);
    
        /* Se construye el eje x insertando un elemento <g>. */
        d3.select("#svg-2").
        append("g").
        attr("transform", "translate(60, 255)").
        style("font-size", "7px").
        call(ejeX);
       
        /* Se crea la escala lineal. */
        const escalaY = d3.scaleLinear().
            domain([0, 12000]).
            range([250, 0]);
    
        /* Se define la función del eje y a partir de d3.axisBottom. */ 
        const ejeY = d3.axisLeft(escalaY);
    
    
        /* Se construye el eje y insertando un elemento <g>. */
        d3.select("#svg-2").
            append("g").
            attr("transform", "translate(60, 5)").
            call(ejeY);
        
        /* Se crea la escala lineal para los colores. */
        const escalaColor = d3.scaleLinear().
            domain([0, serie.length - 1]).
            range(["skyblue", "red"]);
    
    let area = d3.area().
        x((d, i) => escalaX(parseTime(data[i]["index"]))).
        y0(d => escalaY(d[0])).
        y1(d => escalaY(d[1])).
        //curve(d3.curveBasis);
        curve(d3.curveCatmullRom.alpha(0.5));
            
    for (let i = 0; i < serie.length; i++){
        d3.select("#svg-2").
            append("g").
            attr("transform", "translate(60, 5)").
            append("path").
            attr("d", area(serie[i])).
            attr("fill", escalaColor(i)).
            attr("stroke", "black").
            attr("stroke-width", "0.3");
        }
    })
})<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15513230590287874, 'fraction_numerical': 0.028787438208781622, 'mean_word_length': 2.0764758497316635, 'pattern_counts': {'":': 1, '<': 26, '<?xml version=': 0, '>': 30, 'https://': 5, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '373879', 'license': 'MIT', 'n_tokens_mistral': 2382, 'n_tokens_neox': 2295, 'n_words': 578, 'path': '25_stacks_en_d3.ipynb', 'repo_name': 'PythonistaMX/py321', 'size': '6896'}