<template>
  <div class="app-container" ref="svgContainer"></div>
</template>

<script>
import * as d3 from 'd3';

export default {
  mounted() {
    const svgContainer = this.$refs.svgContainer;
    const width = svgContainer.clientWidth;
    const height = svgContainer.clientHeight;

    const links = [
      { source: "A", target: "B", value: 1 },
      { source: "A", target: "C", value: 2 },
      { source: "B", target: "C", value: 3 },
      { source: "B", target: "D", value: 4 },
      { source: "C", target: "D", value: 5 },
    ];

    const nodes = [
      { id: "A", x: 100, y: 100 },
      { id: "B", x: 200, y: 100 },
      { id: "C", x: 150, y: 200 },
      { id: "D", x: 250, y: 200 },
    ];

    const svg = d3.select(svgContainer).append("svg")
      .attr("width", width)
      .attr("height", height);

    const link = svg.selectAll("line")
      .data(links)
      .join("line")
      .attr("stroke", "black")
      .attr("stroke-width", d => d.value);

    const node = svg.selectAll("circle")
      .data(nodes)
      .join("circle")
      .attr("r", 20)
      .attr("fill", "red")
      .call(drag(simulation));

    const label = svg.selectAll("text")
      .data(nodes)
      .join("text")
      .text(d => d.id)
      .attr("x", d => d.x)
      .attr("y", d => d.y);

    const simulation = d3.forceSimulation(nodes)
      .force("link", d3.forceLink(links).id(d => d.id))
      .force("charge", d3.forceManyBody())
      .force("center", d3.forceCenter(width / 2, height / 2));

    simulation.on("tick", () => {
      link
        .attr("x1", d => d.source.x)
        .attr("y1", d => d.source.y)
        .attr("x2", d => d.target.x)
        .attr("y2", d => d.target.y);

      node
        .attr("cx", d => d.x)
        .attr("cy", d => d.y);

      label
        .attr("x", d => d.x)
        .attr("y", d => d.y - 25);
    });

    function drag(simulation) {

      function dragstarted(event) {
        if (!event.active) simulation.alphaTarget(0.3).restart();
        event.subject.fx = event.subject.x;
        event.subject.fy = event.subject.y;
      }

      function dragged(event) {
        event.subject.fx = event.x;
        event.subject.fy = event.y;
      }

      function dragended(event) {
        if (!event.active) simulation.alphaTarget(0);
        event.subject.fx = null;
        event.subject.fy = null;
      }

      return d3.drag()
        .on("start", dragstarted)
        .on("drag",
          dragged)
        .on("end", dragended);
    }
  }
}
</script>

<style>
svg {
  background-color: #eee;
}
</style>