在d3.js支持的多折线图上过滤数据

时间:2019-02-25 17:19:38

标签: d3.js

我有一个运行d3.js的多折线图:

https://codepen.io/rikabel/pres/vbaqzp

// Draw a line chart
var svg = d3.select('#lineChart'),
  margin = { top: 20, right:80, bottom: 40, left: 40 },
  width = +svg.attr('width') - margin.left - margin.right,
  height = +svg.attr('height') - margin.top - margin.bottom,
  g = svg.append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

var div = d3.select(".line-chart-wrapper").append("div").attr("class", "toolTip");
// Function to convert a string into a time
var parseTime = d3.time.format('%Y-%m-%d %H:%M').parse;
// Function to show specific time format
var formatTime = d3.time.format('%e %B');

// Set the X scale
var x = d3.time.scale().range([0, width], 0.5);

// Set the Y scale
var y = d3.scale.linear().range([height, 0]);

// Set the color scale
var colors = ['#fc7950','#4e71d8','#b1ee65','#6d44a8','#e1b53e','#2eabd6','#fb4f84','#5af46e','#aec3fd','#bd41ac','#30dea4'];
var color = d3.scale.ordinal().range(colors);

var xAxis = d3.svg.axis()
.scale(x)
.tickSize(-height)
.orient("bottom");

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

var line = d3.svg.line()
// .interpolate("basis")
.x(function(d) {
  return x(d.date);
})
.y(function(d) {
  return y(d.attackType);
});
  
  // load the data
d3.json("https://api.myjson.com/bins/rczxa", function(error, data) {
  // Select the important columns
  color.domain(d3.keys(data[0]).filter(function(key) {
      return key !== "Time" && key !== "_id";
  }));
  // Correct the types
  data.forEach(function(d) {
    d.date = parseTime(d.Time);
  });

  var attackTypes = color.domain().map(function(name) {
    return {
      name: name,
      values: data.map(function(d) {
        return {
          date: d.date,
          attackType: +d[name]
        };
      })
    };
  });

  // Set the X domain
  x.domain(d3.extent(data, function(d) {
    return d.date;
  }));
  // Set the Y domain
  y.domain([
    d3.min(attackTypes, function(c) {
      return d3.min(c.values, function(v) {
        return v.attackType;
      });
    }),
    d3.max(attackTypes, function(c) {
      return d3.max(c.values, function(v) {
        return v.attackType;
      });
    })
  ]);
  // Set the X axis
  g.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);
  // Set the Y axis
  g.append("g")
    .attr("class", "y axis")
    .call(yAxis)

  // Draw the lines
  var attacker = g.selectAll(".attacker")
    .data(attackTypes)
    .enter().append("g")
    .attr("class", "attacker");

  attacker.append("path")
    .attr("class", "line")
    .attr("d", function(d) {
      return line(d.values);
    })
    .style("stroke", function(d) {
      return color(d.name);
    })
    // .style('opacity', lineOpacity)
    .on("mouseover", function(d) {
        d3.selectAll('.line')
            .style('opacity', otherLinesOpacityHover);
        d3.selectAll('.circle')
            .style('opacity', circleOpacityOnLineHover);
        d3.select(this)
          .style('opacity', lineOpacityHover)
          .style("stroke-width", lineStrokeHover)
          .style("cursor", "pointer");
      });
  
  // Add the circles
  attacker.append("g").selectAll("circle")
    .data(function(d){return d.values})
    .enter()
    .append("circle")
    .attr("r", 3)
    .attr("cx", function(dd){return x(dd.date)})
    .attr("cy", function(dd){return y(dd.attackType)})
    .attr("fill", "none")
    .attr("stroke", function(d){return color(this.parentNode.__data__.name)});
  // Add label to the end of the line
  attacker.append("text")
    .attr("class", "label")
    .datum(function (d) {
      return {
        name: d.name,
        value: d.values[d.values.length - 1]
      };
    })
    .attr("transform", function (d) {
      return "translate(" + x(d.value.date) + "," + y(d.value.attackType) + ")";
    })
    .attr("x", 10)
    .attr("dy", ".35em")
  .attr("fill", function(d){return color(this.parentNode.__data__.name)})
    .text(function (d) {
      return d.name;
  });

// Add the mouse line
var mouseG = g.append("g")
  .attr("class", "mouse-over-effects");

mouseG.append("path")
  .attr("class", "mouse-line")
  .style("stroke", "rgba(255,255,255,.3)")
  .style("stroke-width", "1px")
  .style("opacity", "0");

var lines = document.getElementsByClassName('line');

var mousePerLine = mouseG.selectAll('.mouse-per-line')
  .data(attackTypes)
  .enter()
  .append("g")
  .attr("class", "mouse-per-line");

mousePerLine.append("circle")
  .attr("r", 5)
  .style("stroke", function (d) {
    return color(d.name);
  })
  // .style("fill", "none")
  .style("stroke-width", "2px")
  .style("opacity", "0");

mousePerLine.append("text")
    .attr("class", "hover-text")
    .attr("dy", "-1em")
    .attr("transform", "translate(10,3)")
    .attr("fill", function(d){return color(this.parentNode.__data__.name)});

// Append a rect to catch mouse movements on canvas
mouseG.append('svg:rect') 
  .attr('width', width) 
  .attr('height', height)
  .attr('fill', 'none')
  .attr('pointer-events', 'all')
  .on('mouseout', function () { // on mouse out hide line, circles and text
    d3.select(".mouse-line")
      .style("opacity", ".2");
    d3.selectAll(".mouse-per-line circle")
      .style("opacity", "0");
    d3.selectAll(".mouse-per-line text")
      .style("opacity", "0");
  })
  .on('mouseover', function () { // on mouse in show line, circles and text
    d3.select(".mouse-line")
      .style("opacity", "1");
    d3.selectAll(".mouse-per-line circle")
      .style("opacity", "1");
    d3.selectAll(".mouse-per-line text")
      .style("opacity", "1");
  })
  .on('mousemove', function () { // mouse moving over canvas
    var mouse = d3.mouse(this);

    d3.selectAll(".mouse-per-line")
      .attr("transform", function (d, i) {

        var xDate = x.invert(mouse[0]),
          bisect = d3.bisector(function (d) { return d.date; }).left;
        idx = bisect(d.values, xDate);

        d3.select(this).select('text')
          .text(y.invert(y(d.values[idx].attackType)).toFixed(0) );

        d3.select(".mouse-line")
          .attr("d", function () {
            var data = "M" + x(d.values[idx].date) + "," + height;
            data += " " + x(d.values[idx].date) + "," + 0;
            return data;
          });
        return "translate(" + x(d.values[idx].date) + "," + y(d.values[idx].attackType) + ")";
      });
  });
    
});

正在从此JSON文件读取数据:

[
   {
      “ Time”:“ 2017-05-03 23:17”,       “攻击”:19,       “ Bot”:0,       “ C2”:78,       “ Cdn”:20,       “恶意软件”:0    },    {
      “ Time”:“ 2017-05-04 20:18”,       “攻击”:21,       “ Bot”:0,       “ C2”:90,       “ Cdn”:24,       “恶意软件”:0    },    {
      “ Time”:“ 2017-05-05 19:11”,       “攻击”:20,       “ Bot”:11,       “ C2”:91,       “ Cdn”:24,       “恶意软件”:0    },    {
      “时间”:“ 2017-05-06 18:56”,       “攻击”:20,       “ Bot”:12,       “ C2”:92,       “ Cdn”:25,       “恶意软件”:0    },    {
      “时间”:“ 2017-05-09 0:50”,       “攻击”:21,       “ Bot”:20,       “ C2”:89,       “ Cdn”:28,       “恶意软件”:0    },    {
      “ Time”:“ 2017-05-09 2:15”,       “攻击”:21,       “ Bot”:20,       “ C2”:88,       “ Cdn”:28,       “恶意软件”:34    },    {
      “ Time”:“ 2017-05-09 23:59”,       “攻击”:22,       “ Bot”:17,       “ C2”:87,       “ Cdn”:30,       “恶意软件”:32    },    {
      “时间”:“ 2017-05-11 0:57”,       “攻击”:23,       “ Bot”:18,       “ C2”:86,       “ Cdn”:32,       “恶意软件”:34    },    {
      “ Time”:“ 2017-05-11 22:17”,       “攻击”:24,       “ Bot”:17,       “ C2”:87,       “ Cdn”:29,       “恶意软件”:34    },    {
      “时间”:“ 2017-05-12 1:55”,       “攻击”:24,       “ Bot”:17,       “ C2”:88,       “ Cdn”:30,       “恶意软件”:36    },    {
      “时间”:“ 2017-05-13 1:57”,       “攻击”:22,       “ Bot”:17,       “ C2”:85,       “ Cdn”:27,       “恶意软件”:33    },    {
      “时间”:“ 2017-05-14 15:32”,       “攻击”:23,       “ Bot”:17,       “ C2”:89,       “ Cdn”:28,       “恶意软件”:34    },    {
      “ Time”:“ 2017-05-14 23:34”,       “攻击”:23,       “ Bot”:17,       “ C2”:88,       “ Cdn”:28,       “恶意软件”:33    } ]

我正在使用d3的版本3。我希望能够过滤数据,以便一开始我们只显示“攻击”,“ C2”和“恶意软件”攻击类型,并可以选择最多显示2种类型。

我已在页面上添加了一组复选框,因此,如果可以使用那些很棒的复选框,则非常理想。我正在阅读d3中的过滤功能,但尚未成功运行它,并且没有太多时间来解决它,因此非常感谢收到任何指针:)

0 个答案:

没有答案
相关问题