d3创建一个缺少数据点的区域图,并且define()不起作用

时间:2019-06-04 09:50:39

标签: javascript d3.js

我正在使用d3(也许是v4)创建面积图。在数据库中,它有一些数据点没有我想要的键。我的意思是它缺少数据,这导致我无法使用所有数据创建面积图。

我已经尝试使用以下代码删除缺少数据的数据点,但是它不起作用:

drawAirVisualData(data) {

    var divE = document.createElement("div");
    var divId = document.createAttribute('id');
    divId.value = 'AirVisualDiv';
    divE.setAttributeNode(divId);
    divE.style.textAlign = "center";
    var title = document.createElement("text");
    title.style.lineHeight = "40px";
    title.style.fontSize = "20px";
    title.textContent = "Air Visual";

    document.getElementById('chartDiv').appendChild(divE);
    document.getElementById('AirVisualDiv').appendChild(title);

    // for each chart, the x and xAxis are same, the y and yAxis are always changed.

  var width = w - margin.left - margin.right,
        height = (h - margin.top) / 9;

  var parseTime = d3.time.format.utc("%H:%M").parse,
    midnight = parseTime("00:00");

  var x = d3.time.scale.utc()
      .domain([midnight, d3.time.day.utc.offset(midnight,1)])
      .range([0, width]);

  var xAxis =  d3.svg.axis().scale(x)
    .orient("bottom").ticks(25).tickFormat(d3.time.format.utc("%I %p"));

    //---------------------------- chart 1-------------------------------
    var y = d3.scale.linear()
        .range([height, 0])
        .domain([0, 100]);
    var yAxis = d3.svg.axis().scale(y)
        .orient("left").ticks(10);


    var areaInHumidity = d3.svg.area()
      .defined(function (d) {
        return d.y1 != null;
      })
        .x(function (d) {
          var time = new Date(d.created_at);
          return x(time);
        })
        .y0(height)
        .y1(function (d, i) {
            var humidity = d.data["current"].hm;
            return y(humidity);
        });

    var areaOutHumidity = d3.svg.area()
      .defined(function (d) {
        return d.y1 != null;
      })
      .x(function (d) {
         var time = new Date(d.created_at);
         var dayTime = time.getHours() + time.getMinutes() / 60 + time.getSeconds() / 3600;
         return x(dayTime);
        })
        .y0(height)
        .y1(function (d) {
            var humidity = d.data.outdoor_weather.hu;
            return y(humidity);
        });

    var chart1 = d3.select("#AirVisualDiv")
        .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr('id', 'HumidityChart')
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // Add legend
    chart1.append('text').text('Outdoor Humidity - Indoor Humidity').attr("x", width / 2).attr("y", 0).attr("text-anchor", "middle");
    chart1.append("circle").attr("cx", width * 7 / 10).attr("cy", 10).attr("r", 6)
        .style({
            'fill': "#0d7dfa",
            'opacity': 0.2
        });
    chart1.append("circle").attr("cx", width * 8 / 10).attr("cy", 10).attr("r", 6)
        .style({
            'fill': "#0d7dfa",
            'opacity': 0.6
        });
    chart1.append("text").attr("x", (width * 7 / 10) + 14).attr("y", 10).text("Indoor Humidity").style("font-size", "12px").attr("alignment-baseline", "middle");
    chart1.append("text").attr("x", (width * 8 / 10) + 14).attr("y", 10).text("Outdoor Humidity").style("font-size", "12px").attr("alignment-baseline", "middle");



  chart1.append("g")
    .attr("class", "axisLine")
    .style("font", "12px centralesanscndlight")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);


  // Add the X Axis
    chart1.append("g")
        .style("font", "12px centralesanscndlight")
        .style('stroke-width', 1)
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    // Add the Y Axis
    chart1.append("g")
        .attr("class", "axisLine")
        .style("font", "12px centralesanscndlight")
        .call(yAxis);

    // Add area for indoor humidity
    chart1.append('path')
        .attr({
            'd': areaInHumidity(data),
            'fill': '#0d7dfa',
            'opacity': 0.2
        });

    // Add area for outdoor humidity
    chart1.append('path')
        .attr({
            'd': areaOutHumidity(data),
            'fill': '#0d7dfa',
            'opacity': 0.6
        });

    //---------------------------- chart 2-------------------------------
    var y2 = d3.scale.linear()
        .range([height, 0])
        .domain([0, 50]);
    var yAxis2 = d3.svg.axis().scale(y2)
        .orient("left").ticks(10);

    var areaInTemp = d3.svg.area()
      .defined(function (d) {
        return d.y != null;
      })
        .x(function (d) {
            var time = new Date(d.created_at);
            var dayTime = time.getHours() + time.getMinutes() / 60 + time.getSeconds() / 3600;
            return x(dayTime);
        })
        .y0(height)
        .y1(function (d) {
            var temperature = d.data.current.tp;
            return y2(temperature);
        });

    var areaOutTemp = d3.svg.area()
      .defined(function (d) {
        return d.y != null;
      })
        .x(function (d) {
            var time = new Date(d.created_at);
            var dayTime = time.getHours() + time.getMinutes() / 60 + time.getSeconds() / 3600;
            return x(dayTime);
        })
        .y0(height)
        .y1(function (d) {
            var temperature = d.data.outdoor_weather.tp;
            return y2(temperature);
        });

    var chart2 = d3.select("#AirVisualDiv")
        .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 + ")");

    chart2.append('text').text('Outdoor Temperature - Indoor Temperature').attr("x", width / 2).attr("y", 0).attr("text-anchor", "middle");

    // Add legend
    chart2.append("circle").attr("cx", width * 7 / 10).attr("cy", 10).attr("r", 6)
        .style({
            'fill': "#f26100"
        });
    chart2.append("circle").attr("cx", width * 8 / 10).attr("cy", 10).attr("r", 6)
        .style({
            'fill': "#ff9b00"
        });
    chart2.append("text").attr("x", (width * 7 / 10) + 14).attr("y", 10).text("Indoor Temperature").style("font-size", "12px").attr("alignment-baseline", "middle");
    chart2.append("text").attr("x", (width * 8 / 10) + 14).attr("y", 10).text("Outdoor Temperature").style("font-size", "12px").attr("alignment-baseline", "middle");

    // Add the X Axis
    chart2.append("g")
        .attr("class", "axisLine")
        .style("font", "12px centralesanscndlight")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    // Add the Y Axis
    chart2.append("g")
        .attr("class", "axisLine")
        .style("font", "12px centralesanscndlight")
        .call(yAxis2);

    // Add area for indoor humidity
    chart2.append('path')
        .attr({
            'd': areaInTemp(data),
            'fill': orange,
            'opacity': 0.5
        });

    // Add area for outdoor humidity
    chart2.append('path')
        .attr({
            'd': areaOutTemp(data),
            'fill': lightorange,
            'opacity': 0.5
        });

    //---------------------------- chart 3-------------------------------
    var y3 = d3.scale.linear()
        .range([height, 0])
        .domain([0, 1000]);
    var yAxis3 = d3.svg.axis().scale(y3)
        .orient("left").ticks(10);

    var coLine = d3.svg.line()
      .defined(function (d) {
        return d.y != null;
      })
        .x(function (d) {
            var time = new Date(d.created_at);
            var dayTime = time.getHours() + time.getMinutes() / 60 + time.getSeconds() / 3600;
            return x(dayTime);
        })
        .y(function (d) {
            var co = d.data.current.co;
            return y3(co);
        });

    var chart3 = d3.select("#AirVisualDiv")
        .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 + ")");

    chart3.append('text').text('CO2 Level').attr("x", width / 2).attr("y", 0).attr("text-anchor", "middle");

    // Add the X Axis
    chart3.append("g")
        .attr("class", "axisLine")
        .style("font", "12px centralesanscndlight")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    // Add the Y Axis
    chart3.append("g")
        .attr("class", "axisLine")
        .style("font", "12px centralesanscndlight")
        .call(yAxis3);

    // Add line for co2
    chart3.append('path')
        .attr({
            'd': coLine(data),
            'stroke': grey,
            'stroke-width': '1.5px',
            'fill': 'none'
        });

    //---------------------------- chart 4-------------------------------
    var y4 = d3.scale.linear()
        .range([height, 0])
        .domain([0, 50]);
    var yAxis4 = d3.svg.axis().scale(y4)
        .orient("left").ticks(10);

    var p2Line = d3.svg.line()
      .defined(function (d) {
        return d.y != null;
      })
        .x(function (d) {
            var time = new Date(d.created_at);
            var dayTime = time.getHours() + time.getMinutes() / 60 + time.getSeconds() / 3600;
            return x(dayTime);
        })
        .y(function (d) {
            var p2 = d.data.current.p2;
            return y4(p2);
        });

    var chart4 = d3.select("#AirVisualDiv")
        .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 + ")");

    chart4.append('text').text('PM 2.5 Level').attr("x", width / 2).attr("y", 0).attr("text-anchor", "middle");

    // Add the X Axis
    chart4.append("g")
        .attr("class", "axisLine")
        .style("font", "12px centralesanscndlight")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    // Add the Y Axis
    chart4.append("g")
        .attr("class", "axisLine")
        .style("font", "12px centralesanscndlight")
        .call(yAxis4);

    // Add line for co2
    chart4.append('path')
        .attr({
            'd': p2Line(data),
            'stroke': grey,
            'stroke-width': '1.5px',
            'fill': 'none'
        });
}

正常数据点如下:

{clusterAliases: ["dlab"]
created_at: "2019-06-04T05:15:18.794Z"
data:{
 current:{
    co: 429,
    hm: 62,
    p01: 17,
    p1: 25,
    p2: 22,
    tp: 22.7834,
    ts: "2019-06-04T05:10:10.646Z",
    __proto__: Object},
outdoor_station: {
    p1: {…}, 
    api_id: 1646, 
    ts: "2019-06-04T04:00:00.000Z", 
    p2: {…}, 
    mainus: "p2"},
outdoor_weather: {
    wd: 0, 
    hu: 40, 
    ic: "01d", 
    ts: "2019-06-04T05:00:00.000Z", 
    tp: 33,
    __proto__: Object},
identifier: "54:C9:DF:E3:AE:19",
meta: {version: 0},
type: "AQI_STATUS",
updated_at: "2019-06-04T05:15:18.808Z",
__v: 1,
_id: "5cf5fe661d9b1900213c98ec",
__proto__: Object}

缺少的数据点看起来像:

{clusterAliases: ["dlab"]
created_at: "2019-06-04T05:13:50.977Z"
data:{
    message: "HTTPSConnectionPool(host='www.airvisual.com', port=443): Read timed out. (read timeout=10)"
    status: "ERROR",
    __proto__: Object
    },
identifier: "54:C9:DF:E3:AE:19",
meta: {version: 0},
type: "ERROR",
updated_at: "2019-06-04T05:13:50.990Z",
__v: 1,
_id: "5cf5fe0e1d9b1900213c98e5",
__proto__: Object}

正常数据点和丢失数据点之间的最大区别在于丢失数据点,它在数据下没有“当前”键,并且其类型显示为“ ERROR”。在用于创建面积图之前,我已经尝试删除此数据点,但是无法将其删除。因此我也尝试使用defined()来克服它,但是它不起作用。有人知道如何通过d3克服或删除面积图中丢失的数据点吗?谢谢。

1 个答案:

答案 0 :(得分:0)

“例如,我检查了d3 API,并注意到'''defined()'''必须至少具有该值的键。” ''' 数据{   温度:65,   湿度:无 } ''' “这种数据丢失可以通过“'''define()'''解决 “但是,当缺少密钥(在我们的情况下为湿度)时,'''defined()'''将无法克服丢失的数据。为解决此问题,我目前的解决方案是检查它是否具有密钥,是否否,然后为y / x定义一个值以继续绘制线条或区域。