提交 bcb22ad3 authored 作者: 祖铭松's avatar 祖铭松

feat: 完善环状热图

上级 8416b864
<template>
<div ref="chartRef"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
// import * as d3 from 'd3';
import { chartData, treeData } from '../mock.js';
import * as d3 from 'https://cdn.jsdelivr.net/npm/d3@7/+esm';
import PubSub from 'pubsub-js';
const chartRef = ref(null);
// 配置项数据
const options = ref({});
// 图例实例
const svgInstance = ref(null);
// pubsub实例
const pubSubInstance = ref(null);
// 生成图表
const generateChart = (data) => {
const ret = options.value;
const width = Number(ret.chart_width) || 500;
const height = width;
const minSize = Math.min(width, height);
const titleConfig = {
label: !!ret.title ? ret.title : null,
color: ret.title_font_color || '#333333',
fontSize: ret.title_font_size || 20,
fontStyle: ret.title_font_style ? 'oblique' : 'normal',
fontFamily: ret.title_font_family || 'Arial',
fontWeight: ret.title_font_weight ? 'bold' : 'normal'
};
const color_ls = setColorConfig(ret.data_color_list);
const color = (max, range_count, d) => {
return d3.scaleQuantize().domain([0, max]).range(color_ls);
// .range(d3.merge([[d3.color('steelblue')], d3.quantize((t) => d3.interpolateRainbow(t), range_count - 1).reverse()]))
};
const arc = (index, total) => {
const off = 1;
const radius = (i) => ((Math.min(width, height) / 2) * (i + off + 1)) / (total + off + 3);
return d3
.arc()
.innerRadius(radius(index - 1) + 5)
.outerRadius(radius(index));
};
const arcTotal = (index, total) => {
const off = 1;
const radius = (i) => ((Math.min(width, height) / 2) * (i + off + 1)) / (total + off + 3);
return d3
.arc()
.innerRadius(radius(index - 1) + 20)
.outerRadius(radius(index + 2));
};
const arcCustom = (index, total) => {
const off = 8;
const radius = (i) => ((Math.min(width, height) / 2) * (i + off + 1)) / (total + off + 3);
return d3
.arc()
.innerRadius(radius(index - 1))
.outerRadius(radius(index));
};
const pie = d3.pie().sort(null).value(1);
let categories = Object.keys(data[0]).splice(2);
let cleaned = categories.map((c) => {
return {
name: c,
data: pie(
data
.filter((d) => !!d.index)
.map((d) => {
return {
index: d.index,
value: d[c]
};
})
)
};
});
const svg = d3
.create('svg')
.attr('width', width)
.attr('height', height + width / 5)
.attr('viewBox', [-width / 2, -height / 2, width, height])
.attr('style', 'max-width: 100%; height: auto; font: 10px sans-serif');
let dataMaxNumber = null;
const dataMaxArr = [];
for (var i = 0; i < cleaned.length; i++) {
let set = new Set(cleaned[i].data.map((f) => f.data.value));
let distinct_values = set.size;
let maxNumber = d3.max(cleaned[i].data.map((f) => f.data.value));
let fcolors = color(maxNumber, distinct_values);
dataMaxArr.push(maxNumber);
svg.append('g')
.attr('stroke', 'none')
.attr('stroke-width', 1)
.attr('stroke-linejoin', 'round')
.selectAll('path' + i)
.data(cleaned[i].data.slice(0, 6))
.attr('id', function (d, i) {
return 'catArc_' + i;
})
.join('path')
.attr('fill', (d) => fcolors(d.data.value))
// .attr('d', i == cleaned.length - 1 ? arcTotal(i, cleaned.length) : arc(i, cleaned.length));
.attr('d', arcCustom(i, cleaned.length))
.attr('transform', 'rotate(90)');
svg.append('g')
.attr('stroke', 'none')
.attr('stroke-width', 1)
.attr('stroke-linejoin', 'round')
.selectAll('path' + i)
.data(cleaned[i].data.slice(6, 12))
.attr('id', function (d, i) {
return 'catArc_' + i;
})
.join('path')
.attr('fill', (d) => fcolors(d.data.value))
.attr('d', arcCustom(i, cleaned.length))
.attr('transform', 'rotate(130)');
svg.append('g')
.attr('stroke', 'none')
.attr('stroke-width', 1)
.attr('stroke-linejoin', 'round')
.selectAll('path' + i)
.data(cleaned[i].data.slice(12, 24))
.attr('id', function (d, i) {
return 'catArc_' + i;
})
.join('path')
.attr('fill', (d) => fcolors(d.data.value))
.attr('d', arcCustom(i, cleaned.length))
.attr('transform', 'rotate(155)');
}
dataMaxNumber = Math.round(Math.max.apply(null, dataMaxArr));
// text
svg.append('text')
.attr('x', 0)
.attr('y', -minSize / 1.79)
.attr('fill', titleConfig.color)
.attr('font-size', `${titleConfig.fontSize}px`)
.attr('font-family', `${titleConfig.fontFamily}`)
.attr('font-style', `${titleConfig.fontStyle}`)
.attr('font-weight', `${titleConfig.fontWeight}`)
.style('text-anchor', 'middle')
.text(titleConfig.label);
svg.append('g')
.selectAll()
.data(categories)
.join('g')
.attr('transform', (d, i, nodes) => `rotate(65) translate(-10,${((nodes.length / 2 - i - 1) * minSize) / 33.33})`)
.call((g) =>
g
.append('text')
.attr('x', minSize / 33.33)
.attr('y', -minSize / 3.23)
.attr('dy', '0.35em')
.style('font', `10px sans-serif`)
.text((d) => d)
);
const configObj = {
color,
minSize,
dataMaxNumber
};
// legend
if (ret.show_legend) {
setLegend(configObj, svg);
}
// tree
setTree(configObj, svg);
// A,B,C Label
setSideLabel(configObj, svg);
// category Labels
setLabel(data, configObj, svg);
svgInstance.value = svg.node();
// Append the SVG element.
chartRef.value.appendChild(svgInstance.value);
};
const setColorConfig = (color) => {
let colors = ['#397899', '#60B8E6', '#5C8EE6', '#476EB3', '#E84A43', '#EF8681', '#F7BEBB', '#579967', '#77E691', '#F08230'];
if (Array.isArray(color)) {
colors = !!color.length ? color : colors;
} else if (!!color) {
colors = color.split(',');
}
return colors;
};
const setLegend = (config, svg) => {
const legendData = Array.from({ length: config.dataMaxNumber + 1 }, (item, i) => i);
svg.append('g')
.selectAll()
.data(legendData)
.join('g')
.attr('transform', (d, i, nodes) => `translate(-10,${(nodes.length / 2 - i - 1) * 15})`)
.call((g) => g.append('rect').attr('width', 13).attr('height', 13).attr('fill', config.color(config.dataMaxNumber)))
.call((g) =>
g
.append('text')
.attr('x', 18)
.attr('y', 7)
.attr('dy', '0.3em')
.style('font', '12px sans-serif')
.text((d) => d)
);
return svg.node();
};
const setTree = (config, svg) => {
const innerRadius = config.minSize / 4.3;
const linkStep = (startAngle, startRadius, endAngle, endRadius) => {
const c0 = Math.cos((startAngle = ((startAngle - 90) / 180) * Math.PI));
const s0 = Math.sin(startAngle);
const c1 = Math.cos((endAngle = ((endAngle - 90) / 180) * Math.PI));
const s1 = Math.sin(endAngle);
return (
'M' +
startRadius * c0 +
',' +
startRadius * s0 +
(endAngle === startAngle
? ''
: 'A' +
startRadius +
',' +
startRadius +
' 0 0 ' +
(endAngle > startAngle ? 1 : 0) +
' ' +
startRadius * c1 +
',' +
startRadius * s1) +
'L' +
endRadius * c1 +
',' +
endRadius * s1
);
};
// const linkConstant = (d) => {
// return linkStep(d.source.x, d.source.y, d.target.x, d.target.y);
// };
const linkVariable = (d) => {
return linkStep(d.source.x, d.source.radius, d.target.x, d.target.radius);
};
const maxLength = (d) => d.data.length + (d.children ? d3.max(d.children, maxLength) : 0);
const setRadius = (d, y0, k) => {
d.radius = (y0 += d.data.length) * k;
if (d.children) {
d.children.forEach((d) => setRadius(d, y0, k));
}
};
// tree-A
const clusterA = d3
.cluster()
.size([67, innerRadius])
.separation((a, b) => 1);
const rootA = d3
.hierarchy(treeData.treeA, (d) => d.branchset)
.sum((d) => (d.branchset ? 0 : 1))
.sort((a, b) => a.value - b.value || d3.ascending(a.data.length, b.data.length));
clusterA(rootA);
setRadius(rootA, (rootA.data.length = 0), innerRadius / maxLength(rootA));
const linkA = svg
.append('g')
.attr('class', 'tree')
.attr('fill', 'none')
.attr('stroke', '#FF5252')
.selectAll('path')
.data(rootA.links().slice(1))
.join('path')
.each(function (d) {
d.target.linkNode = this;
})
.attr('d', linkVariable)
.attr('stroke', (d) => d.target.color)
.attr('transform', 'rotate(90)');
// tree-B
const clusterB = d3
.cluster()
.size([67, innerRadius])
.separation((a, b) => 1);
const rootB = d3
.hierarchy(treeData.treeB, (d) => d.branchset)
.sum((d) => (d.branchset ? 0 : 1))
.sort((a, b) => a.value - b.value || d3.ascending(a.data.length, b.data.length));
clusterB(rootB);
setRadius(rootB, (rootB.data.length = 0), innerRadius / maxLength(rootB));
const linkB = svg
.append('g')
.attr('class', 'tree')
.attr('fill', 'none')
.attr('stroke', '#FF5252')
.selectAll('path')
.data(rootB.links().slice(1))
.join('path')
.each(function (d) {
d.target.linkNode = this;
})
.attr('d', linkVariable)
.attr('stroke', (d) => d.target.color)
.attr('transform', 'rotate(197)');
// tree-C
const clusterC = d3
.cluster()
.size([140, innerRadius])
.separation((a, b) => 1);
const rootC = d3
.hierarchy(treeData.treeC, (d) => d.branchset)
.sum((d) => (d.branchset ? 0 : 1))
.sort((a, b) => a.value - b.value || d3.ascending(a.data.length, b.data.length));
clusterC(rootC);
setRadius(rootC, (rootC.data.length = 0), innerRadius / maxLength(rootC));
const linkC = svg
.append('g')
.attr('class', 'tree')
.attr('fill', 'none')
.attr('stroke', '#FF5252')
.selectAll('path')
.data(rootC.links().slice(1))
.join('path')
.each(function (d) {
d.target.linkNode = this;
})
.attr('d', linkVariable)
.attr('stroke', (d) => d.target.color)
.attr('transform', 'rotate(-72)');
return svg.node();
};
const setLabel = (data, config, svg) => {
const x = (index) => (Math.PI / 6) * index * 2 - Math.PI / 3.5;
const labelDataMp = data
.map((item) => ({ category: item.category }))
.map((item, i) => ({ ...item, x: x(i / 5.5), y: config.minSize / 2.34 }));
svg.append('g')
.selectAll('g')
.data(labelDataMp.slice(0, 6))
.join('g')
.attr('transform', (d) => `rotate(${(d.x * 180) / Math.PI - 90 + 147}) translate(${d.y}, 0)`)
.append('text')
.attr('dy', '0.61em')
.attr('text-anchor', 'start')
.attr('font-size', '10px')
.attr('transform', (d) => (d.x >= Math.PI ? 'rotate(180' : null))
.text((d) => d.category);
svg.append('g')
.selectAll('g')
.data(labelDataMp.slice(6, 12))
.join('g')
.attr('transform', (d) => `rotate(${(d.x * 180) / Math.PI - 90 + 188}) translate(${d.y}, 0)`)
.append('text')
.attr('dy', '0.61em')
.attr('text-anchor', 'start')
.attr('font-size', '10px')
.attr('transform', (d) => (d.x >= Math.PI ? 'rotate(180' : null))
.text((d) => d.category);
svg.append('g')
.selectAll('g')
.data(labelDataMp.slice(12, 24))
.join('g')
.attr('transform', (d) => `rotate(${(d.x * 180) / Math.PI - 90 + 217}) translate(${d.y}, 0)`)
.append('text')
.attr('dy', '0.61em')
.attr('text-anchor', 'start')
.attr('font-size', '10px')
// .attr('transform', (d) => (d.x >= Math.PI ? 'rotate(180' : null))
.text((d) => d.category);
return svg.node();
};
const setSideLabel = (config, svg) => {
svg.append('text')
.attr('x', config.minSize / 2.3)
.attr('y', config.minSize / 3.4)
.style('text-anchor', 'middle')
.style('font', '14px sans-serif')
.text('A');
svg.append('text')
.attr('x', -config.minSize / 2.3)
.attr('y', config.minSize / 3.4)
.style('text-anchor', 'middle')
.style('font', '14px sans-serif')
.text('B');
svg.append('text')
.attr('x', 0)
.attr('y', -config.minSize / 1.95)
.style('text-anchor', 'middle')
.style('font', '14px sans-serif')
.text('C');
return svg.node();
};
// 数据处理
const getChartData = (data) => {
const sectionCount = 32; // 整个圆分为32段
const fakeLength = sectionCount - data.length;
const obj = { ...data[0] };
delete obj.category;
for (let key in obj) {
obj[key] = null;
}
const fakeData = Array.from({ length: fakeLength }, () => ({ ...obj }));
return [...data, ...fakeData].map((data, index) => ({ index: index + 1, ...data }));
};
onMounted(() => {
const newChartData = getChartData(chartData);
// console.log(newChartData);
pubSubInstance.value = PubSub.subscribe('options', (m, data) => {
options.value = data;
chartRef.value.removeChild(svgInstance.value);
generateChart(newChartData);
});
generateChart(newChartData);
});
onUnmounted(() => {
PubSub.unsubscribe(pubSubInstance.value);
});
</script>
<style scoped></style>
<template>
<div class="form-container">
<h3 class="type content">画布</h3>
<div class="form-item">
<span>宽:</span>
<input type="text" v-model="dynamic_parameter.chart_width" />
</div>
<div class="form-item">
<span>高:</span>
<input type="text" v-model="dynamic_parameter.chart_height" />
</div>
<h3 class="type content">文本</h3>
<div class="form-item">
<span>标题:</span>
<input type="text" v-model="dynamic_parameter.title" />
</div>
<div class="form-item">
<span>字体:</span>
<input type="text" v-model="dynamic_parameter.title_font_family" />
</div>
<div class="form-item">
<span>字号:</span>
<input type="text" v-model="dynamic_parameter.title_font_size" />
</div>
<div class="form-item">
<span>字体颜色:</span>
<input type="text" v-model="dynamic_parameter.title_font_color" />
</div>
<div class="form-item">
<span>字体加粗:</span>
<input type="checkbox" v-model="dynamic_parameter.title_font_weight" />
</div>
<div class="form-item">
<span>斜体:</span>
<input type="checkbox" v-model="dynamic_parameter.title_font_style" />
</div>
<h3 class="type content">图例</h3>
<div class="form-item">
<span>显示图例:</span>
<input type="checkbox" v-model="dynamic_parameter.show_legend" />
</div>
<div class="btn">
<button @click="submit">提交</button>
</div>
</div>
</template>
<script setup>
import { reactive, onMounted } from 'vue';
import PubSub from 'pubsub-js';
//动态图参数,固定参数
const dynamic_parameter = reactive({
//长宽间距
chart_width: 500,
chart_height: 500,
margin_top: 60,
margin_right: 60,
margin_bottom: 60,
margin_left: 60,
//标题配置
title: '环状热图',
title_font_family: 'Arial',
title_font_weight: true,
title_font_size: 20,
title_font_color: '#333333',
title_font_style: false,
//横轴标题
xtitle_font_family: 'Arial',
xtitle_font_weight: false,
xtitle_font_style: false,
xtitle_font_size: 16,
xtitle_font_color: '#333333',
//纵轴标题
ytitle_font_family: 'Arial',
ytitle_font_weight: false,
ytitle_font_style: false,
ytitle_font_size: 16,
ytitle_font_color: '#333333',
//颜色设置
data_color_list: [],
//图例
show_legend: true,
legend_position: '0,0',
//坐标轴
show_x_axis: true,
show_x_line: true,
show_x_tickMarks: true,
show_x_gridLine: false,
show_x_title: true,
x_title: '',
x_tickMarks_color: '#333333',
x_tickMarks_length: '5',
show_y_axis: true,
show_y_line: true,
show_y_tickMarks: true,
show_y_gridLine: false,
show_y_title: true,
y_title: '',
y_tickMarks_color: '#333333',
y_tickMarks_length: '5',
//节点相关的参数,可能还会有更多
node_id: null, //节点id
node_color: null, //节点颜色
is_delect_node: false, //是否删除节点
node_search_name: null, //节点名称搜索
node_search_color: '#FF0404', //节点搜索后的颜色
node_edit_name: null, //修改节点名称
node_height: 100, //节点大小
path_id: null
});
const submit = () => {
PubSub.publish('options', dynamic_parameter);
};
onMounted(() => {
submit();
});
</script>
<style scoped>
.form-item span {
display: inline-block;
width: 100px;
text-align: left;
}
.btn {
width: 100%;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
}
</style>
<template>
<div class="chart-container">
<Chart />
<Config />
</div>
</template>
<script setup>
import Chart from './components/chart.vue';
import Config from './components/config.vue';
</script>
<style scoped>
.chart-container {
display: flex;
}
</style>
export const chartData = [
{ "category": "gene1", "sample1": 4.4868, "sample2": 2.1028, "sample3": 4.6156, "sample4": 3.6062, "sample5": 2.9296, "sample6": 3.9476 },
{ "category": "gene2", "sample1": 3.9594, "sample2": 3.3652, "sample3": 0.4511, "sample4": 1.3835, "sample5": 1.1056, "sample6": 1.5203 },
{ "category": "gene3", "sample1": 3.2306, "sample2": 3.3767, "sample3": 0.2988, "sample4": 2.9117, "sample5": 3.9578, "sample6": 3.4969 },
{ "category": "gene4", "sample1": 0.3022, "sample2": 4.9327, "sample3": 2.9004, "sample4": 2.3704, "sample5": 3.1998, "sample6": 3.587 },
{ "category": "gene5", "sample1": 2.4354, "sample2": 3.4559, "sample3": 0.1632, "sample4": 4.4134, "sample5": 4.4571, "sample6": 2.6568 },
{ "category": "gene6", "sample1": 4.598, "sample2": 0.0048, "sample3": 3.8677, "sample4": 1.8868, "sample5": 2.9284, "sample6": 3.1901 },
{ "category": "gene7", "sample1": 4.8462, "sample2": 1.5543, "sample3": 2.3545, "sample4": 3.8867, "sample5": 4.5715, "sample6": 0.4517 },
{ "category": "gene8", "sample1": 4.8664, "sample2": 1.2789, "sample3": 1.5975, "sample4": 3.6036, "sample5": 1.5056, "sample6": 2.5582 },
{ "category": "gene9", "sample1": 0.5232, "sample2": 0.6443, "sample3": 0.2087, "sample4": 2.719, "sample5": 1.0114, "sample6": 3.4342 },
{ "category": "gene10", "sample1": 2.0966, "sample2": 0.33, "sample3": 1.9473, "sample4": 0.2564, "sample5": 3.9563, "sample6": 0.2188 },
{ "category": "gene11", "sample1": 3.7602, "sample2": 4.9877, "sample3": 0.838, "sample4": 1.9343, "sample5": 4.756, "sample6": 4.1277 },
{ "category": "gene12", "sample1": 0.3151, "sample2": 1.769, "sample3": 1.9379, "sample4": 2.8278, "sample5": 0.7412, "sample6": 1.198 },
{ "category": "gene13", "sample1": 1.6036, "sample2": 1.0314, "sample3": 2.4763, "sample4": 1.8036, "sample5": 3.8841, "sample6": 1.8738 },
{ "category": "gene14", "sample1": 1.2388, "sample2": 0.3259, "sample3": 0.7626, "sample4": 2.1545, "sample5": 1.5361, "sample6": 4.7494 },
{ "category": "gene15", "sample1": 2.6602, "sample2": 2.5592, "sample3": 0.9081, "sample4": 0.4913, "sample5": 0.2115, "sample6": 4.7097 },
{ "category": "gene16", "sample1": 0.7287, "sample2": 3.9198, "sample3": 4.6308, "sample4": 3.1059, "sample5": 4.1345, "sample6": 1.4114 },
{ "category": "gene17", "sample1": 2.1624, "sample2": 0.8496, "sample3": 4.4815, "sample4": 4.3133, "sample5": 4.1448, "sample6": 4.989 },
{ "category": "gene18", "sample1": 2.9437, "sample2": 1.1908, "sample3": 3.197, "sample4": 2.2078, "sample5": 4.52, "sample6": 4.211 },
{ "category": "gene19", "sample1": 4.4411, "sample2": 1.2893, "sample3": 3.4074, "sample4": 3.2694, "sample5": 2.2056, "sample6": 3.853 },
{ "category": "gene20", "sample1": 4.4721, "sample2": 4.1316, "sample3": 2.429, "sample4": 3.0316, "sample5": 0.1618, "sample6": 1.8447 },
{ "category": "gene21", "sample1": 2.8048, "sample2": 1.8868, "sample3": 4.2447, "sample4": 3.3645, "sample5": 0.8583, "sample6": 4.1797 },
{ "category": "gene22", "sample1": 0.6126, "sample2": 4.6458, "sample3": 4.2906, "sample4": 4.4723, "sample5": 3.8047, "sample6": 2.2496 },
{ "category": "gene23", "sample1": 1.9088, "sample2": 4.737, "sample3": 1.8683, "sample4": 4.7179, "sample5": 2.0124, "sample6": 4.2413 },
{ "category": "gene24", "sample1": 3.5843, "sample2": 2.5398, "sample3": 0.8788, "sample4": 4.76, "sample5": 3.9924, "sample6": 0.0181 },
]
export const treeData = {
treeA: {
"branchset": [
{
"name": "n_85",
"branchset": [
{
"name": "Diffuser_3",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 2.5
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 2.5
}
],
"length": 1
}
],
"length": 0.5
},
{
"name": "Diffuser_1",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 1
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 1
}
],
"length": 1
}
],
"length": 0.5
},
{
"name": "Diffuser_2",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 1
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 1
}
],
"length": 1
}
],
"length": 0.5
}
],
"length": 1
}
],
"length": 0.5
},
],
"length": 30
},
],
},
treeB: {
"branchset": [
{
"name": "n_85",
"branchset": [
{
"name": "Diffuser_1",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 1
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 1
}
],
"length": 1
}
],
"length": 0.5
},
{
"name": "Diffuser_2",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 1
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 1
}
],
"length": 1
}
],
"length": 0.5
}
],
"length": 1
}
],
"length": 0.5
},
{
"name": "Diffuser_3",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 2.5
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 2.5
}
],
"length": 1
}
],
"length": 0.5
},
],
"length": 30
},
],
},
treeC: {
"branchset": [
{
"name": "n_23",
"branchset": [
{
"name": "n_85",
"branchset": [
{
"name": "Diffuser_3",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 2.5
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 2.5
}
],
"length": 1
}
],
"length": 0.5
},
{
"name": "Diffuser_1",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 1
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 1
}
],
"length": 1
}
],
"length": 0.5
},
{
"name": "Diffuser_2",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 1
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 1
}
],
"length": 1
}
],
"length": 0.5
}
],
"length": 1
}
],
"length": 0.5
},
],
"length": 0.8
},
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_3",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 2.5
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 2.5
}
],
"length": 1
}
],
"length": 0.5
},
{
"name": "Diffuser_1",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 1
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 1
}
],
"length": 1
}
],
"length": 0.5
},
{
"name": "Diffuser_2",
"branchset": [
{
"name": "n_88",
"branchset": [
{
"name": "Diffuser_0",
"branchset": [
],
"length": 1
},
{
"name": "Diffuser_2",
"branchset": [
],
"length": 1
}
],
"length": 1
}
],
"length": 0.5
}
],
"length": 1
}
],
"length": 0.5
},
],
"length": 0.8
}
],
"length": 30
}
]
}
}
\ No newline at end of file
......@@ -303,7 +303,7 @@ const generateTree = (svg) => {
};
onMounted(() => {
generateChart();
// generateChart();
});
</script>
......
......@@ -10,15 +10,16 @@
</template>
<script setup>
import { ref, shallowRef } from 'vue';
import Test from '../../components/Test/index.vue';
import LinearFitting from '../../components/LinearFitting/index.vue';
import PcaAnalysis from '../../components/PcaAnalysis/index.vue';
import MsDimplot from '../../components/MsDimplot/index.vue';
import BeeColonyDiagram from '../../components/BeeColonyDiagram/index.vue';
import CorrelationAnalysis from '../../components/CorrelationAnalysis/index.vue';
import ClusterHeatmap from '../../components/ClusterHeatmap/index.vue';
import CircularHeatmap from '../../components/CircularHeatmap/index.vue';
import Test from '../../components/Test/index.vue';
const chartCurrent = ref(0);
const chartCurrent = ref(7);
const chartList = shallowRef([
{ title: '线性拟合图', value: 1, comName: LinearFitting },
......@@ -27,7 +28,8 @@ const chartList = shallowRef([
{ title: '蜂群图', value: 4, comName: BeeColonyDiagram },
{ title: '相关性分析', value: 5, comName: CorrelationAnalysis },
{ title: '聚类热图', value: 6, comName: ClusterHeatmap },
{ title: 'test', value: 0, comName: Test },
{ title: '环状热图', value: 7, comName: CircularHeatmap },
{ title: 'test', value: 0, comName: Test }
]);
const getDefaultShowChart = () => {
......
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论