计算连续蓝条的数量,直到悬停条

Art*_*iga 6 html javascript css d3.js

我需要计算蓝条的最长条纹,直到我们正在悬停的条形图,通过以下代码获得的条形图:在此输入图像描述

例如,如果我悬停在第一个条(红色)上,最长条纹应显示0,第二个悬停(也是红色)也为0.当悬停在第三个蓝色条上时,它应显示1.直到我们在条形图上方悬停18号它应该显示最长条纹为2.从20开始,有两个以上连续的蓝调条,它就说3.即使我在21号栏上盘旋,它仍然应该显示最长条纹为3,它应该继续显示,直到连续出现四个或更多数量的蓝条.

body {
  font: 10px sans-serif;
}

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

.bar {
  fill: orange;
}

.bar:hover {
  fill: cyan ;
}

.x.axis path {
  display: none;
}

    .grid .tick {
        stroke: lightgrey;
        opacity: 0.7;
    }

    .grid path {
        stroke-width: 0;
    }

.d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 12px;
  background: rgba(0, 0, 0, 0.8);
  color: cyan;
  border-radius: 2px;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: rgba(0, 0, 0, 0.8);
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>

var margin = {top: 40, right: 20, bottom: 50, left: 70},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var formatPercent = d3.format(".0%");

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .5);

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

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

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


var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
      return "<strong>Time Used:</strong> <span style='color:cyan'>" + d.frequency + "</span>" + "<br/>" + "<strong>Longest Streak:</strong> <span>" + (d.criteria.match(/lightblue/g) || []).length+"</span>";
  })

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 + ")");

svg.call(tip);

function make_y_axis() {
    return d3.svg.axis()
        .scale(y)
        .orient("left")
        .ticks(10)
}
d3.tsv("pass_fail_bars_data.tsv", type, function (error, data) {
  x.domain(data.map(function(d) { return d.problem_number; }));
  y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("x", -height / 3)
     .attr("y", -50)
     .attr("dy", ".71em")
     .style("text-anchor", "end")
      .text("Time Used (Seconds)");
  svg.append("g")
  .attr("class", "grid")
  .call(make_y_axis()
      .tickSize(-width, 0, 0)
      .tickFormat("")
  )

  svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis)
 .append("text")
 .attr("transform", "rotate(0)")
 .attr("x", width / 2)
  .attr("y", 40)
 .attr("dx", "1em")
 .style("text-anchor", "middle")
 .text("Problem #")
 .attr("fill", "blue");



  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function (d) { return x(d.problem_number); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.frequency); })
      .attr("height", function (d) { return height - y(d.frequency); })
      .style("fill", function(d) { return d.criteria; })
      .on('mouseover', tip.show)
      .on('mouseout', tip.hide)

});

function type(d) {
  d.frequency = +d.frequency;
  return d;
}

</script>
Run Code Online (Sandbox Code Playgroud)

目前它只显示当前的蓝条数.也就是说,如果我将鼠标悬停在蓝色条上,它只计算该条形,并显示最长条纹为1.在这种情况下是真的,但当我将鼠标悬停在条形码#20上时,它也会显示"最长条纹",因为它应该显示为1为3.

任何建议如何进一步修改此代码以获得所需的结果?

这是我使用的数据"pass_fail_bars_data.tsv"

problem_number  frequency   criteria    
1   08167   "red"
2   01492   "red"
3   02780   "lightblue"
4   04253   "red"
5   12702   "red"
6   02288   "lightblue"
7   02022   "red"
8   06094   "red"
9   06973   "lightblue"
10  00153   "lightblue"
11  00747   "red"
12  04025   "red"
13  02517   "lightblue"
14  06749   "red"
15  07507   "lightblue"
16  01929   "red"
17  00098   "red"
18  05987   "lightblue"
19  06333   "lightblue"
20  09056   "lightblue"
21  02758   "red"
22  01037   "lightblue"
23  02465   "lightblue"
24  00150   "red"
25  01971   "lightblue"
26  00074   "lightblue"
Run Code Online (Sandbox Code Playgroud)

Cyr*_*ian 4

您可以通过创建一个小的 for 循环来计算条纹并将其设置在数据中来完成此操作。

像这样的东西:

d3.tsv("my.tsv", type, function (error, data) {
  var count = 0;

  var longestStreak = 0;
  data.forEach(function(d){
    if (d.criteria  == "lightblue"){
      count++;
    } else {
      count  = 0;//reset the count
    }
    if (count > longestStreak){
      longestStreak = count;//set the new streak.
    }

    d.streak = longestStreak;
  });
Run Code Online (Sandbox Code Playgroud)

然后在tip函数中你可以返回条纹而不是计算它。

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
      console.log(d)
      return "<strong>Time Used:</strong> <span style='color:cyan'>" + d.frequency + "</span>" + "<br/>" + "<strong>Longest Streak:</strong> <span>" + d.streak+"</span>";
  })
Run Code Online (Sandbox Code Playgroud)

工作代码在这里

希望这可以帮助!