d3条形图排序

时间:2017-08-08 15:41:14

标签: sorting d3.js bar-chart render

我有一个三条相互重叠的条形图。首先渲染灰色条形图,然后是鲑鱼一和蓝色条形图。但是当它们被排序时,这个顺序似乎随机变化,所以有时会在其他两个上面绘制一个灰色条,然后它们就看不到了。

解决方案: jsFiddle

以下是此问题的jsfiddle

<!DOCTYPE html>
<body>
  <div style="text-align:left;">
    <form id="form">
      <strong>Sort by: </strong><span class="clocktime-radio"><input type="radio" name="stack" checked value="clock">Clock time and place </span>
      <span class="racetime-radio"><input class="racetime-radio" type="radio" name="stack" value="race">Race time </span>
      <span class="handicap-radio"><input type="radio" name="stack" value="hand">Handicap  </span>
    </form>
  </div>
  <div id="race_graph">
  </div>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script>
    // set the dimensions and margins of the graph
    var margin = {
        top: 50,
        right: 50,
        bottom: 100,
        left: 80
      },
      width = 500 - margin.left - margin.right,
      height = 600 - margin.top - margin.bottom;

    // Get the data
    var data = [{
        "name": "RT",
        "clocktime": "21:33",
        "handicap": "02:30",
        "racetime": "19:03"
      },
      {
        "name": "KM",
        "clocktime": "22:13",
        "handicap": "00:45",
        "racetime": "21:28"
      },
      {
        "name": "SD",
        "clocktime": "22:15",
        "handicap": "01:45",
        "racetime": "20:30"
      },
      {
        "name": "DK",
        "clocktime": "22:20",
        "handicap": "02:45",
        "racetime": "19:35"
      },
      {
        "name": "BD",
        "clocktime": "22:21",
        "handicap": "02:15",
        "racetime": "20:06"
      },
      {
        "name": "KC",
        "clocktime": "22:21",
        "handicap": "02:00",
        "racetime": "20:21"
      },
      {
        "name": "PM",
        "clocktime": "22:22",
        "handicap": "00:45",
        "racetime": "21:37"
      },
      {
        "name": "NR",
        "clocktime": "22:23",
        "handicap": "01:45",
        "racetime": "20:38"
      },
      {
        "name": "LM",
        "clocktime": "22:25",
        "handicap": "02:15",
        "racetime": "20:10"
      },
      {
        "name": "SL",
        "clocktime": "22:26",
        "handicap": "00:15",
        "racetime": "22:11"
      }
    ]

    var parseTime = d3.timeParse("%M:%S");
    var timeformat = d3.timeFormat("%M:%S")

    // format the data
    data.forEach(function(d) {
      d.racetime = parseTime(d.racetime);
      d.handicap = parseTime(d.handicap);
      d.clocktime = parseTime(d.clocktime);
      d.place = +d.place;
      d.points = +d.points;
      d.raceplace = +d.raceplace;
      d.timeplace = +d.timeplace;
    });

    // set the domains and ranges
    var x = d3.scaleBand()
      .domain(data.map(function(d) {
        return d.name
      }))
      .range([0, width]);

    // temporal y-scale
    var y = d3.scaleTime()
      .domain([parseTime('00:00'), d3.max(data, function(d) {
        return d.clocktime
        // return d.handicap
      })])
      .range([height, 0]); //time must increase from 0 to height else racetime and handicap are inverted!!!

    // spacial y-scale (race distance)
    var y1 = d3.scaleLinear()
      .domain([0, 1200]) //race distance
      .range([height, 0]);

    // points y-scale
    var y2 = d3.scaleLinear()
      .domain([0, 10]) //points awarded
      .range([height, 0]);

    //****************************
    //***** Main Graph setup *****
    //****************************

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

    // Add the X Axis
    var xAxis = d3.axisBottom(x)
    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
      .selectAll("text")
      .style("text-anchor", "end")
      .style("font", "7px times")
      .attr("dx", "-.8em")
      .attr("dy", ".15em")
      .attr("transform", "rotate(-65)");

    // Add the left Y Axis
    svg.append("g")
      .attr("class", "axis")
      .call(d3.axisLeft(y)
        .ticks(7)
        .tickFormat(d3.timeFormat("%M:%S")));


    // text label for the y axis on left
    svg.append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 0 - margin.left)
      .attr("x", 0 - (height / 2))
      .attr("dy", "1em")
      .style("text-anchor", "middle")
      .text("Time (minutes:seconds)");

    //************************************************************
    //******* BarChart by clocktime *******************************
    //************************************************************

    var rects0 = svg.selectAll(".bar")
      .data(data);

    var newRects0 = rects0.enter();
    // Note: y2(d.points) is the y coordinate of rect
    newRects0.append('rect')
      .attr('x', function(d, i) {
        return x(d.name) + 2;
      })
      .attr('width', 20)
      .attr("transform", "translate(5,0)")
      .style('fill', 'gray')
      .attr("class", "bar")
      .attr('y', function(d, i) {
        return y(d.clocktime);
      })
      .attr('height', function(d, i) {
        return height - y(d.clocktime)
      });


    //************************************************************
    //******* BarChart by racetime *******************************
    //************************************************************

    var newRects1 = rects0.enter();

    // Note: y2(d.points) is the y coordinate of rect
    newRects1.append('rect')
      .attr('class', 'bar')
      .attr('x', function(d, i) {
        return x(d.name) + 2;
      })
      .attr('width', 20)
      .attr("transform", "translate(5,0)")
      .style('fill', 'salmon')
      .attr('y', function(d, i) {
        return y(d.racetime);
      })
      .attr('height', function(d, i) {
        return height - y(d.racetime)
      });

    //************************************************************
    //******* BarCharts by handicap ******************************
    //************************************************************
    var newRects2 = rects0.enter();

    newRects2.append('rect')
      .attr('x', function(d, i) {
        return x(d.name) + 2;
      })
      .attr('width', 20)
      .attr("transform", "translate(5,0)")
      .style('fill', 'blue')
      .attr('y', function(d, i) {
        return y(d.handicap);
      })
      .attr('height', function(d, i) {
        return height - y(d.handicap)
      })
      .attr('class', 'bar');

    d3.selectAll("input[name='stack']").on("change", change);

    function change() {

      var x0 = x.domain(data.sort(this.value == "clock" ?
          (function(a, b) {
            return (new Date(b.clocktime) - new Date(a.clocktime)) * -1;
          }) : (this.value == "race") ?
          (function(a, b) {
            return (new Date(b.racetime) - new Date(a.racetime)) * -1;
          }) : (function(a, b) {
            return (new Date(b.handicap) - new Date(a.handicap)) * -1;
          })).map(function(d) {
          return d.name;
        }))
        .copy();

      svg.selectAll(".bar")
        .sort(function(a, b) {
          return x0(a.name) - x0(b.name);
        });

      var transition = svg.transition().duration(750),
        delay = function(d, i) {
          return i * 5;
        };

      transition.selectAll(".bar")
        .delay(delay)
        .attr("x", function(d) {
          return x0(d.name);
        });

      transition.select(".x.axis") //selects the x-axis
        .call(xAxis)
        .selectAll("g")
        .delay(delay);
    }
  </script>
</body>

也许当我绘制多个条形图时,我不应该像我一样重复每个条形图,并且有一些方法可以更有效地绘制它们,这将摆脱我所拥有的渲染问题。

由于

0 个答案:

没有答案