liveBook · Manning

Database table

As explained in D3.js in Action, Third Edition

An HTML table is a structured HTML element that represents data in rows and columns.

An HTML table presents related data in rows and columns. It can make the underlying values of a visualization available in a human-readable form, giving people an alternative to interpreting a chart through sight or a screen reader description alone. section 10.2.3 section 10.3

Use a table especially when a visualization has many data points or when people may want to inspect or extract its values. For a smaller chart, a descriptive SVG <desc> may be sufficient; a table becomes the more useful alternative as the amount of data grows. section 10.2.3

Build an accessible data table around its meaning, not just its cells:

  • Add a <caption> that identifies the dataset, such as “Cetacean species data.” section 10.2.3
  • Create column headings with <th scope="col"> so each data column has a clear label. section 10.2.3
  • Offer a CSV download link so users can take the displayed dataset with them. section 10.2.3
  • Let users switch explicitly between chart and table modes, and update each button’s aria-pressed state to indicate the selected view. section 10.2.3

A chart/table alternative

A cetacean scatterplot can begin in chart mode and provide a “Display Data Table” button. Selecting it hides the chart container, shows a generated table, and exposes columns for common name, population estimate, maximum size, maximum weight, and conservation status. The table caption can also link to the CSV dataset. section 10.2.3

Listing 10.12 Creating the data table (data-table.js)
const createDataTable = (data) => {

  const table = d3.select(".data-table-container")   #1
    .append("table");                               

  table                                            #2
    .append("caption")                            
      .text("Cetacean species data")              
    .append("a")                                  
      .attr("href", "./data/data.csv")            
      .attr("download", "cetaceans_data")         
      .text("Download the data in CSV format");   

  const tableHeader = table             #3
    .append("tr");                     
  tableHeader                          
    .append("th")                      
      .attr("scope", "col")            
      .text("Common name");            
  tableHeader                          
    .append("th")                      
      .attr("scope", "col")            
      .text("Population estimate");    
  tableHeader                          
    .append("th")                      
      .attr("scope", "col")            
      .text("Maximum size (meter)");   
  tableHeader                          
    .append("th")                      
      .attr("scope", "col")            
      .text("Maximum weight (ton)");   
  tableHeader                          
    .append("th")                      
      .attr("scope", "col")            
      .text("Conservation status");    

  data.forEach(d => {                                                #4
    const tableRow = table                                         
      .append("tr");                                               
    tableRow                                                       
      .append("td")                                                
        .text(d.common_name);                                      
    tableRow                                                       
      .append("td")                                                
        .text(d3.format(".2s")                                     
          (d.global_population_estimate));                         
    tableRow                                                       
      .append("td")                                                
        .text(d.max_size_m);                                       
    tableRow                                                       
      .append("td")                                                
        .text(d.max_weight_t);                                     
     tableRow                                                       #5
      .append("td")                                                
        .text(conservationStatuses.find(status =>                  
          status.id === d.status).label);                          
  });                                                              
};

This implementation creates a table with D3, then adds a caption and scoped column headers before populating its data. section 10.2.3

Tables can also be a source of data. When a page contains many HTML tables, inspect the markup for a shared selector, select the relevant tables with querySelectorAll(), loop through their rows, and account for inconsistent real-world row structures while extracting values. section 14.1

How D3.js in Action, Third Edition covers it

How deep it goes
Walks through generating a D3 table with captions, scoped headers, download access, and chart/table mode switching.
Examples
Uses a cetacean dataset as a chart alternative and extracts painting records from Wikipedia HTML tables.
What it assumes
Assumes basic HTML, JavaScript, DOM inspection, and D3 selection familiarity while demonstrating the table-building steps.
What you can do after
Build it from scratch: generate an accessible D3 data table and toggle it with a chart view.
How it connects
Connects tables with data visualizations, screen readers, semantic HTML, SVG descriptions, keyboard accessibility, and CSV data.

Also explained in

Compare how 12 books explain database table →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of D3.js in Action, Third Edition. The section links point to the parts of the book it draws on.