根据输入D3过滤数据

时间:2019-05-27 12:11:16

标签: javascript d3.js

我正在尝试根据输入将数据过滤为一个值。如果用户输入一个值,我希望它只能在图形上显示该值。但是,它不起作用。我相信代码在所有正确的位置,只是逻辑不存在。

如果我删除尝试执行此操作的功能,那么一切都很好-这意味着,如果我单击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>

1 个答案:

答案 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>