基于x轴上的滑块日期更改图形

基于x轴上的滑块日期更改图形

本文介绍了更新:基于x轴上的滑块日期更改图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编辑了问题,现在的值已经解决了,以前的值不再反映在x轴上.现在,随着滑块的移动,数据在图中没有变化,我可以看到更改x值.

I have edited the question, earlier values were not reflecting on the x axis now that got resolved .Now as the slider moves the data doesn't change in the graph and i can see changing x values.

我正在尝试按照链接在d3中实现一个jquery滑块.该示例以以下格式生成一些随机数的数据:

I'm trying to implement a jquery slider in d3 following this link. The example is generating data of some random numbers while my data is in the below format:

{storeid: 5722646637445120, peoplesum: 87, date: "2018-06-03"}
{storeid: 5722646637445120, peoplesum: 90, date: "2018-06-04"}
{storeid: 5722646637445120, peoplesum: 114, date: "2018-06-05"}

我可以在移动滑块时触发事件,但是这些值现在未反映在图形上.因此,这意味着我的观点是无法正确更新SVG,这是我的假设.我在这里也可能是错的.

I'm able to trigger events when i move my slider but the values are not reflecting on the graph now. So that mean my view is not updating the SVG correctly which is my assumption. I could be wrong here as well.

我的x轴应该有日期范围,而y应该是peoplesum,它可以是单线图或多线图.

My x axis should have the date range and y should be peoplesum and it could be a single or a multiline graph.

更新代码:

private initSvg() {
    d3.select("svg").remove();
    this.svg = d3.select("#d3Id")
    .append("svg")
        .attr("width", this.width + this.margin.left + this.margin.right)
        .attr("height", this.height + this.margin.top + this.margin.bottom)
    .append("g")
        .attr("transform",
              "translate(" + this.margin.left + "," + this.margin.top + ")")
     .attr("stroke-width", 2);
  }
  private initAxis() {
    // Parse the date / time
    var parseDate = timeParse("%b %Y");
    this.formatTime = timeParse("%e %B");

    // Set the ranges
    this.x = d3Scale.scaleTime().range([0, this.width]);
    this.y = d3Scale.scaleLinear().range([this.height, 0]);
  }
  private drawAxis() {
      var X = this.x;
      var Y = this.y;
      this.xAxis = d3.axisBottom(this.x)
          .ticks(5);

      // var xAxis = d3.axisBottom(this.x).tickSize(-this.height).ticks(3);
      // // Add the x-axis.
      // this.svg.append("svg:g")
      //       .attr("class", "x axis")
      //       .attr("transform", "translate(0," + this.height + ")")
      //       .call(xAxis);

      this.yAxis = d3.axisLeft(this.y)
          .ticks(5);
      // Define the line
      this.priceline = d3Shape.line()
          .x(function (d) { return X(new Date(d['date'])); })
          .y(function (d) { return Y(d['peoplesum']); });
  }
  private drawLine() {
    if ( this.data[0]['d3_parameter_maker'] === true)
      {
       this.x.domain([0, d3.max(this.data, function (d) { return d['date']; })]);
      }
      else if ( this.data[0]['d3_parameter_maker'] === undefined)
      {
        //console.log("aksdad")
      var mindate = new Date(this.dashboard_date['startTime']),
          maxdate = new Date(this.dashboard_date['endTime']);
      this.x.domain([mindate,maxdate]);
      }

      console.log(new Date(this.dashboard_date['startTime']));

      // Scale the range of the data
      var svgVar = this.svg;
      var pricelineVar = this.priceline;
      var margin = this.margin;
      var height = this.height;
      let thisObj = this;
      this.mouseOver = [];
      let X = this.x;
      let Y = this.y;
      if ( this.mouseFlag < 0) {
        for ( let i = 0; i < this.peopleInSumArr.length; i++) {
            this.mouseOver[i] = true;
        }
      } else {
          for (let i = 0; i < this.peopleInSumArr.length; i++) {
              if (i !== this.mouseFlag) {
                this.mouseOver[i] = false;
              }
          }
          this.mouseOver[this.mouseFlag] = true;
      }
      this.y.domain([0, d3.max(this.data, function (d) { return d['peoplesum']; })]);
      // Nest the entries by symbol
      var dataNest = d3.nest()
          .key(function (d) { return d['storeid']; })
          .entries(this.data);
      // set the colour scale
      var color = d3.scaleOrdinal(d3.schemeCategory10);
      var legendSpace = this.width / dataNest.length; // spacing for the legend
      var div1 = d3.select("body").append("div")
          .attr("class", "tooltip")
          .style("opacity", 0);
      dataNest.forEach(function (data, i) {
          thisObj.svg.append("path")
              .attr("class", "line")
              .style("fill", "none")
              .attr("d", thisObj.priceline(data.values))
              .attr('opacity', thisObj.mouseOver !== undefined && thisObj.mouseOver[i] === true ? 1 : 0.2)
              .style('cursor', 'pointer')
              .style("stroke", function () { // Add the colours dynamically
                  return data['color'] = color(data.key);
              })
              .attr("stroke-width", 3)
              .on('click', function () { // on mouse in show line, circles and text
                  thisObj.mouseFlag = i;
                  thisObj.initSvg();
                  thisObj.initAxis();
                  thisObj.drawAxis();
                  thisObj.drawLine();
              });
          // Add the scatterplot
          thisObj.svg.selectAll("dot")
              .data(data.values)
              .enter().append("circle")
              .attr("r", 5)
              .attr("cx", function (d) { return thisObj.x(new Date(d.date)); })
              .attr("cy", function (d) { return thisObj.y(d.peoplesum); })
              .style('cursor', 'pointer')
              .on("mouseover", function (d) {
                  div1.transition()
                      .duration(200)
                      .style("opacity", .9);
                  // tslint:disable-next-line:no-unused-expression
                  div1.html("<b>Date: </b>" + d.date + "<br/>" + "<b>Sum: </b>" + d.peoplesum.toFixed(2))
                      .style('position', 'absolute')
                      .style("left", (d3.event.pageX) + "px")
                      .style("top", (d3.event.pageY - 28) + "px")
                      .style('text-align', 'center')
                      .style('width', '100px')
                      .style('height', '30px')
                      .style('padding', '2px')
                      .style('font', '12px sans-serif')
                      .style('background-color', 'lightsteelblue')
                      .style('border', '0px')
                      .style('border-radius', '8px')
                      .style('cursor', 'pointer')
                      .style('pointer-events', 'none');
              })
              .on("mouseout", function (d) {
                  div1.transition()
                      .duration(500)
                      .style("opacity", 0);
              });

          // Add the X Axis


          // Add the Y Axis

          thisObj.svg.append("text")
              .attr("x", (legendSpace / 2) + i * legendSpace)  // space legend
              .attr("y", height + (margin.bottom / 2) + 5)
              .attr("class", "legend")    // style the legend
              .style('cursor', 'pointer')
              .style("fill", function () { // Add the colours dynamically
                  return data['color'] = color(data.key);
              })
              .text(data.key)
              .attr("stroke-width", 3)
              .on('click', function () { // on mouse in show line, circles and text
                  thisObj.mouseFlag = i;
                  thisObj.initSvg();
                  thisObj.initAxis();
                  thisObj.drawAxis();
                  thisObj.drawLine();
              });
      });
      // Add the X Axis
      let xAxisSelection= this.svg.append("g")
          .attr("class", "x-axis")
          .attr("transform", "translate(0," + this.height + ")")

        xAxisSelection.call(d3.axisBottom(this.x));

      // Add the Y Axis

       let yAxisLeft =this.svg.append("g")
            .attr("class", "y axis")

            yAxisLeft.call(d3.axisLeft(this.y));

       var clip = this.svg.append("defs").append("svg:clipPath")
        .attr("id", "clip")
        .append("svg:rect")
        .attr("id", "clip-rect")
        .attr("x", "0")
        .attr("y", "0")
        .attr("width", this.width)
        .attr("height", this.height);


      // Add the line by appending an svg:path element with the data line we created above
      // do this AFTER the axes above so that the line is above the tick-lines
      var path = this.svg.append("svg")
        .attr("class","path")
        .attr("clip-path", "url(#clip)")
        .attr( thisObj.priceline(this.data));



    function zoom(begin, end) {
    thisObj.x.domain([begin, end - 1]);

    var t = thisObj.svg.transition().duration(0);

    var size = moment(moment(end).toDate()).diff(moment(begin).toDate(), 'days');
    console.log("size",size);
    var step = size / 10;
    var ticks = [];
    const startDate = new Date(moment(begin).toDate());
    for (var i = 0; i <= 10; i++) {
        var xAxisDate = new Date(moment(begin).toDate())
        // Add a day
        xAxisDate.setDate(startDate.getDate() + i)

        ticks.push(xAxisDate);
    }

    xAxisSelection.call(d3.axisBottom(thisObj.x.domain(d3.extent(ticks))));
  }

  //console.log("this.data)",this.data)
  $(function() {
        $( "#slider-range" ).slider({
            range: true,
           min: new Date(mindate).getTime() / 1000,
      max: new Date(maxdate).getTime() / 1000,
      step: 86400,
             values: [ new Date(mindate).getTime() / 1000, new Date(maxdate).getTime() / 1000 ],
            slide: function( event, ui ) {
              //console.log("ui.values[0]",ui.values)

              var begin = d3.min([(new Date(ui.values[ 0 ] *1000).toDateString() ), thisObj.data.length]);
              var end = new Date(ui.values[ 1 ] *1000).toDateString(); // 0]);
              //console.log("begin:", moment(begin).toDate(), "end:", moment(end).format('yyyy-mm-dd'), thisObj.data);
              console.log(begin);
              console.log(end);

              zoom(begin, end);
            }
        });
    });

    }
}

请在下面的图表屏幕截图中找到

Please find below the screenshot of the graph

推荐答案

添加剪切路径功能,因为数据超出了y轴.

Adding the clip path functionality because data was going beyond y axis.

    private initSvg() {
        d3.select("svg").remove();
        this.svg = d3.select("#d3Id")
            .append("svg")
            .attr("width", this.width + this.margin.left + this.margin.right)
            .attr("height", this.height + this.margin.top + this.margin.bottom)
            .append("g")
            .attr("transform",
                "translate(" + this.margin.left + "," + this.margin.top + ")")
            .attr("stroke-width", 2);
    }
    private initAxis() {
        // Parse the date / time
        // var parseDate = timeParse("%b %Y");
        // this.formatTime = timeParse("%e %B");

        // Set the ranges
        this.x = d3Scale.scaleTime().range([0, this.width]);
        this.y = d3Scale.scaleLinear().range([this.height, 0]);
    }
    private drawAxis() {
        var X = this.x;
        var Y = this.y;
        this.xAxis = d3.axisBottom(this.x)
            .ticks(5);

        // var xAxis = d3.axisBottom(this.x).tickSize(-this.height).ticks(3);
        // // Add the x-axis.
        // this.svg.append("svg:g")
        //       .attr("class", "x axis")
        //       .attr("transform", "translate(0," + this.height + ")")
        //       .call(xAxis);

        this.yAxis = d3.axisLeft(this.y)
            .ticks(5);
        // Define the line
        this.priceline = d3Shape.line()
            .x(function(d) {
                return X(new Date(d['date']));
            })
            .y(function(d) {
                return Y(d['peoplesum']);
            });
    }
    private drawLine() {

        if (this.data[0]['d3_parameter_maker'] === true) {
            this.x.domain([1, d3.max(this.data, function(d) {
                return parseInt(d['date']);
            })]);
        } else if (this.data[0]['d3_parameter_maker'] === undefined) {
            var mindate = new Date(this.dashboard_date['startTime']),
                maxdate = new Date(this.dashboard_date['endTime']);
            this.x.domain([mindate, maxdate]);
        }

        console.log(new Date(this.dashboard_date['startTime']));

        // Scale the range of the data
        var svgVar = this.svg;
        var pricelineVar = this.priceline;
        var margin = this.margin;
        var height = this.height;
        let thisObj = this;
        this.mouseOver = [];
        let X = this.x;
        let Y = this.y;
        if (this.mouseFlag < 0) {
            for (let i = 0; i < this.peopleInSumArr.length; i++) {
                this.mouseOver[i] = true;
            }
        } else {
            for (let i = 0; i < this.peopleInSumArr.length; i++) {
                if (i !== this.mouseFlag) {
                    this.mouseOver[i] = false;
                }
            }
            this.mouseOver[this.mouseFlag] = true;
        }
        this.y.domain([0, d3.max(this.data, function(d) {
            return d['peoplesum'];
        })]);

        var clip = thisObj.svg.append("defs").append("svg:clipPath")
            .attr("id", "clip")
            .append("svg:rect")
            .attr("id", "clip-rect")
            .attr("x", "0")
            .attr("y", "0")
            .attr("width", this.width)
            .attr("height", this.height);
        // Nest the entries by symbol
        var dataNest = d3.nest()
            .key(function(d) {
                return d['storeid'];
            })
            .entries(this.data);
        // set the colour scale
        var color = d3.scaleOrdinal(d3.schemeCategory10);
        var legendSpace = this.width / dataNest.length; // spacing for the legend
        var div1 = d3.select("body").append("div")
            .attr("class", "tooltip")
            .style("opacity", 0);
        dataNest.forEach(function(data, i) {
            thisObj.svg.append("path")
                .attr("class", "line")
                .style("fill", "none")
                .datum(data)
                .attr("d", function(d) {
                    return thisObj.priceline(d.values);
                })
                .attr('opacity', thisObj.mouseOver !== undefined && thisObj.mouseOver[i] === true ? 1 : 0.2)
                .style('cursor', 'pointer')
                .style("stroke", function() { // Add the colours dynamically
                    return data['color'] = color(data.key);
                })
                .attr("stroke-width", 3)
                .attr("clip-path", "url(#clip)")
                .on('click', function() { // on mouse in show line, circles and text
                    thisObj.mouseFlag = i;
                    thisObj.initSvg();
                    thisObj.initAxis();
                    thisObj.drawAxis();
                    thisObj.drawLine();
                });
            // Add the scatterplot
            thisObj.svg.selectAll("dot")
                .data(data.values)
                .enter().append("circle")
                .attr("r", 5)
                .attr("cx", function(d) {
                    return thisObj.x(new Date(d.date));
                })
                .attr("cy", function(d) {
                    return thisObj.y(d.peoplesum);
                })
                .style('cursor', 'pointer')
                .on("mouseover", function(d) {
                    div1.transition()
                        .duration(200)
                        .style("opacity", .9);
                    // tslint:disable-next-line:no-unused-expression
                    div1.html("<b>Date: </b>" + d.date + "<br/>" + "<b>Sum: </b>" + d.peoplesum.toFixed(2))
                        .style('position', 'absolute')
                        .style("left", (d3.event.pageX) + "px")
                        .style("top", (d3.event.pageY - 28) + "px")
                        .style('text-align', 'center')
                        .style('width', '100px')
                        .style('height', '30px')
                        .style('padding', '2px')
                        .style('font', '12px sans-serif')
                        .style('background-color', 'lightsteelblue')
                        .style('border', '0px')
                        .style('border-radius', '8px')
                        .style('cursor', 'pointer')
                        .style('pointer-events', 'none');
                })
                .on("mouseout", function(d) {
                    div1.transition()
                        .duration(500)
                        .style("opacity", 0);
                });

            // Add the X Axis


            // Add the Y Axis

            thisObj.svg.append("text")
                .attr("x", (legendSpace / 2) + i * legendSpace) // space legend
                .attr("y", height + (margin.bottom / 2) + 5)
                .attr("class", "legend") // style the legend
                .style('cursor', 'pointer')
                .style("fill", function() { // Add the colours dynamically
                    return data['color'] = color(data.key);
                })
                .text(data.key)
                .attr("stroke-width", 3)
                .on('click', function() { // on mouse in show line, circles and text
                    thisObj.mouseFlag = i;
                    thisObj.initSvg();
                    thisObj.initAxis();
                    thisObj.drawAxis();
                    thisObj.drawLine();
                });
        });
        // Add the X Axis
        let xAxisSelection = this.svg.append("g")
            .attr("class", "x-axis")
            .attr("transform", "translate(0," + this.height + ")")

        xAxisSelection.call(d3.axisBottom(this.x));

        // Add the Y Axis
        this.svg.append("g")
            .attr("class", "axis")
            .call(d3.axisLeft(this.y));
        if (this.data[0]['d3_parameter_maker'] === undefined)
        {
          this.daily_Data_slider(mindate,xAxisSelection,maxdate)
        }
       else
        {
          this.hourly_Data_slider(xAxisSelection)
        }
   }

  private daily_Data_slider(mindate,xAxisSelection,maxdate){
    var svgVar = this.svg;
        var pricelineVar = this.priceline;
        var margin = this.margin;
        var height = this.height;
        let thisObj = this;
    function zoom(begin, end) {

            thisObj.x.domain([new Date(begin), new Date(end)]);
            var t = thisObj.svg.transition().duration(0);

            var size = moment(moment(end).toDate()).diff(moment(begin).toDate(), 'days');
            console.log("size", size);
            var step = size / 10;
            var ticks = [];
            const startDate = new Date(moment(begin).toDate());
            for (var i = 0; i <= 10; i++) {
                var xAxisDate = new Date(moment(begin).toDate())
                // Add a day
                xAxisDate.setDate(startDate.getDate() + i)

                ticks.push(xAxisDate);
            }

            xAxisSelection.call(d3.axisBottom(thisObj.x.domain(d3.extent(ticks))));
            // Redraw the line:
            d3.selectAll("circle")
                .attr("cx", function(d) {
                    return thisObj.x(new Date(d.date));
                })
                .attr("cy", function(d) {
                    return thisObj.y(d.peoplesum);
                })

            d3.selectAll(".line").attr("d", function(d) {
                return thisObj.priceline(d.values);
            })
        }

        //console.log("this.data)",this.data)
        $(function() {
            $("#slider-range").slider({
                range: true,
                min: new Date(mindate).getTime() / 1000,
                max: new Date(maxdate).getTime() / 1000,
                step: 86400,
                values: [new Date(mindate).getTime() / 1000, new Date(maxdate).getTime() / 1000],
                slide: function(event, ui) {
                    //console.log("ui.values[0]",ui.values)

                    var begin = d3.min([(new Date(ui.values[0] * 1000).toDateString()), thisObj.data.length]);
                    var end = new Date(ui.values[1] * 1000).toDateString(); // 0]);
                    //console.log("begin:", moment(begin).toDate(), "end:", moment(end).format('yyyy-mm-dd'), thisObj.data);
                    console.log("begin", begin);
                    console.log("end", end);

                    if (new Date(moment(moment(moment(begin).toDate()).add(10, 'days')).format("YYYY-MM-DD")) <= new Date(end)) {
                        zoom(begin, end);
                    }

                }
            });
        });
  }

这篇关于更新:基于x轴上的滑块日期更改图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 05:22