Javascript D3图表缺少数据

Javascript D3图表缺少数据,javascript,c#,d3.js,Javascript,C#,D3.js,我有一个d3线图,它工作得很好。它映射了当月或当年收到的电话和电子邮件的数量。然而,唯一的问题是,如果只在一个月的一天收到电话,那么该值上只显示一个点。我希望发生的是,每天都没有一个值,然后该值被视为0。我环顾了一下谷歌,但我只能找到相反的例子。有人能帮忙吗 我目前的准则是: function buildCommunicationLineChart(data, placeholder, callback, type) { var margin = { top: 20, right: 30, bo

我有一个d3线图,它工作得很好。它映射了当月或当年收到的电话和电子邮件的数量。然而,唯一的问题是,如果只在一个月的一天收到电话,那么该值上只显示一个点。我希望发生的是,每天都没有一个值,然后该值被视为0。我环顾了一下谷歌,但我只能找到相反的例子。有人能帮忙吗

我目前的准则是:

function buildCommunicationLineChart(data, placeholder, callback, type) {
var margin = { top: 20, right: 30, bottom: 40, left: 50 },
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom,
    tooltipTextColour = "white";

var color = ["#FF9797", "#86BCFF", "#33FDC0", "#EFA9FE", "#7BCAE1", "#8C8CFF", "#80B584", "#C88E8E", "#DD597D", "#D8F0F8", "#DD597D", "#D6C485", "#990099", "#5B5BFF", "#1FCB4A", "#000000", "#00BFFF", "#BE81F7", "#BDBDBD", "#F79F81"];

if (type == "month") {
    var x = d3.scale.linear()
                    .domain([1, 31])
                    .range([0, width]);

    var tip = d3.tip()
      .attr('class', 'd3-tip')
      .offset([-10, 0])
      .html(function (d) {
          return "<strong>Value:</strong> <span style='color:" + tooltipTextColour + "'>" + d.Value + "</span><br /><strong>Day of Month:</strong><span style='color:white'>" + d.xValue + "</span>";
      });
}
else if (type == "year")
{
    var x = d3.scale.linear()
                    .domain([1, 12])
                    .range([0, width]);

    var tip = d3.tip()
      .attr('class', 'd3-tip')
      .offset([-10, 0])
      .html(function (d) {
          return "<strong>Value:</strong> <span style='color:" + tooltipTextColour + "'>" + d.Value + "</span><br /><strong>Month of Year:</strong><span style='color:white'>" + d.xValue + "</span>";
      });
}

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

var xAxis = d3.svg.axis()
    .scale(x)
    .tickSize(-height)
    .tickPadding(10)
    .tickSubdivide(true)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .tickPadding(10)
    .tickSize(-width)
    .tickSubdivide(true)
    .orient("left");

var line = d3.svg.line()
            .x(function (d) { var xTest = x(d.xValue); return x(d.xValue); })
            .y(function (d) { var yTest = y(d.Value); return y(d.Value); });

var svg = placeholder.append("svg")
    .attr("width", width + margin.left + margin.right + 50)
    .attr("height", height + margin.top + margin.bottom)
    .attr("class", "chart")
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

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

if (type == "year") {
    svg.append("g")
        .attr("class", "x axis")
        .append("text")
        .attr("class", "axis-label")
        .attr("transform", "none")
        .attr("y", (-margin.left) + 530)
        .attr("x", -height + 860)
        .text('Month');
}
else if (type == "month") {
    svg.append("g")
        .attr("class", "x axis")
        .append("text")
        .attr("class", "axis-label")
        .attr("transform", "none")
        .attr("y", (-margin.left) + 525)
        .attr("x", -height + 860)
        .text('Day');
}

var methods = d3.entries(data);
y.domain([
    d3.min(methods, function (c) { return d3.min(c.value.DataPoints, function (v) { return v.Value; }); }) -1,
    d3.max(methods, function (c) { return d3.max(c.value.DataPoints, function (v) { return v.Value; }); }) +1
]);

svg.call(tip);

svg.append("g")
    .attr("class", "y axis")
    .call(yAxis);

svg.append("g")
    .attr("class", "y axis")
    .append("text")
    .attr("class", "axis-label")
    .attr("transform", "rotate(-90)")
    .attr("y", (-margin.left) + 15)
    .attr("x", -height / 2)
    .text('Communications');

var method = svg.selectAll('.method')
                    .data(methods)
                    .enter().append('g')
                    .attr('class', 'method')
                    .style('fill',function(d,i){
                        return color[i];
                    })
                    .style('stroke', function (d, i) {
                        return color[i];
                    });

var m = method.append('path')
        .attr('class', function (d, i) { return 'line line-' + i; })
        .attr('d', function (d) { return line(d.value.DataPoints); });

method.selectAll('circle')
        .data(function (d) { return d.value.DataPoints; })
         .enter().append("circle")
        .attr('class', function (d, i) { return 'circle circle-' + i; })
         .attr("cx", function (dd) { return x(dd.xValue); })
         .attr("cy", function (dd) { return y(dd.Value); })
         .attr("r", 3.5)
         .on('mouseover', tip.show)
         .on('mouseout', tip.hide);

method.append('text')
        .datum(function (d) { return { commType: d.value.Type, value: d.value.DataPoints[d.value.DataPoints.length - 1] }; })
        .attr("transform", function (d) { return "translate(" + x(d.value.xValue) + "," + y(d.value.Value) + ")"; })
        .attr('x', 5)
        .attr('class',function(d,i){return 'text text-'+i;})
        .attr('dy', '.15em')
        .style('stroke','none')
        .text(function (d) { return d.commType; });

if (callback) {
    callback();
}
}

我将假设以下几点:

您从数据源接收到的是一年一个月的数组(如果您按月接收,则每个月都必须发出Get请求,这很容易,但我希望您有一条路线可以提供一年一次的数据,为这个结果执行12次http Get不会很酷)数据,如:

[
    {
        month: "January",
        data: [{
        "Type": "Email",
        "DataPoints": 
            [{
                "xValue": 1,
                "Value": 17
            },
            {
                "xValue": 2,
                "Value": 59
            }]
        },
        {
            "Type": "Phone",
            "DataPoints": [{
                "xValue": 1,
                "Value": 1
            }]
        }]
    }
    },{
    month: "February",
    data: [...]
    },
    ...
]
我将在Js中完成客户端:

假设每个月是31天,我懒得去想确切地做这件事,但它不应该那么难,而xValue是一个月中的一天

function completeMonths(data){
    _.each(data, function(month){
        _.each(month.data, function(typeSource){
            for(var i = 1; i < 32; i++){
                var dayOnList = _.some(typeSource.DataPoints, function(day){
                    return day.xValue == i;
                });
                if(!dayOnList)
                    typeSource.DataPoints.push({xValue: i, Value: 0});
            }
            typeSource.DataPoints = _.sortBy(typeSource.DataPoints, function(ite){
                return ite.xValue;
            });
        });
    });

    return data;
}
函数完成月数(数据){
_.每个(数据、功能(月){
_.每个月.数据,函数(类型源){
对于(变量i=1;i<32;i++){
var dayOnList=\ uu0.some(typeSource.DataPoints,函数(day){
返回日.xValue==i;
});
如果(!dayOnList)
typeSource.DataPoints.push({xValue:i,Value:0});
}
typeSource.DataPoints=uu.sortBy(typeSource.DataPoints,函数(ite){
返回ite.xValue;
});
});
});
返回数据;
}
可能不是更优化的代码,但我已经尝试过了,它正在工作。 实际上,我认为最好映射当前月份的天数,并从和1到31数组中拒绝它们。
顺便说一句,您的Json格式不好,您缺少一个结尾“]”

我将假设以下几点:

您从数据源接收到的是一年一个月的数组(如果您按月接收,则每个月都必须发出Get请求,这很容易,但我希望您有一条路线可以提供一年一次的数据,为这个结果执行12次http Get不会很酷)数据,如:

[
    {
        month: "January",
        data: [{
        "Type": "Email",
        "DataPoints": 
            [{
                "xValue": 1,
                "Value": 17
            },
            {
                "xValue": 2,
                "Value": 59
            }]
        },
        {
            "Type": "Phone",
            "DataPoints": [{
                "xValue": 1,
                "Value": 1
            }]
        }]
    }
    },{
    month: "February",
    data: [...]
    },
    ...
]
我将在Js中完成客户端:

假设每个月是31天,我懒得去想确切地做这件事,但它不应该那么难,而xValue是一个月中的一天

function completeMonths(data){
    _.each(data, function(month){
        _.each(month.data, function(typeSource){
            for(var i = 1; i < 32; i++){
                var dayOnList = _.some(typeSource.DataPoints, function(day){
                    return day.xValue == i;
                });
                if(!dayOnList)
                    typeSource.DataPoints.push({xValue: i, Value: 0});
            }
            typeSource.DataPoints = _.sortBy(typeSource.DataPoints, function(ite){
                return ite.xValue;
            });
        });
    });

    return data;
}
函数完成月数(数据){
_.每个(数据、功能(月){
_.每个月.数据,函数(类型源){
对于(变量i=1;i<32;i++){
var dayOnList=\ uu0.some(typeSource.DataPoints,函数(day){
返回日.xValue==i;
});
如果(!dayOnList)
typeSource.DataPoints.push({xValue:i,Value:0});
}
typeSource.DataPoints=uu.sortBy(typeSource.DataPoints,函数(ite){
返回ite.xValue;
});
});
});
返回数据;
}
可能不是更优化的代码,但我已经尝试过了,它正在工作。 实际上,我认为最好映射当前月份的天数,并从和1到31数组中拒绝它们。
顺便说一句,您的Json格式不好,缺少一个结尾“]”

,Json的结构如下:

[{
    "Type": "Email",
    "DataPoints": [{
        "xValue": 1,
        "Value": 17
    },
    {
        "xValue": 2,
        "Value": 59
    }]
},
{
    "Type": "Phone",
    "DataPoints": [{
        "xValue": 1,
        "Value": 1
    }]
}]
假设您的
DataPoints
数组按
xValue
和当月31天排序:

var maxDaysInMonth = 31;
// for each dataset
dataset.forEach(function(d){
  // loop our month
  for (var i = 1; i <= maxDaysInMonth; i++){
    // if there's no xValue at that location
    if (!d.DataPoints.some(function(v){ return (v.xValue === i) })){
      // add a zero in place
      d.values.splice((i - 1), 0, {xValue: i, Value: 0});
    }
  }
});
var maxDaysInMonth=31;
//对于每个数据集
dataset.forEach(函数(d){
//循环我们的月份

对于(var i=1;i,JSON结构如下:

[{
    "Type": "Email",
    "DataPoints": [{
        "xValue": 1,
        "Value": 17
    },
    {
        "xValue": 2,
        "Value": 59
    }]
},
{
    "Type": "Phone",
    "DataPoints": [{
        "xValue": 1,
        "Value": 1
    }]
}]
假设您的
DataPoints
数组按
xValue
和当月31天排序:

var maxDaysInMonth = 31;
// for each dataset
dataset.forEach(function(d){
  // loop our month
  for (var i = 1; i <= maxDaysInMonth; i++){
    // if there's no xValue at that location
    if (!d.DataPoints.some(function(v){ return (v.xValue === i) })){
      // add a zero in place
      d.values.splice((i - 1), 0, {xValue: i, Value: 0});
    }
  }
});
var maxDaysInMonth=31;
//对于每个数据集
dataset.forEach(函数(d){
//循环我们的月份


对于(var i=1;我能告诉你导致这个问题的数据样本吗?如果只是因为你的数据集没有价值,没有调用,只需预先处理你的数据,用零值添加缺失的日期。我需要你的数据结构更精确。@JulienLeray我编辑了我的问题,以提供我的数据结构和c#检索。我希望s有帮助。如果我还能提供什么,请告诉我:)实际上,我说的是Json数据示例。就像您想要显示的Json月呼叫/邮件号码,只有一天。抱歉,我没有太多的Json经验,无法从我的对象创建它,也不知道如何在visual studio中查看它。有什么建议我如何获取我数据的Json吗?@JulienLeray我现在添加了一些Json dat示例a、 如您所见,电子邮件将是一个2点的短线,电话将是一个单点。我如何使一年中所有月份的缺失值结果为0和绘图?您可以发布导致此问题的数据样本吗?如果只是因为您的数据集上没有值而没有电话,只需预处理您的数据添加缺失日期使用零值。我需要您的数据结构更精确。@JulienLeray我已经编辑了我的问题,以提供我的数据结构和c#检索。我希望这有帮助。如果我可以提供其他信息,请告诉我:)实际上,我说的是Json数据示例。就像您想要显示的Json月呼叫/邮件号码,只有一天。抱歉,我没有太多的Json经验,无法从我的对象创建它,也不知道如何在visual studio中查看它。有什么建议我如何获取我数据的Json吗?@JulienLeray我现在添加了一些Json dat示例正如你所看到的,电子邮件将是一个短的2分线,电话将是一个单一的点。我怎么能使一年中的所有月份的缺失值结果为0,并用它来绘制?我得到的是未定义的。不,我从来没有听说过这些……在香草JS上会更冗长。你应该考虑其中一个非常好和有用的东西。l这种治疗的工具我已经按照你的建议实施了,但是,d3绘制原始点,然后绘制新点,所以