在dc.js seriesChart中为d3.time.scale()添加自定义刻度/标记

时间:2014-03-03 17:39:23

标签: d3.js dc.js

我想为日期轴添加特定日期的标记。请参阅下面的折线图。

我的xAxis由此函数绘制,其中dateMin和dateMax可由用户通过前端(或画笔等)设置。

d3.time.scale.utc().domain([dateMin,dateMax]);

这意味着tickValues会自动计算。

现在,我们的数据有一个固定日期,其中有一个截止日期。例如,我们可能会有截至2014年1月31日的合并数据,然后是2014年2月1日起的预测数据。

我需要做的是在视觉上清楚截止点的截止日期。我已经在日期手动绘制了一条红色垂直线到下面的JPG。但是我如何用d3以编程方式执行此操作?

有一点需要注意的是,用户可能会选择不包括截止日期的日期范围(使用画笔等)(例如,2014年1月1日至2014年1月20日)。在这种情况下,不应绘制任何行。

如果可能的话,如果折线图的实际线条与截止日期不同,那将会更好。它们可以是点缀而不是实心,或者它们的颜色可能不那么饱和(。更亮?),以便在视觉上清楚地表明基础数据尚未合并。

感谢您提供给我的任何提示。

很抱歉我无法将图片发布到StackOverflow,因此我在此处上传了示例:

从答案中试用代码

使用下面的代码,绘制线条和标签,但不是在给定的x值(cutoffDate),而是在时间尺度上“早期”,大约在2014-01-29的晚上。

        var cutoffDate = new Date("2014-02-01T00:00:00Z");

        seriesChart.svg().append("svg:line")
                .attr("x1", xScale(cutoffDate))
                .attr("x2", xScale(cutoffDate))
                .attr("y1", yScale.range()[1])
                .attr("y2", yScale.range()[0])
                .style("stroke", "rgb(225,0,0)")
                .style("stroke-width", "1");

        seriesChart.svg()
                .append("text")
                .attr("text-anchor", "start")
                .attr("x", xScale(cutoffDate))
                .attr("y", 80)
                .text("Projected data");

在此处查看结果: http://i.imgur.com/0PXKFup.jpg

在我原来的问题中,我没有提到我正在使用dc.js中的seriesChart: seriesChart API docs 我认为当它组成seriesChart时,它会对xScale执行某些操作,因此稍后在xScale上设置值将导致显示移位。将进一步调查。

更新:x位置已修复

将svg元素附加到dc.js图表​​的正确方法是不使用

chart.svg().append()

chart.chartBodyG().append()

这可以修复添加到图表中的自定义元素的位置偏移。将此与Lars的回答结合使用。

1 个答案:

答案 0 :(得分:0)

使用一个轴很难实现,但使用单独的轴很容易实现。首先,对于分界线,您可以使用以下代码:

svg.append("line")
   .attr("x1", xScale(cutoffDate))
   .attr("x2", xScale(cutoffDate))
   .attr("y1", yScale.range()[0])
   .attr("y2", yScale.range()[1]);
svg.append("text").attr("x", xScale(cutoffDate) + 10).attr("y", yCoord)
   .text("projected");

要使用不同的样式,请使用两个不同的轴:

var xScale1 = d3.time.scale().domain([..., cutoffDate]).range([0, 100]),
    xScale2 = d3.time.scale().domain([cutoffDate, ...]).range([100, 200]);
svg.append("g").attr("class", "before")
    .call(d3.svg.axis().scale(xScale1));
svg.append("g").attr("class", "after")
   .attr("transform", "translate(" + xScale1.range()[1] + ",0)")
   .call(d3.svg.axis().scale(xScale2));

添加后,您可以使用类或选择单个DOM元素来设置轴的样式。这意味着您最终会得到两个比例 - 使用它们更容易计算坐标,您可以将它们包裹起来:

var xScale = function(x) { return x < cutoffDate ? xScale1(x) : xScale2(x); };

实现这一目标的最佳方式取决于您的具体应用,但上述内容应为您提供如何操作的粗略指南。