Javascript D3.js分组条形图渲染x轴不正确

Javascript D3.js分组条形图渲染x轴不正确,javascript,d3.js,bar-chart,Javascript,D3.js,Bar Chart,我正在尝试实现分组条形图,但无法使其工作。我的数据结构如下: [{ "Type": "Email", "DataPoints": [{ "xValue": 1, "Value": 17 }, { "xValue": 2, "Value": 59 }] }, { "Type": "Phone", "DataPoints": [{ "xValue": 1,

我正在尝试实现分组条形图,但无法使其工作。我的数据结构如下:

[{
    "Type": "Email",
    "DataPoints": [{
        "xValue": 1,
        "Value": 17
    },
    {
        "xValue": 2,
        "Value": 59
    }]
},
{
    "Type": "Phone",
    "DataPoints": [{
        "xValue": 1,
        "Value": 1
    }]
}]
var margin = { top: 20, right: 0, bottom: 40, left: 50 },
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom,
    tooltipTextColour = "white";

if (data.length > 0) {
    var x0 = d3.scale.ordinal()
                    .rangeRoundBands([0, width], .1);

    var x1 = d3.scale.ordinal();

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

    var xAxis = d3.svg.axis()
                        .scale(x0)
                        .orient("bottom");

    var yAxis = d3.svg.axis()
                        .scale(y)
                        .orient("left")
                        .tickFormat(d3.format(".2s"));

    var svg = placeholder.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 + ')');

    var types = d3.entries(data);

    x0.domain(types.map(function (d) { return d.Type; }));
    x1.domain(types).rangeRoundBands([0, x0.rangeBand()]);
    y.domain([0, d3.max(types, function (d) { return d3.max(d.value.DataPoints, function (d) { return d.Value; }); })]);

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

    svg.append('g')
        .attr('class', 'y axis')
        .call(yAxis)
        .append('text')
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", ".71em")
          .style("text-anchor", "end")
          .text("Complaints");

    var type = svg.selectAll(".type")
                    .data(data)
                    .enter()
                    .append('g')
                        .attr('class', 'type')
                        .attr('transform', function (d) { return 'translate(' + x0(d.Type) + ',0)'; });

    type.selectAll("rect")
            .data(function (d) { return d.DataPoints; })
            .enter()
            .append('rect')
            .attr('width', x1.rangeBand())
            .attr('x', function (d) { return x1(d.xValue); })
            .attr('y', function (d) { return y(d.Value); })
            .attr('height', function (d) { return height - y(d.Value); })
            .style('fill', function (d, i) { return color(d.xValue); });
}
else {
    placeholder.append('p').text('No Data to Display').style('font-weight', 'bold');
}
我的代码如下:

[{
    "Type": "Email",
    "DataPoints": [{
        "xValue": 1,
        "Value": 17
    },
    {
        "xValue": 2,
        "Value": 59
    }]
},
{
    "Type": "Phone",
    "DataPoints": [{
        "xValue": 1,
        "Value": 1
    }]
}]
var margin = { top: 20, right: 0, bottom: 40, left: 50 },
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom,
    tooltipTextColour = "white";

if (data.length > 0) {
    var x0 = d3.scale.ordinal()
                    .rangeRoundBands([0, width], .1);

    var x1 = d3.scale.ordinal();

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

    var xAxis = d3.svg.axis()
                        .scale(x0)
                        .orient("bottom");

    var yAxis = d3.svg.axis()
                        .scale(y)
                        .orient("left")
                        .tickFormat(d3.format(".2s"));

    var svg = placeholder.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 + ')');

    var types = d3.entries(data);

    x0.domain(types.map(function (d) { return d.Type; }));
    x1.domain(types).rangeRoundBands([0, x0.rangeBand()]);
    y.domain([0, d3.max(types, function (d) { return d3.max(d.value.DataPoints, function (d) { return d.Value; }); })]);

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

    svg.append('g')
        .attr('class', 'y axis')
        .call(yAxis)
        .append('text')
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", ".71em")
          .style("text-anchor", "end")
          .text("Complaints");

    var type = svg.selectAll(".type")
                    .data(data)
                    .enter()
                    .append('g')
                        .attr('class', 'type')
                        .attr('transform', function (d) { return 'translate(' + x0(d.Type) + ',0)'; });

    type.selectAll("rect")
            .data(function (d) { return d.DataPoints; })
            .enter()
            .append('rect')
            .attr('width', x1.rangeBand())
            .attr('x', function (d) { return x1(d.xValue); })
            .attr('y', function (d) { return y(d.Value); })
            .attr('height', function (d) { return height - y(d.Value); })
            .style('fill', function (d, i) { return color(d.xValue); });
}
else {
    placeholder.append('p').text('No Data to Display').style('font-weight', 'bold');
}
这将产生以下结果:

有人知道这是为什么吗?我认为这是因为它没有正确渲染x轴,但是,我无法找出原因


任何帮助都将不胜感激。

您没有正确设置
x0
x1
域。应该是这样的:

  // x0 is easy it's just the type
  x0.domain(data.map(function(d) {
    return d.Type
  }));
  // x1 is messy
  // this reduces each DataPoints xValue into a single array
  // and then creates a set from it to remove duplicates
  x1.domain(
    d3.set(data.reduce(function(previousValue, currentValue) {
      return previousValue.concat(currentValue.DataPoints.map(function(d) {
        return d.xValue
      }))
    }, [])).values()
  ).rangeRoundBands([0, x0.rangeBand()]);

工作代码:


变量占位符=d3。选择(“#占位符”);
var color=d3.scale.category10();
var保证金={
前20名,
右:0,,
底数:40,
左:50
},
宽度=960-margin.left-margin.right,
高度=500-页边距.顶部-页边距.底部,
ToolTiptextColor=“白色”;
风险值数据=[{
“类型”:“电子邮件”,
“数据点”:[{
“xValue”:1,
“价值”:17
}, {
“xValue”:2,
“价值”:59
}]
}, {
“类型”:“电话”,
“数据点”:[{
“xValue”:1,
“价值”:1
},{
“xValue”:3,
“价值”:30
}]
}];
如果(data.length>0){
var x0=d3.scale.ordinal()
.rangeRoundBands([0,宽度],.1);
var x1=d3.scale.ordinal();
变量y=d3.scale.linear().range([height,0]);
var xAxis=d3.svg.axis()
.比例(x0)
.东方(“底部”);
var yAxis=d3.svg.axis()
.比例(y)
.东方(“左”)
.tick格式(d3格式(“.2s”);
var svg=placeholder.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+'));
x0.domain(data.map)(函数(d){
返回d.类型
}));
x1.1域(
d3.设置(数据.减少(功能)(先前值,当前值){
返回previousValue.concat(currentValue.DataPoints.map)(函数(d){
返回d.xValue
}))
},[])。值()
).rangeRoundBands([0,x0.rangeBand()]);
y、 域([0,d3.max(数据,函数(d)){
返回d3.最大值(d.数据点,函数(d){
返回d.值;
});
})]);
append('g')
.attr('class','x轴')
.attr('transform','translate(0',+height+'))
.呼叫(xAxis);
append('g')
.attr('class','y轴')
.呼叫(yAxis)
.append('文本')
.attr(“变换”、“旋转(-90)”)
.attr(“y”,6)
.attr(“dy”,“.71em”)
.style(“文本锚定”、“结束”)
.文本(“投诉”);
var type=svg.selectAll(“.type”)
.数据(数据)
.输入()
.append('g')
.attr('class','type')
.attr('transform',函数(d){
返回'translate('+x0(d.Type)+',0');
});
键入。选择全部(“rect”)
.数据(功能(d){
返回d.DataPoints;
})
.输入()
.append('rect')
.attr('width',x1.rangeBand())
.attr('x',函数(d){
返回x1(d.xValue);
})
.attr('y',函数(d){
返回y(d值);
})
.attr(高度),功能(d){
返回高度-y(d值);
})
.样式(“填充”,功能(d,i){
返回颜色(d.xValue);
});
}否则{
占位符。追加('p')。文本('No Data to Display')。样式('font-weight','bold');
}

您没有正确设置
x0
x1
域。应该是这样的:

  // x0 is easy it's just the type
  x0.domain(data.map(function(d) {
    return d.Type
  }));
  // x1 is messy
  // this reduces each DataPoints xValue into a single array
  // and then creates a set from it to remove duplicates
  x1.domain(
    d3.set(data.reduce(function(previousValue, currentValue) {
      return previousValue.concat(currentValue.DataPoints.map(function(d) {
        return d.xValue
      }))
    }, [])).values()
  ).rangeRoundBands([0, x0.rangeBand()]);

工作代码:


变量占位符=d3。选择(“#占位符”);
var color=d3.scale.category10();
var保证金={
前20名,
右:0,,
底数:40,
左:50
},
宽度=960-margin.left-margin.right,
高度=500-页边距.顶部-页边距.底部,
ToolTiptextColor=“白色”;
风险值数据=[{
“类型”:“电子邮件”,
“数据点”:[{
“xValue”:1,
“价值”:17
}, {
“xValue”:2,
“价值”:59
}]
}, {
“类型”:“电话”,
“数据点”:[{
“xValue”:1,
“价值”:1
},{
“xValue”:3,
“价值”:30
}]
}];
如果(data.length>0){
var x0=d3.scale.ordinal()
.rangeRoundBands([0,宽度],.1);
var x1=d3.scale.ordinal();
变量y=d3.scale.linear().range([height,0]);
var xAxis=d3.svg.axis()
.比例(x0)
.东方(“底部”);
var yAxis=d3.svg.axis()
.比例(y)
.东方(“左”)
.tick格式(d3格式(“.2s”);
var svg=placeholder.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+'));
x0.domain(data.map)(函数(d){
返回d.类型
}));
x1.1域(
d3.设置(数据.减少(功能)(先前值,当前值){
返回previousValue.concat(currentValue.DataPoints.map)(函数(d){
返回d.xValue
}))
},[])。值()
).rangeRoundBands([0,x0.rangeBand()]);
y、 域([0,d3.max(数据,函数(d)){
返回d3.最大值(d.数据点,函数(d){
返回d.值;
});
})]);
append('g')
.attr('class','x轴')
.attr('transform','translate(0',+height+'))
.呼叫(xAxis);
append('g')
.attr('class','y轴')
.呼叫(yAxis)
.append('文本')
.attr(“变换”、“旋转(-90)”)
.attr(“y”,6)
.attr(“dy”,“.71em”)
.style(“文本锚定”、“结束”)
.文本(“投诉”);
var type=svg.selec