d3.js象形图

时间:2014-08-12 16:16:40

标签: javascript d3.js

我正在制作象形图应用程序。

这是我的最新代码。我将尝试在矩形块的顶部放置纹理图层。有没有办法控制各轴的填充?

var pictogramData = [
        {
            "label": "8",
            "value": 8
        },
        {
            "label": "9",
            "value": 4
        },
        {
            "label": "10",
            "value": 9
        },
        {
            "label": "11",
            "value": 12
        }    
    ];


var margins = {
    top: 0,
    left: 30,
    right: 24,
    bottom: 0
};

var chart,
    width = 300,
    pixelGap = 2,
    bar_height = 15,
    height = ((bar_height + pixelGap) * pictogramData.length),
    gapHeights = (pixelGap) * pictogramData.length;



svg = d3.select("#step-1") 
  .append('svg');


svg
  .append('defs')
  .append('pattern')
    .attr('id', 'diagonalHatch')
    .attr('patternUnits', 'userSpaceOnUse')
    .attr('width', 4)
    .attr('height', 4)
  .append('path')
    .attr('d', 'M-1,1 l2,-2 M0,4 l4,-4 M3,5 l2,-2')
    .attr('stroke', '#000000')
    .attr('stroke-width', 1);


chartWidth =  width * 0.8;

chart = svg.append('g')
  .attr('class', 'chart')
  .attr('width', chartWidth)
  .attr('height', height+gapHeights)
  .attr('transform', 'translate(' + margins.left + ',' + margins.top + ')');


valueList = svg.append('g')
    .attr('class', 'axis')
 .attr('width', width *0.2)
.attr('transform', 'translate(' + (width - margins.right) + ',' + margins.top + ')')


chart
.append('g')

var x, y;

var max = d3.max(pictogramData, function(d) { return +d.value;} );

    function getValueDomain(data){
        var valueDomain = new Array();

        for (i = 0; i < data.length; ++i) {
            valueDomain.push(data[i].value);
        }
        return valueDomain;
    }

var valueArray = getValueDomain(pictogramData);

x = d3.scale.linear()
    .domain([0, max])
    .range([0, chartWidth]);

y = d3.scale.ordinal()
   .domain(valueArray)
   .rangeBands([0, height]);

    function plotRectangleGroups(groupName, pictogramData, chartWidth){
            //Add a group to hold the rects
            var group = chart.append("g")
                .attr("class", groupName+"group");

            group.selectAll("rect")
                .data(pictogramData)
                .enter().append("rect")
                .attr("x", 0)
                .attr("y", function(d, i){
                    return y(d.value) + (pixelGap*i);
                })
                .attr("width", function(d, i){
                    var barWidth = chartWidth;
                    if(
                        groupName != "base" &&
                        groupName != "pattern"
                      ){
                       barWidth = x(d.value);                     
                    }                    
                    return barWidth;
                })
                .attr("height", y.rangeBand())
            .attr('fill', function(){
                var fill;
                if(groupName == "pattern"){
                    fill = 'url(#diagonalHatch)';
                }

                return fill;
            });        


    }

plotRectangleGroups("base", pictogramData, chartWidth);
plotRectangleGroups("rects", pictogramData, chartWidth);
plotRectangleGroups("pattern", pictogramData, chartWidth);

//left labels
labels = pictogramData.map(function (d) {
    return d.label;
});

yScale = d3.scale.ordinal()
        .domain(labels)
        .rangeRoundBands([0, height]),    

yAxis = d3.svg.axis()
    .scale(yScale)
    .orient('left'),    

chart.append('g')
    .attr('class', 'axis')
    .call(yAxis);



//right labels
values = pictogramData.map(function (d) {
    return d.value;
});

yScale = d3.scale.ordinal()
        .domain(values)
        .rangeRoundBands([0, height]),    

yAxis = d3.svg.axis()
    .scale(yScale)
    .orient('right'),    


valueList
    .call(yAxis);

http://jsfiddle.net/4zt64yj8/18/

1 个答案:

答案 0 :(得分:1)

Y轴上的条形和刻度标签的错位来自pixelGap值。

pixelGap = 1,
...
.attr("y", function(d, i){
  return y(d.value) + (pixelGap*i);
})

正如您所看到的,pixelgap用于在条形图之间添加一点空白区域,但您(或创建图表的任何人)忘记在范围内补偿它们。 pixelGap*i意味着每个下一个栏都会被进一步向下推,而相应的标签不会被推下。

最简单的解决方法是删除乘法并修改yheight属性:

        group.selectAll("rect")
            .data(pictogramData)
            .enter().append("rect")
            .attr("x", 0)
            .attr("y", function(d, i){
                return y(d.value) + pixelGap;
            })
            .attr("width", function(d, i){
                var barWidth = chartWidth;
                if(
                    groupName != "base" &&
                    groupName != "pattern"
                  ){
                   barWidth = x(d.value);                     
                }                    
                return barWidth;
            })
            .attr("height", y.rangeBand() - pixelGap)

通过此更改,垂直填充基本上均匀地分布在条形图的上方和下方,从而消除了不对齐。