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

feat: update

上级 18ad5e72
......@@ -8,7 +8,7 @@
import { ref, onMounted, onUnmounted } from 'vue';
import * as d3 from 'https://cdn.jsdelivr.net/npm/d3@7/+esm';
import { chartMockData } from '../utils/mock';
import { setTips, setMaxMinNumber, coordinateScale, setColor, setCluster, setLegend, setLabel } from '../utils/index';
import { setTips, setMaxMinNumber, coordinateScale, setColor, setCluster, setLegend, legendActive, setLabel } from '../utils/index';
import PubSub from 'pubsub-js';
// 根节点实例
......@@ -35,7 +35,10 @@ const generateChart = (data) => {
let marginLeft = Number(ret.margin_left) || 60;
let radius = Number(ret.point_radius) || 4;
let colors = ret.data_color_list || ['#E53935', '#1E88E5'];
let legendData = ['Cancer', 'Non-cance'];
let legendData = [
{ name: 'Cancer', checked: true },
{ name: 'Non-cance', checked: true }
];
const titleConfig = {
label: !!ret.title ? ret.title : '',
......@@ -85,7 +88,7 @@ const generateChart = (data) => {
setTips(cluster);
// legend
configObj.show_legend && setLegend(configObj);
configObj.show_legend && setLegend(configObj, data);
// label
setLabel(configObj);
......
......@@ -2,13 +2,14 @@ import * as d3 from 'https://cdn.jsdelivr.net/npm/d3@7/+esm';
// color config
export const setColor = (config) => {
let colors = ['#E53935', '#1E88E5'];
let colors = [];
if (Array.isArray(config.colors)) {
colors = !!config.colors.length ? config.colors : colors;
} else if (!!config.colors) {
colors = config.colors.split(',');
}
return d3.scaleOrdinal(colors).domain(config.legendData);
const legend = config.legendData.map(item => item.name)
return d3.scaleOrdinal(colors).domain(legend);
};
// paddedMin paddedMax
......@@ -26,12 +27,13 @@ export const setMaxMinNumber = (data) => {
export const setCluster = (config, data) => {
return config.svg
.append('g')
.attr('class', 'main-chart')
.style('isolation', 'isolate')
.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('class', 'points')
.attr('class', (d) => `points-${d.group}`)
.attr('cx', (d) => config.x(d.x))
.attr('cy', (d) => config.y(d.y))
.attr('fill', (d) => config.color(d.group))
......@@ -84,15 +86,17 @@ export const setTips = (rect) => {
};
// legend
export const setLegend = (config) => {
export const setLegend = (config, data) => {
config.svg.append('g')
.attr('transform', `translate(${config.width - config.marginLeft - 70}, ${100})`)
.attr('cursor', 'pointer')
.selectAll()
.data(config.legendData)
.join('g')
.attr('class', 'legend-rect')
.attr('transform', (d, i) => `translate(0, ${i * 20})`)
.call((g) => g.append('rect').attr('width', 15).attr('height', 15).attr('fill', d => config.color(d)))
.call((g) => g.append('rect').attr('class', 'rect-legend').attr('width', 15).attr('height', 15).attr('fill', d => config.color(d.name)))
.call((g) =>
g
.append('text')
......@@ -100,8 +104,10 @@ export const setLegend = (config) => {
.attr('y', 8)
.attr('dy', '0.3em')
.style('font', '13px sans-serif')
.text((d) => d)
.text((d) => d.name)
);
legendActive(config, data);
};
// title
......@@ -115,5 +121,59 @@ export const setLabel = (config) => {
.attr('font-style', `${config.titleConfig.fontStyle}`)
.attr('font-weight', `${config.titleConfig.fontWeight}`)
.style('text-anchor', 'middle')
.text('group');
.text(config.titleConfig.label);
};
// legend active
export const legendActive = (config) => {
const legend = config.svg.selectAll('.legend-rect')
legend.on('click', (e, d) => {
config.legendData = config.legendData.map(item => {
if (item.name === d.name) {
return { ...item, checked: !item.checked }
} else {
return { ...item }
}
})
const currentLegend = config.legendData.find(item => item.name == d.name);
config.svg.selectAll('.rect-legend').data(config.legendData).attr('fill', (d) => d.checked ? config.color(d.name) : '#aaa');
config.svg.selectAll(`.points-${currentLegend.name}`).attr('display', `${currentLegend.checked ? 'block' : 'none'}`)
})
}
export const legendDataActive = (config) => {
const legend = config.svg.selectAll('.legend-rect')
const legendRect = legend.select('rect')
legend.on('click', (e, d) => {
config.legendData = config.legendData.map(item => {
if (item.name === d.name) {
return { ...item, checked: !item.checked }
} else {
return { ...item }
}
})
legendRect.data(config.legendData).attr('fill', (d, i) => d.checked ? config.color(d.name) : '#aaa');
const activeLegend = [];
let newData = [];
for (let i = 0; i < config.legendData.length; i++) {
if (config.legendData[i].checked) {
activeLegend.push(config.legendData[i].name)
}
}
if (activeLegend.length > 0) {
activeLegend.forEach(name => {
newData.push(...chartData.filter(item => item.group == name))
})
} else {
newData = []
}
config.svg.select('.main-chart').remove();
setTips(setCluster(config, newData))
})
}
\ No newline at end of file
......@@ -34,7 +34,10 @@ const generateChart = (data) => {
let marginLeft = Number(ret.margin_left) || 120;
let legendPosition = ret.legend_position?.split(',') || [0.5, 1];
let colors = ret.data_color_list || ['#155C9C', '#44A79D'];
let legendData = ['AD', 'Non_AD'];
let legendData = [
{ name: 'AD', checked: true },
{ name: 'Non_AD', checked: true }
];
// 标题配置
const titleConfig = {
......@@ -80,6 +83,7 @@ const generateChart = (data) => {
let configObj = {
...ret,
data,
svg,
width,
height,
......
......@@ -8,7 +8,8 @@ export const setColor = (config) => {
} else if (!!config.colors) {
colors = config.colors.split(',');
}
return d3.scaleOrdinal(colors).domain(config.legendData);
const legendData = config.legendData.map(item => item.name)
return d3.scaleOrdinal(colors).domain(legendData);
};
// tips
......@@ -54,20 +55,22 @@ export const setLegend = (config) => {
g.append('g')
.attr('transform', `translate(0, 15)`)
.attr('cursor', 'pointer')
.selectAll()
.data(config.legendData)
.join('g')
.attr('class', 'legend-rect')
.attr('transform', (d, i) => `translate(${i * 90 + 20}, 0)`)
.call((g) =>
g.append("path")
.attr("class", "dot")
.attr("class", "dot-legend")
.attr("opacity", 1)
.attr("stroke-opacity", 1)
.attr("stroke-width", 2)
.attr("stroke", (d) => config.color(d))
.attr("stroke", (d) => config.color(d.name))
.attr("fill", 'transparent')
.attr("fill-opacity", 1)
.attr("d", (d) => setSymbol(d)))
.attr("d", (d) => setSymbol(d.name)))
.call((g) =>
g
.append('text')
......@@ -75,8 +78,10 @@ export const setLegend = (config) => {
.attr('y', 0)
.attr('dy', '0.3em')
.style('font', '13px sans-serif')
.text((d) => d)
.text((d) => d.name)
);
legendActive(config);
};
// scale
......@@ -184,6 +189,7 @@ export const setElliptic = (config) => {
rects
.append('ellipse')
.attr('class', `elliptic-${config.legendData[0].name}`)
.attr('cx', `${config.ellipticAD.cx}`)
.attr('cy', `${config.ellipticAD.cy}`)
.attr('rx', `${config.ellipticAD.rx}`)
......@@ -195,6 +201,7 @@ export const setElliptic = (config) => {
rects
.append('ellipse')
.attr('class', `elliptic-${config.legendData[1].name}`)
.attr('cx', `${config.ellipticNon_AD.cx}`)
.attr('cy', `${config.ellipticNon_AD.cy}`)
.attr('rx', `${config.ellipticNon_AD.rx}`)
......@@ -212,7 +219,7 @@ export const setPoint = (config, data) => {
.selectAll("path")
.data(data)
.join("path")
.attr("class", "dot")
.attr("class", d => `dot-${d.name}`)
.attr("opacity", 1)
.attr("stroke-opacity", 1)
.attr("stroke-width", 2)
......@@ -236,3 +243,23 @@ export const setLabel = (config) => {
.style('text-anchor', 'middle')
.text(`${config.titleConfig.label}`);
};
// legend active
export const legendActive = (config) => {
const legend = config.svg.selectAll('.legend-rect');
legend.on('click', (e, d) => {
config.legendData = config.legendData.map(item => {
if (item.name === d.name) {
return { ...item, checked: !item.checked }
} else {
return { ...item }
}
})
const currentLegend = config.legendData.find(item => item.name == d.name);
config.svg.selectAll('.dot-legend').data(config.legendData).attr('stroke', (d) => d.checked ? config.color(d.name) : '#aaa');
config.svg.selectAll(`.dot-${currentLegend.name}`).attr('display', `${currentLegend.checked ? 'block' : 'none'}`)
config.svg.select(`.elliptic-${currentLegend.name}`).attr('display', `${currentLegend.checked ? 'block' : 'none'}`)
})
}
\ No newline at end of file
......@@ -22,7 +22,7 @@ import ClusterHeatmapSecond from '../../components/ClusterHeatmapSecond/index.vu
import CircularHeatmap from '../../components/CircularHeatmap/index.vue';
import Test from '../../components/Test/index.vue';
const chartCurrent = ref(0);
const chartCurrent = ref(4);
const chartList = shallowRef([
{ title: '线性拟合图', value: 1, comName: LinearFitting },
......
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论