gpt4 book ai didi

javascript - 如何隐藏和显示折线图上的点

转载 作者:可可西里 更新时间:2023-11-01 13:18:33 26 4
gpt4 key购买 nike

当我点击我的图例文本时,我试图在我的折线图上隐藏和显示点。这是 link到我现在的 fiddle 。从我的 fiddle 中,我的蓝线工作正常,因为它在每次点击“值”时显示和隐藏。但是,当我单击“点”时,点并没有这样做。

我也尝试遵循此 link 中的建议但无济于事。非常感谢任何帮助!

    var data = [ {x: 0, y: 0}, {x: 5, y: 30}, {x: 10, y: 40},
{x: 15, y: 60}, {x: 20, y: 70}, {x: 25, y: 100} ];

const margin = {
left: 20,
right: 20,
top: 20,
bottom: 80
};

const svg = d3.select('svg');
svg.selectAll("*").remove();

const width = 200 - margin.left - margin.right;
const height = 200 - margin.top - margin.bottom;

const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);


var x = d3.scaleLinear()
.domain([0, d3.max(data, function(d){ return d.x; })])
.range([0,width])
.nice();

var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d){ return d.y; })])
.range([0,height])
.nice();

const xAxis = d3.axisTop()
.scale(x)
.ticks(5)
.tickPadding(5)
.tickSize(-height)

const yAxis = d3.axisLeft()
.scale(y)
.ticks(5)
.tickPadding(5)
.tickSize(-width);

svg.append("g")
.attr("class", "x axis")
.attr("transform", `translate(20,${height-margin.top-60})`)
.call(xAxis);

svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(20,20)")
.call(yAxis);

var lineFunction = d3.line()
.x(function(d) {return x(d.x); })
.y(function(d) {return y(d.y); })
.curve(d3.curveLinear);

//defining and plotting the lines
var path = g.append("path")
.attr("class", "path1")
.attr("id", "blueLine")
.attr("d", lineFunction(data))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none")
.attr("clip-path", "url(#clip)");

// plot a circle at each data point
g.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("cx", function(d) { return x(d.x); } )
.attr("cy", function(d) { return y(d.y); } )
.attr("r", 3)
.attr("class", "blackDot")
.attr("clip-path", "url(#clip)");

//************* Legend ***************
var legend = svg.selectAll(".legend")
.data(data)
.enter().append("g")

legend.append("rect")
.attr("x", width + 65)
.attr("y", 50)
.attr("width", 18)
.attr("height", 4)
.style("fill", "blue")

legend.append("text")
.attr("x", width + 60)
.attr("y", 50)
.attr("dy", ".35em")
.style("text-anchor", "end")
.on("click", function(){
// Determine if current line is visible
var active = blueLine.active ? false : true,
newOpacity = active ? 0 : 1;
// Hide or show the elements
d3.select("#blueLine").style("opacity", newOpacity);
// Update whether or not the elements are active
blueLine.active = active;
})
.text(function(d) {
return "Value";
});

var pointLegend = svg.selectAll(".pointLegend")
.data(data)
.enter().append("g")

pointLegend.append("circle")
.attr("r", 3)
.attr("cx", width + 70)
.attr("cy", 70)

pointLegend.append("text")
.attr("x", width + 60)
.attr("y", 70)
.attr("dy", ".35em")
.style("text-anchor", "end")
.on("click", function(){
// Determine if dots are visible
var active = blackDot.active ? false : true,
newOpacity = active ? 0 : 1;
// Hide or show the elements
d3.selectAll(".blackDot").style("opacity", newOpacity);
// Update whether or not the elements are active
blackDot.active = active;
})
.text(function(d) {
return "Point";
});

最佳答案

问题在于您跟踪点击状态的方式。具体来说,该行的变量...

//Determine if current line is visible
var active = blueLine.active ? false : true;

...和这个圆圈的变量:

// Determine if dots are visible
var active = blackDot.active ? false : true;

该行(实际上是一个 <path> 元素)有一个名为 blueLine 的 id .因此,元素本身是 window 的属性。对象,即全局变量。例如,看看这个:

console.log(window.foo)
<div id="foo"></div>

因此,blueLine.active有效,即使你从未声明过 blueLine代码中的任何位置。

但是,虽然该行有一个 ID,但您的圈子没有(blackDot 或不是)。此外,有问题的行是只有一个,因此可以有一个 id,但是你有几个圆圈,因此,不能使用 id(更多关于下)。

因此,解决方案是以另一种方式跟踪点击状态。例如,使用数据的属性:

.on("click", function(d){
// Determine if dots are visible
var active = d.active ? false : true;

下面是修改后的代码:

var data = [{
x: 0,
y: 0
}, {
x: 5,
y: 30
}, {
x: 10,
y: 40
},
{
x: 15,
y: 60
}, {
x: 20,
y: 70
}, {
x: 25,
y: 100
}
];

const margin = {
left: 20,
right: 20,
top: 20,
bottom: 80
};

const svg = d3.select('svg');
svg.selectAll("*").remove();

const width = 200 - margin.left - margin.right;
const height = 200 - margin.top - margin.bottom;

const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);


var x = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.x;
})])
.range([0, width])
.nice();

var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.y;
})])
.range([0, height])
.nice();

const xAxis = d3.axisTop()
.scale(x)
.ticks(5)
.tickPadding(5)
.tickSize(-height)

const yAxis = d3.axisLeft()
.scale(y)
.ticks(5)
.tickPadding(5)
.tickSize(-width);

svg.append("g")
.attr("class", "x axis")
.attr("transform", `translate(20,${height-margin.top-60})`)
.call(xAxis);

svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(20,20)")
.call(yAxis);

var lineFunction = d3.line()
.x(function(d) {
return x(d.x);
})
.y(function(d) {
return y(d.y);
})
.curve(d3.curveLinear);

//defining and plotting the lines
var path = g.append("path")
.attr("class", "path1")
.attr("id", "blueLine")
.attr("d", lineFunction(data))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none")
.attr("clip-path", "url(#clip)");

// plot a circle at each data point
g.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("cx", function(d) {
return x(d.x);
})
.attr("cy", function(d) {
return y(d.y);
})
.attr("r", 3)
.attr("class", "blackDot")
.attr("clip-path", "url(#clip)");

//************* Legend ***************
var legend = svg.selectAll(".legend")
.data(data)
.enter().append("g")

legend.append("rect")
.attr("x", width + 65)
.attr("y", 50)
.attr("width", 18)
.attr("height", 4)
.style("fill", "blue")

legend.append("text")
.attr("x", width + 60)
.attr("y", 50)
.attr("dy", ".35em")
.style("text-anchor", "end")
.on("click", function() {
// Determine if current line is visible
var active = blueLine.active ? false : true,
newOpacity = active ? 0 : 1;
// Hide or show the elements
d3.select("#blueLine").style("opacity", newOpacity);
// Update whether or not the elements are active
blueLine.active = active;
})
.text(function(d) {
return "Value";
});

var pointLegend = svg.selectAll(".pointLegend")
.data(data)
.enter().append("g")

pointLegend.append("circle")
.attr("r", 3)
.attr("cx", width + 70)
.attr("cy", 70);

pointLegend.append("text")
.attr("x", width + 60)
.attr("y", 70)
.attr("dy", ".35em")
.style("text-anchor", "end")
.on("click", function(d) {
// Determine if dots are visible
var active = d.active ? false : true,
newOpacity = active ? 0 : 1;
// Hide or show the elements
d3.selectAll(".blackDot").style("opacity", newOpacity);
// Update whether or not the elements are active
d.active = active;
})
.text(function(d) {
return "Point";
});
.xy_chart {
position: relative;
left: 50px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg class="xy_chart"></svg>

请记住,虽然将单个 id 设置为多个元素不可取,但它会起作用,正如您在下面的演示中看到的那样,我只是按原样使用您的代码并且设置blackDot圈子的ID:

var data = [{
x: 0,
y: 0
}, {
x: 5,
y: 30
}, {
x: 10,
y: 40
},
{
x: 15,
y: 60
}, {
x: 20,
y: 70
}, {
x: 25,
y: 100
}
];

const margin = {
left: 20,
right: 20,
top: 20,
bottom: 80
};

const svg = d3.select('svg');
svg.selectAll("*").remove();

const width = 200 - margin.left - margin.right;
const height = 200 - margin.top - margin.bottom;

const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);


var x = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.x;
})])
.range([0, width])
.nice();

var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.y;
})])
.range([0, height])
.nice();

const xAxis = d3.axisTop()
.scale(x)
.ticks(5)
.tickPadding(5)
.tickSize(-height)

const yAxis = d3.axisLeft()
.scale(y)
.ticks(5)
.tickPadding(5)
.tickSize(-width);

svg.append("g")
.attr("class", "x axis")
.attr("transform", `translate(20,${height-margin.top-60})`)
.call(xAxis);

svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(20,20)")
.call(yAxis);

var lineFunction = d3.line()
.x(function(d) {
return x(d.x);
})
.y(function(d) {
return y(d.y);
})
.curve(d3.curveLinear);

//defining and plotting the lines
var path = g.append("path")
.attr("class", "path1")
.attr("id", "blueLine")
.attr("d", lineFunction(data))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none")
.attr("clip-path", "url(#clip)");

// plot a circle at each data point
g.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("cx", function(d) {
return x(d.x);
})
.attr("cy", function(d) {
return y(d.y);
})
.attr("r", 3)
.attr("id", "blackDot")
.attr("class", "blackDot")
.attr("clip-path", "url(#clip)");

//************* Legend ***************
var legend = svg.selectAll(".legend")
.data(data)
.enter().append("g")

legend.append("rect")
.attr("x", width + 65)
.attr("y", 50)
.attr("width", 18)
.attr("height", 4)
.style("fill", "blue")

legend.append("text")
.attr("x", width + 60)
.attr("y", 50)
.attr("dy", ".35em")
.style("text-anchor", "end")
.on("click", function() {
// Determine if current line is visible
var active = blueLine.active ? false : true,
newOpacity = active ? 0 : 1;
// Hide or show the elements
d3.select("#blueLine").style("opacity", newOpacity);
// Update whether or not the elements are active
blueLine.active = active;
})
.text(function(d) {
return "Value";
});

var pointLegend = svg.selectAll(".pointLegend")
.data(data)
.enter().append("g")

pointLegend.append("circle")
.attr("r", 3)
.attr("cx", width + 70)
.attr("cy", 70)

pointLegend.append("text")
.attr("x", width + 60)
.attr("y", 70)
.attr("dy", ".35em")
.style("text-anchor", "end")
.on("click", function() {
// Determine if dots are visible
var active = blackDot.active ? false : true,
newOpacity = active ? 0 : 1;
// Hide or show the elements
d3.selectAll(".blackDot").style("opacity", newOpacity);
// Update whether or not the elements are active
blackDot.active = active;
})
.text(function(d) {
return "Point";
});
.xy_chart {
position: relative;
left: 50px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg class="xy_chart"></svg>

但是,同样,不建议为多个元素设置相同的 id:id 必须是唯一的。

关于javascript - 如何隐藏和显示折线图上的点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58265706/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com