function configurableTL()

in src/core/configurableTL.ts [55:265]


  function configurableTL(selection) {
    const promises = [];
    selection.each(function (data) {
      if (data.min_start_date === undefined || data.max_end_date === undefined) {
        data.min_start_date = globals.global_min_start_date;
        data.max_end_date = globals.global_max_end_date;
      }

      // update timeline dimensions
      var g = d3.select(this),
        log_bounds = -1,
        curve_margin = 20;

      render_path = d3.svg.line()
        .x(function (d) {
          if (d[0] < curve_margin) {
            return curve_margin;
          }
          if (d[0] > width - curve_margin) {
            return d3.max([0, width - curve_margin]);
          }
          return d[0];
        })
        .y(function (d) {
          if (d[1] < curve_margin) {
            return curve_margin;
          }
          if (d[1] > height - curve_margin) {
            return d3.max([0, height - curve_margin]);
          }
          return d[1];
        })
        .interpolate("basis");

      // remove event annotations during a transition
      selectAllWithParent(".event_annotation").remove();

      //logEvent("timeline initialized", "drawing");

      /**
      ---------------------------------------------------------------------------------------
      GLOBAL DIMENSIONS
      ---------------------------------------------------------------------------------------
      **/

      // add parent container for entire timeline
      var timeline_container = g.selectAll(".timeline")
        .data([null]);

      // define the parent container
      var timeline_container_enter = timeline_container.enter()
        .append("g")
        .attr("class", "timeline")
        .attr("transform", function () {
          return "translate(" + globals.padding.left + "," + globals.padding.top + ")";
        });

      timeline_container_enter.append("rect")
        .attr("class", "timeline_frame")
        .attr("width", width)
        .attr("height", height)
        .on("mouseover", function () {
          d3.select(this)
            .style("opacity", 0.8)
            .style("stroke", "#ccc")
            .style("stroke-width", "0.5px");
        })
        .on("mouseout", function () {
          d3.select(this)
            .style("opacity", 0.1)
            .style("stroke", "none");
        })
        .on("dblclick", function () {
          //logEvent("curve reset", "curve_reset");

          configurableTL.resetCurve();
        })
        .call(d3.behavior.drag()
          .on("dragstart", dragStarted)
          .on("drag", dragged)
          .on("dragend", dragEnd));

      /**
      CURVE-specific timeline
      --*/

      timeline_container_enter.append("path")
        .attr("id", "timecurve")
        .style("visibility", "hidden");

      var timeline_container_update = g.selectAll(".timeline")
        .transition("timeline_container_update")
        .duration(duration);

      timeline_container_update.select("#timecurve")
        .transition()
        .delay(0)
        .duration(duration)
        .style("visibility", () => tl_representation !== "Curve" ? "hidden" : "visible");

      // update parent container
      timeline_container_update.selectAll(".timeline_frame")
        .attr("width", width)
        .attr("height", height);

      //logEvent("timeline container updated", "drawing");

      /**
      ---------------------------------------------------------------------------------------
      FACETS
      ---------------------------------------------------------------------------------------
      **/

      // add facet containers
      if (tl_layout === "Faceted" || prev_tl_layout === "Faceted") {
        timeline_facet = configureFacets(timeline_container, duration, width, height, tl_layout, tl_representation, tl_scale, unit_width).timeline_facet;
      }

      /**
      ---------------------------------------------------------------------------------------
      SEGMENTS
      ---------------------------------------------------------------------------------------
      **/

      // add segment containers
      if (tl_layout === "Segmented" || prev_tl_layout === "Segmented") {
        timeline_segment = configureSegments(timeline_container, duration, width, height, tl_layout, tl_representation, tl_scale, unit_width).timeline_segment;
      }

      /**
      ---------------------------------------------------------------------------------------
      SCALES
      ---------------------------------------------------------------------------------------
      **/

      const tssResults = configureTimelineScaleSegments(tl_layout, tl_representation, tl_scale, timeline_scale, tick_format, data, width, height, unit_width, log_bounds, interim_duration_scale);
      interim_duration_scale = tssResults.interim_duration_scale;
      log_bounds = tssResults.log_bounds;
      tick_format = tssResults.tick_format;
      timeline_scale = tssResults.timeline_scale;
      timeline_scale_segments = tssResults.timeline_scale_segments;

      // stash the new scales
      this.__chart__ = timeline_scale;

      /**
      ---------------------------------------------------------------------------------------
      AXES
      Linear Axes
      ---------------------------------------------------------------------------------------
      **/

      configureLinearAxis(timeline_scale, tl_layout, tl_representation, prev_tl_representation, tl_scale, data, tick_format, unit_width, timeline_container, duration, width, height);

      /**
      ---------------------------------------------------------------------------------------
      AXES
      Collapsed Axis
      ---------------------------------------------------------------------------------------
      **/
      configureCollapsedAxis(tl_representation, prev_tl_scale, tl_scale, tl_layout, interim_duration_axis, interim_duration_scale, duration, data, timeline_container, width, height, unit_width);

      /**
       * AXES
       * Radial Axes
       */
      radial_axis_quantiles = configureRadialAxes(tl_representation, tl_layout, tl_scale, timeline_container, timeline_scale, prev_tl_layout, prev_tl_representation, width, height, radial_axis_quantiles, timeline_scale_segments, radial_axis, duration, timeline_facet, timeline_segment, prev_tl_scale);

      /**
      ---------------------------------------------------------------------------------------
      AXES
      Calendar Axis
      ---------------------------------------------------------------------------------------
      **/
      configureCalendarAxis(tl_representation, duration, data, calendar_axis, timeline_container, prev_tl_representation);

      /**
      ---------------------------------------------------------------------------------------
      AXES
      Grid Axis
      ---------------------------------------------------------------------------------------
      **/
      configureGridAxis(tl_representation, duration, data, grid_axis, timeline_container, prev_tl_representation);

      // It is important that these guys get set here, in case the transitions get interrupted
      const old_scale = prev_tl_scale;
      const old_rep = prev_tl_representation;
      const old_layout = prev_tl_layout;
      prev_tl_scale = tl_scale;
      prev_tl_layout = tl_layout;
      prev_tl_representation = tl_representation;

      // Creates all the elements to be used
      const timeline_event_g = initializeElements(timeline_container, data, duration, width, height, unit_width, tl_representation, configurableTL);

      // Updates those elements to position/size/color them correctly
      const renderComplete = updateElements(interim_duration_scale, timeline_event_g, duration, configurableTL, tl_layout, tl_scale, tl_representation, width, height, data, unit_width, old_layout, old_rep, old_scale, timeline_scale);
      promises.push(renderComplete);
    });
    d3.timer.flush();

    promises.push(new Promise(resolve => {
      // HACK: A way to ensure that we always at least delay the full animation length
      setTimeout(resolve, duration * 3);
    }));

    (<any>configurableTL).renderComplete = Promise.all(promises);
    (<any>configurableTL).renderComplete.then(() => {
      (<any>configurableTL).renderComplete = undefined;
    });
  }