饼图怎么让hover 部分放大呢?跟 echarts 一样 #5947
YY88Xu posted onGitHub
问题描述
<img width="725" alt="image" src="https://github.com/antvis/G2/assets/14836228/2e42ae74-37cf-429b-9473-ea83553d87b1"> <img width="707" alt="image" src="https://github.com/antvis/G2/assets/14836228/8a619500-d651-49a2-a48c-7a3ed9678cdf">
重现链接
No response
重现步骤
No response
预期行为
No response
平台
- 操作系统: [macOS, Windows, Linux, React Native ...]
- 网页浏览器: [Google Chrome, Safari, Firefox]
屏幕截图或视频(可选)
No response
补充说明(可选)
No response
理论上如下是可以的:
/**
* A recreation of this demo: https://nivo.rocks/pie/
*/
import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
width: 500,
height: 400,
});
chart.coordinate({ type: 'theta', innerRadius: 0.25, outerRadius: 0.8 });
chart
.interval()
.data([
{ id: 'c', value: 526 },
{ id: 'sass', value: 220 },
{ id: 'php', value: 325 },
{ id: 'elixir', value: 561 },
{ id: 'rust', value: 54 },
])
.transform({ type: 'stackY' })
.encode('y', 'value')
.encode('color', 'id')
.state('active', { transform: 'scale(1.5, 1.5)'})
chart.interaction("elementHighlight", true)
chart.render();
但目前存在 bug,近期可以修复一下。
大佬,这个修复了吗? 可以用吗
大佬,这个修复了吗? 可以用吗
@pearmini
@pearmini 这个在做了没有呢 大佬
@YY88Xu @xiaoiver 会来看一下这个问题
应该是 transformOrigin 的问题
应该是 transformOrigin 的问题
所以要怎么写呢?能不能给个例子呢 @xiaoiver
应该是 transformOrigin 的问题
所以要怎么写呢?能不能给个例子呢 @xiaoiver
我们先尝试在 G2 内部修复
应该是 transformOrigin 的问题
所以要怎么写呢?能不能给个例子呢 @xiaoiver
我们先尝试在 G2 内部修复
大概什么时候可以修复好呢?
@xiaoiver 大佬好了吗
@pearmini @xiaoiver 大佬好了吗
@YY88Xu
当前的自定义方法,但对 label 还是有点问题。
import { Chart } from '@antv/g2';
const data = [
{ item: '事例一', count: 40, percent: 0.4 },
{ item: '事例二', count: 21, percent: 0.21 },
{ item: '事例三', count: 17, percent: 0.17 },
{ item: '事例四', count: 13, percent: 0.13 },
{ item: '事例五', count: 9, percent: 0.09 },
];
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.coordinate({ type: 'theta', outerRadius: 0.8 });
chart
.interval()
.data(data)
.transform({ type: 'stackY' })
.encode('y', 'percent')
.encode('color', 'item')
.legend('color', { position: 'bottom', layout: { justifyContent: 'center' } })
.label({
position: 'outside',
text: (data) => `${data.item}: ${data.percent * 100}%`,
})
.tooltip((data) => ({
name: data.item,
value: `${data.percent * 100}%`,
}));
const scale = 0.05;
chart.render().then((chart) => {
// Get G Canvas instance
const { canvas } = chart.getContext();
const center = chart.getCoordinate().getCenter();
// Find graphic elements
const elements = canvas.document.getElementsByClassName(
G2.ELEMENT_CLASS_NAME,
);
// Highlight
for (const element of elements) {
const path = element.attributes.path;
let r = 0;
let newR = 0;
const newPath = path.replace(/[a-zA-Z](\d|\.|\,)+/g, (v) => {
if (v[0] === 'M') {
const [x, y] = v.replace('M', '').split(',');
r = Math.sqrt(Math.pow(x - center[0], 2) + Math.pow(y - center[1], 2));
newR = r * (1 + scale);
return `M${Number(x) + (x - center[0]) * scale},${Number(y) + (y - center[1]) * scale}`
}
if (v[0] === "A") {
const list = v.split(',');
const y = list.pop();
const x = list.pop();
return `A${newR},${newR},0,0,1,${Number(x) + (x - center[0]) * scale},${Number(y) + (y - center[1]) * scale}`;
}
return v;
});
element.addEventListener('mouseenter', () => {
element.attr('path', newPath)
element.attr('zIndex', 2244)
});
element.addEventListener('mouseleave', () => {
element.attr('path', path)
});
}
});
@YY88Xu 最新的 看看符不符合你的要求
import { Chart } from '@antv/g2';
const data = [
{ item: '事例一', count: 40, percent: 0.4 },
{ item: '事例二', count: 21, percent: 0.21 },
{ item: '事例三', count: 17, percent: 0.17 },
{ item: '事例四', count: 13, percent: 0.13 },
{ item: '事例五', count: 9, percent: 0.09 },
];
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.coordinate({ type: 'theta', outerRadius: 0.8 });
chart
.interval()
.data(data)
.transform({ type: 'stackY' })
.encode('y', 'percent')
.encode('color', 'item')
.legend('color', { position: 'bottom', layout: { justifyContent: 'center' } })
.label({
position: 'outside',
text: (data) => `${data.item}: ${data.percent * 100}%`,
})
.tooltip((data) => ({
name: data.item,
value: `${data.percent * 100}%`,
}));
const scale = 0.05;
chart.render().then((chart) => {
// Get G Canvas instance
const { canvas } = chart.getContext();
const center = chart.getCoordinate().getCenter();
// Find graphic elements
const elements = canvas.document.getElementsByClassName(
G2.ELEMENT_CLASS_NAME,
);
// Highlight
for (const element of elements) {
const path = element.attributes.path;
let r = 0;
let newR = 0;
const newPath = path.replace(/[a-zA-Z](\d|\.|\,)+/g, (v) => {
if (v[0] === 'M') {
const [x, y] = v.replace('M', '').split(',');
r = Math.sqrt(Math.pow(x - center[0], 2) + Math.pow(y - center[1], 2));
newR = r * (1 + scale);
return `M${Number(x) + (x - center[0]) * scale},${Number(y) + (y - center[1]) * scale}`
}
if (v[0] === "A") {
const list = v.split(',');
const y = list.pop();
const x = list.pop();
return `A${newR},${newR},0,0,1,${Number(x) + (x - center[0]) * scale},${Number(y) + (y - center[1]) * scale}`;
}
return v;
});
element.parentNode.attr('zIndex', 2)
element.addEventListener('mouseenter', () => {
element.attr('path', newPath)
});
element.addEventListener('mouseleave', () => {
element.attr('path', path)
});
}
});
@ai-qing-hai 是放大了,但是有点卡顿,不知道你能不能感觉到?不知道为啥感觉不够丝滑
@ai-qing-hai 还有一个明显的 bug,就是浏览器窗口变小或变大,在 hover 的时候,会错位 <img width="659" alt="image" src="https://github.com/antvis/G2/assets/14836228/df00060a-1b61-4e2e-b4ff-cf34e554acfa">
@YY88Xu import { Chart } from '@antv/g2';
const data = [ { item: '事例一', count: 40, percent: 0.4 }, { item: '事例二', count: 21, percent: 0.21 }, { item: '事例三', count: 17, percent: 0.17 }, { item: '事例四', count: 13, percent: 0.13 }, { item: '事例五', count: 9, percent: 0.09 }, ];
const chart = new Chart({ container: 'container', autoFit: true, });
chart.coordinate({ type: 'theta', outerRadius: 0.8 });
chart
.interval()
.data(data)
.transform({ type: 'stackY' })
.encode('y', 'percent')
.encode('color', 'item')
.legend('color', { position: 'bottom', layout: { justifyContent: 'center' } })
.label({
position: 'outside',
text: (data) => ${data.item}: ${data.percent * 100}%
,
})
.tooltip((data) => ({
name: data.item,
value: ${data.percent * 100}%
,
}));
const scale = 0.05; let elements; const create = (init) => { // Get G Canvas instance const { canvas } = chart.getContext();
const center = chart.getCoordinate().getCenter();
if (elements) { for (const element of elements) {
element.removeEventListener('mouseenter', element.mouseenter);
element.removeEventListener('mouseleave', element.mouseleave);
}
}
// Find graphic elements elements = canvas.document.getElementsByClassName( G2.ELEMENT_CLASS_NAME, );
const initY = elements[0].attributes.path.replace(/A.+/, '').split(',')[1]; const r = init ? -initY : center[1] - initY; // Highlight for (const element of elements) { let { path } = element.attributes; console.log(r) const newR = r * (1 + scale);
if (init) {
path = path.replace(/[a-zA-Z](\d|\.|\,|\-)+/g, (v) => {
if (v[0] === 'M') {
const [x, y] = v.replace('M', '').split(',');
return `M${Number(x) + center[0]},${Number(y) + center[1]}`;
}
if (v[0] === "A") {
const list = v.split(',');
const y = list.pop();
const x = list.pop();
return list.join(',') + `,${Number(x) + center[0]},${Number(y) + center[1]}`;
}
if (v[0] === "L") {
return `L${center[0]},${center[1]}`
}
return v;
});
}
const newPath = path.replace(/[a-zA-Z](\d|\.|\,|\-)+/g, (v) => {
if (v[0] === 'M') {
const [x, y] = v.replace('M', '').split(',');
return `M${Number(x) + (x - center[0]) * scale},${Number(y) + (y - center[1]) * scale}`
}
if (v[0] === "A") {
const list = v.split(',');
const y = list.pop();
const x = list.pop();
return `A${newR},${newR},0,0,1,${Number(x) + (x - center[0]) * scale},${Number(y) + (y - center[1]) * scale}`;
}
return v;
});
element.parentNode.attr('zIndex', 2);
element.mouseenter = () => {
element.attr('path', newPath);
}
element.mouseleave = () => {
element.attr('path', path)
}
element.addEventListener('mouseenter', element.mouseenter);
element.addEventListener('mouseleave', element.mouseleave);
} }
chart.render().then(() => { create(); });
chart.on('afterchangesize', () => { create(true); })