typescript - D3 Mouseover y Mouseout
He creado un gráfico circular usando TypeScript y D3. Me gustaría resaltar las secciones respectivas del gráfico circular durante el evento mouseover. Mi código actual solo está cambiando el color del texto, en lugar de todo el arco. ¿Alguien puede sugerir una solución?
Aquí está mi código de TypeScript:
interface Data {
quantity: number;
category: string;
}
let testData: Data[] = [
{
quantity: 25,
category: 'a'
},
{
quantity: 50,
category: 'b'
},
{
quantity: 100,
category: 'c'
},
{
quantity: 200,
category: 'd'
},
{
quantity: 300,
category: 'e'
}];
drawChart(testData);
function drawChart(data: Data[]) {
let width = 400,
height = 400,
radius = Math.min(width, height) / 2,
colourValues = d3.scale.category20c();
let arc = d3.svg.arc<d3.layout.pie.Arc<Data>>()
.innerRadius(0)
.outerRadius(radius-20);
let arcHover=d3.svg.arc<d3.layout.pie.Arc<Data>>()
.innerRadius(0)
.outerRadius(radius+10);
let pie = d3.layout.pie<Data>().value((d: Data):number => d.quantity);
let fill = (d: d3.layout.pie.Arc<Data>): string => colourValues(d.data.category);
let tf = (d: d3.layout.pie.Arc<Data>): string => `translate(${arc.centroid(d)})`;
let text = (d: d3.layout.pie.Arc<Data>): string => d.data.category;
let svg = d3.select('.pie-chart').append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
let g = svg.selectAll('.arc')
.data(pie(data))
.enter().append('g').attr('class', 'arc')
.data(pie(data))
.on("mouseover",function(d)
{
d3.select(this).attr('fill','blue').attr('d',arcHover)})
.on("mouseout",function(d)
{
d3.select(this).attr('fill','black').attr('d',arc)
});
g.append('path').attr('d', arc).attr('fill', fill)
g.append('text').attr('transform', tf).text(text);
}
Aquí está mi HTML:
<head>
</head>
<body>
<div class="pie-chart"></div>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="piechart1.js"></script>
</body>
Respuesta #1
Debes adjuntar tus funciones manejadoras de eventos en el elemento path, no en el g:
g.append('path')
.on("mouseover", function(d) {
d3.select(this).attr('fill', 'blue').attr('d', arcHover)
})
.on("mouseout", function(d) {
d3.select(this).attr('fill', 'black').attr('d', arc)
});
Otra forma: adjuntar manejadores de eventos al elemento g y cambiar el color de text y path por separado:
let g = svg.selectAll('.arc')
.data(pie(data))
.enter().append('g').attr('class', 'arc')
.data(pie(data))
.on("mouseover", function(d) {
d3.select(this).select('path').attr('fill', 'blue').attr('d', arcHover);
d3.select(this).select('text').attr('fill', 'blue')
})
.on("mouseout", function(d) {
d3.select(this).select('path').attr('fill', 'black').attr('d', arc);
d3.select(this).select('text').attr('fill', 'black')
});
Aquí - https://jsfiddle.net/tafxrkdL/1/ - un ejemplo con JavaScript puro (no TypeScript).
