chartexample.com
  • About
  • Blog
  • Charts

Density chart D3 example

  • Home
  • Charts
  • Density
  • Density chart D3 example
function makeDensity() {
  //empty data set
  let data = [0, 0, 0, 0, 0, 0, 0, 0]

  const strokeColor = '#d0d4fc'
  const fillColor = '#285674'

  // max data item value
  const max = 10
  // min data item value
  const min = 0 
  // setting values for margins of svg content
  const margin = {top: 20, left: 50, right: 30, bottom: 40}
  // selecting root element for plot
  const svg = d3.select('#chart')
  // getting root element width
  const width = parseInt(svg.style('width')) 
  // getting root element height
  const height = parseInt(svg.style('height')) 

  // creating linear scaling for Y
  const scaleY = d3.scaleLinear()
    .domain([max, min])
    .range([margin.top, height - margin.bottom]) 
  // creating linear scaling for X
  // data.length is used because we want scaling by X
  // depends on item count, not values 
  const scaleX = d3.scaleLinear()
    .domain([0, data.length - 1])
    .range([margin.left, width - margin.right]) 

  // creating of X axis 
  const axisX = d3.axisBottom(scaleX)

  // creating of Y axis
  // swapping range values because they should increase
  // from bottom to top. its opposite by default
  const axisY = d3.axisRight(
    d3.scaleLinear()
      .domain([min, max])
      .range([height - margin.bottom, margin.top])
  )

  // creating area generator function
  const area = d3.area()

  // applying options to area generator
  area
    // x coord according to data item index
    .x((d, i) => scaleX(i))
    // y0 is static and should be the bottom of the plot
    .y0(height - margin.bottom)
    // y1 is the data item value
    .y1(d => scaleY(d))
    // using curveBasis to set curve
    .curve(d3.curveBasis)

  // creating group for plot items
  const items = svg.append('g')

  // creating empty selection
  items.selectAll('path')
    // applying data
    // data is wrapped by array because we need only one
    // data element for one density curve 
    .data([data])
    // joining data to new path element
    .join('path')
    // setting d attr of every path element by calling area generator
    .attr('d', d => area(d))
    // setting fill color
    .attr('fill', fillColor)
    // setting stroke color
    .attr('stroke', strokeColor)

  // creating wrapper element for Y axis
  svg.append('g')
    // calling Y axis component function
    .call(axisY)
    // adding slight alignment
    .attr('transform', `translate(${margin.left - 30}, 0)`)

  // creating wrapper element for X axis
  svg.append('g')
    // calling X axis component function
    .call(axisX)
    // setting X axis position to be on the plot bottom
    // +5 is slight corretion for better visibility
    .attr('transform', `translate(0, ${height - margin.bottom + 5})`)

  // function for showing dynamic data and view change
  // it generates new data, applies to plot and
  // changes the view with animation
  function change() {
    // generating new dataset
    data = data.map(() => Math.floor(Math.random() * max))
    // selecting path element
    items.select('path')
      // applying new dataset
      .data([data])
      // creating transition
      .transition()
      // setting transition duration
      .duration(300)
      // setting new value for d attribute of path element
      .attr('d', d => area(d))
  }

  // calling change function every second
  setInterval(change, 1000)
}

Alex Chirkin
Powered by Hugo