|
@@ -4,7 +4,7 @@
|
|
|
<h3 class="text-lg">成长树</h3>
|
|
|
|
|
|
<el-select class="w-400px" v-model="xh" filterable remote reserve-keyword placeholder="请输入学生姓名"
|
|
|
- :remote-method="remoteMethod" :loading="loading" @change="xhChange" clearable @clear="remoteMethod" >
|
|
|
+ :remote-method="remoteMethod" :loading="loading" @change="xhChange" clearable @clear="remoteMethod">
|
|
|
<el-option v-for="item in options" :key="item.xdxx_xsxh" :label="item.xdxx_xsxm + ' ' + item.xdxx_xsxh"
|
|
|
:value="item.xdxx_xsxh" />
|
|
|
</el-select>
|
|
@@ -18,6 +18,7 @@
|
|
|
import request from '@/utils/request';
|
|
|
import * as d3 from 'd3'
|
|
|
console.log('d3 : ', d3)
|
|
|
+
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
@@ -25,6 +26,8 @@ export default {
|
|
|
loading: false,
|
|
|
options: [],
|
|
|
xh: undefined
|
|
|
+ // xh: 'G112233'
|
|
|
+
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
@@ -35,90 +38,171 @@ export default {
|
|
|
url: '/xddy/dygl_wypj_pjjl/tree_pjjl',
|
|
|
data: {
|
|
|
wdwp_xs_xjh: this.xh
|
|
|
+ // wdwp_xs_xjh:
|
|
|
}
|
|
|
}).then(res => {
|
|
|
if (res.code == '1') {
|
|
|
if (res.data.data?.length === 0) return;
|
|
|
- this.treeData = {
|
|
|
+ const data = this.treeData = {
|
|
|
name: '',
|
|
|
children: [{
|
|
|
name: '',
|
|
|
- children: res.data.data.map(({ xdww_name, pfx_list }) => ({ name: xdww_name, children: pfx_list.map(({ xdwwp_name, wdwp_xs_df }) => ({ name: xdwwp_name + ' (' + wdwp_xs_df + ')' })) }))
|
|
|
+ children: [{
|
|
|
+ name: '',
|
|
|
+ children: res.data.data.map(({ xdww_name, pfx_list }) => ({ name: xdww_name, children: pfx_list.map(({ xdwwp_name, wdwp_xs_df }) => ({ name: xdwwp_name + ' (' + wdwp_xs_df + ')' })) }))
|
|
|
+ }]
|
|
|
}]
|
|
|
}
|
|
|
|
|
|
+ console.log('data : ', data)
|
|
|
+ {
|
|
|
+ const width = 1200;
|
|
|
+
|
|
|
+ // Compute the tree height; this approach will allow the height of the
|
|
|
+ // SVG to scale according to the breadth (width) of the tree layout.
|
|
|
+ const root = d3.hierarchy(data);
|
|
|
+ const dx = 100;
|
|
|
+ const dy = 80;
|
|
|
+ console.log('dx,dy : ', dx, dy)
|
|
|
+ // Create a tree layout.
|
|
|
+ const tree = d3.tree().nodeSize([dx, dy]);
|
|
|
+
|
|
|
+ // Sort the tree and apply the layout.
|
|
|
+ root.sort((a, b) => d3.ascending(a.data.name, b.data.name));
|
|
|
+ tree(root);
|
|
|
+
|
|
|
+ // Compute the extent of the tree. Note that x and y are swapped here
|
|
|
+ // because in the tree layout, x is the breadth, but when displayed, the
|
|
|
+ // tree extends right rather than down.
|
|
|
+ let x0 = Infinity;
|
|
|
+ let x1 = -x0;
|
|
|
+ root.each(d => {
|
|
|
+ if (d.x > x1) x1 = d.x;
|
|
|
+ if (d.x < x0) x0 = d.x;
|
|
|
+ });
|
|
|
+
|
|
|
+ // Compute the adjusted height of the tree.
|
|
|
+ const height = 400;
|
|
|
+
|
|
|
+ const svg = d3.select("#d3").append("svg")
|
|
|
+ .attr("width", width)
|
|
|
+ .attr("height", height)
|
|
|
+ .attr("viewBox", [-600, -360, width, height])
|
|
|
+ .attr("style", "max-width: 100%; height: auto; font: 10px sans-serif;");
|
|
|
+
|
|
|
+ const link = svg.append("g")
|
|
|
+ .attr("fill", "none")
|
|
|
+ .attr("stroke", "rgb(134,61,34)")
|
|
|
+ .attr("stroke-opacity", 1)
|
|
|
+ // .attr("stroke-width", 8)
|
|
|
+ .attr("transform", "rotate(-90)")
|
|
|
+ .selectAll()
|
|
|
+ .data(root.links())
|
|
|
+ .join("path")
|
|
|
+ .attr("d", d3.linkHorizontal()
|
|
|
+ .x(d => d.y)
|
|
|
+ .y(d => d.x))
|
|
|
+ .attr("stroke-width", (d) => d.source.depth < 2 ? 18 : 18 - d.source.depth * 3)
|
|
|
+
|
|
|
+ const node = svg.append("g")
|
|
|
+ .attr("stroke-linejoin", "round")
|
|
|
+ .attr("stroke-width", 3)
|
|
|
+ .attr("transform", "rotate(-90)")
|
|
|
+ .selectAll()
|
|
|
+ .data(root.descendants())
|
|
|
+ .join("g")
|
|
|
+ .attr("transform", d => `translate(${d.y},${d.x})`)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ node.append("circle")
|
|
|
+ .attr("fill", d => 'rgb(134,61,34)')
|
|
|
+ .attr("r", 0);
|
|
|
+
|
|
|
+ node.append("text")
|
|
|
+ .attr("transform", "rotate(90)")
|
|
|
+ .attr("dy", "0.31em")
|
|
|
+ .attr("x", d => d.children ? -12 : 12)
|
|
|
+ .attr("text-anchor", d => d.children ? "end" : "start")
|
|
|
+ .text(d => d.data.name)
|
|
|
+ .clone(true).lower()
|
|
|
+ .attr("stroke", "white");
|
|
|
+
|
|
|
+ return svg.node();
|
|
|
+ }
|
|
|
|
|
|
|
|
|
- // Specify the chart’s dimensions.
|
|
|
- const width = 820;
|
|
|
- const height = 450;
|
|
|
- const cx = width * 0.5; // adjust as needed to fit
|
|
|
- const cy = height; // adjust as needed to fit
|
|
|
- const radius = 360;
|
|
|
-
|
|
|
- // Create a radial tree layout. The layout’s first dimension (x)
|
|
|
- // is the angle, while the second (y) is the radius.
|
|
|
- const tree = d3.tree()
|
|
|
- .size([5 / 6 * Math.PI, radius])
|
|
|
- .separation((a, b) => (a.parent == b.parent ? 1 : 2) / a.depth);
|
|
|
-
|
|
|
- // Sort the tree and apply the layout.
|
|
|
- const root = tree(d3.hierarchy(this.treeData)
|
|
|
- .sort((a, b) => d3.ascending(a.data.name, b.data.name)));
|
|
|
-
|
|
|
- // Creates the SVG container.
|
|
|
- const svg = d3.select("#d3")
|
|
|
- .append("svg")
|
|
|
- .attr("width", width)
|
|
|
- .attr("height", height)
|
|
|
- .attr("viewBox", [-cx, -cy, width, height])
|
|
|
- .attr("style", "width: 100%; height: auto; font: 10px sans-serif;")
|
|
|
- // .attr("transform", "rotate(-70)");
|
|
|
-
|
|
|
- // Append links.
|
|
|
- svg.append("g")
|
|
|
- .attr("fill", "none")
|
|
|
- .attr("stroke", "rgb(134,61,34)")
|
|
|
- .attr("stroke-opacity", 1)
|
|
|
- .attr("stroke-linejoin", "round")
|
|
|
- .selectAll()
|
|
|
- .data(root.links())
|
|
|
- .join("path")
|
|
|
- .attr("d", d3.linkRadial()
|
|
|
- .angle(d => d.x)
|
|
|
- .radius(d => d.y))
|
|
|
- .attr("stroke-width", (d) => (3 - d.source.depth) * 8)
|
|
|
- .attr("stroke-linejoin", "round")
|
|
|
- .attr("transform", "rotate(-70)");
|
|
|
-
|
|
|
- // Append nodes.
|
|
|
- svg.append("g")
|
|
|
- .selectAll()
|
|
|
- .data(root.descendants())
|
|
|
- .join("circle")
|
|
|
- .attr("transform", d => `rotate(${d.x * 180 / Math.PI - 90}) translate(${d.y},0)`)
|
|
|
- .attr("fill", "rgb(134,61,34)")
|
|
|
- .attr("r", 0)
|
|
|
-
|
|
|
- // Append labels.
|
|
|
- svg.append("g")
|
|
|
- .attr("stroke-linejoin", "round")
|
|
|
- .attr("stroke-width", 3)
|
|
|
- .selectAll()
|
|
|
- .data(root.descendants())
|
|
|
- .join("text")
|
|
|
- .attr("transform", d => `rotate(-70) rotate(${d.x * 180 / Math.PI - 90}) translate(${d.y},0) rotate(${d.x >= Math.PI ? 180 : 0})`)
|
|
|
- .attr("dy", "0.51em")
|
|
|
- .attr("x", d => d.x < Math.PI === !d.children ? 3 : -3)
|
|
|
- .attr("text-anchor", d => d.x < Math.PI === !d.children ? "start" : "end")
|
|
|
- .attr("paint-order", "stroke")
|
|
|
- .attr("stroke", "white")
|
|
|
- .attr("fill", "currentColor")
|
|
|
- .text(d => d.data.name);
|
|
|
-
|
|
|
-
|
|
|
- svg.node();
|
|
|
-
|
|
|
+ // {
|
|
|
+ // // Specify the chart’s dimensions.
|
|
|
+ // const width = 820;
|
|
|
+ // const height = 450;
|
|
|
+ // const cx = width * 0.5; // adjust as needed to fit
|
|
|
+ // const cy = height; // adjust as needed to fit
|
|
|
+ // const radius = 360;
|
|
|
+
|
|
|
+ // // Create a radial tree layout. The layout’s first dimension (x)
|
|
|
+ // // is the angle, while the second (y) is the radius.
|
|
|
+ // const tree = d3.tree()
|
|
|
+ // .size([5 / 6 * Math.PI, radius])
|
|
|
+ // .separation((a, b) => (a.parent == b.parent ? 1 : 2) / a.depth);
|
|
|
+
|
|
|
+ // // Sort the tree and apply the layout.
|
|
|
+ // const root = tree(d3.hierarchy(this.treeData)
|
|
|
+ // .sort((a, b) => d3.ascending(a.data.name, b.data.name)));
|
|
|
+
|
|
|
+ // // Creates the SVG container.
|
|
|
+ // const svg = d3.select("#d3")
|
|
|
+ // .append("svg")
|
|
|
+ // .attr("width", width)
|
|
|
+ // .attr("height", height)
|
|
|
+ // .attr("viewBox", [-cx, -cy, width, height])
|
|
|
+ // .attr("style", "width: 100%; height: auto; font: 10px sans-serif;")
|
|
|
+ // // .attr("transform", "rotate(-70)");
|
|
|
+
|
|
|
+ // // Append links.
|
|
|
+ // svg.append("g")
|
|
|
+ // .attr("fill", "none")
|
|
|
+ // .attr("stroke", "rgb(134,61,34)")
|
|
|
+ // .attr("stroke-opacity", 1)
|
|
|
+ // .attr("stroke-linejoin", "round")
|
|
|
+ // .selectAll()
|
|
|
+ // .data(root.links())
|
|
|
+ // .join("path")
|
|
|
+ // .attr("d", d3.linkRadial()
|
|
|
+ // .angle(d => d.x)
|
|
|
+ // .radius(d => d.y))
|
|
|
+ // .attr("stroke-width", (d) => (3 - d.source.depth) * 8)
|
|
|
+ // .attr("stroke-linejoin", "round")
|
|
|
+ // .attr("transform", "rotate(-70)");
|
|
|
+
|
|
|
+ // // Append nodes.
|
|
|
+ // svg.append("g")
|
|
|
+ // .selectAll()
|
|
|
+ // .data(root.descendants())
|
|
|
+ // .join("circle")
|
|
|
+ // .attr("transform", d => `rotate(${d.x * 180 / Math.PI - 90}) translate(${d.y},0)`)
|
|
|
+ // .attr("fill", "rgb(134,61,34)")
|
|
|
+ // .attr("r", 0)
|
|
|
+
|
|
|
+ // // Append labels.
|
|
|
+ // svg.append("g")
|
|
|
+ // .attr("stroke-linejoin", "round")
|
|
|
+ // .attr("stroke-width", 3)
|
|
|
+ // .selectAll()
|
|
|
+ // .data(root.descendants())
|
|
|
+ // .join("text")
|
|
|
+ // .attr("transform", d => `rotate(-70) rotate(${d.x * 180 / Math.PI - 90}) translate(${d.y},0) rotate(${d.x >= Math.PI ? 180 : 0})`)
|
|
|
+ // .attr("dy", "0.51em")
|
|
|
+ // .attr("x", d => d.x < Math.PI === !d.children ? 3 : -3)
|
|
|
+ // .attr("text-anchor", d => d.x < Math.PI === !d.children ? "start" : "end")
|
|
|
+ // .attr("paint-order", "stroke")
|
|
|
+ // .attr("stroke", "white")
|
|
|
+ // .attr("fill", "currentColor")
|
|
|
+ // .text(d => d.data.name);
|
|
|
+
|
|
|
+
|
|
|
+ // svg.node();
|
|
|
+ // }
|
|
|
}
|
|
|
|
|
|
})
|