import { r as registerInstance, h, g as getElement } from './index-148a7577.js';
import { _ as _t } from './text-26e02c8d.js';
import { s as select, e as dispatch, r as range, a as axisLeft, f as formatLocale, p as polyInOut, b as axisBottom, l as linear, m as max, c as min, o as ordinal, g as interpolate, d as linear$1 } from './linear-78b9219d.js';
import { r as randomIdGenerator } from './randomIdGenerator.util-56406f2e.js';

function sourceEvent(event) {
  let sourceEvent;
  while (sourceEvent = event.sourceEvent) event = sourceEvent;
  return event;
}

function pointer(event, node) {
  event = sourceEvent(event);
  if (node === undefined) node = event.currentTarget;
  if (node) {
    var svg = node.ownerSVGElement || node;
    if (svg.createSVGPoint) {
      var point = svg.createSVGPoint();
      point.x = event.clientX, point.y = event.clientY;
      point = point.matrixTransform(node.getScreenCTM().inverse());
      return [point.x, point.y];
    }
    if (node.getBoundingClientRect) {
      var rect = node.getBoundingClientRect();
      return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
    }
  }
  return [event.pageX, event.pageY];
}

// These are typically used in conjunction with noevent to ensure that we can
// preventDefault on the event.
const nonpassive = {passive: false};
const nonpassivecapture = {capture: true, passive: false};

function nopropagation(event) {
  event.stopImmediatePropagation();
}

function noevent(event) {
  event.preventDefault();
  event.stopImmediatePropagation();
}

function dragDisable(view) {
  var root = view.document.documentElement,
      selection = select(view).on("dragstart.drag", noevent, nonpassivecapture);
  if ("onselectstart" in root) {
    selection.on("selectstart.drag", noevent, nonpassivecapture);
  } else {
    root.__noselect = root.style.MozUserSelect;
    root.style.MozUserSelect = "none";
  }
}

function yesdrag(view, noclick) {
  var root = view.document.documentElement,
      selection = select(view).on("dragstart.drag", null);
  if (noclick) {
    selection.on("click.drag", noevent, nonpassivecapture);
    setTimeout(function() { selection.on("click.drag", null); }, 0);
  }
  if ("onselectstart" in root) {
    selection.on("selectstart.drag", null);
  } else {
    root.style.MozUserSelect = root.__noselect;
    delete root.__noselect;
  }
}

const constant$1 = x => () => x;

function DragEvent(type, {
  sourceEvent,
  subject,
  target,
  identifier,
  active,
  x, y, dx, dy,
  dispatch
}) {
  Object.defineProperties(this, {
    type: {value: type, enumerable: true, configurable: true},
    sourceEvent: {value: sourceEvent, enumerable: true, configurable: true},
    subject: {value: subject, enumerable: true, configurable: true},
    target: {value: target, enumerable: true, configurable: true},
    identifier: {value: identifier, enumerable: true, configurable: true},
    active: {value: active, enumerable: true, configurable: true},
    x: {value: x, enumerable: true, configurable: true},
    y: {value: y, enumerable: true, configurable: true},
    dx: {value: dx, enumerable: true, configurable: true},
    dy: {value: dy, enumerable: true, configurable: true},
    _: {value: dispatch}
  });
}

DragEvent.prototype.on = function() {
  var value = this._.on.apply(this._, arguments);
  return value === this._ ? this : value;
};

// Ignore right-click, since that should open the context menu.
function defaultFilter(event) {
  return !event.ctrlKey && !event.button;
}

function defaultContainer() {
  return this.parentNode;
}

function defaultSubject(event, d) {
  return d == null ? {x: event.x, y: event.y} : d;
}

function defaultTouchable() {
  return navigator.maxTouchPoints || ("ontouchstart" in this);
}

function drag() {
  var filter = defaultFilter,
      container = defaultContainer,
      subject = defaultSubject,
      touchable = defaultTouchable,
      gestures = {},
      listeners = dispatch("start", "drag", "end"),
      active = 0,
      mousedownx,
      mousedowny,
      mousemoving,
      touchending,
      clickDistance2 = 0;

  function drag(selection) {
    selection
        .on("mousedown.drag", mousedowned)
      .filter(touchable)
        .on("touchstart.drag", touchstarted)
        .on("touchmove.drag", touchmoved, nonpassive)
        .on("touchend.drag touchcancel.drag", touchended)
        .style("touch-action", "none")
        .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
  }

  function mousedowned(event, d) {
    if (touchending || !filter.call(this, event, d)) return;
    var gesture = beforestart(this, container.call(this, event, d), event, d, "mouse");
    if (!gesture) return;
    select(event.view)
      .on("mousemove.drag", mousemoved, nonpassivecapture)
      .on("mouseup.drag", mouseupped, nonpassivecapture);
    dragDisable(event.view);
    nopropagation(event);
    mousemoving = false;
    mousedownx = event.clientX;
    mousedowny = event.clientY;
    gesture("start", event);
  }

  function mousemoved(event) {
    noevent(event);
    if (!mousemoving) {
      var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny;
      mousemoving = dx * dx + dy * dy > clickDistance2;
    }
    gestures.mouse("drag", event);
  }

  function mouseupped(event) {
    select(event.view).on("mousemove.drag mouseup.drag", null);
    yesdrag(event.view, mousemoving);
    noevent(event);
    gestures.mouse("end", event);
  }

  function touchstarted(event, d) {
    if (!filter.call(this, event, d)) return;
    var touches = event.changedTouches,
        c = container.call(this, event, d),
        n = touches.length, i, gesture;

    for (i = 0; i < n; ++i) {
      if (gesture = beforestart(this, c, event, d, touches[i].identifier, touches[i])) {
        nopropagation(event);
        gesture("start", event, touches[i]);
      }
    }
  }

  function touchmoved(event) {
    var touches = event.changedTouches,
        n = touches.length, i, gesture;

    for (i = 0; i < n; ++i) {
      if (gesture = gestures[touches[i].identifier]) {
        noevent(event);
        gesture("drag", event, touches[i]);
      }
    }
  }

  function touchended(event) {
    var touches = event.changedTouches,
        n = touches.length, i, gesture;

    if (touchending) clearTimeout(touchending);
    touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
    for (i = 0; i < n; ++i) {
      if (gesture = gestures[touches[i].identifier]) {
        nopropagation(event);
        gesture("end", event, touches[i]);
      }
    }
  }

  function beforestart(that, container, event, d, identifier, touch) {
    var dispatch = listeners.copy(),
        p = pointer(touch || event, container), dx, dy,
        s;

    if ((s = subject.call(that, new DragEvent("beforestart", {
        sourceEvent: event,
        target: drag,
        identifier,
        active,
        x: p[0],
        y: p[1],
        dx: 0,
        dy: 0,
        dispatch
      }), d)) == null) return;

    dx = s.x - p[0] || 0;
    dy = s.y - p[1] || 0;

    return function gesture(type, event, touch) {
      var p0 = p, n;
      switch (type) {
        case "start": gestures[identifier] = gesture, n = active++; break;
        case "end": delete gestures[identifier], --active; // falls through
        case "drag": p = pointer(touch || event, container), n = active; break;
      }
      dispatch.call(
        type,
        that,
        new DragEvent(type, {
          sourceEvent: event,
          subject: s,
          target: drag,
          identifier,
          active: n,
          x: p[0] + dx,
          y: p[1] + dy,
          dx: p[0] - p0[0],
          dy: p[1] - p0[1],
          dispatch
        }),
        d
      );
    };
  }

  drag.filter = function(_) {
    return arguments.length ? (filter = typeof _ === "function" ? _ : constant$1(!!_), drag) : filter;
  };

  drag.container = function(_) {
    return arguments.length ? (container = typeof _ === "function" ? _ : constant$1(_), drag) : container;
  };

  drag.subject = function(_) {
    return arguments.length ? (subject = typeof _ === "function" ? _ : constant$1(_), drag) : subject;
  };

  drag.touchable = function(_) {
    return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$1(!!_), drag) : touchable;
  };

  drag.on = function() {
    var value = listeners.on.apply(listeners, arguments);
    return value === listeners ? drag : value;
  };

  drag.clickDistance = function(_) {
    return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);
  };

  return drag;
}

function quadInOut(t) {
  return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
}

const pi$1 = Math.PI,
    tau$1 = 2 * pi$1,
    epsilon = 1e-6,
    tauEpsilon = tau$1 - epsilon;

function append(strings) {
  this._ += strings[0];
  for (let i = 1, n = strings.length; i < n; ++i) {
    this._ += arguments[i] + strings[i];
  }
}

function appendRound(digits) {
  let d = Math.floor(digits);
  if (!(d >= 0)) throw new Error(`invalid digits: ${digits}`);
  if (d > 15) return append;
  const k = 10 ** d;
  return function(strings) {
    this._ += strings[0];
    for (let i = 1, n = strings.length; i < n; ++i) {
      this._ += Math.round(arguments[i] * k) / k + strings[i];
    }
  };
}

class Path {
  constructor(digits) {
    this._x0 = this._y0 = // start of current subpath
    this._x1 = this._y1 = null; // end of current subpath
    this._ = "";
    this._append = digits == null ? append : appendRound(digits);
  }
  moveTo(x, y) {
    this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}`;
  }
  closePath() {
    if (this._x1 !== null) {
      this._x1 = this._x0, this._y1 = this._y0;
      this._append`Z`;
    }
  }
  lineTo(x, y) {
    this._append`L${this._x1 = +x},${this._y1 = +y}`;
  }
  quadraticCurveTo(x1, y1, x, y) {
    this._append`Q${+x1},${+y1},${this._x1 = +x},${this._y1 = +y}`;
  }
  bezierCurveTo(x1, y1, x2, y2, x, y) {
    this._append`C${+x1},${+y1},${+x2},${+y2},${this._x1 = +x},${this._y1 = +y}`;
  }
  arcTo(x1, y1, x2, y2, r) {
    x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;

    // Is the radius negative? Error.
    if (r < 0) throw new Error(`negative radius: ${r}`);

    let x0 = this._x1,
        y0 = this._y1,
        x21 = x2 - x1,
        y21 = y2 - y1,
        x01 = x0 - x1,
        y01 = y0 - y1,
        l01_2 = x01 * x01 + y01 * y01;

    // Is this path empty? Move to (x1,y1).
    if (this._x1 === null) {
      this._append`M${this._x1 = x1},${this._y1 = y1}`;
    }

    // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
    else if (!(l01_2 > epsilon));

    // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
    // Equivalently, is (x1,y1) coincident with (x2,y2)?
    // Or, is the radius zero? Line to (x1,y1).
    else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {
      this._append`L${this._x1 = x1},${this._y1 = y1}`;
    }

    // Otherwise, draw an arc!
    else {
      let x20 = x2 - x0,
          y20 = y2 - y0,
          l21_2 = x21 * x21 + y21 * y21,
          l20_2 = x20 * x20 + y20 * y20,
          l21 = Math.sqrt(l21_2),
          l01 = Math.sqrt(l01_2),
          l = r * Math.tan((pi$1 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
          t01 = l / l01,
          t21 = l / l21;

      // If the start tangent is not coincident with (x0,y0), line to.
      if (Math.abs(t01 - 1) > epsilon) {
        this._append`L${x1 + t01 * x01},${y1 + t01 * y01}`;
      }

      this._append`A${r},${r},0,0,${+(y01 * x20 > x01 * y20)},${this._x1 = x1 + t21 * x21},${this._y1 = y1 + t21 * y21}`;
    }
  }
  arc(x, y, r, a0, a1, ccw) {
    x = +x, y = +y, r = +r, ccw = !!ccw;

    // Is the radius negative? Error.
    if (r < 0) throw new Error(`negative radius: ${r}`);

    let dx = r * Math.cos(a0),
        dy = r * Math.sin(a0),
        x0 = x + dx,
        y0 = y + dy,
        cw = 1 ^ ccw,
        da = ccw ? a0 - a1 : a1 - a0;

    // Is this path empty? Move to (x0,y0).
    if (this._x1 === null) {
      this._append`M${x0},${y0}`;
    }

    // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
    else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {
      this._append`L${x0},${y0}`;
    }

    // Is this arc empty? We’re done.
    if (!r) return;

    // Does the angle go the wrong way? Flip the direction.
    if (da < 0) da = da % tau$1 + tau$1;

    // Is this a complete circle? Draw two arcs to complete the circle.
    if (da > tauEpsilon) {
      this._append`A${r},${r},0,1,${cw},${x - dx},${y - dy}A${r},${r},0,1,${cw},${this._x1 = x0},${this._y1 = y0}`;
    }

    // Is this arc non-empty? Draw an arc!
    else if (da > epsilon) {
      this._append`A${r},${r},0,${+(da >= pi$1)},${cw},${this._x1 = x + r * Math.cos(a1)},${this._y1 = y + r * Math.sin(a1)}`;
    }
  }
  rect(x, y, w, h) {
    this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}h${w = +w}v${+h}h${-w}Z`;
  }
  toString() {
    return this._;
  }
}

function constant(x) {
  return function constant() {
    return x;
  };
}

const sqrt = Math.sqrt;
const pi = Math.PI;
const tau = 2 * pi;

function withPath(shape) {
  let digits = 3;

  shape.digits = function(_) {
    if (!arguments.length) return digits;
    if (_ == null) {
      digits = null;
    } else {
      const d = Math.floor(_);
      if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);
      digits = d;
    }
    return shape;
  };

  return () => new Path(digits);
}

function array(x) {
  return typeof x === "object" && "length" in x
    ? x // Array, TypedArray, NodeList, array-like
    : Array.from(x); // Map, Set, iterable, string, or anything else
}

function Linear(context) {
  this._context = context;
}

Linear.prototype = {
  areaStart: function() {
    this._line = 0;
  },
  areaEnd: function() {
    this._line = NaN;
  },
  lineStart: function() {
    this._point = 0;
  },
  lineEnd: function() {
    if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
    this._line = 1 - this._line;
  },
  point: function(x, y) {
    x = +x, y = +y;
    switch (this._point) {
      case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
      case 1: this._point = 2; // falls through
      default: this._context.lineTo(x, y); break;
    }
  }
};

function curveLinear(context) {
  return new Linear(context);
}

function x(p) {
  return p[0];
}

function y(p) {
  return p[1];
}

function line(x$1, y$1) {
  var defined = constant(true),
      context = null,
      curve = curveLinear,
      output = null,
      path = withPath(line);

  x$1 = typeof x$1 === "function" ? x$1 : (x$1 === undefined) ? x : constant(x$1);
  y$1 = typeof y$1 === "function" ? y$1 : (y$1 === undefined) ? y : constant(y$1);

  function line(data) {
    var i,
        n = (data = array(data)).length,
        d,
        defined0 = false,
        buffer;

    if (context == null) output = curve(buffer = path());

    for (i = 0; i <= n; ++i) {
      if (!(i < n && defined(d = data[i], i, data)) === defined0) {
        if (defined0 = !defined0) output.lineStart();
        else output.lineEnd();
      }
      if (defined0) output.point(+x$1(d, i, data), +y$1(d, i, data));
    }

    if (buffer) return output = null, buffer + "" || null;
  }

  line.x = function(_) {
    return arguments.length ? (x$1 = typeof _ === "function" ? _ : constant(+_), line) : x$1;
  };

  line.y = function(_) {
    return arguments.length ? (y$1 = typeof _ === "function" ? _ : constant(+_), line) : y$1;
  };

  line.defined = function(_) {
    return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), line) : defined;
  };

  line.curve = function(_) {
    return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
  };

  line.context = function(_) {
    return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
  };

  return line;
}

const circle = {
  draw(context, size) {
    const r = sqrt(size / pi);
    context.moveTo(r, 0);
    context.arc(0, 0, r, 0, tau);
  }
};

const diamond2 = {
  draw(context, size) {
    const r = sqrt(size) * 0.62625;
    context.moveTo(0, -r);
    context.lineTo(r, 0);
    context.lineTo(0, r);
    context.lineTo(-r, 0);
    context.closePath();
  }
};

const square = {
  draw(context, size) {
    const w = sqrt(size);
    const x = -w / 2;
    context.rect(x, x, w, w);
  }
};

const sqrt3 = sqrt(3);

const triangle = {
  draw(context, size) {
    const y = -sqrt(size / (sqrt3 * 3));
    context.moveTo(0, y * 2);
    context.lineTo(-sqrt3 * y, -y);
    context.lineTo(sqrt3 * y, -y);
    context.closePath();
  }
};

const c = -0.5;
const s = sqrt(3) / 2;
const k = 1 / sqrt(12);
const a = (k / 2 + 1) * 3;

const wye = {
  draw(context, size) {
    const r = sqrt(size / a);
    const x0 = r / 2, y0 = r * k;
    const x1 = x0, y1 = r * k + r;
    const x2 = -x1, y2 = y1;
    context.moveTo(x0, y0);
    context.lineTo(x1, y1);
    context.lineTo(x2, y2);
    context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
    context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
    context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
    context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
    context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
    context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
    context.closePath();
  }
};

function Symbol(type, size) {
  let context = null,
      path = withPath(symbol);

  type = typeof type === "function" ? type : constant(type || circle);
  size = typeof size === "function" ? size : constant(size === undefined ? 64 : +size);

  function symbol() {
    let buffer;
    if (!context) context = buffer = path();
    type.apply(this, arguments).draw(context, +size.apply(this, arguments));
    if (buffer) return context = null, buffer + "" || null;
  }

  symbol.type = function(_) {
    return arguments.length ? (type = typeof _ === "function" ? _ : constant(_), symbol) : type;
  };

  symbol.size = function(_) {
    return arguments.length ? (size = typeof _ === "function" ? _ : constant(+_), symbol) : size;
  };

  symbol.context = function(_) {
    return arguments.length ? (context = _ == null ? null : _, symbol) : context;
  };

  return symbol;
}

function point(that, x, y) {
  that._context.bezierCurveTo(
    (2 * that._x0 + that._x1) / 3,
    (2 * that._y0 + that._y1) / 3,
    (that._x0 + 2 * that._x1) / 3,
    (that._y0 + 2 * that._y1) / 3,
    (that._x0 + 4 * that._x1 + x) / 6,
    (that._y0 + 4 * that._y1 + y) / 6
  );
}

function Basis(context) {
  this._context = context;
}

Basis.prototype = {
  areaStart: function() {
    this._line = 0;
  },
  areaEnd: function() {
    this._line = NaN;
  },
  lineStart: function() {
    this._x0 = this._x1 =
    this._y0 = this._y1 = NaN;
    this._point = 0;
  },
  lineEnd: function() {
    switch (this._point) {
      case 3: point(this, this._x1, this._y1); // falls through
      case 2: this._context.lineTo(this._x1, this._y1); break;
    }
    if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
    this._line = 1 - this._line;
  },
  point: function(x, y) {
    x = +x, y = +y;
    switch (this._point) {
      case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
      case 1: this._point = 2; break;
      case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // falls through
      default: point(this, x, y); break;
    }
    this._x0 = this._x1, this._x1 = x;
    this._y0 = this._y1, this._y1 = y;
  }
};

function basis(context) {
  return new Basis(context);
}

const chartLineCss = ".sc-digi-chart-line-h{display:block;height:100%;width:100%;position:relative}.sc-digi-chart-line-h .digi-chart-line.sc-digi-chart-line{color:var(--MY-PROP);height:100%;width:100%;min-height:fit-content}.chart.sc-digi-chart-line{box-sizing:content-box;width:auto}.topWrapper.sc-digi-chart-line,.chartTitle.sc-digi-chart-line .digi-typography.sc-digi-chart-line{display:flex;flex-direction:column;gap:0.75rem}.topWrapper.sc-digi-chart-line{margin-bottom:0.75rem}.chartTitle.sc-digi-chart-line{--MARGIN--HEADING-2:0;--MARGIN--HEADING-3:0;--MARGIN--HEADING-4:0;--MARGIN--HEADING-5:0;--MARGIN--HEADING-6:0}.buttonWrapper.sc-digi-chart-line{--digi--button--padding--medium:0 0 0.75rem 0}.close.sc-digi-chart-line{--digi--icon--color:rgb(245, 245, 245);cursor:pointer;margin-top:-5px}.legend.sc-digi-chart-line{display:flex;flex-direction:row;flex-wrap:no-wrap;gap:0.5rem;margin:0.5rem 0 0.25rem 0;height:2.675rem;overflow-x:auto;overflow-y:hidden;cursor:default;max-width:100%}.chip.sc-digi-chart-line{box-sizing:border-box}.legend.sc-digi-chart-line::-webkit-scrollbar,.table.sc-digi-chart-line::-webkit-scrollbar{height:10px;width:10px}.legend.sc-digi-chart-line::-webkit-scrollbar-track,.table.sc-digi-chart-line::-webkit-scrollbar-track{background:whitesmoke;border-radius:4px}.legend.sc-digi-chart-line::-webkit-scrollbar-thumb,.table.sc-digi-chart-line::-webkit-scrollbar-thumb{background-color:lightgray;border-radius:4px;border:0}.chartTooltip.sc-digi-chart-line{box-sizing:border-box;position:absolute;background-color:rgba(10, 10, 10, 0.9);color:white;padding:5px 10px;padding-right:5px;border-radius:4px;display:flex;flex-direction:column;align-items:flex-start;box-shadow:rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 2px 6px 2px;font-size:14px;display:none}.scChartStatus.sc-digi-chart-line{border:0;clip:rect(1px, 1px, 1px, 1px);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.table.sc-digi-chart-line{display:none;overflow-y:scroll;height:fit-content;border-radius:4px;padding:0.25rem;background:linear-gradient(white 30%, rgba(255, 255, 255, 0)) center top, linear-gradient(rgba(255, 255, 255, 0), white 70%) center bottom, radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)) center top, radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)) center bottom;background-repeat:no-repeat;background-size:100% 40px, 100% 40px, 100% 14px, 100% 14px;background-attachment:local, local, scroll, scroll}.tableIcon.sc-digi-chart-line{--digi--icon--color:var(--digi--global--color--neutral--grayscale--darker);width:26px;height:26px;pointer-events:none}.tableIcon.sc-digi-chart-line:hover{--digi--icon--color:var(\n    --digi--global--color--neutral--grayscale--darkest-3\n  )}.tooltipHead.sc-digi-chart-line{display:flex;width:100%;justify-content:space-between;margin-bottom:0.25rem;flex-direction:row}.tooltipBody.sc-digi-chart-line{display:flex;flex-direction:column;padding-right:5px;max-height:100px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgb(245, 245, 245) transparent}";
const DigiChartLineStyle0 = chartLineCss;

const ChartLine = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this._lineTypes = [null, '18, 7', '8,7', '2,6'];
        this._strokeWidth = 2.75;
        this._lineCap = 'round';
        this._strokeGlyphs = [circle, triangle, square, wye, diamond2];
        this._toggled = false;
        this._tickSize = 0;
        // Selection list from legend chips
        this._selectedLines = [];
        // Dragging
        this._dragStart = 0;
        this._dragDir = 0;
        this._loading = false;
        this.margin = {
            bottom: 0,
            top: 6,
            left: 5,
            right: 15
        };
        this.fontSize = '0.875rem';
        this.xPadding = 5;
        this.yPadding = 8;
        this.xTickSize = 5;
        // Formats
        this.formatStyle = ',d';
        this.axisNumberFormat = {
            decimal: ',',
            thousands: ' ',
            grouping: [3],
            currency: ['', 'kr']
        };
        // Observer for watching size changes when in line chart mode
        this.lineChartObserver = new ResizeObserver((entries) => {
            entries.forEach(() => {
                this.resizeSvg();
                this.resizeLines();
                this.repositionTooltip(); // Called on both div.resize, and window.resize
                select(this._legendDiv).style('width', this.dims.width + 'px');
            });
        });
        // Observer for watching size changes when in table mode
        this.tableObserver = new ResizeObserver((entries) => {
            entries.forEach(() => {
                select(this._legendDiv).style('width', this.dims.width + 'px');
                this.resizeTable();
            });
        });
        this.dragStart = (e) => {
            const container = select(this._legendDiv).node();
            this._dragStart = e.x - container.offsetLeft;
            this._scrollLeft = container.scrollLeft;
        };
        this.drag = (e) => {
            const container = select(this._legendDiv);
            this._dragDir = e.x;
            const delta = this._dragDir - container.node().offsetLeft;
            const walk = (delta - this._dragStart) * 1; //scroll-fast
            container.property('scrollLeft', this._scrollLeft - walk);
        };
        // Set yTicks
        this.setYTicks = (init = false) => {
            // Fixed number of y-axis lines
            const step = this._chartData.meta && this._chartData.meta.numberOfReferenceLines
                ? this._chartData.meta.numberOfReferenceLines
                : 5, min = this._yAxis.domain()[0], max = this._yAxis.domain()[1], stepValue = (max - min) / (step - 1), tickValues = range(min, max + stepValue, stepValue);
            if (!init) {
                this._yAxisHandle
                    .style('font-size', this.fontSize)
                    .transition()
                    .duration(400)
                    .call(axisLeft(this._yAxis)
                    .ticks(step)
                    .tickPadding(this.yPadding)
                    .tickValues(tickValues)
                    .tickSize(-(this.dims.width - this.margin.left))
                    .tickFormat((d) => formatLocale(this.axisNumberFormat).format(this.formatStyle)(d)))
                    .on('end', () => this.leftSetAxis());
            }
            else {
                this._yAxisHandle.style('font-size', this.fontSize).call(axisLeft(this._yAxis)
                    .ticks(step)
                    .tickPadding(this.yPadding)
                    .tickValues(tickValues)
                    .tickSize(-(this.dims.width - this.margin.left))
                    .tickFormat((d) => formatLocale(this.axisNumberFormat).format(this.formatStyle)(d)));
            }
            this._yAxisHandle
                .selectAll('line')
                .attr('stroke', '#BDBDBD');
            this._yAxisHandle.select('.domain').attr('display', 'none');
            if (init)
                this.leftSetAxis(init);
        };
        // Adding event listeners to the chart
        this.addListenersToChart = () => {
            this._Tipbox
                .style('cursor', 'pointer')
                .on('mousemove', this.drawTooltipLine)
                .on('touchmove', 'ontouchstart' in window || window.navigator.maxTouchPoints
                ? this.drawTooltip
                : null)
                .on('mouseup', this.drawTooltip)
                .on('mouseleave', () => {
                this._secondaryLine.attr('display', 'none');
                if (!this._toggled) {
                    this._TooltipLine.attr('display', 'none');
                    this._Circles.selectAll('circle').attr('display', 'none');
                }
            });
        };
        // Initialize legend
        this.initLegend = () => {
            const container = select(this._legendDiv);
            select(this._legendDiv).style('width', this.dims.width + 'px');
            container.selectAll('.chip').remove();
            container.call(drag().on('start', this.dragStart).on('drag', this.drag));
            container
                .selectAll('legendChips')
                .data(this._chartData.data.series)
                .join('button')
                .attr('class', 'chip')
                .attr('type', 'button')
                .attr('aria-pressed', false)
                .style('padding', '0.15rem 0.75rem')
                .style('border', '2px solid white')
                .style('border-radius', '6px')
                .style('display', 'flex')
                .style('flex-direction', 'row')
                .style('gap', '0.5rem')
                .style('align-items', 'center')
                .style('flex-wrap', 'nowrap')
                .style('min-width', 'fit-content')
                .style('height', 'calc(2rem - 2px)')
                .style('font-size', this.fontSize)
                .style('white-space', 'nowrap')
                .style('box-sizing', 'border-box')
                .style('background-color', 'white')
                .style('cursor', 'pointer')
                .html((d) => {
                return '<span style="pointer-events:none;">' + d.title + '</span>';
            })
                .on('click', this.togglePath)
                .on('mouseover', this.highlightPath)
                .on('focus', this.highlightPath)
                .on('mouseleave', this.colorLines)
                .on('blur', this.colorLines)
                .datum((d) => d)
                .insert('svg', 'span')
                .attr('class', 'legendSvg')
                .attr('pointer-events', 'none')
                .attr('width', 32)
                .attr('height', 28)
                .append('line')
                .attr('stroke', (d) => this.colorFunction(d))
                .attr('stroke-linecap', this._lineCap)
                .attr('stroke-width', 4)
                .attr('stroke-dasharray', (d, i) => this.dashFunction(d, i))
                .attr('x1', 3)
                .attr('x2', 29)
                .attr('y1', '50%')
                .attr('y2', '50%');
            // Only if data contains many lines
            if (this._chartData.data.series.length <= this._lineTypes.length)
                return;
            container
                .selectAll('.legendSvg')
                .filter((...[, i]) => {
                return i > (this._lineTypes.length - 1);
            })
                .append('path')
                .attr('d', (...[, i]) => this.symbolType(i, 70))
                .attr('fill', (d) => this.colorFunction(d))
                .attr('transform', 'translate(16,14)');
        };
        // Highlights a line
        this.highlightPath = (event, element) => {
            if (event.target.className != 'chip')
                return;
            const target = select(event.target);
            target.style('border', (d) => '2px solid ' + this.colorFunction(d));
            this._lineChartContainer
                .selectAll('.linePath')
                .transition('highlight')
                .duration(150)
                .attr('stroke', (d, i, nodelist) => {
                if (d.title === element.title) {
                    select(nodelist[i]).raise();
                    return this.colorFunction(d);
                }
                else
                    return '#E3E3E3';
            })
                .attr('stroke-width', (d) => {
                if (d.title === element.title)
                    return this._strokeWidth * 1.25;
                else
                    return this._strokeWidth;
            });
            this._lineChartContainer
                .selectAll('.symbolGroup')
                .attr('fill', (d, i, nodelist) => {
                if (d.title === element.title) {
                    select(nodelist[i]).raise();
                }
            });
            this._lineChartContainer
                .selectAll('.symbolGroup')
                .selectAll('.symbol')
                .transition('highlight')
                .duration(150)
                .attr('fill', (d) => {
                if (!d)
                    return;
                if (d.title === element.title) {
                    return this.colorFunction(d);
                }
                else
                    return '#E3E3E3';
            });
        };
        // Selecting a path to view sollely from legend
        this.togglePath = (event) => {
            if (event.target.className != 'chip')
                return;
            const target = select(event.target);
            // Using color of text to identify what state the legend chip is in, so resetting this the last thing we do
            const swap = 'white' === target.style('color');
            target
                .style('border', (d) => '2px solid ' + this.colorFunction(d))
                .style('background-color', (d) => swap ? 'white' : this.colorFunction(d))
                .style('color', () => (swap ? 'black' : 'white'))
                .attr('aria-pressed', target.attr('aria-pressed') == 'false' ? true : false)
                .select('line')
                .attr('stroke', (d) => (swap ? this.colorFunction(d) : 'white'));
            target
                .select('path')
                .attr('fill', (d) => (swap ? this.colorFunction(d) : 'white'));
            if (swap) {
                this._selectedLines = this._selectedLines.filter((elem) => {
                    return elem.title === target.datum()['title'] ? false : true;
                });
            }
            else {
                this._selectedLines.push(this._coreSeries.filter((elem) => elem.title === target.datum()['title'])[0]);
            }
            if (this._selectedLines.length < 1)
                this._chartData.data.series = JSON.parse(JSON.stringify(this._coreSeries));
            else {
                this._chartData.data.series.map((serie) => {
                    const index = this._selectedLines.findIndex((selected) => {
                        return serie.title === selected.title;
                    });
                    if (index != -1) {
                        serie.yValues = this._selectedLines[index].yValues;
                    }
                    else {
                        serie.yValues = [];
                    }
                });
            }
            this.updateSvg();
        };
        // Coloring all lines
        this.colorLines = (event) => {
            const target = select(event.target);
            target.style('border', '2px solid white');
            this._lineChartContainer
                .selectAll('.linePath')
                .transition('highlight')
                .duration(150)
                .attr('stroke', (d) => this.colorFunction(d))
                .attr('stroke-width', this._strokeWidth);
            this._lineChartContainer
                .selectAll('.symbolGroup')
                .selectAll('.symbol')
                .transition('highlight')
                .duration(150)
                .attr('fill', (d) => (d ? this.colorFunction(d) : null));
        };
        // Returns a line type given a integer value
        this.dashFunction = (...[, index]) => {
            return this._lineTypes[index % this._lineTypes.length];
        };
        // Initialize the drawing of the lines
        this.initLines = () => {
            this.defineLineAndScale();
            // TODO: do this data appending somewhere else
            this._lineChartContainer
                .selectAll('linePath')
                .data(this.reshapeData(this._chartData.data.series))
                .join('path')
                .attr('class', 'linePath')
                .attr('stroke', (d) => this.colorFunction(d))
                .attr('stroke-linecap', this._lineCap)
                .attr('stroke-width', (d) => (d.length > 1 ? this._strokeWidth : 4))
                .attr('stroke-dasharray', (d, i) => d.length > 1 ? this.dashFunction(d, i) : null)
                .attr('fill', 'none')
                .attr('d', (d) => this._LineFunc(d.line));
            this.addSymbols();
        };
        this.defineLineAndScale = () => {
            this._LineFunc = line()
                .defined((d) => d[1] != null && d[1] != undefined && !isNaN(d[1]))
                .x((d) => this._lineScale(d[0]))
                .y((d) => this._yAxis(d[1]));
        };
        // Modifies data object adds a line member to object, line is an array of pairs of number: [number, number][]
        // Line is used to feed into _LineFunc
        this.reshapeData = (series) => {
            return series.map((obj) => {
                obj.line = this._chartData.data.xValues.map((elem, ind) => {
                    return [elem, obj.yValues[ind]];
                });
                obj.length = obj.yValues.filter((e) => e != null && e != undefined).length;
                return obj;
            });
        };
        // Adding symbols to lines where needed
        this.addSymbols = (transition = false) => {
            // Remove all old symbols
            this._lineChartContainer
                .selectAll('.symbolGroup')
                .data(this.reshapeData(this._chartData.data.series.filter(
            // Symbols are only needed, when we are out of line types
            (...[, index]) => index > (this._lineTypes.length - 1))))
                .join((enter) => {
                if (!transition) {
                    enter
                        .append('g')
                        .attr('class', 'symbolGroup')
                        .selectAll('symbols')
                        .data((d, i) => {
                        return d.line.map((num) => {
                            if (num[1] != null)
                                return {
                                    val: num[1],
                                    x: num[0],
                                    title: d.title,
                                    colorToken: d.colorToken,
                                    index: i
                                };
                            else
                                return null;
                        });
                    })
                        .join('path')
                        .attr('class', 'symbol')
                        .attr('d', (d) => (d ? this.symbolType(d.index) : null))
                        .attr('fill', (d) => (d ? this.colorFunction(d) : null))
                        .attr('transform', (d) => d
                        ? `translate(${this._lineScale(d.x)},${this._yAxis(d.val)})`
                        : null);
                }
                else {
                    enter
                        .append('g')
                        .attr('class', 'symbolGroup')
                        .selectAll('symbol')
                        .data((d, i) => {
                        return d.line.map((num) => {
                            if (num[1] != null)
                                return {
                                    val: num[1],
                                    x: num[0],
                                    title: d.title,
                                    colorToken: d.colorToken,
                                    index: i
                                };
                            else
                                return null;
                        });
                    })
                        .join('path')
                        .attr('class', 'symbol')
                        .attr('d', (d) => (d ? this.symbolType(d.index) : null))
                        .attr('fill', (d) => (d ? this.colorFunction(d) : null))
                        .attr('transform', (d) => d
                        ? `translate(${this._lineScale(d.x)},${this._yAxis(d.val)})`
                        : null);
                }
            }, (update) => {
                if (!transition) {
                    update
                        .selectAll('.symbol')
                        .data((d, i) => {
                        return d.line.map((num) => {
                            console.log(d.title, i);
                            if (num[1] != null)
                                return {
                                    val: num[1],
                                    x: num[0],
                                    title: d.title,
                                    colorToken: d.colorToken,
                                    index: i
                                };
                            else
                                return null;
                        });
                    })
                        .join('path')
                        .attr('class', 'symbol')
                        .attr('d', (d) => (d ? this.symbolType(d.index) : null))
                        .attr('fill', (d) => (d ? this.colorFunction(d) : null))
                        .attr('transform', (d) => d
                        ? `translate(${this._lineScale(d.x)},${this._yAxis(d.val)})`
                        : null);
                }
                else {
                    update
                        .selectAll('path')
                        .data((d, i) => {
                        const toReturn = d.line.map((num) => {
                            if (num[1] != null)
                                return {
                                    val: num[1],
                                    x: num[0],
                                    title: d.title,
                                    colorToken: d.colorToken,
                                    index: i
                                };
                            else
                                return null;
                        });
                        return toReturn.filter((e) => e);
                    })
                        .join((enter) => {
                        enter
                            .append('path')
                            .attr('class', 'symbol')
                            .attr('d', (d) => d ? this.symbolType(d.index) : null)
                            .attr('fill', (d) => d ? this.colorFunction(d) : null)
                            .attr('transform', (d) => d
                            ? `translate(${this._lineScale(d.x)},${this._yAxis(d.val)})`
                            : null)
                            .attr('opacity', 0)
                            .transition()
                            .duration(400)
                            .ease(polyInOut)
                            .attr('opacity', 1);
                    }, (update) => {
                        update
                            .transition()
                            .duration(400)
                            .ease(polyInOut)
                            .attr('d', (d) => d ? this.symbolType(d.index) : null)
                            .attr('fill', (d) => d ? this.colorFunction(d) : null)
                            .attr('transform', (d) => d
                            ? `translate(${this._lineScale(d.x)},${this._yAxis(d.val)})`
                            : null);
                    }, (exit) => exit.remove());
                }
            }, (exit) => exit.remove());
        };
        // Returns a symbol type given a index
        this.symbolType = (index, size) => {
            return Symbol()
                .type(this._strokeGlyphs[Math.trunc(index / this._lineTypes.length)])
                .size(size ? size : 60)();
        };
        // Setting dimension variable
        this.setDims = (onlyHeight = false) => {
            // Get title dimensions
            const tempTitle = select(this._titleDiv).node().getBoundingClientRect(), tempLegend = select(this._legendDiv).node().getBoundingClientRect();
            const rem = parseFloat(getComputedStyle(document.documentElement).fontSize);
            if (!onlyHeight)
                this.dims = select(this._chartDiv).node().getBoundingClientRect();
            this.dims.height =
                this._maxHeight - tempLegend.height - tempTitle.height - 1.75 * rem;
        };
        // Resizing svg element and its children
        this.resizeSvg = () => {
            if (this._loading)
                return this.loadingResize();
            this.setDims();
            this._svg.attr('width', this.dims.width).attr('height', this.dims.height);
            /****  Update yAxis ****/
            this._yAxis.range([this.dims.height - this.margin.bottom, this.margin.top]);
            // Fixed number of y-axis lines
            this.setYTicks(true);
            /****  Update xAxis ****/
            this._xAxis.range([
                0,
                this.dims.width - this.margin.left - this.margin.right
            ]);
            const ticks = Math.min(Math.max(Math.floor((this.dims.width - this.margin.left - this.margin.right) /
                this._tickSize) - 2, 1), this._chartData.data.xValues.length);
            this._xAxisHandle
                .attr('transform', 'translate(0,' + (this.dims.height - this.margin.bottom) + ')')
                .call(axisBottom(this._xAxis)
                .ticks(ticks)
                .tickPadding(this.xPadding)
                .tickFormat((d) => {
                if (this._chartData.data.xValueNames)
                    return this._chartData.data.xValueNames[this._chartData.data.xValues.indexOf(d)];
                else
                    return d;
            }));
            this._Tipbox
                .attr('width', this.dims.width - this.margin.left / 2)
                .attr('height', this.dims.height - this.margin.top - this.margin.bottom)
                .attr('transform', `translate(${this.margin.left / 2},${this.margin.top})`);
        };
        // resizing chart while loading
        this.loadingResize = () => {
            this.setDims();
            this._svg.attr('width', this.dims.width);
            this.setYTicks();
            this._xAxis.range([
                0,
                this.dims.width - this.margin.left - this.margin.right
            ]);
            const ticks = Math.min(Math.floor((this.dims.width - this.margin.left - this.margin.right) /
                this._tickSize) - 2, this._xAxis.domain()[1]);
            this._xAxisHandle.call(axisBottom(this._xAxis)
                .ticks(ticks)
                .tickPadding(this.xPadding)
                .tickFormat((d) => {
                if (this._chartData.data && this._chartData.data.xValueNames)
                    return this._chartData.data.xValueNames[this._chartData.data.xValues.indexOf(d)];
                else
                    return d;
            }));
            this._lineScale.range([
                0,
                this.dims.width - this.margin.left - this.margin.right
            ]);
            const LineFunc = line()
                .defined((d) => d[1] != null)
                .x((d) => this._lineScale(d[0]))
                .y((d) => this._yAxis(d[1]))
                .curve(basis);
            this._lineChartContainer
                .selectAll('.linePath')
                .attr('d', (d) => LineFunc(d));
        };
        this.resizeLines = () => {
            if (this._loading)
                return;
            this._lineScale.range([
                0,
                this.dims.width - this.margin.left - this.margin.right
            ]);
            this.defineLineAndScale();
            this._lineChartContainer
                .selectAll('.linePath')
                .attr('stroke', (d) => this.colorFunction(d))
                .attr('d', (d) => this._LineFunc(d.line));
            this._lineChartContainer
                .selectAll('.symbolGroup')
                .selectAll('.symbol')
                .attr('transform', (d, i) => d
                ? `translate(${this._lineScale(this._chartData.data.xValues[i])},${this._yAxis(d.val)})`
                : null);
        };
        this.colorFunction = (properties) => {
            return properties.colorToken
                ? getComputedStyle(document.documentElement)
                    .getPropertyValue(properties.colorToken)
                    .trim()
                    .toLocaleLowerCase()
                : this._Color(properties.title);
        };
        this.drawTooltipLine = (event) => {
            if (this._toggled)
                return this.drawDottedLine(event);
            this.drawMainLineAndCircles(event);
        };
        this.closeTooltip = () => {
            this._toggled = false;
            this._tooltip.style('display', 'none');
            this._secondaryLine.attr('display', 'none');
            this._TooltipLine.attr('display', 'none');
            this._Circles.selectAll('circle').attr('display', 'none');
            this._Circles
                .selectAll('circle')
                .attr('fill', 'white')
                .attr('stroke', (d) => this.colorFunction(d));
            this._svg.select('.tooltipPointer').remove();
        };
        this.drawDottedLine = (event) => {
            this._hoverPoint = this.closest(Math.round(this._lineScale.invert(pointer(event, this._Tipbox.node())[0] - this.margin.left / 2)));
            if (this._hoverPoint === this._tooltipPoint)
                return this._secondaryLine.attr('display', 'none');
            this._secondaryLine
                .attr('display', null)
                .attr('stroke', 'gray')
                .attr('stroke-dasharray', 4)
                .attr('x1', this._xAxis(this._hoverPoint.toString()) + this.margin.left)
                .attr('x2', this._xAxis(this._hoverPoint.toString()) + this.margin.left)
                .attr('y1', this._yAxis(this._maxVal))
                .attr('y2', this.dims.height - this.margin.bottom)
                .style('pointer-events', 'none');
        };
        this.drawMainLineAndCircles = (event) => {
            this._hoverPoint = this.touchPosition(event);
            const stringPoint = this._hoverPoint.toString();
            this._TooltipLine
                .attr('display', null)
                .attr('stroke', 'gray')
                .attr('x1', this._xAxis(stringPoint) + this.margin.left)
                .attr('x2', this._xAxis(stringPoint) + this.margin.left)
                .attr('y1', this._yAxis(this._maxVal))
                .attr('y2', this.dims.height - this.margin.bottom)
                .style('pointer-events', 'none');
            this._Circles
                .selectAll('circle')
                .attr('display', null)
                .attr('pointer-events', 'none');
            this.positionCircles(stringPoint);
        };
        // Returns the position/index to draw tooltip/tooltip line
        this.touchPosition = (event) => {
            if (event.type === 'touchmove') {
                event.preventDefault();
                return this.closest(Math.round(this._lineScale.invert(pointer(event.touches[0], this._Tipbox.node())[0] -
                    this.margin.left / 2)));
            }
            else {
                return this.closest(Math.round(this._lineScale.invert(pointer(event, this._Tipbox.node())[0] - this.margin.left / 2)));
            }
        };
        // Function for drawing tooltip
        this.drawTooltip = (event) => {
            this.drawMainLineAndCircles(event);
            this._toggled = true;
            this._tooltipPoint = this.touchPosition(event);
            this._tooltipDataIndex = this._chartData.data.xValues.indexOf(this._tooltipPoint);
            // Heading
            this._tooltip.style('display', 'flex');
            const tooltipBody = this._tooltip.select('.tooltipBody');
            const tooltipHead = this._tooltip.select('.tooltipHead');
            tooltipHead
                .select(this._tooltipHeading)
                .style('margin', '0 0.75rem 0 0 ')
                .html(() => {
                if (this._chartData.data.xValueNames)
                    return this._chartData.data.xValueNames[this._chartData.data.xValues.indexOf(this._tooltipPoint)];
                return this._tooltipPoint;
            });
            // Body
            tooltipBody
                .selectAll('div')
                .data(this._chartData.data.series)
                .join('div')
                .style('display', 'flex')
                .style('flex-direction', 'row')
                .style('flex-wrap', 'nowrap')
                .style('white-space', 'nowrap')
                .style('justify-content', 'space-between')
                .html((d) => {
                return d.yValues[this._tooltipDataIndex] != null
                    ? '<span>' +
                        d.title +
                        '</span><span style="margin-left:0.75rem;">' +
                        formatLocale(this.axisNumberFormat).format(this.formatStyle)(d.yValues[this._tooltipDataIndex]) +
                        '</span>'
                    : null;
            });
            this.positionTooltipWithinBounds(this._xAxis(this._tooltipPoint.toString()) + this.margin.left);
            this._Circles
                .selectAll('circle')
                .attr('fill', (d) => this.colorFunction(d))
                .attr('stroke', 'white');
            this._svg.select('.tooltipPointer').remove();
            const sym = Symbol().type(triangle).size(60);
            this._svg
                .append('path')
                .attr('d', sym)
                .attr('class', 'tooltipPointer')
                .attr('fill', 'rgba(10, 10, 10, 0.90)')
                .style('filter', 'drop-shadow(gray 0px -1px 1px)')
                .attr('transform', `translate(${this._xAxis(this._tooltipPoint.toString()) + this.margin.left},${this._yAxis(this._maxVal) - 7}) rotate(180) scale(1.5,1.0)`);
        };
        this.initYAxis = (empty) => {
            // Y Axis
            this._yAxis = linear()
                .domain([0, empty ? 10 : this._maxVal])
                .nice(3)
                .range([this.dims.height - this.margin.bottom, this.margin.top]);
            // The magic number is just needed in initialization, because getting the exact size is impossible during the initialization
            this.margin.left =
                this.getTextSize(formatLocale(this.axisNumberFormat).format(this.formatStyle)(this._yAxis.domain()[1])) +
                    this.yPadding +
                    3;
            this._lineChartContainer = this._svg
                .append('g')
                .attr('transform', `translate(${this.margin.left},0)`);
            this._yAxisHandle = this._lineChartContainer
                .append('g')
                .attr('class', 'yAxis');
            this.setYTicks(true);
        };
        this.initXAxis = (empty) => {
            this._lineChartContainer.select('.xAxis').remove();
            // X axis
            if (!empty) {
                if (this._chartData.data.xValueNames)
                    this.margin.right =
                        this.getTextSize(this._chartData.data.xValueNames[this._chartData.data.xValueNames.length - 1]) /
                            2 +
                            1;
                else
                    this.margin.right =
                        this.getTextSize(max(this._chartData.data.xValues).toString()) /
                            2 +
                            1;
            }
            this._xAxis = linear()
                .domain([
                empty ? 1 : min(this._chartData.data.xValues),
                empty ? 10 : max(this._chartData.data.xValues)
            ]) // This is the min and the max of the data
                .range([0, this.dims.width - this.margin.left - this.margin.right]);
            this._lineScale = linear()
                .domain([
                empty ? 1 : min(this._chartData.data.xValues),
                empty ? 10 : max(this._chartData.data.xValues)
            ]) // This is the min and the max of the data
                .range([0, this.dims.width - this.margin.left - this.margin.right]);
            const ticks = Math.min(Math.max(Math.floor((this.dims.width - this.margin.left - this.margin.right) /
                this._tickSize) - 2, 2), empty ? 10 : this._chartData.data.xValues.length);
            this._xAxisHandle = this._lineChartContainer
                .append('g')
                .attr('transform', 'translate(0,' + (this.dims.height - this.margin.bottom) + ')')
                .attr('class', 'xAxis')
                .style('font-size', this.fontSize)
                .call(axisBottom(this._xAxis)
                .ticks(ticks)
                .tickSize(this.xTickSize)
                .tickPadding(this.xPadding)
                .tickFormat((d) => {
                if (!empty && this._chartData.data.xValueNames)
                    return this._chartData.data.xValueNames[this._chartData.data.xValues.indexOf(d)];
                else
                    return d;
            }));
            // Removing the domain
            this._xAxisHandle.select('.domain').attr('display', 'none');
            this._xAxisHandle
                .selectAll('line')
                .attr('stroke-linecap', this._lineCap)
                .attr('stroke', '#757575');
        };
        this.positionCircles = (point, transition) => {
            if (transition) {
                this._Circles
                    .selectAll('circle')
                    .transition('positioncircles')
                    .duration(transition)
                    .attr('cx', () => {
                    return this._xAxis(point) + this.margin.left;
                })
                    .attr('cy', (d, i, circleList) => {
                    const selData = d.yValues[this._chartData.data.xValues.indexOf(parseInt(point))];
                    if (this._yAxis(selData))
                        return this._yAxis(selData);
                    else {
                        select(circleList[i]).attr('display', 'none');
                        return null;
                    }
                });
            }
            else {
                this._Circles
                    .selectAll('circle')
                    .attr('cx', () => {
                    return this._xAxis(point) + this.margin.left;
                })
                    .attr('cy', (d, i, circleList) => {
                    const selData = d.yValues[this._chartData.data.xValues.indexOf(parseInt(point))];
                    if (this._yAxis(selData))
                        return this._yAxis(selData);
                    else {
                        select(circleList[i]).attr('display', 'none');
                        return null;
                    }
                });
            }
        };
        this.repositionTooltip = () => {
            if (!this._toggled)
                return;
            const stringPoint = this._chartData.data.xValues[this._tooltipDataIndex].toString();
            this._TooltipLine
                .attr('stroke', 'gray')
                .attr('x1', this._xAxis(stringPoint) + this.margin.left)
                .attr('x2', this._xAxis(stringPoint) + this.margin.left)
                .attr('y1', this._yAxis(this._maxVal))
                .attr('y2', this.dims.height - this.margin.bottom);
            this.positionTooltipWithinBounds(this._xAxis(stringPoint) + this.margin.left);
            this._svg
                .select('.tooltipPointer')
                .attr('transform', `translate(${this._xAxis(this._tooltipPoint.toString()) + this.margin.left},${this._yAxis(this._maxVal) - 7}) rotate(180) scale(1.5,1.0)`);
            this.positionCircles(stringPoint);
        };
        // Checks if tooltip bounding box is outside svg width, if so, moves tooltip within svg bounds
        this.positionTooltipWithinBounds = (pos, transitionTimer) => {
            this._tooltip.style('transform', () => {
                // We reset the position of the tooltip, and adjust for the maximum value, -1px for it to align perfectly
                return `translateY(${this._yAxis(this._maxVal) - this._tooltip.node().getBoundingClientRect().height - 9}px)`;
            });
            const rect = this._chartDiv.getBoundingClientRect();
            const comparativePosition = pos + rect.left;
            const tooltipWidth = this._tooltip.node().getBoundingClientRect().width / 2;
            if (rect.left < comparativePosition - tooltipWidth &&
                rect.right > comparativePosition + tooltipWidth) {
                this._tooltip.style('left', pos - tooltipWidth + 'px');
            }
            else if (rect.right < comparativePosition + tooltipWidth) {
                this._tooltip.style('left', pos -
                    this._tooltip.node().getBoundingClientRect().width +
                    Math.max(this.margin.right, 10) +
                    'px');
            }
            else if (rect.left > comparativePosition - tooltipWidth) {
                if (transitionTimer)
                    this._tooltip
                        .transition('moveTooltip')
                        .duration(transitionTimer)
                        .ease(polyInOut)
                        .style('left', pos - this.margin.left + 'px');
                else
                    this._tooltip.style('left', pos - this.margin.left + 'px');
            }
            else {
                this._tooltip.style('left', pos -
                    document.getElementById(this.afId).getBoundingClientRect().width / 2 +
                    'px');
            }
        };
        this.mapColorToLine = () => {
            // list of group names
            this._Color = ordinal()
                .domain(this._chartData.data.series.map(function (d) {
                return d.title;
            }))
                .range([
                '#00005a',
                '#D43372',
                '#058470',
                '#0058A3',
                '#556D22',
                '#1616B2',
                '#AA295B',
                '#035548'
            ]);
        };
        this.computeMaxVal = () => {
            // Compute max value from datasets
            this._maxVal = parseFloat(max(this._chartData.data.series, (d) => max(d['yValues'])));
        };
        // Updates number format if specified to be in percentage
        this.checkPercentage = () => {
            if (this._chartData.meta && this._chartData.meta.percentage)
                this.formatStyle = '.1%';
            else
                this.formatStyle = ',d';
        };
        this.closest = (target) => {
            return this._chartData.data.xValues.reduce(function (prev, curr) {
                return Math.abs(curr - target) < Math.abs(prev - target) ? curr : prev;
            });
        };
        // Removes resize observer for chart and inits table
        this.activateTable = (event) => {
            this.closeTooltip();
            this.lineChartObserver.disconnect();
            this.tableObserver.observe(this._chartDiv);
            this._status.innerHTML = '<p>Visas som tabell</p>';
            select(this._host).select('.tableButton').style('display', 'none');
            select(this._host).select('.chartButton').style('display', null);
            event.target.nextSibling.lastChild.focus();
            const duration = 150;
            this._svg
                .attr('opacity', 1)
                .transition('fadeout')
                .duration(duration)
                .attr('opacity', 0)
                .on('end', () => {
                this._svg.remove();
                this._legendDiv.style['display'] = 'none';
                this._tableDiv.style['display'] = 'block';
                this.setTableContent();
                this.setTableDimensions();
                select(this._tableDiv)
                    .style('opacity', 0)
                    .transition('fadein')
                    .duration(duration)
                    .style('opacity', 1);
            });
            select(this._legendDiv)
                .style('opacity', 1)
                .transition('fadeout')
                .duration(duration)
                .style('opacity', 0);
        };
        // Resize table
        this.resizeTable = () => {
            this.setDims();
            this.setTableDimensions();
        };
        // Removes observer and calls init functions for line chart
        this.reInitChart = (event) => {
            this.tableObserver.disconnect();
            this._status.innerHTML = '<p>Visas som diagram</p>';
            select(this._host).select('.tableButton').style('display', null);
            select(this._host).select('.chartButton').style('display', 'none');
            event.target.previousSibling.lastChild.focus();
            const table = select(this._tableDiv);
            table
                .style('opacity', 1)
                .transition()
                .duration(150)
                .style('opacity', 0)
                .on('end', () => {
                table.style('display', 'none');
                this.initSvg();
                this.initLines();
                this._svg
                    .attr('opacity', 0)
                    .transition()
                    .duration(150)
                    .attr('opacity', 1);
                select(this._legendDiv)
                    .style('display', null)
                    .style('opacity', 0)
                    .transition()
                    .duration(150)
                    .style('opacity', 1);
            });
        };
        this.afHeadingLevel = undefined;
        this.afId = randomIdGenerator('tooltip');
        this.afChartData = undefined;
    }
    afChartDataUpdate() {
        const data = this.afChartData;
        if (typeof data === 'object') {
            this._chartData = Object.assign({}, data);
            return;
        }
        this._chartData = JSON.parse(data);
        // Making deep copy of this
        if (this._chartData.data)
            this._coreSeries = JSON.parse(JSON.stringify(this._chartData.data.series));
    }
    initSvg() {
        this.margin.bottom =
            Number(window
                .getComputedStyle(document.body)
                .getPropertyValue('font-size')
                .match(/\d+/)[0]) *
                Number(this.fontSize.replace(/[^\d.]|\.(?=.*\.)/g, '')) +
                this.xPadding +
                this.xTickSize;
        this.lineChartObserver.observe(this._chartDiv);
        select(this._chartDiv).select('svg').remove();
        // Initialize an empty div, that we can place info in for tooltip
        // Styling for tooltip is in .scss file
        this._tooltip = select('#' + this.afId);
        this._tooltip.select('.close').on('click', this.closeTooltip);
        this._tooltipHeading =
            'h' + (parseInt(this.afHeadingLevel.replace(/\D/g, '')) + 1);
        // Add heading placeholder for heading
        this._tooltip
            .selectAll('.tooltipHead')
            .insert(this._tooltipHeading, ':first-child') // increment heading level by one
            .style('margin', '0 0.75rem')
            .style('font-weight', '500');
        this._maxHeight = select(this._host)
            .node()
            .parentNode.getBoundingClientRect().height;
        this.setDims();
        this.setTickSize();
        this.checkPercentage();
        select(this._chartDiv).attr('height', this.dims.height + 'px');
        // Appending svg
        this._svg = select(this._chartDiv)
            .append('svg')
            .attr('aria-hidden', true)
            .attr('role', 'img')
            .attr('aria-label', this._chartData && this._chartData.title
            ? 'Linjediagram om ' + this._chartData.title.toLowerCase()
            : 'Linjediagram');
        this._svg.attr('width', this.dims.width).attr('height', this.dims.height);
        this.mapColorToLine();
        this._TooltipLine = this._svg
            .append('line')
            .attr('id', 'toolTipLine' + this.afId);
        this._secondaryLine = this._svg
            .append('line')
            .attr('id', 'secondaryLine' + this.afId);
        this.computeMaxVal();
        this.initYAxis();
        this.initXAxis();
        this._Tipbox = this._svg
            .append('rect')
            .attr('class', 'svgRect')
            .attr('width', this.dims.width - this.margin.left / 2)
            .attr('height', this.dims.height - this.margin.top - this.margin.bottom)
            .attr('opacity', 0)
            .attr('transform', `translate(${this.margin.left / 2},0)`);
        this.addListenersToChart();
        this._Circles = this._svg
            .append('g')
            .attr('class', 'circleGroup')
            .on('mousemove', this.drawTooltipLine);
        this._Circles
            .selectAll('circle')
            .data(this._chartData.data.series)
            .join('circle')
            .attr('stroke', (d) => this.colorFunction(d))
            .attr('fill', 'white')
            .attr('stroke-width', '1px')
            .attr('r', 7)
            .attr('display', 'none');
        select(window).on('resize.' + this.afId, this.repositionTooltip);
    }
    // Initializing chart with empty dataset
    initEmpty() {
        this.margin.bottom =
            Number(window
                .getComputedStyle(document.body)
                .getPropertyValue('font-size')
                .match(/\d+/)[0]) *
                Number(this.fontSize.replace(/[^\d.]|\.(?=.*\.)/g, '')) +
                this.xPadding +
                this.xTickSize;
        select(this._chartDiv).select('svg').remove();
        // Initialize an empty div, that we can place info in for tooltip
        // Styling for tooltip is in .scss file
        this._tooltip = select('#' + this.afId);
        select('digi-icon-x').on('click', this.closeTooltip);
        this._tooltipHeading =
            'h' + (parseInt(this.afHeadingLevel.replace(/\D/g, '')) + 1);
        // Add heading placeholder for heading
        this._tooltip
            .selectAll('.tooltipHead')
            .insert(this._tooltipHeading, ':first-child') // increment heading level by one
            .style('margin', '0 0.75rem')
            .style('font-weight', '500');
        this._maxHeight = select(this._host)
            .node()
            .parentNode.getBoundingClientRect().height;
        this.setDims();
        select(this._chartDiv).attr('height', this.dims.height + 'px');
        this._svg = select(this._chartDiv)
            .append('svg')
            .attr('aria-hidden', true);
        this._svg.attr('width', this.dims.width).attr('height', this.dims.height);
        this._TooltipLine = this._svg
            .append('line')
            .attr('id', 'toolTipLine' + this.afId);
        this._secondaryLine = this._svg
            .append('line')
            .attr('id', 'secondaryLine' + this.afId);
        this.initYAxis(true);
        this.initXAxis(true);
        this._Tipbox = this._svg
            .append('rect')
            .attr('class', 'svgRect')
            .attr('width', this.dims.width - this.margin.left / 2)
            .attr('height', this.dims.height - this.margin.top - this.margin.bottom)
            .attr('opacity', 0)
            .attr('transform', `translate(${this.margin.left / 2},0)`);
        this._Circles = this._svg
            .append('g')
            .attr('class', 'circleGroup')
            .on('mousemove', this.drawTooltipLine);
        this.defineLineAndScale();
        this.lineChartObserver.observe(this._chartDiv);
        this.loadingState(true);
    }
    loadingState(empty) {
        this._loading = true;
        select('.tableButton').style('display', 'none');
        const duration = 400;
        const LineFunc = line()
            .defined((d) => d[1] != null)
            .x((d) => this._lineScale(d[0]))
            .y((d) => this._yAxis(d[1]))
            .curve(basis);
        // close potentially open tooltip
        this.closeTooltip();
        // Remove hover listeners from chart
        this._Tipbox
            .style('cursor', 'wait')
            .on('mousemove', null)
            .on('touchmove', null)
            .on('mouseup', null)
            .on('mouseleave', null);
        select(this._titleDiv)
            .select(this.afHeadingLevel)
            .html(`${_t.loading}...`);
        const height = select(this._titleDiv).style('height');
        select(this._titleDiv)
            .style('height', this._prevHeight)
            .transition('adjust')
            .duration(400)
            .style('height', height)
            .on('end', () => select(this._titleDiv).style('height', null));
        select(this._legendDiv).style('display', 'none');
        const animateRandomLine = () => {
            let firstVal = this._xAxis.domain()[0];
            const randomData = [...Array(this._xAxis.domain()[1])].map(() => {
                const dataPoint = [
                    firstVal,
                    Math.round(Math.random() * this._yAxis.domain()[1] * 100) / 100
                ]; // This assumes domain is from 0 to maxVal
                firstVal++;
                return dataPoint;
            });
            this._lineChartContainer.selectAll('.linePath').remove();
            this._lineChartContainer
                .selectAll('linePath')
                .data([randomData])
                .join('path')
                .attr('class', 'linePath')
                .attr('stroke', 'lightgray')
                .attr('stroke-linecap', this._lineCap)
                .attr('stroke-width', this._strokeWidth)
                .attr('fill', 'none')
                .attr('d', (d) => LineFunc(d))
                .transition()
                .duration(duration * 3)
                .ease(quadInOut)
                .attrTween('stroke-dasharray', function () {
                const length = this.getTotalLength();
                return interpolate(`0,${length}`, `${length},${length}`);
            })
                .on('end', () => {
                this._lineChartContainer
                    .selectAll('.linePath')
                    .attr('stroke-dasharray', function () {
                    const length = this.getTotalLength();
                    return length + ' ' + length;
                })
                    .attr('stroke-dashoffset', 0)
                    .transition()
                    .duration(duration * 3)
                    .ease(quadInOut)
                    .attr('stroke-dashoffset', function () {
                    return -this.getTotalLength();
                })
                    .on('end', () => animateRandomLine());
            });
        };
        const flattenLines = () => {
            const data = this._lineChartContainer
                .selectAll('.linePath')
                .data()
                .map((elem) => {
                elem.line = elem.line.map((point) => {
                    return point[1]
                        ? [point[0], this._yAxis.domain()[0]]
                        : [point[0], undefined];
                });
                return elem;
            });
            this._lineChartContainer
                .selectAll('.linePath')
                .data(data)
                .transition()
                .duration(duration)
                .ease(polyInOut)
                .attr('d', (d) => this._LineFunc(d.line))
                .on('end', (...[, i]) => (i === 0 ? animateRandomLine() : null));
            this._lineChartContainer
                .selectAll('.symbolGroup')
                .selectAll('.symbol')
                .transition()
                .duration(duration)
                .ease(linear$1)
                .attr('transform', (d) => d
                ? `translate(${this._lineScale(d.x)},${this._yAxis(this._yAxis.domain()[0])})`
                : null)
                .attr('opacity', 0);
        };
        // Start loadingstate, either from empty set or last set
        if (empty)
            animateRandomLine();
        else
            flattenLines();
    }
    updateSvg() {
        // displaying legend again
        if (this._loading) {
            select(this._host).select('.tableButton').style('display', null);
            select(this._legendDiv).style('display', null);
            select(this._titleDiv).style('height', null);
        }
        if (this._chartData.data.xValueNames)
            this.margin.right =
                this.getTextSize(this._chartData.data.xValueNames[this._chartData.data.xValueNames.length - 1]) /
                    2 +
                    1;
        else
            this.margin.right =
                this.getTextSize(max(this._chartData.data.xValues).toString()) / 2 +
                    1;
        this.checkPercentage();
        this.setDims(true);
        this.mapColorToLine();
        this.computeMaxVal();
        this.setTickSize();
        select(this._chartDiv).attr('height', this.dims.height + 'px');
        // Updating Svg attributes
        this._svg
            .attr('width', this.dims.width + 'px')
            .attr('height', this.dims.height + 'px')
            .attr('aria-label', this._chartData && this._chartData.title
            ? 'Linjediagram om ' + this._chartData.title.toLowerCase()
            : 'Linjediagram');
        // Y Axis
        this._yAxis = linear()
            .domain([0, this._maxVal])
            .nice(3)
            .range([this.dims.height - this.margin.bottom, this.margin.top]);
        // Updating margins
        this.margin.left =
            this.getTextSize(formatLocale(this.axisNumberFormat).format(this.formatStyle)(this._yAxis.domain()[1])) +
                this.yPadding +
                3;
        /****  Update xAxis ****/
        const oldDomain = this._xAxis.domain();
        this.initXAxis();
        this._lineChartContainer
            .transition('position')
            .duration(400)
            .ease(polyInOut)
            .attr('width', this.dims.width)
            .attr('height', this.dims.height)
            .attr('transform', `translate(${this.margin.left},0)`);
        this.setYTicks();
        this.defineLineAndScale();
        //this.leftSetAxis();
        this.addSymbols(true);
        if (this._loading) {
            select(this._host).select('.tableButton').style('display', null);
            this.addListenersToChart();
            const height = select(this._titleDiv).style('height');
            select(this._titleDiv)
                .style('height', this._prevHeight)
                .transition('adjust')
                .duration(400)
                .style('height', height)
                .on('end', () => select(this._titleDiv).style('height', null));
            select(this._legendDiv)
                .style('opacity', 0)
                .transition()
                .duration(400)
                .ease(polyInOut)
                .style('opacity', 1);
            this._lineChartContainer.selectAll('.linePath').on('end', null);
            // Setting starting state for symbols
            this._lineChartContainer
                .selectAll('.symbolGroup')
                .selectAll('.symbol')
                .attr('opacity', 0)
                .attr('transform', (d) => d
                ? `translate(${this._lineScale(d.x)},${this._yAxis(this._yAxis.domain()[0])})`
                : null);
            this._lineChartContainer
                .selectAll('.linePath')
                .transition()
                .duration(400)
                .ease(quadInOut)
                .attr('stroke-dashoffset', function () {
                return -this.getTotalLength();
            })
                .on('end', () => {
                this._lineChartContainer
                    .selectAll('.linePath')
                    .data(this.reshapeData(this._chartData.data.series))
                    .join('path')
                    .attr('class', 'linePath')
                    .attr('stroke', (d) => this.colorFunction(d))
                    .attr('stroke-linecap', this._lineCap)
                    .attr('stroke-width', this._strokeWidth)
                    .attr('fill', 'none')
                    .attr('stroke-dasharray', this.dashFunction)
                    .attr('stroke-dashoffset', null)
                    .attr('d', (d) => this._LineFunc(d.line.map((pair) => [
                    pair[0],
                    this._yAxis.domain()[0]
                ])));
                // Transitioning in lines
                this._lineChartContainer
                    .selectAll('.linePath')
                    .transition()
                    .duration(400)
                    .ease(polyInOut)
                    .attr('d', (d) => this._LineFunc(d.line));
                // Transitioning in symbols
                this._lineChartContainer
                    .selectAll('.symbolGroup')
                    .selectAll('.symbol')
                    .transition()
                    .duration(400)
                    .ease(polyInOut)
                    .attr('transform', (d) => d
                    ? `translate(${this._lineScale(d.x)},${this._yAxis(d.val)})`
                    : null)
                    .attr('opacity', 1);
                this._loading = false;
            });
        }
        else {
            this._lineChartContainer
                .selectAll('.linePath')
                .data(this.reshapeData(this._chartData.data.series))
                .join('path')
                .transition()
                .duration(400)
                .ease(polyInOut)
                .attr('class', 'linePath')
                .attr('stroke', (d) => this.colorFunction(d))
                .attr('stroke-linecap', this._lineCap)
                .attr('stroke-width', (d) => (d.length > 1 ? this._strokeWidth : 4))
                .attr('fill', 'none')
                .attr('stroke-dasharray', (d, i) => d.length > 1 ? this.dashFunction(d, i) : null)
                .attr('d', (d) => this._LineFunc(d.line));
        }
        // If we have the exact same domain, the tooltip may continue to be active
        if (this._toggled && oldDomain === this._xAxis.domain()) {
            const stringPoint = this._chartData.data.xValues[this._tooltipDataIndex].toString();
            this._Circles
                .selectAll('circle')
                .data(this._chartData.data.series)
                .join('circle')
                .transition('New circles')
                .duration(400)
                .ease(polyInOut)
                .attr('stroke', 'white')
                .attr('fill', (d) => this.colorFunction(d))
                .attr('stroke-width', '1px')
                .attr('r', 7);
            this.positionCircles(stringPoint, 400);
            const oldPos = this._TooltipLine.attr('y1');
            this._TooltipLine
                .transition()
                .duration(400)
                .ease(polyInOut)
                .attr('x1', this._xAxis(stringPoint) + this.margin.left)
                .attr('x2', this._xAxis(stringPoint) + this.margin.left)
                .attr('y1', this._yAxis(this._maxVal))
                .attr('y2', this.dims.height - this.margin.bottom);
            const tooltipBody = this._tooltip.select('.tooltipBody');
            const tooltipHead = this._tooltip.select('.tooltipHead');
            tooltipHead
                .select(this._tooltipHeading)
                .style('margin', '0 0.75rem')
                .html(() => {
                if (this._chartData.data.xValueNames)
                    return this._chartData.data.xValueNames[this._tooltipPoint - 1];
                return this._tooltipPoint;
            });
            // Body
            tooltipBody
                .selectAll('div')
                .data(this._chartData.data.series)
                .join('div')
                .style('display', 'flex')
                .style('flex-direction', 'row')
                .style('flex-wrap', 'nowrap')
                .style('white-space', 'nowrap')
                .style('justify-content', 'space-between')
                .html((d) => {
                return ('<span>' +
                    d.title +
                    ':&nbsp</span><span class="tooltipVal">' +
                    d.yValues[this._tooltipDataIndex] +
                    '</span>');
            });
            this.positionTooltipWithinBounds(this._xAxis(stringPoint) + this.margin.left, 400);
            this._tooltip
                .style('transform', () => {
                // We reset the position of the tooltip, and adjust for the maximum value, -1px for it to align perfectly
                return `translateY(${oldPos - this._tooltip.node().getBoundingClientRect().height - 9}px)`;
            })
                .transition()
                .duration(400)
                .ease(polyInOut)
                .style('transform', () => {
                // We reset the position of the tooltip, and adjust for the maximum value, -1px for it to align perfectly
                return `translateY(${this._yAxis(this._maxVal) - this._tooltip.node().getBoundingClientRect().height - 9}px)`;
            });
            this._svg
                .select('.tooltipPointer')
                .transition()
                .duration(400)
                .ease(polyInOut)
                .attr('transform', `translate(${this._xAxis(stringPoint) + this.margin.left},${this._yAxis(this._maxVal) - 7}) rotate(180) scale(1.5,1.0)`);
        }
        else {
            this._Circles
                .selectAll('circle')
                .data(this._chartData.data.series)
                .join('circle')
                .attr('stroke', (d) => this.colorFunction(d))
                .attr('fill', 'white')
                .attr('stroke-width', '1px')
                .attr('r', 7)
                .attr('display', 'none');
            this.closeTooltip();
        }
    }
    componentWillLoad() {
        this.afChartDataUpdate();
    }
    componentDidLoad() {
        if (Object.keys(this._chartData).length === 0)
            return this.initEmpty();
        // clearing selection
        this._selectedLines = [];
        this.initSvg();
        this.initLegend();
        this.initLines();
        document.fonts.onloadingdone = () => {
            this.setTickSize();
            this.resizeSvg();
        };
    }
    componentWillUpdate() {
        this._prevHeight = select(this._titleDiv).style('height');
    }
    componentDidUpdate() {
        if (Object.keys(this._chartData).length === 0)
            return this.loadingState();
        // clearing selection
        this._selectedLines = [];
        this.updateSvg();
        this.initLegend();
        this.updateTableContent();
    }
    disconnectedCallback() {
        this.lineChartObserver.disconnect();
    }
    // Returns pixelwidth of text given the current fontSize (costly function using .each)
    getTextSize(text) {
        const textWidth = [];
        const svg = select(this._chartDiv).append('svg');
        svg
            .selectAll('dummyText')
            .data([text])
            .join('text')
            .attr('font-size', this.fontSize)
            .attr('font-family', 'sans-serif')
            .text((d) => d)
            .each((...[, i, nodelist]) => {
            const thisWidth = nodelist[i].getComputedTextLength() + 5; // A little extra padding, text sizes seems to be a little small compared to real life
            textWidth.push(thisWidth);
            nodelist[i].remove();
        });
        svg.remove().exit();
        return textWidth[0];
    }
    // Goes through all tick values and checks the biggest in size, this one will decide the default tick-size
    setTickSize() {
        // Padding on both sides comined
        const textPadding = 25; // 12.5 pixel padding on each side
        if (this._chartData.data.xValueNames) {
            for (const elem of this._chartData.data.xValueNames) {
                const size = this.getTextSize(elem) + textPadding;
                if (size > this._tickSize)
                    this._tickSize = size;
            }
        }
        else {
            for (const elem of this._chartData.data.xValues) {
                const size = this.getTextSize(elem.toString()) + textPadding;
                if (size > this._tickSize)
                    this._tickSize = size;
            }
        }
    }
    // Left-orients Y-axis text
    leftSetAxis(init = false) {
        const shiftArray = [];
        if (!init) {
            this._yAxisHandle
                .selectAll('text')
                .transition('shuffle text')
                .duration(400)
                .attr('transform', (...[, i, nodelist]) => {
                const size = nodelist[i].getComputedTextLength();
                shiftArray.push(size);
                return `translate(${-1 * (this.margin.left - (size + this.yPadding))},0)`;
            });
            this._yAxisHandle
                .selectAll('line')
                .transition('shuffle line')
                .duration(400)
                .attr('x1', (...[, i]) => {
                return -1 * (this.margin.left - (shiftArray[i] + this.yPadding));
            });
        }
        else {
            this._yAxisHandle
                .selectAll('text')
                .attr('transform', (...[, i, nodelist]) => {
                const size = nodelist[i].getComputedTextLength();
                shiftArray.push(size);
                return `translate(${-1 * (this.margin.left - (size + this.yPadding))},0)`;
            });
            this._yAxisHandle.selectAll('line').attr('x1', (...[, i]) => {
                return -1 * (this.margin.left - (shiftArray[i] + this.yPadding));
            });
        }
    }
    // Updating data if content changes
    updateTableContent() {
        if (this._tableDiv.style['display'] === '' ||
            this._tableDiv.style['display'] === 'none')
            return;
        this.setTableContent();
        this.animateTableDimensions();
    }
    // Setting table content from this._chartData
    setTableContent() {
        this._tableDiv.innerHTML = `<digi-table af-size="small" af-variation="primary"> <table><caption>${this._chartData.title}</caption><thead><tr>${this.headings()}</tr></thead><tbody>${this.tableBody()}</tbody></table></digi-table>`;
    }
    setTableDimensions() {
        const table = select(this._tableDiv);
        table
            // The last value is for compensating the padding set on the table element, changing padding in css, will need change in these two lines
            .style('height', this._maxHeight -
            select(this._titleDiv).node().getBoundingClientRect().height -
            parseFloat(getComputedStyle(document.documentElement).fontSize) *
                0.65 +
            'px');
        table.style('width', this.dims.width -
            parseFloat(getComputedStyle(document.documentElement).fontSize) * 0.65 +
            'px');
    }
    animateTableDimensions() {
        const height = select(this._titleDiv).style('height');
        select(this._titleDiv)
            .style('height', this._prevHeight)
            .transition('adjust')
            .duration(400)
            .style('height', height)
            .on('end', () => select(this._titleDiv).style('height', null));
        const table = select(this._tableDiv);
        table
            .transition('adjustHeight')
            .duration(400)
            // The last value is for compensating the padding set on the table element, changing padding in css, will need change in these two lines
            .style('height', this._maxHeight -
            (parseFloat(height) +
                parseFloat(getComputedStyle(document.documentElement).fontSize) *
                    1.25) -
            parseFloat(getComputedStyle(document.documentElement).fontSize) *
                0.65 +
            'px');
        table.style('width', this.dims.width -
            parseFloat(getComputedStyle(document.documentElement).fontSize) * 0.65 +
            'px');
    }
    // Extracting all headings from data and returning a string with <th>-elements with headings
    headings() {
        let headingsString = `<th scope="col">${this._chartData.x}</th>`;
        this._coreSeries.forEach((elem) => {
            headingsString = headingsString.concat(`<th scope="col">${elem.title}</th>`);
        });
        return headingsString;
    }
    // Building the table body
    tableBody() {
        let body = '';
        const loopable = this._chartData.data.xValueNames
            ? this._chartData.data.xValueNames
            : this._chartData.data.xValues;
        loopable.forEach((elem, index) => {
            let cells = '';
            this._coreSeries.forEach((serie) => {
                cells = cells.concat(`<td>${serie.yValues[index] != null ? formatLocale(this.axisNumberFormat).format(this.formatStyle)(serie.yValues[index]) : '-'}</td>`);
            });
            body = body.concat(`<tr><th scope='row'>${elem}${cells}</th></tr>`);
        });
        return body;
    }
    render() {
        let heading = '';
        if (!this._chartData.subTitle)
            heading = `<${this.afHeadingLevel}>${this._chartData.title}</${this.afHeadingLevel}>`;
        else
            heading = `<${this.afHeadingLevel}>${this._chartData.title}</${this.afHeadingLevel}><p>${this._chartData.subTitle}</p>`;
        return (h("host", { key: 'eedf8d79973aa2d15f474e93134acbdfb9ef3d0c', ref: (el) => (this._host = el) }, h("div", { key: 'd8500c2d3ca271fac9ebf5ec35c4c4da9aef0abd', class: "topWrapper", ref: (el) => (this._titleDiv = el) }, h("digi-typography", { key: '5c9b87f00f5bba14becd10154e3b13cac48124b7', class: "chartTitle", innerHTML: heading }), h("digi-button", { key: '859a31da8c6afc1c07474ea4914af732588cef5b', class: "buttonWrapper tableButton", "af-size": "medium", "af-variation": "function", "af-full-width": "false", onAfOnClick: this.activateTable, afAriaLabel: `Visa tabell ${this._chartData.title ? this._chartData.title.toLowerCase() : ''}` }, h("digi-icon-table", { key: '3852def8d78f96314ee1a304a8b4b5d787e6f456', slot: "icon" }), "Visa tabell"), h("digi-button", { key: 'b4c53c45553bce7c77d20653d52a39c431597491', style: { display: 'none' }, class: "buttonWrapper chartButton", "af-size": "medium", "af-variation": "function", "af-full-width": "false", onAfOnClick: this.reInitChart, afAriaLabel: `Visa diagram ${this._chartData.title ? this._chartData.title.toLowerCase() : ''}` }, h("digi-icon-chart", { key: '8f5fabf6d507e5e664dcf9c89a73a2bfb5572645', slot: "icon" }), "Visa diagram"), h("div", { key: '7678960d000f436d5b0a9dce2f4489f9b48a0fee', class: "scChartStatus", role: "status", ref: (el) => (this._status = el) })), h("div", { key: '64edcbc78f51256719674dc4f9dc01af0ee7998a', class: "chartTooltip", id: this.afId }, h("div", { key: '0e9d9ffed55146e7aef132df07eea7ff2f5996c0', class: "tooltipHead" }, h("digi-icon-x", { key: '0463a7d4892199fb684f536a07a45132ad458c62', class: "close" }), ' '), h("div", { key: 'a703ec0152cee394b60a9110dfba8090c8e2e0bb', class: "tooltipBody" })), h("div", { key: '36fe4d1b5ede71ff5fd0e04be1ce33a6a5dfa7bd', class: "chart", ref: (el) => (this._chartDiv = el) }), h("div", { key: '558f1c0c8d1c6921d76a2e017197914af3b4e83c', class: "legend", ref: (el) => (this._legendDiv = el) }), h("div", { key: 'f003d37dd680bf77a0fda37ba976edce57a7fcfe', class: "table", ref: (el) => (this._tableDiv = el) }, ' ')));
    }
    get element() { return getElement(this); }
    static get watchers() { return {
        "afChartData": ["afChartDataUpdate"]
    }; }
};
ChartLine.style = DigiChartLineStyle0;

export { ChartLine as digi_chart_line };
