Search

Vue.js Integration

Vue.js Integration
Scroll to example

This demo is a version of Time Periods demo and uses Vue version 3.

This demo shows how to use the KeyLines Vue component to:

  • Declare multiple components
  • Add font icons and tooltips
  • Set options on the chart
  • Listen for the change events on time bar and capture them on the controller to filter the chart

Vue Component

The source for this demo and its Vue chart component is available in the code tabs below.

See also

Tutorial: Vue Tutorial

KeyLines Vue component: Vue Reference

Vue official page: vuejs.org

Key functions used:

import { createApp } from "vue";
import Demo from "./App.vue";

createApp(Demo).mount("#kl-container");
import KlChart from "./Chart.vue";
import KlTimebar from "./Timebar.vue";
import LeftPanel from "./LeftPanel.vue";
import RightPanel from "./RightPanel.vue";
import data from "./data";
import { reactive, ref, onMounted } from "vue";

const chartOptions = {
  logo: { u: "/public/images/Logo.png" },
  handMode: true,
  iconFontFamily: "Font Awesome 5 Free",
  selectionColour: "#35495E",
  hover: 0,
  selectedNode: {
    fbc: "rgba(0,0,0,0)",
  },
  selectedLink: {
    fbc: "rgba(0,0,0,0)",
  },
};

const timebarOptions = {
  histogram: {
    colour: "#42B883",
    highlightColour: "#35495E",
    markColour: "rgb(192, 192, 192)",
    markHiColour: "rgb(105, 105, 105)",
  },
  playSpeed: 30,
};

const greyColours = ["rgb(105, 105, 105)", "rgb(192, 192, 192)"];
// only style the first 3 selections
const selectionColours = [
  ["#9600d5", "#d0a3cb"],
  ["#0044ff", "#6b93ff"],
  ["#ff0000", "#ff9e9e"],
];

const tooltip = reactive({
  start: "",
  end: "",
  left: "",
  top: "",
  tooltipClass: "hidden",
  arrowClass: "arrow",
});

onMounted(() => {
  document.fonts.load('24px "Font Awesome 5 Free"'),
    // set font icons for each node type
    data.items.forEach((item) => {
      if (item && item.type === "node") {
        item.fi = {
          c: greyColours[0],
          t: item.d.type === "person" ? "fas fa-user" : "fas fa-building",
        };
      }
    });
});

const chart = ref(null);

function onChartReady(loadedChart) {
  chart.value = loadedChart;
}

const timebar = ref(null);

function onTimebarReady(loadedTimebar) {
  timebar.value = loadedTimebar;
  timebar.value.mark([
    {
      dt1: new Date("01 Jan 2018 01:00:00"),
      dt2: new Date("01 Jan 2050 01:00:00"),
    },
  ]);
}

function onTimebarChange() {
  if (chart.value && timebar.value) {
    // filter the chart to show only items in the new range
    chart.value
      .filter(timebar.value.inRange, { animate: false, type: "link" })
      .then(() => {
        chart.value.layout("organic", {
          time: 500,
          mode: "adaptive",
          easing: "linear",
        });
      });
  }
}

function buildItemStyling(item, width, colour, border = false) {
  if (item.type === "node") {
    return {
      id: item.id,
      fi: {
        c: colour,
        t: item.d.type === "person" ? "fas fa-user" : "fas fa-building",
      },
      b: border ? colour : null,
    };
  }
  // else it's a link
  return { id: item.id, w: width || 4, c: colour };
}

function highlightSelections() {
  if (!chart.value || !timebar.value) return;
  const timebarSelection = [];
  const chartProperties = {};
  // set default colouring
  chart.value.each({ type: "all" }, (item) => {
    chartProperties[item.id] = buildItemStyling(
      item,
      3,
      item.type === "node" ? greyColours[0] : greyColours[1],
    );
  });

  let selectedIds = chart.value.selection();

  if (!selectedIds) return;
  if (selectedIds.length > selectionColours.length) {
    selectedIds = selectedIds.slice(0, selectionColours.length);
    chart.value.selection(selectedIds);
  }

  selectedIds.forEach((id, index) => {
    let neighbouringNodes = [];
    let links = [];
    const item = chart.value?.getItem(id);
    const colour =
      index < selectionColours.length
        ? selectionColours[index][0]
        : greyColours[1];
    const linkColour = selectionColours[index][1];

    if (item?.type === "node") {
      // all: true - applies styles to hidden nodes + links not in current time range
      const neighbours = chart.value?.graph().neighbours(id, { all: true });
      if (neighbours && neighbours.links) {
        links = neighbours.links;
        neighbouringNodes = neighbours.nodes;
      }

      // colour node
      chartProperties[id] = buildItemStyling(item, 3, colour, true);
      links.forEach((link) => {
        const linkItem = chart.value?.getItem(link);
        chartProperties[link] = buildItemStyling(linkItem, 5, linkColour);
      });
    } else if (item?.type === "link") {
      links.push(id);
      neighbouringNodes.push(item.id1, item.id2);

      // colour link
      chartProperties[id] = buildItemStyling(item, 5, colour);
    }
    // colour neighbour nodes
    neighbouringNodes.forEach((neighbourId) => {
      if (
        chartProperties[neighbourId].fi.c === greyColours[0] &&
        index < selectionColours.length
      ) {
        chartProperties[neighbourId] = buildItemStyling(
          chart.value?.getItem(neighbourId),
          3,
          selectionColours[index][1],
        );
      }
    });
    // and select in the timebar
    timebarSelection.push({
      id: links,
      index,
      c: colour,
    });
  });

  // clear any previous selections if less than 3 items are selected
  for (let i = selectedIds.length; i < selectionColours.length; i++) {
    timebarSelection.push({ id: [], index: i });
  }

  timebar.value.selection(timebarSelection);
  chart.value.setProperties(
    Object.keys(chartProperties).map((key) => chartProperties[key]),
  );
}

function getDateFromTimestamp(timestamp) {
  return timestamp ? new Date(timestamp).toDateString().slice(4) : "n/a";
}

function toggleTooltip({ id, x, y }) {
  if (chart.value) {
    const item = id ? chart.value.getItem(id) : null;
    const viewWidth = chart.value.viewOptions().width;

    if (item && item.type === "link") {
      const timebarItem = data.items.filter((tbItem) => {
        if (tbItem.id === item.id) {
          return tbItem;
        }
      });
      tooltip.start = getDateFromTimestamp(timebarItem[0].dt[0].dt1);
      tooltip.end = getDateFromTimestamp(timebarItem[0].dt[0].dt2);

      // style tooltip to left of cursor if it's x position + width exceeds
      // the remaining chart space.
      if (viewWidth && viewWidth > x + 250) {
        tooltip.top = `${y - 24}px`;
        tooltip.left = `${x + 22}px`;
        tooltip.tooltipClass = "";
      } else {
        tooltip.top = `${y - 24}px`;
        tooltip.left = `${x - 218}px`;
        tooltip.tooltipClass = "right";
      }
    } else {
      tooltip.tooltipClass = "hidden";
    }
  }
}
import KlComponent from "./Keylines.vue";
export default {
  name: "KlChart",
  extends: KlComponent,
  data: () => ({
    type: "chart",
  }),
  methods: {
    onLoad(options) {
      return this.component.layout("organic", options);
    },
  },
};
import KlComponent from "./Keylines.vue";
export default {
  name: "KlTimebar",
  extends: KlComponent,
  data: () => ({
    type: "timebar",
  }),
  methods: {
    onLoad() {
      return this.component.zoom("fit");
    },
  },
};
export default {
  name: "LeftPanel",
  props: {
    name: String,
  },
  mounted() {
    const sourceCodeElement = document.getElementById("lhsSource");
    const sourceCode = `<iframe id="sourceView" style="width: 100%; height: 100%; border: none;" src="source-${this.name}.js.htm" scrolling="no"></iframe>`;
    sourceCodeElement.innerHTML = sourceCode;
  },
};
export default {
  name: "RightPanel",
  props: {
    title: String,
    name: String,
    description: String,
    isFullscreenAvailable: {
      type: Boolean,
      default: () => typeof doFullScreen === "function",
    },
  },
  mounted() {
    const sourcePanel = document.getElementById("sourcePanel");
    const aboutPanel = document.getElementById("aboutPanel");
    if (sourcePanel && aboutPanel) {
      // re-assign parent of child elements, rather than copy HTML so as to not remove any event handlers
      this.$refs.sourceTab.appendChild(sourcePanel);
      for (const child of Array.from(sourcePanel.children)) {
        this.$refs.sourceTab.appendChild(child);
      }
      const aboutTemplate = aboutPanel.innerHTML;
      this.$refs.aboutTab.innerHTML = aboutTemplate;
    }
  },
  computed: {
    image() {
      return {
        src: `/public/images/${this.name}/vuejs.png`,
        alt: "Vue.js logo",
      };
    },
  },
};
import KeyLines from "keylines";

export default {
  name: "KlComponent",
  props: {
    id: String,
    container: Object,
    containerClass: String,
    styleObject: Object,
    options: Object,
    data: Object,
    animateOnLoad: {
      type: Boolean,
      default: false,
    },
    selection: {
      type: Array,
      default: () => [],
    },
  },
  mounted() {
    KeyLines.create({
      id: this.id,
      options: this.options,
      container: this.$refs ? this.$refs.container : null,
      type: this.type,
    })
      .then((component) => {
        this.klcreate(component);
      })
      .catch(console.err);
  },
  beforeUnmount() {
    if (this.component) {
      this.component.destroy();
    }
  },
  methods: {
    onEvent(props) {
      const name = "kl-" + props.name;
      this.$emit("kl-all", props);
      this.$emit(name, props.event);
    },
    klcreate(component) {
      this.component = component;
      this.component.on("all", this.onEvent);
      this.component
        .load(this.data)
        .then(() => this.onLoad({ animate: !!this.animateOnLoad }))
        .then(() => {
          component.selection(this.selection);
          this.$emit("kl-ready", component);
        });
    },
  },
};
export default {
  type: "LinkChart",
  items: [
    {
      type: "node",
      id: "Brooke Fields",
      t: "Brooke Fields",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Gina Carlson",
      t: "Gina Carlson",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Guillermo Vaughn",
      t: "Guillermo Vaughn",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Rose Ingram",
      t: "Rose Ingram",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Jeannie Wolfe",
      t: "Jeannie Wolfe",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Dave Rice",
      t: "Dave Rice",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Paul Watts",
      t: "Paul Watts",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Danny Matthews",
      t: "Danny Matthews",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Anthony Mitchell",
      t: "Anthony Mitchell",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Alfred Hicks",
      t: "Alfred Hicks",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Adrian Mcdaniel",
      t: "Adrian Mcdaniel",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Kerry Waters",
      t: "Kerry Waters",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Felix Floyd",
      t: "Felix Floyd",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Noel Luna",
      t: "Noel Luna",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Tami Lindsey",
      t: "Tami Lindsey",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Damon Douglas",
      t: "Damon Douglas",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Diana Greene",
      t: "Diana Greene",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Gary King",
      t: "Gary King",
      d: {
        type: "person",
      },
    },
    {
      type: "node",
      id: "Phantom Corporation",
      t: "Phantom Corporation",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Melon Arts",
      t: "Melon Arts",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Green",
      t: "Green",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Marblightning",
      t: "Marblightning",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Cycloration",
      t: "Cycloration",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Bluetronics",
      t: "Bluetronics",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Summitechnologies",
      t: "Summitechnologies",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Cloudwalk",
      t: "Cloudwalk",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Jettechs",
      t: "Jettechs",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Quadbridge",
      t: "Quadbridge",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Crow Navigations",
      t: "Crow Navigations",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Grasshopper Co.",
      t: "Grasshopper Co.",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Daydream Security",
      t: "Daydream Security",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Joytechs",
      t: "Joytechs",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Dwarfoods",
      t: "Dwarfoods",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Cliffoods",
      t: "Cliffoods",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Vinedustries",
      t: "Vinedustries",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Bansheewares",
      t: "Bansheewares",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Moonshine",
      t: "Moonshine",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Mapleway",
      t: "Mapleway",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Diamond Aviation",
      t: "Diamond Aviation",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Grotto Corp",
      t: "Grotto Corp",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Root Aviation",
      t: "Root Aviation",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "White Wolfoods",
      t: "White Wolfoods",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Greenetworks",
      t: "Greenetworks",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Honeytelligence",
      t: "Honeytelligence",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Tempestechnologies",
      t: "Tempestechnologies",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Phoenixland",
      t: "Phoenixland",
      d: {
        type: "company",
      },
    },
    {
      type: "node",
      id: "Crystalsun",
      t: "Crystalsun",
      d: {
        type: "company",
      },
    },
    {
      type: "link",
      id: "Brooke Fields-Phantom Corporation",
      id1: "Brooke Fields",
      id2: "Phantom Corporation",
      dt: [
        {
          dt1: 1339014193119,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Brooke Fields-Melon Arts",
      id1: "Brooke Fields",
      id2: "Melon Arts",
      dt: [
        {
          dt1: 1247271160185,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Brooke Fields-Green",
      id1: "Brooke Fields",
      id2: "Green",
      dt: [
        {
          dt1: 1237397195464,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Brooke Fields-Marblightning",
      id1: "Brooke Fields",
      id2: "Marblightning",
      dt: [
        {
          dt1: 1268721087691,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Brooke Fields-Cycloration",
      id1: "Brooke Fields",
      id2: "Cycloration",
      dt: [
        {
          dt1: 1310952185992,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Gina Carlson-Bluetronics",
      id1: "Gina Carlson",
      id2: "Bluetronics",
      dt: [
        {
          dt1: 1191238914316,
          dt2: 1270569157085,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Gina Carlson-Summitechnologies",
      id1: "Gina Carlson",
      id2: "Summitechnologies",
      dt: [
        {
          dt1: 1276109390365,
          dt2: 1348661017536,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Gina Carlson-Cloudwalk",
      id1: "Gina Carlson",
      id2: "Cloudwalk",
      dt: [
        {
          dt1: 1348270245074,
          dt2: 1412908707443,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Gina Carlson-Jettechs",
      id1: "Gina Carlson",
      id2: "Jettechs",
      dt: [
        {
          dt1: 1415551838802,
          dt2: 1465786744438,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Gina Carlson-Quadbridge",
      id1: "Gina Carlson",
      id2: "Quadbridge",
      dt: [
        {
          dt1: 1459806246849,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Guillermo Vaughn-Crow Navigations",
      id1: "Guillermo Vaughn",
      id2: "Crow Navigations",
      dt: [
        {
          dt1: 1418792877334,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Rose Ingram-Grasshopper Co.",
      id1: "Rose Ingram",
      id2: "Grasshopper Co.",
      dt: [
        {
          dt1: 1383109469104,
          dt2: 1498149360662,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Rose Ingram-Daydream Security",
      id1: "Rose Ingram",
      id2: "Daydream Security",
      dt: [
        {
          dt1: 1236890263269,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Jeannie Wolfe-Joytechs",
      id1: "Jeannie Wolfe",
      id2: "Joytechs",
      dt: [
        {
          dt1: 1266649394407,
          dt2: 1418563289105,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Dave Rice-Dwarfoods",
      id1: "Dave Rice",
      id2: "Dwarfoods",
      dt: [
        {
          dt1: 1435235563645,
          dt2: 1439593633782,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Paul Watts-Cliffoods",
      id1: "Paul Watts",
      id2: "Cliffoods",
      dt: [
        {
          dt1: 1348460379175,
          dt2: 1430497186231,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Paul Watts-Vinedustries",
      id1: "Paul Watts",
      id2: "Vinedustries",
      dt: [
        {
          dt1: 1342980716145,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Danny Matthews-Bansheewares",
      id1: "Danny Matthews",
      id2: "Bansheewares",
      dt: [
        {
          dt1: 1212592504689,
          dt2: 1506411552619,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Anthony Mitchell-Moonshine",
      id1: "Anthony Mitchell",
      id2: "Moonshine",
      dt: [
        {
          dt1: 1294680086436,
          dt2: 1513775556429,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Anthony Mitchell-Mapleway",
      id1: "Anthony Mitchell",
      id2: "Mapleway",
      dt: [
        {
          dt1: 1404224388156,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Alfred Hicks-Diamond Aviation",
      id1: "Alfred Hicks",
      id2: "Diamond Aviation",
      dt: [
        {
          dt1: 1302567304700,
          dt2: 1435579135260,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Adrian Mcdaniel-Grotto Corp",
      id1: "Adrian Mcdaniel",
      id2: "Grotto Corp",
      dt: [
        {
          dt1: 1275605687635,
          dt2: 1302441510735,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Kerry Waters-Root Aviation",
      id1: "Kerry Waters",
      id2: "Root Aviation",
      dt: [
        {
          dt1: 1357157613919,
          dt2: 1497198217881,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Kerry Waters-White Wolfoods",
      id1: "Kerry Waters",
      id2: "White Wolfoods",
      dt: [
        {
          dt1: 1186565644914,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Felix Floyd-Greenetworks",
      id1: "Felix Floyd",
      id2: "Greenetworks",
      dt: [
        {
          dt1: 1281749075420,
          dt2: 1425911470613,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Noel Luna-Honeytelligence",
      id1: "Noel Luna",
      id2: "Honeytelligence",
      dt: [
        {
          dt1: 1428549346398,
          dt2: 1497935675353,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Tami Lindsey-Tempestechnologies",
      id1: "Tami Lindsey",
      id2: "Tempestechnologies",
      dt: [
        {
          dt1: 1345276788162,
          dt2: 1402559251417,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Tami Lindsey-Phoenixland",
      id1: "Tami Lindsey",
      id2: "Phoenixland",
      dt: [
        {
          dt1: 1272650321596,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Damon Douglas-Crystalsun",
      id1: "Damon Douglas",
      id2: "Crystalsun",
      dt: [
        {
          dt1: 1439239127664,
          dt2: 1446474483161,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Damon Douglas-Phantom Corporation",
      id1: "Damon Douglas",
      id2: "Phantom Corporation",
      dt: [
        {
          dt1: 1432259515171,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Diana Greene-Melon Arts",
      id1: "Diana Greene",
      id2: "Melon Arts",
      dt: [
        {
          dt1: 1250937080868,
          dt2: 1272043917343,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Diana Greene-Green",
      id1: "Diana Greene",
      id2: "Green",
      dt: [
        {
          dt1: 1388980546097,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Gary King-Marblightning",
      id1: "Gary King",
      id2: "Marblightning",
      dt: [
        {
          dt1: 1341532138270,
          dt2: 1348971910953,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Brooke Fields-Cycloration",
      id1: "Brooke Fields",
      id2: "Cycloration",
      dt: [
        {
          dt1: 1252224410783,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Brooke Fields-Bluetronics",
      id1: "Brooke Fields",
      id2: "Bluetronics",
      dt: [
        {
          dt1: 1327698610449,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Brooke Fields-Summitechnologies",
      id1: "Brooke Fields",
      id2: "Summitechnologies",
      dt: [
        {
          dt1: 1176476394850,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Brooke Fields-Cloudwalk",
      id1: "Brooke Fields",
      id2: "Cloudwalk",
      dt: [
        {
          dt1: 1343570952015,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Brooke Fields-Jettechs",
      id1: "Brooke Fields",
      id2: "Jettechs",
      dt: [
        {
          dt1: 1183735407623,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Gina Carlson-Quadbridge",
      id1: "Gina Carlson",
      id2: "Quadbridge",
      dt: [
        {
          dt1: 1203779987419,
          dt2: 1286114861583,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Gina Carlson-Crow Navigations",
      id1: "Gina Carlson",
      id2: "Crow Navigations",
      dt: [
        {
          dt1: 1252864333111,
          dt2: 1332066374345,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Gina Carlson-Grasshopper Co.",
      id1: "Gina Carlson",
      id2: "Grasshopper Co.",
      dt: [
        {
          dt1: 1318370099782,
          dt2: 1367155178043,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Gina Carlson-Daydream Security",
      id1: "Gina Carlson",
      id2: "Daydream Security",
      dt: [
        {
          dt1: 1445086054970,
          dt2: 1494164214919,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Gina Carlson-Joytechs",
      id1: "Gina Carlson",
      id2: "Joytechs",
      dt: [
        {
          dt1: 1508949404869,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Guillermo Vaughn-Dwarfoods",
      id1: "Guillermo Vaughn",
      id2: "Dwarfoods",
      dt: [
        {
          dt1: 1439419710533,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Rose Ingram-Cliffoods",
      id1: "Rose Ingram",
      id2: "Cliffoods",
      dt: [
        {
          dt1: 1447743740784,
          dt2: 1475561870381,
        },
      ],
      a2: true,
      w: 3,
    },
    {
      type: "link",
      id: "Jeannie Wolfe-Vinedustries",
      id1: "Jeannie Wolfe",
      id2: "Vinedustries",
      dt: [
        {
          dt1: 1302350026690,
          dt2: 1362601707946,
        },
      ],
      a2: true,

// ...truncated 291 lines
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Vue.js Integration</title>
    <link rel="stylesheet" type="text/css" href="@ci/theme/kl/css/keylines.css">
    <link
      rel="stylesheet"
      type="text/css"
      href="@ci/theme/kl/css/minimalsdk.css"
    >
    <link
      rel="stylesheet"
      type="text/css"
      href="@ci/theme/kl/css/sdk-layout.css"
    >
    <link rel="stylesheet" type="text/css" href="@ci/theme/kl/css/demo.css">
    <link
      rel="stylesheet"
      type="text/css"
      href="@ci/theme/kl/css/examples-chrome.css"
    >
    <link
      rel="stylesheet"
      type="text/css"
      href="@fortawesome/[email protected]/css/fontawesome.css"
    >
    <link
      rel="stylesheet"
      type="text/css"
      href="@fortawesome/[email protected]/css/solid.css"
    >
    <link rel="stylesheet" href="./style.css">
  </head>
  <body>
    <div id="kl-container"></div>
    <script type="module" src="./code.js"></script>
  </body>
</html>
/* --- vuechartfilter.css --- */
#tooltip {
  position: absolute;
  padding: 5px;
  display: block;
  color: black;
  float: left;
  border: 1px solid #ccc;
  background-color: #fff;
  z-index: 1000;
  width: 208px;
}

.arrow {
  position: absolute;
  top: 22px;
  left: -9px;
  border-width: 0px 0px 1px 1px;
  border-style: solid;
  border-color: #ccc;
  background-color: #fff;
  transform: rotateZ(45deg);
  height: 15px;
  width: 15px;
}

.right .arrow {
  left: 199px;
  transform: rotateZ(225deg);
}

.tooltip-content {
  padding: 5px;
  line-height: 1.5;
}

Terms of use

These terms do not alter or supersede any existing agreements between you (or your employer) and us.

By accessing or using any Content you agree to be bound by these Terms of Use. Please review these terms carefully before using the website.

The contents of this website, including but not limited to any text, code samples, API references, schemas, interactive tools, and other materials (collectively, the 'Content'), are made available for informational and internal evaluation purposes only. All intellectual property rights in the Content are reserved. No licence is granted to use the Content for any commercial purpose, or to copy, distribute, modify, reverse-engineer, or incorporate any part of the Content into any product or service, without our prior written consent.

This Content is provided “as is” and “as available,” without any representations, warranties, or guarantees of any kind, whether express or implied, including but not limited to implied warranties of merchantability, fitness for a particular purpose, non-infringement, or accuracy. To the fullest extent permitted by applicable law, we expressly exclude and disclaim all implied warranties, conditions, and other terms that might otherwise be implied.

We disclaim all liability for any loss or damage, whether direct, indirect, incidental, consequential, or otherwise, arising from any reliance placed on the Content or from your use of it, to the fullest extent permitted by applicable law. By continuing to access or use the Content, you acknowledge and agree to these terms.