使用scaleBand()的轴刻度中的文本值

时间:2019-03-07 03:24:12

标签: javascript d3.js

我已经使用SVG创建了条形图。我目前正在尝试将我的刻度值作为沿x轴的字符串。在我的情况下,x轴将代表颜色(表示为字符串)。我有秤,有轴。我想要一个x轴,该轴显示与每个小节相对应的字符串值。我该怎么办?

[{
  "color":"blue",
  "num":"8"
},
{
  "color":"green",
  "num": "8"
},
{
  "color":"red",
  "num":"6"
},
{
  "color":"black",
  "num":"2"
},
{
  "color":"purple",
  "num":"3"
},
{
  "color":"gold",
  "num":"4"
},
{
  "color":"teal",
  "num":"1"
}];

 var arr = data.map(function(d){return d.color;});

        // create scale for X-AXIS (1) //
        var band = d3.scaleBand() //
        .domain(d3.range(data.length))
        .range([0,width])           
        .paddingInner(0.1);


        // DEFINE X AXIS
        var xAxis = d3.axisBottom(band)
         .tickValues(d3.range(data.length))
         .tickFormat(function(d,i) {return d.color;});

        // CREATE X-AXIS
        d3.select(location).append("g")
        .attr("class","axis") // set class for x-axis
        .attr("transform","translate(0,"+height+")")
        .call(xAxis);

3 个答案:

答案 0 :(得分:1)

问题出在这里:

var band = d3.scaleBand()
    .domain(d3.range(data.length))

如您所见,您只传递了一组数字(我想您是将它们用作索引)。他们在这里:

var data = [{
    "color": "blue",
    "num": "8"
  },
  {
    "color": "green",
    "num": "8"
  },
  {
    "color": "red",
    "num": "6"
  },
  {
    "color": "black",
    "num": "2"
  },
  {
    "color": "purple",
    "num": "3"
  },
  {
    "color": "gold",
    "num": "4"
  },
  {
    "color": "teal",
    "num": "1"
  }
];

console.log(d3.range(data.length))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

因此,您的轴将只有数字(除非您再次麻烦地tickFormat加入data

var data = [{
    "color": "blue",
    "num": "8"
  },
  {
    "color": "green",
    "num": "8"
  },
  {
    "color": "red",
    "num": "6"
  },
  {
    "color": "black",
    "num": "2"
  },
  {
    "color": "purple",
    "num": "3"
  },
  {
    "color": "gold",
    "num": "4"
  },
  {
    "color": "teal",
    "num": "1"
  }
];

var svg = d3.select("svg")
var scale = d3.scaleBand()
  .domain(d3.range(data.length))
  .range([20, 480]);
var axis = d3.axisBottom(scale);
axis(svg.append("g").attr("transform", "translate(0,50)"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="100"></svg>

惯用的解决方案将要在数据可视化中描绘的类别变量传递给波段标度。这似乎是条形图或类似的可视化类型,其中color是类别变量。在这种情况下,请将其传递到秤:

.domain(data.map(d => d.color))

这是轴的样子:

var data = [{
    "color": "blue",
    "num": "8"
  },
  {
    "color": "green",
    "num": "8"
  },
  {
    "color": "red",
    "num": "6"
  },
  {
    "color": "black",
    "num": "2"
  },
  {
    "color": "purple",
    "num": "3"
  },
  {
    "color": "gold",
    "num": "4"
  },
  {
    "color": "teal",
    "num": "1"
  }
];

var svg = d3.select("svg")
var scale = d3.scaleBand()
  .domain(data.map(d => d.color))
  .range([20, 480]);
var axis = d3.axisBottom(scale);
axis(svg.append("g").attr("transform", "translate(0,50)"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="100"></svg>

答案 1 :(得分:0)

我认为问题出在您的tickFormat,而不是scaleBand。格式函数应类似于:

.tickFormat((i) => { return data[i].color; });

我不确定您数据中的num字段应该代表什么(如果相关)。也许您需要清理数据表示以更好地适应d3。

答案 2 :(得分:0)

对于 2021 年以上的读者来说,在一些具有多个字段的数据上使用刻度格式时,以前的 tickFormat 解决方案是可行的方法。将您的数据域绑定到已接受的解决方案中的标签/文本字段是一个坏主意 (TM)。

在给定的示例中,这很好,因为没有重复的标签,但在其他情况下无法保证。例如,如果您的数据描述美国县 - 您必须处理“华盛顿县”的所有 31 个实例。

轴上的 select ,V_QUOTE_CASE_OPP_FROM2020.SR_NUM ,V_SF_OPPORTUNITY_ITEMS.PROD_FAMILY ,case when PROD_FAMILY like '%Tax%' then 'Tax' when PROD_FAMILY like '%Practice Manager%' then 'Practice Manager' when PROD_FAMILY like '%Compliance%' then 'Compliance' else PROD_FAMILY end as PRODUCT_FAMILY ,CONCAT(V_QUOTE_CASE_OPP_FROM2020.SR_NUM, PRODUCT_FAMILY) as 'RN_PRODFAM' FROM [COMMOPSDB].[dbo].[V_QUOTE_CASE_OPP_FROM2020] LEFT JOIN [COMMOPSDB].[dbo].[V_SF_OPPORTUNITY_ITEMS] 应该是 id 字段,domain 处理显示。

tickFormat