简体   繁体   中英

differentiating mouseover from mouseout event in d3.js visualization

I am using this d3.js example for a visualization project. I have trouble changing the style of lines. I want the lines to be gray when mouse is out and red when mouse is over. Now the problem is when mouse is out of all lines, lines are red while I need them gray and when mouse is over one line it goes red and the rest stay gray. please help me. this is the original example .

here is the css.

svg {
  font: 10px sans-serif;
}

.background path {
  fill: none;
  stroke: none;
  color:#ccc;
  stroke-width: 20px;
  pointer-events: stroke;
}

.foreground path {
  fill: none;
  stroke: red;
  stroke-width: 1.5px;
}

.axis .title {
  font-size: 11px;
  font-weight: bold;
  text-transform: uppercase;
}

.axis line,
.axis path {
  fill: none;
  stroke:  #000;
  shape-rendering: crispEdges;
}

.label {
  -webkit-transition: fill 125ms linear;
}

.active .label:not(.inactive) {
  font-weight: bold;
}

.label.inactive {
  fill: #ccc;
}

.foreground path.inactive {
  stroke: #ccc;
  stroke-opacity: .5;
  stroke-width: 1px;
}   

and this is the Javascript of the d3 example.

var margin = {top: 30, right: 40, bottom: 20, left: 200},
    width = 1000 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var dimensions = [
  {
    name: "مبدأ",
    scale: d3.scale.ordinal().rangePoints([0, height]),
    type: String
  },
  {
    name: "شغل",
    scale: d3.scale.ordinal().rangePoints([0, height]),
    type: String
  },
  {
    name: "کار (ساعت)",
    scale: d3.scale.ordinal().rangePoints([0, height]),
    type: String
  },
  {
    name: "مُد",
    scale: d3.scale.ordinal().rangePoints([0, height]),
    type: String
  },
  {
    name: "جابه‌جایی (ساعت)",
    scale: d3.scale.ordinal().rangePoints([0, height]),
    type: String
  },
  {
    name: "استراحت (ساعت)",
    scale: d3.scale.ordinal().rangePoints([0, height]),
    type: String
  },
  {
    name: "مقصد",
    scale: d3.scale.ordinal().rangePoints([0, height]),
    type: String
  }
];

var x = d3.scale.ordinal()
    .domain(dimensions.map(function(d) { return d.name; }))
    .rangePoints([0, width]);

var line = d3.svg.line()
    .defined(function(d) { return !isNaN(d[1]); });

var yAxis = d3.svg.axis()
    .orient("left");

var svg = d3.select("body").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 + ")");

var dimension = svg.selectAll(".dimension")
    .data(dimensions)
  .enter().append("g")
    .attr("class", "dimension")
    .attr("transform", function(d) { return "translate(" + x(d.name) + ")"; });

d3.tsv("DataEntryabridged.tsv", function(error, data) {
  if (error) throw error;

  dimensions.forEach(function(dimension) {
    dimension.scale.domain(dimension.type === Number
        ? d3.extent(data, function(d) { return +d[dimension.name]; })
        : data.map(function(d) { return d[dimension.name]; }).sort());
  });

  svg.append("g")
      .attr("class", "background")
    .selectAll("path")
      .data(data)
    .enter().append("path")
      .attr("d", draw);

  svg.append("g")
      .attr("class", "foreground")
    .selectAll("path")
      .data(data)
    .enter().append("path")
      .attr("d", draw);

  dimension.append("g")
      .attr("class", "axis")
      .each(function(d) { d3.select(this).call(yAxis.scale(d.scale)); })
    .append("text")
      .attr("class", "title")
      .attr("text-anchor", "middle")
      .attr("y", -9)
      .text(function(d) { return d.name; });

  // Rebind the axis data to simplify mouseover.
  svg.select(".axis").selectAll("text:not(.title)")
      .attr("class", "label")
      .data(data, function(d) { return d.name || d; });

  var projection = svg.selectAll(".axis text,.background path,.foreground path")
      .on("mouseover", mouseover)
      .on("mouseout", mouseout);

  function mouseover(d) {
    svg.classed("active", true);
    projection.classed("inactive", function(p) { return p !== d; });
    projection.filter(function(p) { return p === d; }).each(moveToFront);
  }

  function mouseout(d) {
    svg.classed("active", false);
    projection.classed("inactive", false);
  }

  function moveToFront() {
    this.parentNode.appendChild(this);
  }
});

function draw(d) {
  return line(dimensions.map(function(dimension) {
    return [x(dimension.name), dimension.scale(d[dimension.name])];
  }));
}

Projection here contains elements from multiple class. So, select all the lines separately and change their style on mouseover and undo in mouseout part.

Modified functions are below, change the style as you need. Also change .foreground path fill to #ccc(default color).

Hope this helps!

function mouseover(d) {
    svg.classed("active", true);
    projection.classed("inactive", function(p) { return p !== d; });
    projection.filter(function(p) { return p === d; }).each(moveToFront);
    // new line added 
    svg.selectAll(".foreground path").filter(function(p) { 
        return p === d;}).each(function(i) { d3.select(this).style("stroke", "red")}); }

function mouseout(d) {
   svg.classed("active", false);
   projection.classed("inactive", false);
   // new line here
   svg.selectAll(".foreground path").each(function(i) { 
   d3.select(this).style("stroke", "#ccc")});
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM