简体   繁体   English

在 dc.js 中向 SeriesChart 添加水平基线

[英]Adding a horizontal baseline to a SeriesChart in dc.js

So I have a SeriesChart with this code:所以我有一个带有以下代码的 SeriesChart:

'use strict';

var sectorChart = new dc.SeriesChart('#test-chart');

d3.json('php/query.php?option=sectors').then(data => {
    const dateFormatSpecifier = '%Y-%m-%d';
    const dateFormat = d3.timeFormat(dateFormatSpecifier);
    const dateFormatParser = d3.timeParse(dateFormatSpecifier);
    const numberFormat = d3.format('.2f');
    var minDate = new Date();
    var maxDate = new Date();
    var minRatio = .5
    var maxRatio = .5
    data.forEach(d => {
        d.dd = dateFormatParser(d.date);
        d.ratio = +d.ratio; // coerce to number
        if (d.dd < minDate ) minDate = d.dd;
        if (d.dd > maxDate ) maxDate = d.dd;
        if (d.ratio < minRatio ) minRatio = d.ratio
        if (d.ratio > maxRatio ) maxRatio = d.ratio
    });
    
    const ndx = crossfilter(data);
    const all = ndx.groupAll();

    // Dimension is an array of sector and date. 
    // Later we'll take the date for the y-axis 
    // and the sector for the labels
    const dateDimension = ndx.dimension(d => [d.name, d.dd]);
    // group by the average, the value we'll plot
    var avgGroup = dateDimension.group().reduceSum(d => d.average);
    
    sectorChart /* dc.lineChart('#monthly-move-chart', 'chartGroup') */
        .width(990)
        .height(500)
        .chart(c => new dc.LineChart(c))
        .x(d3.scaleTime().domain([minDate, maxDate]))
        .y(d3.scaleLinear().domain([minRatio, maxRatio]))
        .margins({top: 30, right: 10, bottom: 20, left: 40})
        .brushOn(false)
        .yAxisLabel("ratio avg 10")
        .renderHorizontalGridLines(true)
        .dimension(dateDimension)
        .group(avgGroup)
        .seriesAccessor(d => d.key[0])
        .keyAccessor(d => d.key[1])
        .valueAccessor(d => +d.value)
        .legend(dc.legend().x(450).y(15).itemHeight(13).gap(5).horizontal(1).legendWidth(340).autoItemWidth(true));        
    dc.renderAll();
});

It works all right, but now I would like to add a black horizontal line at 0.5 value.它工作正常,但现在我想在 0.5 值处添加一条黑色水平线。 I guess I could modify the query to return a fictious "name" to the dataset with all values at 0.5, but that won't allow me to control the color, and anyway I would like to know if there is a better way, not to mess with the returned data.我想我可以修改查询以将所有值都为 0.5 的数据集返回一个虚构的“名称”,但这不允许我控制颜色,无论如何我想知道是否有更好的方法,而不是弄乱返回的数据。

Edit: According to Gordon's info, I have transposed as good as I could the vertical line to a horizontal line.编辑:根据 Gordon 的信息,我已经尽可能地将垂直线转换为水平线。 It has worked, with some eccentricities.它奏效了,但有些古怪。 One, the line starts at the left side of the viewport, not on the y axis as it should.一,这条线从视口的左侧开始,而不是应该在 y 轴上。 Two, and more mysterious, the line is drawn at 0.51 instead of 0.50.第二,更神秘的是,这条线是在 0.51 而不是 0.50 处绘制的。 I have created a fiddle if anybody wants to play with it.如果有人想玩它,我已经创建了一个小提琴。

Fiddle小提琴

Thanks in advance.提前致谢。

Although you can add artificial data series in order to display extra lines, it's often easier to "escape to D3", especially if the lines are static and don't move.尽管您可以添加人工数据系列以显示额外的行,但“逃到 D3”通常更容易,尤其是当行是 static 并且不移动时。

The row vertical line example shows how to do this. 行垂直线示例显示了如何执行此操作。

The basic outline is:基本大纲是:

  1. use the pretransition event to draw something each time the chart is updated每次更新图表时使用pretransition事件绘制一些东西
  2. create two x/y points of data to draw, using the chart's scales and margins to determine pixel coordinates创建两个要绘制的 x/y 数据点,使用图表的比例和边距来确定像素坐标
  3. select a path with a unique class name (here .extra ) and join the data to it select 具有唯一 class 名称的path (此处.extra )并将数据加入其中

For a horizontal line, it could look like this:对于水平线,它可能如下所示:

    .on('pretransition', function(chart) {
        var y_horiz = 0.5;
        var extra_data = [
            {y: chart.y()(y_horiz) + chart.margins().top, x: chart.margins().left},
            {y: chart.y()(y_horiz) + chart.margins().top, x: chart.margins().left + chart.effectiveWidth()}
        ];
        var line = d3.line()
            .x(function(d) { return d.x; })
            .y(function(d) { return d.y; });
        var chartBody = chart.select('g');
        var path = chartBody.selectAll('path.extra').data([extra_data]);
        path = path.enter()
                .append('path')
                .attr('class', 'extra')
                .attr('stroke', 'black')
                .attr('id', 'oeLine')
                .attr("stroke-width", 1)
                .merge(path);
        path.attr('d', line);
    });

Each X coordinate is offset by chart.margins().left , each Y coordinate by chart.margins().top .每个 X 坐标由chart.margins().left偏移,每个 Y 坐标由chart.margins().top

The width of the chart in pixels is chart.effectiveWidth() and the height in pixels is chart.effectiveHeight() .以像素为单位的图表宽度为chart.effectiveWidth() ,以像素为单位的高度为chart.effectiveHeight() (These are just the .width() and .height() with margins subtracted.) (这些只是减去边距的.width().height() 。)

0.50 处的水平线截图

Fork of your fiddle你的小提琴叉

(Note: the example apparently has a typo, using oeExtra instead of extra in the join. This could cause multiple lines to be drawn when the chart is updated. The class in the select should match the class in the join.) (注意:该示例显然有一个错字,在连接中使用oeExtra而不是extra 。这可能导致在更新图表时绘制多条线。select 中的 class 应与 AB 连接中的 ZA2F2ED4F8EBC2CBB14C21A29DZ40 匹配

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM