javascript - 将线条附加到 D3 条形图 - 绝对没有任何反应

标签 javascript d3.js

我有一个工作良好的分组条形图脚本,我正在尝试向其中添加简单的引用线。相关代码:

//Set up margins and dimensions according to http://bl.ocks.org/3019563
var margin = {top: 20, right: 10, bottom: 20, left: 30},
    width = 810 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

/* Set up the primary x scale */
var x0 = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1)
    .domain(data.map(function (d) {
        return options.xPrimaryScaleAccessor(d);
    }));

/* Set up the secondary x scale */
var x1 = d3.scale.ordinal()
    .domain(xSecondaryScaleValues)
    .rangeRoundBands([0, x0.rangeBand()]);

/* Set up the y scale as a linear (continous) scale with a total range of 0 - full height and a domain of 0-100 */
var y = d3.scale.linear()
    .range([height, 0])
    .domain([0, 100]);

/* Set up a color space of 20 colors */
var color = d3.scale.category20();

/* Set up the x axis using the primary x scale and align it to the bottom */
var xAxis = d3.svg.axis()
    .scale(x0)
    .orient("bottom");

/* Set up the y axis using the y scale and align it to the left */
var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

/* Create an SVG element and append it to the body, set its dimensions, append a <g> element to
 * it and apply a transform translating all coordinates according to the margins set up. */
var svg = d3.select(options.target).append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

//Create a space for definitions
var defs = svg.append("defs");

setupDropShadowFilter(defs, 3, 3, 3); //Sets up a gaussian blur filter with id 'drop-shadow'

/* Append a <g> element to the chart and turn it into a representation of the x axis */
svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

/* Append a <g> element to the chart and turn it into a representation of the y axis */
svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text(options.yLabel);

var dataArr = y.ticks(yAxis.ticks());

/* Draw the reference lines */  
svg.selectAll("line")
   .data(dataArr)
   .enter().append("line")
   .attr("x1", 0)
   .attr("x2", width)
   .attr("y1", y)
   .attr("y2", y)
   .style("stroke", "#ccc");

/* Set up the bar groups */
var group = svg.selectAll(".group")
    .data(data)
    .enter().append("g")
    .attr("class", "g")
    .attr("transform", function(d) { return "translate(" + x0(options.xPrimaryScaleAccessor(d)) + ",0)"; });

/* Draw the bars */
group.selectAll("rect")
    .data(options.valueAccessor)
    .enter().append("rect")
    .attr("width", x1.rangeBand())
    .attr("x", function(d) { return x1(d.label); })
    .attr("y", function(d) { return y(d.value); })
    .attr('rx', options.barCornerRadius)
    .attr('ry', options.barCornerRadius)
    .attr("height", function(d) { return height - y(d.value); })
    .style("fill", function(d) { return getStripedPattern(defs, color(d.label)); //Sets up a pattern and returns its ID })//Todo: fill with pattern instead. see http://tributary.io/tributary/2929255
    .style("filter", "url(#drop-shadow)");

/* Draw a legend */
var legend = svg.selectAll(".legend")
    .data(xSecondaryScaleValues)
    .enter().append("g")
    .attr("class", "legend")
    .attr("transform", function(d, i) { return "translate(0," + (xSecondaryScaleValues.length-i-.25) * (height/xSecondaryScaleValues.length) + ")"; });

legend.append("rect")
    .attr("x", width - 9)
    .attr("width", 18)
    .attr("height", 18)
    .style("fill", color);

legend.append("text")
    .attr("y", 9)
    //.attr("dy", ".35em")
    .attr("transform", "translate(" + (width - 6) + ",-8)rotate(-90)" )
    .style("text-anchor", "start")
    .text(function(d) { return d; });

编辑:我还尝试附加 rect 元素,而不是使用硬编码的坐标和尺寸,但这些也没有进入 DOM。

编辑 2:现在包含或多或少完整的代码。

基本上,什么也没有发生。没有附加任何行,控制台中也没有错误。 dataArr 是一个普通的数字数组,并且 y(number) 被确认在输出范围内返回正确的值。

我认为(并且调试表明)该链在 append() 阶段终止,可能是因为 .enter() 返回了无用的内容。

.data()之后的控制台日志:

Console log after .data()

.enter()后的控制台日志:

Console log after .enter()

.append()后的控制台日志:

Console log after .append():

我已经在这个问题上坚持了一段时间了,非常感谢任何关于可能出现问题的想法。我确信我忽略了一些明显的事情......

最佳答案

问题是生成坐标区的代码附加 line元素到 SVG。由于它在附加引用线之前运行,因此调用 svg.selectAll("line").data(...)将现有行与数据进行匹配。行数多于数据元素,因此不需要添加新元素,.enter()选择为空。

有几种方法可以解决这个问题。您可以将生成引用线的代码进一步向上移动。您添加 g包含这些行的元素。您可以为这些行设置一个特殊的类,并相应地调整选择器。或者您可以为 .data() 提供自定义匹配函数.

关于javascript - 将线条附加到 D3 条形图 - 绝对没有任何反应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16942299/

相关文章:

javascript - Django 翻译 - 翻译星期几

javascript - 将鼠标事件分配给 svg :text in d3. js

javascript - Web 开发人员如何查看用户控制台错误?

javascript - 在 TinyMCE 内的元素旁边显示一个按钮

javascript - 从 C# webbrowser 控件捕获 HTTP Web 请求

d3.js - 是否有一个选择查询可以获取除我当前选择之外的所有内容?

javascript - 在 React Redux 中调度操作之前等待多个 Axios 调用

javascript - 将数组转换为一组对象

javascript - 如何将 D3 csv 数据放入不同的变量中

javascript - 将文本放置在 d3 中的形状上