2020年8月29日 星期六

VueJS D3 2020 Tidy Tree Vue Component

 https://observablehq.com/@d3/tidy-tree


Dentro.vue

<!--

<template><div><dentro></dentro></div></template>

<script>

import Dentro from "@/views/Dentro.vue";

export default {components: {Dentro}};

</script>

-->


<template>

  <div>

    <h1>Dentro</h1>

    <div id="arc" class="svgborder" />

    <div id="den" class="svgborder" />

    <h1>End</h1>

  </div>

</template>

<script>

import * as d3 from "d3";

import flareJson from "@/assets/dentro.json";


export default {

  name: "Dentro",

  data() {

    return {

      gdp: [

        { country: "USA", value: 20.5 },

        { country: "China", value: 13.4 },

        { country: "Germany", value: 4.0 },

        { country: "Japan", value: 4.9 },

        { country: "France", value: 2.8 }

      ]

    };

  },

  mounted() {

    this.generateArc("#arc", this.gdp);

    this.generateDen("#den");

  },

  methods: {

    generateDen(id) {

      const width = 1280;

      const data = flareJson;


      const temp = d3.hierarchy(data);

      temp.dx = 10;

      temp.dy = width / (temp.height + 1);

      const root = d3.tree().nodeSize([temp.dx, temp.dy])(temp);


      let x0 = Infinity;

      let x1 = -x0;

      root.each(d => {

        if (d.x > x1) x1 = d.x;

        if (d.x < x0) x0 = d.x;

      });


      const svg = d3

        .select(id)

        .append("svg")

        .attr("viewBox", [0, 0, width, x1 - x0 + root.dx * 2]);


      const g = svg

        .append("g")

        .attr("font-family", "sans-serif")

        .attr("font-size", 10)

        .attr("transform", `translate(${root.dy / 3},${root.dx - x0})`);


      const link = g

        .append("g")

        .attr("fill", "none")

        .attr("stroke", "#555")

        .attr("stroke-opacity", 0.4)

        .attr("stroke-width", 1.5)

        .selectAll("path")

        .data(root.links())

        .join("path")

        .attr(

          "d",

          d3

            .linkHorizontal()

            .x(d => d.y)

            .y(d => d.x)

        );


      console.log(link);


      const node = g

        .append("g")

        .attr("stroke-linejoin", "round")

        .attr("stroke-width", 3)

        .selectAll("g")

        .data(root.descendants())

        .join("g")

        .attr("transform", d => `translate(${d.y},${d.x})`);


      node

        .append("circle")

        .attr("fill", d => (d.children ? "#555" : "#999"))

        .attr("r", 2.5);


      node

        .append("text")

        .attr("dy", "0.31em")

        .attr("x", d => (d.children ? -6 : 6))

        .attr("text-anchor", d => (d.children ? "end" : "start"))

        .text(d => d.data.name)

        .clone(true)

        .lower()

        .attr("stroke", "white");


      const chart = svg.node();

      console.log(chart);

    },

    generateArc(id, gdp) {

      const w = 500;

      const h = 500;


      const svg = d3

        .select(id)

        .append("svg")

        .attr("width", w)

        .attr("height", h);


      const sortedGDP = gdp.sort((a, b) => (a.value > b.value ? 1 : -1));

      const color = d3.scaleOrdinal(d3.schemeDark2);


      const max_gdp = d3.max(sortedGDP, o => o.value);


      const angleScale = d3

        .scaleLinear()

        .domain([0, max_gdp])

        .range([0, 1.5 * Math.PI]);


      const arc = d3

        .arc()

        .innerRadius((d, i) => (i + 1) * 25)

        .outerRadius((d, i) => (i + 2) * 25)

        .startAngle(angleScale(0))

        .endAngle(d => angleScale(d.value));


      const g = svg.append("g");


      g.selectAll("path")

        .data(sortedGDP)

        .enter()

        .append("path")

        .attr("d", arc)

        .attr("fill", (d, i) => color(i))

        .attr("stroke", "#FFF")

        .attr("stroke-width", "1px")

        .on("mouseenter", function() {

          d3.select(this)

            .transition()

            .duration(200)

            .attr("opacity", 0.5);

        })

        .on("mouseout", function() {

          d3.select(this)

            .transition()

            .duration(200)

            .attr("opacity", 1);

        });


      g.selectAll("text")

        .data(gdp)

        .enter()

        .append("text")

        .text(d => `${d.country} -  ${d.value} Trillion`)

        .attr("x", -150)

        .attr("dy", -8)

        .attr("y", (d, i) => -(i + 1) * 25);


      g.attr("transform", "translate(200,300)");

    }

  }

};

</script>

<style scope>

.svgborder svg {

  border: 2px solid;

}

</style>



Middle

End

沒有留言:

張貼留言

2023 Promox on Morefine N6000 16GB 512GB

2023 Promox on Morefine N6000 16GB 512GB Software Etcher 100MB (not but can be rufus-4.3.exe 1.4MB) Proxmox VE 7.4 ISO Installer (1st ISO re...