我正在尝试根据输入将数据过滤为一个值。如果用户输入一个值,我希望它只能在图形上显示该值。但是,它不起作用。我相信代码在所有正确的位置,只是逻辑不存在。
如果我删除尝试执行此操作的功能,那么一切都很好-这意味着,如果我单击A,则只返回类型为A的数据,而对B则返回相同的数据。但这在实现我的代码时不起作用尝试使值下降到一个值。
问题:
如何根据用户输入沿x轴向下过滤一个值,但仍保留允许用户在数据类型之间切换的功能。
$(document).ready(function() {
$("#input").attr("value", 0);
});
const margin = {
top: 10,
right: 30,
bottom: 70,
left: 65
},
width = 520,
height = 480;
function SVGmaker(target) {
const svg = d3.selectAll(target)
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
svg.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("height", height)
.attr("width", width)
.attr("fill", "white")
return svg;
}
const svgOne = SVGmaker("#svg");
const data = [{
x: "1",
y: "5",
type: "A"
},
{
x: "2",
y: "4",
type: "B"
},
{
x: "3",
y: "3",
type: "B"
},
{
x: "4",
y: "2",
type: "A"
},
{
x: "5",
y: "1",
type: "A"
}
]
let x = d3.scaleLinear()
.domain([1, 5])
.range([0, width]);
// DC SVG Settings
const xAxis = d3.axisBottom(x);
svgOne.append("g")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
const yAxis = d3.scaleLinear()
.domain([0, 6])
.range([height, 0])
svgOne.append("g")
.call(d3.axisLeft(yAxis));
const colors = d3.scaleOrdinal()
.domain(["A", "B"])
.range(["red", "blue"]);
function updateData(data, type, theSVG, xAxis, yAxis, colors, value) {
// Filters through the data
const changeData = data.filter(function(d) {
if (type === "A") {
return d.type === "A"
} else if (type === "B") {
return d.type === "B"
} else {
return true;
}
});
var min = d3.min(data, function(d) {
return d.x;
});
const gra = theSVG
.selectAll("circle")
.data(changeData);
gra.enter()
.append("circle")
.filter(function(d) {
if (value <= min) {
return d.x
} else {
return d.x >= value && d.x <= value
}
})
.attr("cx", function(d) {
return xAxis(d.x);
})
.attr("cy", function(d) {
return yAxis(d.y);
})
.style("fill", function(d) {
return colors(d.type)
})
.merge(gra)
.attr("r", 11)
.filter(function(d) {
if (value <= min) {
return d.x
} else {
return d.x >= value && d.x <= value
}
})
.attr("cx", function(d) {
return xAxis(d.x);
})
.attr("cy", function(d) {
return yAxis(d.y);
})
.style("fill", function(d) {
return colors(d.type)
})
gra.exit()
.remove();
}
updateData(data, "", svgOne, x, yAxis, colors, 0);
let value;
function getMessage() {
value = document.getElementById("#input").value;
}
d3.select("#a")
.on("click", function() {
updateData(data, "A", svgOne, x, yAxis, colors, value);
});
d3.select("#b")
.on("click", function() {
updateData(data, "B", svgOne, x, yAxis, colors, value);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<!DOCTYPE html>
<div id="svg"></div>
<button id="a">a</button>
<button id="b">b</button>
<input type="number" id="input" value=0>
<button id="submit">submit</button>
<script type="text/javascript" src="scripts.js"></script>
答案 0 :(得分:0)
我有点想知道您想做什么,但实际上问题是您从未设置'value'变量,因此您总是传递未定义的变量。
调用getElementById时,请勿包括#
。
通常,如果您不是用d3或js生成标记/元素,我个人会将带有onclick
属性的点击监听器直接附加在html而不是d3.on中。
$(document).ready(function() {
$("#input").attr("value", 0);
});
const margin = {
top: 10,
right: 30,
bottom: 70,
left: 65
},
width = 520,
height = 480;
function SVGmaker(target) {
const svg = d3.selectAll(target)
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
svg.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("height", height)
.attr("width", width)
.attr("fill", "white")
return svg;
}
const svgOne = SVGmaker("#svg");
const data = [{
x: "1",
y: "5",
type: "A"
},
{
x: "2",
y: "4",
type: "B"
},
{
x: "3",
y: "3",
type: "B"
},
{
x: "4",
y: "2",
type: "A"
},
{
x: "5",
y: "1",
type: "A"
}
]
let x = d3.scaleLinear()
.domain([1, 5])
.range([0, width]);
// DC SVG Settings
const xAxis = d3.axisBottom(x);
svgOne.append("g")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
const yAxis = d3.scaleLinear()
.domain([0, 6])
.range([height, 0])
svgOne.append("g")
.call(d3.axisLeft(yAxis));
const colors = d3.scaleOrdinal()
.domain(["A", "B"])
.range(["red", "blue"]);
function updateData(data, type, theSVG, xAxis, yAxis, colors, value) {
// Filters through the data
var min = d3.min(data, function(d) {
return d.x;
});
const changeData = data
.filter(function(d) {
if (value >= min) {
return d.x == value;
} else {
return true;
}
})
.filter(function(d) {
if (type === "A") {
return d.type === "A"
} else if (type === "B") {
return d.type === "B"
} else {
return true;
}
});
const gra = theSVG
.selectAll("circle")
.data(changeData);
gra.enter()
.append("circle")
.attr("r", 11)
.style("fill", function(d) {
return colors(d.type)
})
.merge(gra)
.attr("cx", function(d) {
return xAxis(d.x);
})
.attr("cy", function(d) {
return yAxis(d.y);
})
.style("fill", function(d) {
return colors(d.type)
})
gra.exit()
.remove();
}
updateData(data, "", svgOne, x, yAxis, colors, 0);
d3.select("#submit")
.on("click", function() {
var value = document.getElementById("input").value;
updateData(data, "", svgOne, x, yAxis, colors, value);
});
d3.select("#a")
.on("click", function() {
updateData(data, "A", svgOne, x, yAxis, colors, 0);
});
d3.select("#b")
.on("click", function() {
updateData(data, "B", svgOne, x, yAxis, colors, 0);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<!DOCTYPE html>
<div id="svg"></div>
<button id="a">a</button>
<button id="b">b</button>
<input type="number" id="input" value=0>
<button id="submit">submit</button>
<script type="text/javascript" src="scripts.js"></script>