function determineSize()

in src/main.js [3155:3585]


  function determineSize(data, scale, layout, representation) {
    logEvent("timeline: " + scale + " - " + layout + " - " + representation, "sizing");

    switch (representation) {

    case "Linear":
      switch (scale) {

      case "Chronological":
        switch (layout) {

        case "Unified":
            // justifiable
          assignTracks(data, [], layout);
          logEvent("# tracks: " + globals.num_tracks, "sizing");

          globals.width = instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth();
          globals.height = globals.num_tracks * globals.track_height + 1.5 * globals.track_height + globals.margin.top + globals.margin.bottom;
          break;

        case "Faceted":
            // justifiable
          processFacets(data);
          logEvent("# within-facet tracks: " + (globals.max_num_tracks + 1), "sizing");

          globals.width = instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth();
          globals.height = (globals.max_num_tracks * globals.track_height + 1.5 * globals.track_height) * globals.num_facets + globals.margin.top + globals.margin.bottom;
          break;

        case "Segmented":
            // justifiable
          assignTracks(data, [], layout);
          logEvent("# tracks: " + globals.num_tracks, "sizing");

          globals.width = instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth();
          globals.height = (globals.num_tracks * globals.track_height + 1.5 * globals.track_height) * globals.num_segments + globals.margin.top + globals.margin.bottom;
          break;
        default:
          break;
        }
        break;

      case "Relative":
        if (layout === "Faceted") {
          // justifiable
          processFacets(data);
          logEvent("# within-facet tracks: " + (globals.max_num_tracks + 1), "sizing");

          globals.width = instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth();
          globals.height = (globals.max_num_tracks * globals.track_height + 1.5 * globals.track_height) * globals.num_facets + globals.margin.top + globals.margin.bottom;
        } else {
          // not justifiable
          logEvent("scale-layout-representation combination not possible/justifiable", "error");

          globals.width = 0;
          globals.height = 0;
        }
        break;

      case "Log":
        if (layout === "Unified") {
          // justifiable
          assignTracks(data, [], layout);
          logEvent("# tracks: " + globals.num_tracks, "sizing");

          globals.width = instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth();
          globals.height = globals.num_tracks * globals.track_height + 1.5 * globals.track_height + globals.margin.top + globals.margin.bottom;
        } else if (layout === "Faceted") {
          // justifiable
          processFacets(data);
          logEvent("# within-facet tracks: " + (globals.max_num_tracks + 1), "sizing");

          globals.width = instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth();
          globals.height = (globals.max_num_tracks * globals.track_height + 1.5 * globals.track_height) * globals.num_facets + globals.margin.top + globals.margin.bottom;
        } else {
          // not justifiable
          logEvent("scale-layout-representation combination not possible/justifiable", "error");

          globals.width = 0;
          globals.height = 0;
        }
        break;

      case "Collapsed":
        if (layout === "Unified") {
          // justifiable
          assignSequenceTracks(data, []);
          globals.max_seq_index = d3.max(data, function (d) { return d.seq_index; }) + 1;
          var bar_chart_height = (4 * globals.unit_width);
          globals.width = globals.max_seq_index * 1.5 * globals.unit_width + globals.margin.left + 3 * globals.margin.right;
          globals.height = (globals.num_seq_tracks * globals.track_height + 1.5 * globals.track_height) + bar_chart_height + globals.margin.top + globals.margin.bottom;
        } else {
          // not justifiable
          logEvent("scale-layout-representation combination not possible/justifiable", "error");

          globals.width = 0;
          globals.height = 0;
        }
        break;

      case "Sequential":
        if (layout === "Unified") {
          // justifiable
          assignSequenceTracks(data, []);
          globals.max_seq_index = d3.max(data, function (d) { return d.seq_index; }) + 1;
          globals.width = d3.max([
            globals.max_seq_index * 1.5 * globals.unit_width + globals.margin.left + globals.margin.right,
            instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth()
          ]);
          globals.height = globals.num_seq_tracks * globals.track_height + 1.5 * globals.track_height + globals.margin.top + globals.margin.bottom;
        } else if (layout === "Faceted") {
          // justifiable
          processFacets(data);
          globals.max_seq_index = d3.max(data, function (d) { return d.seq_index; }) + 1;
          globals.width = d3.max([
            globals.max_seq_index * 1.5 * globals.unit_width + globals.margin.left + globals.margin.right,
            instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth()
          ]);
          globals.height = (globals.max_num_seq_tracks * globals.track_height + 1.5 * globals.track_height) * globals.num_facets + globals.margin.top + globals.margin.bottom;
        } else {
          // not justifiable
          logEvent("scale-layout-representation combination not possible/justifiable", "error");

          globals.width = 0;
          globals.height = 0;
        }
        break;
      default:
        break;
      }
      break;

    case "Radial":

      globals.centre_radius = 50;

      var effective_size = instance._render_width - globals.margin.right - globals.padding.right - globals.margin.left - globals.padding.left - getScrollbarWidth();

      switch (scale) {

      case "Chronological":

        switch (layout) {

        case "Unified":
          // justifiable
          assignTracks(data, [], layout);
          logEvent("# tracks: " + globals.num_tracks, "sizing");

          globals.centre_radius = d3.max([50, (effective_size - ((globals.num_tracks + 2) * 2 * globals.track_height)) / 2]);
          globals.width = (2 * globals.centre_radius + (globals.num_tracks + 2) * 2 * globals.track_height) + globals.margin.left + globals.margin.right;
          if (globals.centre_radius > 200)          { globals.centre_radius = 200; }
          globals.height = (2 * globals.centre_radius + (globals.num_tracks + 2) * 2 * globals.track_height) + globals.margin.top + globals.margin.bottom;
          break;

        case "Faceted":
          // justifiable
          processFacets(data);

          globals.centre_radius = 50;
          var estimated_facet_width = (2 * globals.centre_radius + (globals.max_num_tracks + 2) * 2 * globals.track_height);

          globals.num_facet_cols = d3.max([1, d3.min([globals.num_facet_cols, Math.floor(effective_size / estimated_facet_width)])]);
          globals.num_facet_rows = Math.ceil(globals.num_facets / globals.num_facet_cols);

          globals.centre_radius = d3.max([50, (effective_size / globals.num_facet_cols - ((globals.max_num_tracks + 2) * 2 * globals.track_height)) / 2]);
          globals.width = (2 * globals.centre_radius + (globals.max_num_tracks + 2) * 2 * globals.track_height) * globals.num_facet_cols + globals.margin.left + globals.margin.right;
          if (globals.centre_radius > 200)          { globals.centre_radius = 200; }
          globals.height = (2 * globals.centre_radius + (globals.max_num_tracks + 2) * 2 * globals.track_height) * globals.num_facet_rows + globals.margin.top + globals.margin.bottom + globals.num_facet_rows * globals.buffer;
          break;

        case "Segmented":
          // justifiable
          assignTracks(data, [], layout);
          logEvent("# tracks: " + globals.num_tracks, "sizing");

          globals.centre_radius = 50;
          var estimated_segment_width = (2 * globals.centre_radius + (globals.num_tracks + 2) * 2 * globals.track_height);

          globals.num_segment_cols = d3.max([1, d3.min([globals.num_segment_cols, Math.floor(effective_size / estimated_segment_width)])]);
          globals.num_segment_rows = Math.ceil(globals.num_segments / globals.num_segment_cols);

          globals.centre_radius = d3.max([50, (effective_size / globals.num_segment_cols - ((globals.num_tracks + 2) * 2 * globals.track_height)) / 2]);
          globals.width = (2 * globals.centre_radius + (globals.num_tracks + 2) * 2 * globals.track_height) * globals.num_segment_cols + globals.margin.left + globals.margin.right;
          if (globals.centre_radius > 200) {
            globals.centre_radius = 200;
          }
          globals.height = (2 * globals.centre_radius + (globals.num_tracks + 2) * 2 * globals.track_height) * globals.num_segment_rows + globals.margin.top + globals.margin.bottom + globals.num_segment_rows * globals.buffer;
          break;
        default:
          break;
        }
        break;

      case "Relative":
        if (layout === "Faceted") {
          // justifiable
          processFacets(data);
          logEvent("# within-facet tracks: " + (globals.max_num_tracks + 1), "sizing");

          globals.centre_radius = 50;
          estimated_facet_width = (2 * globals.centre_radius + (globals.max_num_tracks + 2) * 2 * globals.track_height);

          globals.num_facet_cols = d3.min([globals.num_facet_cols, Math.floor(effective_size / estimated_facet_width)]);
          globals.num_facet_rows = Math.ceil(globals.num_facets / globals.num_facet_cols);

          globals.centre_radius = d3.max([50, (effective_size / globals.num_facet_cols - ((globals.max_num_tracks + 2) * 2 * globals.track_height)) / 2]);
          globals.width = (2 * globals.centre_radius + (globals.max_num_tracks + 2) * 2 * globals.track_height) * globals.num_facet_cols + globals.margin.left + globals.margin.right;
          if (globals.centre_radius > 200) {
            globals.centre_radius = 200;
          }
          globals.height = (2 * globals.centre_radius + (globals.max_num_tracks + 2) * 2 * globals.track_height) * globals.num_facet_rows + globals.margin.top + globals.margin.bottom + globals.num_facet_rows * globals.buffer;
        } else {
          // not justifiable
          logEvent("scale-layout-representation combination not possible/justifiable", "error");

          globals.width = 0;
          globals.height = 0;
        }
        break;

      case "Sequential":
        if (layout === "Unified") {
          // justifiable
          assignSequenceTracks(data, []);
          globals.max_seq_index = d3.max(data, function (d) { return d.seq_index; }) + 1;
          globals.centre_radius = (effective_size - (4 * globals.track_height)) / 2;
          globals.width = (2 * globals.centre_radius + 4 * globals.track_height) + globals.margin.left + globals.margin.right;
          if (globals.centre_radius > 200) {
            globals.centre_radius = 200;
          }
          globals.height = (2 * globals.centre_radius + 4 * globals.track_height) + globals.margin.top + globals.margin.bottom;
        } else if (layout === "Faceted") {
          // justifiable

          processFacets(data);
          globals.max_seq_index = d3.max(data, function (d) { return d.seq_index; }) + 1;

          globals.centre_radius = 50;
          estimated_facet_width = (2 * globals.centre_radius + (4 * globals.track_height));

          globals.num_facet_cols = d3.min([globals.num_facet_cols, Math.floor(effective_size / estimated_facet_width)]);
          globals.num_facet_rows = Math.ceil(globals.num_facets / globals.num_facet_cols);

          globals.centre_radius = d3.max([50, (effective_size / globals.num_facet_cols - (4 * globals.track_height)) / 2]);
          globals.width = (2 * globals.centre_radius + 4 * globals.track_height) * globals.num_facet_cols + globals.margin.left + globals.margin.right;
          if (globals.centre_radius > 200) {
            globals.centre_radius = 200;
          }
          globals.height = (2 * globals.centre_radius + 4 * globals.track_height) * globals.num_facet_rows + globals.margin.top + globals.margin.bottom + globals.num_facet_rows * globals.buffer;
        } else {
          // not justifiable
          logEvent("scale-layout-representation combination not possible/justifiable", "error");

          globals.width = 0;
          globals.height = 0;
        }
        break;
      default:
        break;
      }
      break;

    case "Grid":

      if (scale === "Chronological" && layout === "Segmented") {
        // justifiable

        assignTracks(data, [], layout);

        var cell_size = 50,
          century_height = cell_size * globals.unit_width,
          century_width = cell_size * 10;

        // determine the range, round to whole centuries
        var range_floor = Math.floor(data.min_start_date.getUTCFullYear() / 100) * 100,
          range_ceil = Math.ceil((data.max_end_date.getUTCFullYear() + 1) / 100) * 100;

        // determine the time domain of the data along a linear quantitative scale
        var year_range = d3.range(range_floor, range_ceil);

        // determine maximum number of centuries given year_range
        var num_centuries = (Math.ceil(year_range.length / 100));

        globals.width = century_width + globals.margin.left + globals.margin.right;
        globals.height = num_centuries * century_height + num_centuries * cell_size + globals.margin.top + globals.margin.bottom - cell_size;
      } else {
        // not justifiable
        logEvent("scale-layout-representation combination not possible/justifiable", "error");

        globals.width = 0;
        globals.height = 0;
      }
      break;

    case "Calendar":

      if (scale === "Chronological" && layout === "Segmented") {
        // justifiable

        assignTracks(data, [], layout);

        cell_size = 20;
        var year_height = cell_size * 8, // 7 days of week + buffer
          year_width = cell_size * 53; // 53 weeks of the year + buffer

        // determine the range, round to whole centuries
        range_floor = data.min_start_date.getUTCFullYear();
        range_ceil = data.max_end_date.getUTCFullYear();

        // determine the time domain of the data along a linear quantitative scale
        year_range = d3.range(range_floor, range_ceil + 1);

        globals.width = year_width + globals.margin.left + globals.margin.right;
        globals.height = year_range.length * year_height + globals.margin.top + globals.margin.bottom - cell_size;
      } else {
        // not justifiable
        logEvent("scale-layout-representation combination not possible/justifiable", "error");

        globals.width = 0;
        globals.height = 0;
      }
      break;

    case "Spiral":

      if (scale === "Sequential") {
        if (layout === "Unified") {
          // justifiable

          assignSequenceTracks(data, []);
          globals.max_seq_index = d3.max(data, function (d) { return d.seq_index; }) + 1;
          var angle = 0,
            i = 0;

          data.forEach(function (item) {
            var radius = Math.sqrt(i + 1);
            angle += Math.asin(1 / radius);
            i++;
            item.spiral_index = i;
            item.spiral_x = Math.cos(angle) * (radius * globals.spiral_padding);
            item.spiral_y = Math.sin(angle) * (radius * globals.spiral_padding);
          });

          var max_x = d3.max(data, function (d) { return d.spiral_x; });
          var max_y = d3.max(data, function (d) { return d.spiral_y; });
          var min_x = d3.min(data, function (d) { return d.spiral_x; });
          var min_y = d3.min(data, function (d) { return d.spiral_y; });

          globals.spiral_dim = d3.max([(max_x + 2 * globals.spiral_padding) - (min_x - 2 * globals.spiral_padding), (max_y + 2 * globals.spiral_padding) - (min_y - 2 * globals.spiral_padding)]);

          globals.width = d3.max([
            globals.spiral_dim + globals.spiral_padding + globals.margin.right + globals.margin.left,
            instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth()
          ]);

          // USES EFFECTIVE_HEIGHT
          globals.height = d3.max([
            globals.spiral_dim + globals.spiral_padding + globals.margin.top + globals.margin.bottom,
            instance._render_height - globals.margin.top - globals.margin.bottom - getScrollbarWidth()
          ]);
        } else if (layout === "Faceted") {
          // justifiable
          processFacets(data);
          globals.max_seq_index = d3.max(data, function (d) { return d.seq_index; }) + 1;

          globals.timeline_facets.forEach(function (timeline) {
            angle = 0;
            i = 0;

            timeline.values.forEach(function (item) {
              var radius = Math.sqrt(i + 1);
              angle += Math.asin(1 / radius);
              i++;
              item.spiral_index = i;
              item.spiral_x = Math.cos(angle) * (radius * globals.spiral_padding);
              item.spiral_y = Math.sin(angle) * (radius * globals.spiral_padding);
            });
          });

          max_x = d3.max(data, function (d) { return d.spiral_x; });
          max_y = d3.max(data, function (d) { return d.spiral_y; });
          min_x = d3.min(data, function (d) { return d.spiral_x; });
          min_y = d3.min(data, function (d) { return d.spiral_y; });

          globals.spiral_dim = d3.max([(max_x + 2 * globals.spiral_padding) - (min_x - 2 * globals.spiral_padding), (max_y + 2 * globals.spiral_padding) - (min_y - 2 * globals.spiral_padding)]);

          effective_size = instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth();

          globals.num_facet_cols = d3.min([globals.num_facet_cols, Math.floor(effective_size / globals.spiral_dim)]);
          globals.num_facet_rows = Math.ceil(globals.num_facets / globals.num_facet_cols);

          globals.width = d3.max([
            globals.num_facet_cols * globals.spiral_dim + globals.margin.right + globals.margin.left,
            instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth()
          ]);
          globals.height = globals.num_facet_rows * globals.spiral_dim + globals.margin.top + globals.margin.bottom;
        } else {
          // not justifiable
          globals.width = 0;
          globals.height = 0;
        }
      } else {
        // not justifiable
        logEvent("scale-layout-representation combination not possible/justifiable", "error");

        globals.width = 0;
        globals.height = 0;
      }
      break;

    case "Curve":
      if (scale === "Sequential" && layout === "Unified") {
        // justifiable
        assignSequenceTracks(data, []);
        globals.max_seq_index = d3.max(data, function (d) { return d.seq_index; }) + 1;
        globals.width = instance._render_width - globals.margin.right - globals.margin.left - getScrollbarWidth();
        globals.height = instance._render_height - globals.margin.top - globals.margin.bottom - getScrollbarWidth();
      } else {
        // not justifiable
        logEvent("scale-layout-representation combination not possible/justifiable", "error");

        globals.width = 0;
        globals.height = 0;
      }
      break;
    default:
      break;
    }
    logEvent("dimensions: " + globals.width + " (W) x " + globals.height + " (H)", "sizing");
  }