使用D3制作双水平线图

时间:2016-04-14 18:31:57

标签: javascript d3.js

我刚开始使用D3,需要使用csv文件制作水平条形图。数据是比较美国不同州的男女工资。每个州都需要有两个触摸栏(一个用于男性,一个用于女性的工资)。 CSV文件的标题行为State,Women,Men,下面的每一行都有每个州的名称和相应的数据。

这是我到目前为止所做的事情。

var margin = { top: 20, right: 10, bottom: 100, left: 40 },
    width = 700 - margin.right - margin.left,
    height = 500 - margin.top - margin.bottom;

var svg = d3.select('body')
    .append('svg')
    .attr ({ 
    "width" : width + margin.right + margin.left,
    "height" : height + margin.top + margin.bottom
})

    .append('g')
        .attr("transform", "translate(" + margin.left + ',' + margin.right + ')');

var xScale = d3.scale.ordinal()
     .rangeRoundBands([height,0], 0.2, 0.2);

var yScale = d3.scale.linear()
    .range([0, width]);

var xAxis = d3.svg.axis()
    .scale(xScale)
    .orient("left");

var yAxis = d3.svg.axis()
    .scale(yScale)
    .orient("bottom");

d3.csv("state-women-men.csv", function(error, data) {
    if(error) console.log("Error, data not loaded");

    data.forEach(function(d) {
        d.Women = +d.Women;
        d.Men = +d.Men;
        d.State = d.State;
        console.log(d.Men);
        console.log(d.Women);
    });

    xScale.domain(data.map(function(d) { return d.State;}) );
    yScale.domain([0, d3.max(data,function (d) { return d.Women; }) ] );

    svg.selectAll('rect')
        .data(data)
        .enter()
        .append('rect')
        .attr ({
            "x": function(d) { return xScale(d.State); },
            "y": function(d) { return yScale(d.Women); },
            "height": xScale.rangeBand(),
            "width": function(d) { return (width - xScale(d.State)); }
        });

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

    svg.append("g")
        .attr("class", "y axis")
        .attr("transform", "translate(0," + height +")")
        .call(yAxis);
});

首先,我只是使用女性的数据,我会弄清楚如何让男性进入以后。现在更大的问题是格式化;正如你在图片中看到的那样,条形图是靠近屏幕底部并且距屏幕底部太远而且条形图从屏幕右侧而不是左侧开始的方式。任何人都可以指出我的代码中的原因导致图形看起来像这样,并给我建议添加第二个条,以及颜色到酒吧?感谢。

图表图片: enter image description here

1 个答案:

答案 0 :(得分:1)

看起来主要问题是您的rect属性混淆了。尝试使用以下内容,您将获得更好的结果:

svg.selectAll('rect')
    .data(data)
    .enter()
    .append('rect')
    .attr ({
        "x": 0,
        "y": function(d) { return xScale(d.State); },
        "height": xScale.rangeBand(),
        "width": function(d) { return (yScale(d.Women)); }
});

推理:

  • x值应固定为零,以便与轴
  • 对齐
  • y值应基于您的xScaleState属性。由于您的比例名称被翻转,有点令人困惑
  • width应该只是使用yScale属性的x轴(Women)。