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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17226576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 07:32:47  来源:igfitidea点击:

Creating a Text Labeled x-Axis with an Ordinal Scale in D3.js

javascriptd3.jsdata-visualization

提问by arete

I'm building a bar chart in d3.js with an ordinal x-axis whose ticks should label the chart with text. Could anyone explain how the ordinal scale "maps" x ticks to the corresponding bar positions? Specifically, if I want to designate the x tick labels with an array of text values to the corresponding bars in a bar chart.

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

Currently I'm setting the domain as the following:

目前我将域设置如下:

    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)

However, values of 1-19 are showing after the text labels.

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

As seen in this fiddle:

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

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

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

Associated Fiddle Source Code:

相关的小提琴源代码:

//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;
               });

回答by nsonnad

You can set the tick values of an ordinal axis explicitly using d3.svg.axis().tickValues(*array*).

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

But this is an odd way to do it because it dangerously separates your keys and values, meaning you have to take care to manually align the scales and make sure that your data corresponds correctly. It helps to group the keys and values in a single object and then use the format:

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

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

to map your axis domains.

映射您的轴域。

I have reworked your data and fiddle to do it in what I see as the more d3 way. (Also note that I made some other changes just for fun, namely improved the margins and cleaned up the axis alignment, etc.)

我已经重新处理了你的数据,并以我认为更d3 的方式来完成它。(另请注意,我做了一些其他更改只是为了好玩,即改进边距和清理轴对齐等。)