1

Webソケット接続からフィードされる単純な折れ線グラフがあり、「モノトーン」フィルターを適用して線を滑らかにしているので、新しいデータが入ってくるときに線が調整されるのを避けるために、グラフを切り取って最も非表示にしますこの記事でアドバイスされている最近のデータポイント...

http://bost.ocks.org/mike/path/

しかし、これにより私の軸が正しく見えなくなります。右端には、ご覧のとおり、クリップの長方形と実際の出力ドメインの違いを示すギャップがあります...

ここに画像の説明を入力してください

ドメインのサイズをクリップ長方形に縮小する別のxスケールを追加することでこれを修正することができましたが、それは私にはハックであり、特にクリーンなソリューションではないようです。

これを修正する正しい方法はありますか?

これは、関連する部分を示す簡略化されたコードリストです...

// Create an x-scale
var x = d3.scale.linear()
    .domain([0, saved_points])
    .range([0, width - margin]);

// Create the axis
var xAxis = d3.svg.axis()
            .scale(x)
            .tickSize(-height)
            .tickValues([10,20,30,40,50,60,70,80,90]);

// Clip path truncates the last two points from the line, because adding new
// control points alters the shape of the line, and it "wiggles"
chart.append("defs")
    .append("clipPath")
    .attr("id", "clip")
    .append("rect")
    .attr("width", width - margin - x(2))
    .attr("height", height);

// Create the stack of lines
y_bands = d3.scale.ordinal().rangeBands([0,height]);
line = d3.svg.line()
    .x(function(d,i){ return x(i); })
    .y(function(d,i){
        var a = -1.0 * (y(d.value) / y_bands.domain().length);
        var b = y_bands(d.name);
        var result = a + height - b;
        return result;
    })
    .interpolate("monotone");

// Put the Axis at the bottom of the graph
d3.select("svg")
    .append("svg:g")
    .attr("class", "xaxis")
    .attr("transform", "translate(0," + (height) + ")")
    .call(xAxis);

// Finally create all the paths
chart.selectAll("path")
    .data(my_line_chart.values)
    .enter()
    .append("g")
    .attr("clip-path", "url(#clip)")
    .append("svg:path")
    .attr("class", "line_chart")
    .attr("stroke", function(d, i) { return color(i); })
    .attr('d', function(d,i){ return line(my_line_chart.values[i]);} );
4

1 に答える 1

1

これに対する理想的な解決策は見つかりませんでしたが、質問で述べた手法は機能します。

実際のデータ範囲ではなく、クリップパスサイズに一致する2番目のスケールを作成することで、それを使用して軸を描画し、それらを一致させることができます。

        // define actual scales
        var x = d3.scale.linear()
            .domain([0, saved_points])
            .range([0, width - margin]);

        // Define a scale that's reduced in size of the output range by the
        //  length of two points of the actual scale.
        var fake_x = d3.scale.linear()
            .domain([0, saved_points - 2])
            .range([0, width - margin - x(2)]);

        // Use this fake scale for the axis instead of the real scale.
        var xAxis = d3.svg.axis()
                    .scale(fake_x)
                    .tickSize(-height)
                    .tickValues(ticks);

        // The clip path uses the same width reduced by two points
        chart.append("defs")
            .append("clipPath")
            .attr("id", "clip")
            .append("rect")
            .attr("width", width - margin - x(2))
            .attr("height", height);

この方法で私が見た唯一の欠点は、fake_xスケールのx(2)値が遷移しないため、幅のアニメーション化に問題があることです。

于 2012-07-26T15:19:02.717 に答える