title: d3 v5 timeline example
body: <p>I have this example in codepen, but looking to implement the same features in d3 v5.
  <a href="https://codepen.io/manglass/pen/MvLBRz" rel="nofollow noreferrer">https://codepen.io/manglass/pen/MvLBRz</a>.</p>
  
  <p>I am using typescript and my code breaks at g.selectall('svg') down below.
  If i have                           d3.select(g).selectAll('svg').data(data).enter(). It's throwing this.querySelectorAll is not a function</p>
  
  <p>Could anyone please help me here?</p>
  
  <pre><code> setTimeout(function () {
          (function timelines() {
              const appendTimeAxis = function (g, xAxis, yPosition) {
                  const axis = g.append('g')
                      .attr('class', 'axis')
                      .attr('transform', 'translate(' + 0 + ',' + yPosition + ')')
                      .call(xAxis);
              };
  
              const appendLabel = function (gParent, yAxisMapping, index, hasLabel, datum) {
                  const fullItemHeight = itemHeight + itemMargin;
                  const rowsDown = margin.top + (fullItemHeight / 2) + fullItemHeight * (yAxisMapping[index] || 1);
                  gParent.append('text')
                      .attr('class', 'timeline-label')
                      .attr('transform', 'translate(' + labelMargin + ',' + rowsDown + ')')
                      .text(hasLabel ? labelFunction(datum.label) : datum.id)
                      .on('click', function (d, i) {// click(d, index, datum);
                      });
              };
  
  
              (function timeline(gParent) {
                  const temp: any = d3.select('#timeline3');
                  console.log('d3 selector');
                  console.log(temp);
                  //  gParent = temp._groups[0][0].firstChild;
                  gParent = d3.select(temp._groups[0][0].firstChild);
                  console.log('gParent');
                  console.log(gParent);
                  let g = temp._groups[0][0].firstChild.firstChild.firstChild;
                  // const g = gParent.append('g');
                  console.log('g');
                  console.log(g);
                  const gParentSize = temp._groups[0][0].firstChild.getBoundingClientRect();
                  let gParentItem = temp._groups[0][0].firstChild;
                  gParentItem = d3.select(gParentItem);
                  console.log(d3.select(gParentItem));
                  const yAxisMapping = {};
                  let maxStack = 1,
                      minTime = 0,
                      maxTime = 0;
  
                  setWidth();
  
                  if (stacked || ending === 0 || beginning === 0) {
                      g = d3.select(g);
                      input = g._groups[0][0].__data__;
                      g = g._groups;
                      console.log(g);
                      g.forEach(function (d, i) {
                          console.log('d');
                          d = input;
                          console.log(d);
                          d.forEach(function (datum, index) {
                              console.log(datum);
                              console.log(index);
                              // create y mapping for stacked graph
                              if (stacked &amp;&amp; Object.keys(yAxisMapping).indexOf(index) == -1) {
                                  yAxisMapping[index] = maxStack;
                                  maxStack++;
                              }
                              // figure out beginning and ending times if they are unspecified
                              datum.times.forEach(function (time, i) {
                                  if (beginning === 0) {
                                      if (time.starting_time &lt; minTime || (minTime === 0 &amp;&amp; timeIsRelative === false)) {
                                          minTime = time.starting_time;
                                      }
                                  }
                                  if (ending === 0) {
                                      if (time.ending_time &gt; maxTime) {
                                          maxTime = time.ending_time;
                                      }
                                  }
                              });
                          });
                      });
                      if (ending === 0) {
                          ending = maxTime;
                      }
                      if (beginning === 0) {
                          beginning = minTime;
                      }
                  }
  
                  const scaleFactor = (1 / (ending - beginning)) * (width - margin.left - margin.right);
  
                  // draw the axis
                  const xScale = d3.scaleTime()
                      .domain([beginning, ending])
                      .range([margin.left, width - margin.right]);
  
                  const xAxis = d3.axisBottom(xScale)
                      .tickFormat(tickFormat.format)
                      .tickSize(tickFormat.tickSize);
  
                  if (tickFormat.tickValues != null) {
                      xAxis.tickValues(tickFormat.tickValues);
                  } else {
                      xAxis.ticks(tickFormat.tickTime, tickFormat.tickInterval);
                  }
                  // setHeight();
                  // draw the chart
                  console.log(g);
                  g.forEach(function (d, i) {
                      d = input;
                      console.log(d);
                      chartData = d;
                      // console.log(g._groups[0][0].__data__);
                      d.forEach(function (datum, index) {
                          const data = datum.times;
                          console.log('data');
                          console.log(data);
  
                          const hasLabel = (typeof (datum.label) != 'undefined');
                          g.selectAll('svg').data(data).enter()
                              .append(function (d, i) {
                                  return document.createElementNS(d3.namespaces.svg, 'display' in d ? d.display : display);
                              })
                              .attr('x', getXPos)
                              .attr('y', getStackPosition)
                              .attr('width', function (d, i) {
                                  return (d.ending_time - d.starting_time) * scaleFactor;
                              })
                              .attr('cy', function (d, i) {
                                  return getStackPosition(d, i) + itemHeight / 2;
                              })
                              .attr('cx', getXPos)
                              .attr('r', itemHeight / 2)
                              .attr('height', itemHeight)
                              .style('fill', function (d, i) {
                                  let dColorPropName;
                                  if (d.color) { return d.color; }
                                  if (colorPropertyName) {
                                      dColorPropName = d[colorPropertyName];
                                      if (dColorPropName) {
                                          return colorCycle(dColorPropName);
                                      } else {
                                          return colorCycle(datum[colorPropertyName]);
                                      }
                                  }
                                  return colorCycle(index);
                              })
                              .attr('class', function (d, i) {
                                  return datum.class ? 'timelineSeries_' + datum.class : 'timelineSeries_' + index;
                              })
                              .attr('id', function (d, i) {
                                  // use deprecated id field
                                  if (datum.id &amp;&amp; !d.id) {
                                      return 'timelineItem_' + datum.id;
                                  }
  
                                  return d.id ? d.id : 'timelineItem_' + index + '_' + i;
                              })
                              ;
  
                          g.selectAll('svg').data(data).enter()
                              .append('text')
                              .attr('x', getXTextPos)
                              .attr('y', getStackTextPosition)
                              .text(function (d) {
                                  return d.label;
                              })
                              ;
  
  
                          // add the label
                          if (hasLabel) { appendLabel(gParent, yAxisMapping, index, hasLabel, datum); }
  
                          if (typeof (datum.icon) !== 'undefined') {
                              gParent.append('image')
                                  .attr('class', 'timeline-label')
                                  // tslint:disable-next-line:max-line-length
                                  .attr('transform', 'translate(' + 0 + ',' + (margin.top + (itemHeight + itemMargin) * yAxisMapping[index]) + ')')
                                  .attr('xlink:href', datum.icon)
                                  .attr('width', margin.left)
                                  .attr('height', itemHeight);
                          }
  
                          function getStackPosition(d, i) {
                              if (stacked) {
                                  return margin.top + (itemHeight + itemMargin) * yAxisMapping[index];
                              }
                              return margin.top;
                          }
                          function getStackTextPosition(d, i) {
                              if (stacked) {
                                  return margin.top + (itemHeight + itemMargin) * yAxisMapping[index] + itemHeight * 0.75;
                              }
                              return margin.top + itemHeight * 0.75;
                          }
                      });
                  });
                  const belowLastItem = (margin.top + (itemHeight + itemMargin) * maxStack);
                  const aboveFirstItem = margin.top;
                  const timeAxisYPosition = showAxisTop ? aboveFirstItem : belowLastItem;
                  if (showTimeAxis) { appendTimeAxis(g, xAxis, timeAxisYPosition); }
  
  
  
  
                  const gSize = g[0][0].getBoundingClientRect();
                  // console.log('he');
                  setHeight();
  
  
  
                  function getXPos(d, i) {
                      return margin.left + (d.starting_time - beginning) * scaleFactor;
                  }
  
                  function getXTextPos(d, i) {
                      return margin.left + (d.starting_time - beginning) * scaleFactor + 5;
                  }
  
                  function setHeight() {
                      if (!height &amp;&amp; !gParentItem.attr('height')) {
                          console.log('itemheight called1' + itemHeight);
                          if (itemHeight) {
                              console.log(height);
                              // set height based off of item height
                              height = gSize.height + gSize.top - gParentSize.top;
                              // set bounding rectangle height
                              // console.log('itemheight called2' + itemHeight);
                              d3.select(gParent[0][0]).attr('height', height);
                          } else {
                              throw new Error('height of the timeline is not set');
                          }
                      } else {
                          // console.log('itemheight called3' + itemHeight);
                          if (!height) {
                              // console.log('itemheight called4' + itemHeight);
                              height = gParentItem.attr('height');
                          } else {
                              // console.log('itemheight called5' + itemHeight);
                              gParentItem.attr('height', height);
                          }
                      }
                  }
  
                  function setWidth() {
                      if (!width &amp;&amp; !gParentSize.width) {
                          try {
                              width = gParentItem.attr('width');
                              console.log('width if');
                              console.log(width);
                              if (!width) {
                                  // tslint:disable-next-line:max-line-length
                                  throw new Error('width of the timeline is not set. As of Firefox 27, timeline().with(x) needs to be explicitly set in order to render');
                              }
                          } catch (err) {
                              console.log(err);
                          }
                      } else if (!(width &amp;&amp; gParentSize.width)) {
                          try {
                              console.log('width else');
                              width = gParentItem.attr('width');
                              console.log(width);
                          } catch (err) {
                              console.log(err);
                          }
                      }
                      // if both are set, do nothing
                  }
  
              }.call(this));
  </code></pre>