8

私はd3を使用して、d3.behavior.zoomを使用したパンとズームを使用して、簡略化されたガントチャートをレンダリングしています。

xスケールは時間スケール(列の暦日を中央に配置するなどにわずかに変更)であり、正常に機能しますが、yスケールをズーム/パンする方法を決定するのに問題があります。そのドメインは、多くの場合、タスクのリストです。チャート領域に収まらないほど多すぎるため、パン/ズームが必要です。

ズーム/パンイベントに反応するようにデフォルトの順序スケールを指示する方法はありますか、またはカスタムスケールを作成する必要がありますか?また、カスタムスケールを作成する必要がある場合は、d3.scale.ordinal(タスクのリスト全体を格納し、表示されているサブセットのみをドメインとして使用する)またはd3.scaleに基づいた方がよいでしょうか。線形(そして、範囲帯域などの順序スケールに似たものを実装しますか?)。

または、私が見逃しているものがありますか(d3を使用した最初のプロジェクトであるため、完全に可能性があります)?

4

2 に答える 2

3

私がこれをどのように行ったかを説明するために私的に連絡されたので、私の前の答えからわずかに拡大します。

まず、問題のアプリのスクリーンショット。主な仕事は、さまざまなソース(PowerPointファイル、企業データベースなど)から収集された計画データを集約して表示することです。

スクリーンショット

関連するビットは、色付きのドットが付いた右側の垂直軸です。各ドットは、プロジェクトの取り組みと関連する組織を表しています。軸の灰色の領域はd3.jsブラシであり、パン/サイズ変更してチャート/テーブルデータをリアルタイムで変更できます。

// the axis is a regular ordinal axis, with a brush
y2 = d3.scale.ordinal(),
brush = d3.svg.brush().y(y2).on('brush', brushReact),
// [...]
// brush event handler
function brushReact() {
    if (tasksSlice == null)
        return;
    var yrb = y2.rangeBand(),
        extent = brush.extent(),
        s0 = Math.round(extent[0]/yrb),
        s1 = Math.round(extent[1]/yrb);
    if (s0 == tasksSlice[0] && s1 == tasksSlice[1])
        return;
    tasksSlice = [s0, s1];
    inner.refresh();
}

ハンドラー内で行われることは非常に単純です。

  • ブラシ範囲を取得する
  • データ配列のインデックスに転置します
  • データ配列をスライスし、結果を表示するデータとして設定します
  • チャートとテーブルを更新します

これで問題が解決することを願っています。

于 2014-10-07T12:59:24.910 に答える
2

それはそれほど難しいことではないことがわかりました、私はしなければなりませんでした:

  • ドメイン値の全範囲を格納し、表示されるドメイン値の範囲を設定するslice([min、max])メソッドを実装することを除いて、d3.scale.ordinalとほとんど同じカスタムスケールを記述します
  • ズームイベントコールバックでy変換デルタを追跡し、合計y変換を格納する変数に追加します
  • 合計変換量が2つの範囲値間のyデルタよりも大きいかどうかを確認し、(可視または非可視)ドメイン境界(0または長さ)のいずれかにまだ達していないことを確認します。スライスインデックスを1ずつインクリメントまたはデクリメントせず、合計変換変数をリセットしてから、軸を再描画します
于 2012-11-12T22:35:54.540 に答える