代码之家  ›  专栏  ›  技术社区  ›  SiddP

缺少点和线的不完整折线图

  •  2
  • SiddP  · 技术社区  · 10 年前
    var maindata=[
    {"date":"21-APR-16 04:19 AM","Delhi":30,"Mumbai":28},
    {"date":"21-APR-16 05:19 AM","Delhi":32,"Mumbai":30},
    {"date":"21-APR-16 06:19 AM","Delhi":34,"Mumbai":34},
    {"date":"21-APR-16 10:19 AM","Kolkata":34},
    {"date":"21-APR-16 11:19 AM","Delhi":48,"Chennai":40,"Kolkata":36}
    ];
    
    
                var that = this;
                var deepClonedCopy = jQuery.extend(true, {}, maindata);
                var data;
                data = $.map(deepClonedCopy, function(el) { return el });
                //  var passedheight = this.getHeight();
                //var containerWidth = jQuery.sap.byId(this.oParent.sId).width() || 800; // gets super parent width
                var margin = {top: 15, right: 30, bottom: 20, left: 30},
                width = 960- margin.left - margin.right,
                 height = 500 - margin.top - margin.bottom;
                if(data.length >= 1){
                    //alert(JSON.stringify(data));
                var parseDate = d3.time.format("%d-%b-%y %H:%M %p").parse;
                var maxDate = d3.time.hour.offset(parseDate(d3.max(data, function(d) { return d.date; })),+1);
                var minDate = d3.time.hour.offset(parseDate(d3.min(data, function(d) { return d.date; })),-1);
    
                var div = d3.select("#toolTip");
    
                var x = d3.time.scale()
                .domain([minDate, maxDate])
                .range([0, width]);
    
                var y = d3.scale.linear()
                    .range([Math.ceil(height), 0]);
    
                var color = d3.scale.category10();
    
                var xAxis = d3.svg.axis()
                    .scale(x)
                    .orient("bottom").ticks(4);
    
                var yAxis = d3.svg.axis()
                    .scale(y)
                    .orient("left").ticks(4).tickSize(-width, 0, 0);
    
                var line = d3.svg.line()
                    .x(function(d) { return x(d.date); })
                    .y(function(d) { return y(d.tonneValue); });
    
                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 + ")");
    
                  color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date" && key !== "maxLength"; }));
    
                  data.forEach(function(d) {
                    d.date = parseDate(d.date);
                  });
    
                  var wsfs = color.domain().map(function(name) {
                    return {
                      name: name,
                      values: data.map(function(d) {
                        return {date: d.date, tonneValue: +d[name]};
                      })
                    };
                  });
    
                  //x.domain(d3.extent(data, function(d) { return d.date; }));
    
                  y.domain([
                    //d3.min(wsfs, function(c) { return d3.min(c.values, function(v) { return v.tonneValue; }); }),
                    0,
                    Math.ceil(d3.max(wsfs, function(c) { return d3.max(c.values, function(v) { return v.tonneValue; }); }))
                  ]);
    
                  svg.append("g")
                      .attr("class", "x axis")
                      .attr("transform", "translate(0," + height + ")")
                      .call(xAxis);
    
                  svg.append("g")
                      .attr("class", "y axis")
                      .call(yAxis);
    
                  var wsf = svg.selectAll(".wsf")
                      .data(wsfs)
                      .enter().append("g")
                      .attr("class", "wsf");
    
                  wsf.append("path")
                      .attr("class", "line")
                      .attr("d", function(d) { return line(d.values); })
                      .style("stroke", function(d) { return color(d.name); });
                  wsf.selectAll("dot")                                  
                     .data(function(d) { return d.values;})                                         
                     .enter().append("circle")
                     .attr("class", "dot")
                     .attr("r", 3)  
                     .attr("cx", function(d) { return x(d.date); })      
                     .attr("cy", function(d) { return y(d.tonneValue); })
                     .attr("stroke", function (d) {
                            return color(this.parentNode.__data__.name) })
                     .attr("fill", function (d) {
                            return color(this.parentNode.__data__.name) })
                     //.attr("fill-opacity", .5)
                     //.attr("stroke-width", 2)
                     .on("mouseover", function (d) {
                         formatDate = d3.time.format("%d-%m-%Y %H:%M %p");
                            div.transition().duration(100).style("opacity", .9);
                            div.html(/*this.parentNode.__data__.name + "<br/>" +*/ d.tonneValue /*+ "<br/>" + "<br/>"*/ +" Tonne handled at "+ formatDate(d.date))
                            .style("left", (d3.event.pageX) + "px").style("top", (d3.event.pageY - 28) + "px").attr('r', 8);
                            d3.select(this).attr('r', 8)
                        }).on("mouseout", function (d) {
                            div.transition().duration(600).style("opacity", 0)
                            d3.select(this).attr('r', 3);
                        });
                  var legendNames = d3.keys(data[0]).filter(function(key) { return key !== "date" });
    
                  data.forEach(function(d) {
                    d.ages = legendNames.map(function(name) { return {name: name, value: +d[name]}; });
                  });
                 var legend = svg.selectAll(".legend")
                      .data(legendNames.slice())
                    .enter().append("g")
                      .attr("class", "legend")
                      .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
    
                  legend.append("rect")
                      .attr("x", width - 18)
                      .attr("width", 18)
                      .attr("height", 4)
                      .style("fill", function(d) {return color(d); });
    
                  legend.append("text")
                      .attr("x", width - 24)
                      .attr("y", 6)
                      .attr("dy", ".35em")
                      .style("text-anchor", "end")
                      .text(function(d) {  return d; });
                }
    

    上面的代码给出了2行,直到前3个json元素,直到数据格式相似。
    但从第四个元素来看没有 Delhi / Mumbai 还有就是 Kolkata ,但我找不到 加尔各答 34, 加尔各答 36两者都不是 德里 48分,其中 德里 的线应该从34延伸到48,金奈应该是一个简单的点,因为金奈只有一个点,即40。
    谁能告诉我哪里做错了。这里有一个 fiddle .

    2 回复  |  直到 10 年前
        1
  •  1
  •   Cyril Cherian    10 年前

    代码中的主要问题(缺少行和点以及不完整的图例)是您的数据需要一些结构化。

    您的数据集有时包含可能存在或不存在的城市。

    因此,第一个任务是创建一个适当的数据集

    由此:

    var maindata = [{
      "date": "21-APR-16 04:19 AM",
      "Delhi": 30,
      "Mumbai": 28
    }, {
      "date": "21-APR-16 05:19 AM",
      "Delhi": 32,
      "Mumbai": 30
    }, {
      "date": "21-APR-16 06:19 AM",
      "Delhi": 34,
      "Mumbai": 34
    }, {
      "date": "21-APR-16 10:19 AM",
      "Kolkata": 34
    }, {
      "date": "21-APR-16 11:19 AM",
      "Delhi": 48,
      "Chennai": 40,
      "Kolkata": 36
    }];
    

    为此:

    [
       {
          "name":"Delhi",
          "values":[
             {
                "date":"2016-04-20T22:49:00.000Z",
                "value":30
             },
             {
                "date":"2016-04-20T23:49:00.000Z",
                "value":32
             },
             {
                "date":"2016-04-21T00:49:00.000Z",
                "value":34
             },
             {
                "date":"2016-04-21T05:49:00.000Z",
                "value":48
             }
          ]
       },
       {
          "name":"Mumbai",
          "values":[
             {
                "date":"2016-04-20T22:49:00.000Z",
                "value":28
             },
             {
                "date":"2016-04-20T23:49:00.000Z",
                "value":30
             },
             {
                "date":"2016-04-21T00:49:00.000Z",
                "value":34
             }
          ]
       },
       {
          "name":"Kolkata",
          "values":[
             {
                "date":"2016-04-21T04:49:00.000Z",
                "value":34
             },
             {
                "date":"2016-04-21T05:49:00.000Z",
                "value":36
             }
          ]
       },
       {
          "name":"Chennai",
          "values":[
             {
                "date":"2016-04-21T05:49:00.000Z",
                "value":40
             }
          ]
       }
    ]
    

    所以现在所有城市都有各自的数据。 城市数量x,因此线路数量将为x。

    要使数据集执行此操作,请执行以下操作:

    var cities = []
    var parseDate = d3.time.format("%d-%b-%y %H:%M %p").parse;
    maindata.forEach(function(d) {
      cities.push(d3.keys(d).filter(function(key) {
          return key !== "date" && key !== "maxLength";
        }));
      });
    cities = d3.set(d3.merge(cities)).values();//get all  cites and make it unique
    console.log(cities)
    var myData = [];
    var allValues = [];
    var allDates =[];
    //generate cities and its values as shown in my dataset above.
    cities.forEach(function(city){
        var cityData = {};
        cityData.name = city;
        cityData.values = [];
        maindata.forEach(function(md){
            if (md[city]){
              allValues.push(md[city])
                allDates.push(parseDate(md.date))
                cityData.values.push({date: parseDate(md.date), value: md[city]})
            }
        })
        myData.push(cityData)
    });
    

    接下来像这样画线:

      var wsf = svg.selectAll(".wsf")
        .data(myData)
        .enter().append("g")
        .attr("class", "wsf");
    
      wsf.append("path")
        .attr("class", "line")
        .attr("d", function(d) {
          return line(d.values);
        })
        .style("stroke", function(d) {
          return color(d.name);
        });
    

    还有这样的传说:

      var legend = svg.selectAll(".legend")
        .data(cities)
        .enter().append("g")
        .attr("class", "legend")
        .attr("transform", function(d, i) {
          return "translate(0," + i * 20 + ")";
        });
    
      legend.append("rect")
        .attr("x", width - 18)
        .attr("width", 18)
        .attr("height", 4)
        .style("fill", function(d) {
          return color(d);
        });
    
      legend.append("text")
        .attr("x", width - 24)
        .attr("y", 6)
        .attr("dy", ".35em")
        .style("text-anchor", "end")
        .text(function(d) {
          return d;
        });
    }
    

    工作代码 here

        2
  •  1
  •   David Guan    10 年前

    这是最新的 fiddle

    一些键(即。 Kolkata )不包含在绑定数据中

    原始代码:

              color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date" && key !== "maxLength"; }));
    
              data.forEach(function(d) {
                d.date = parseDate(d.date);
              });
    
              var wsfs = color.domain().map(function(name) {
                return {
                  name: name,
                  values: data.map(function(d) {
                    return {date: d.date, tonneValue: +d[name]};
                  })
                };
              });
    

    至(您需要更改 ['Delhi', 'Mumbai', 'Kolkata', 'Chennai'] 进行更正式的编码):

              var wsfs = ['Delhi', 'Mumbai', 'Kolkata', 'Chennai'].map(function(name) {
                return {
                  name: name,
                  values: data.map(function(d) {
                    return {date: d.date, tonneValue: +d[name]};
                  }).filter(function(d) {
                return !isNaN(d.tonneValue)
            })
                };
              });
    

    过滤器数据
    原始代码:

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

    收件人:

              var wsfs = ['Delhi', 'Mumbai', 'Kolkata', 'Chennai'].map(function(name) {
                return {
                  name: name,
                  values: data.map(function(d) {
                    return {date: d.date, tonneValue: +d[name]};
                  }).filter(function(d) {
                    return !isNaN(d.tonneValue)
                })};
              });