在 D3.js 中创建带有序数刻度的文本标记 x 轴

Posted

技术标签:

【中文标题】在 D3.js 中创建带有序数刻度的文本标记 x 轴【英文标题】:Creating a Text Labeled x-Axis with an Ordinal Scale in D3.js 【发布时间】:2013-06-18 01:45:45 【问题描述】:

我正在 d3.js 中构建一个带有序数 x 轴的条形图,其刻度应该用文本标记图表。谁能解释序数比例如何“映射” x 对应的条形位置?具体来说,如果我想将带有文本值数组的 x 刻度标签指定给条形图中的相应条形。

目前我将域设置如下:

    var labels = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t"];
    var xScale = d3.scale.ordinal()
                .domain(labels)

但是,1-19 的值显示在文本标签之后。

正如在这个小提琴中看到的那样:

http://jsfiddle.net/chartguy/FbqjD/

相关的小提琴源代码:

//Width and height
            var margin = top: 20, right: 20, bottom: 30, left: 40;           
            var width = 600 - margin.left - margin.right;
            var height= 500-margin.top -margin.bottom;
            var w = width;
            var h = height;


            var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
                            11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];

            var labels = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t"];
            var xScale = d3.scale.ordinal()
            .domain(labels)
                            .rangeRoundBands([margin.left, width], 0.05);
            var xAxis = d3.svg.axis().scale(xScale).orient("bottom");


            var yScale = d3.scale.linear()
                            .domain([0, d3.max(dataset)])
                            .range([h,0]);


            //Create SVG element
            var svg = d3.select("body")
                        .append("svg")
                        .attr("width", w)
                        .attr("height", h);

            //Create bars
            svg.selectAll("rect")
               .data(dataset)
               .enter()
               .append("rect")
               .attr("x", function(d, i) 
                    return xScale(i);
               )
               .attr("y", function(d) 
                    return yScale(d);
               )
               .attr("width", xScale.rangeBand())
               .attr("height", function(d) 
                    return h - yScale(d);
               )
               .attr("fill", function(d) 
                    return "rgb(0, 0, 0)";
               );

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

            //Create labels
            svg.selectAll("text")
               .data(dataset)
               .enter()
               .append("text")
               .text(function(d) 
                    return d;
               )
               .attr("x", function(d, i) 
                    return xScale(i) + xScale.rangeBand() / 2;
               )
               .attr("y", function(d) 
                    return h - yScale(d) + 14;
               );

【问题讨论】:

【参考方案1】:

您可以使用d3.svg.axis().tickValues(*array*) 显式设置序数轴的刻度值。

但这是一种奇怪的方法,因为它危险地将键和值分开,这意味着您必须小心手动对齐刻度并确保数据正确对应。它有助于将键和值分组到单个对象中,然后使用以下格式:

       axis.domain(array.map(function (d)  return d.value; ))

映射您的轴域。

我已经修改了您的数据,并按照我认为更多 d3 way 的方式进行操作。 (另请注意,我做了一些其他更改只是为了好玩,即改进边距和清理轴对齐等)

【讨论】:

那么,将值-标签对合并到 d3 中的单个对象中而不是将其标签链接到对象并将值链接到对象是什么?感谢您的回复,但我想加倍努力,确切地了解幕后发生的事情,所以我不仅仅是巧合地编程。 这是因为您使用一组数据明确定义域,然后在执行.attr("x", function(d, i) return xScale(i); ) 时将另一组传递给它。 API 参考中的relevant line 说:“如果明确设置了域,则将添加传递给比例尺但不明确属于该域的值。”为此,您可能会注意到,在您的原始代码中,在矩形之前调用 x 轴将导致仅调用您的显式数组。

以上是关于在 D3.js 中创建带有序数刻度的文本标记 x 轴的主要内容,如果未能解决你的问题,请参考以下文章

从 D3.js 轴中删除结束标记

无法使用 D3 更改组元素内图例文本的 x 位置

D3 x刻度定位

如何在 d3.js 中为颜色图例添加刻​​度线

对条形图中的 x 轴使用序数刻度 ('d3.scale.ordinal')

如何在 d3.js 中创建家谱?