web-dev-qa-db-ja.com

D3.jsを使用した3次元(X、Y、Z)グラフ

私は3次元(x、y、およびz)を持ち、D3.jsを使用するグラフを検索しています。そのようなグラフを見つけることができるデータビジュアライゼーションサイトがあるかどうか、または d3js.org にあるものがあるかどうかを教えてください。

48
Kish

VividDとLars Kotthoffによってリンクされた3D散布図は、おそらくあなたが求めているものの最良の例ですが、私は反対になり、間違った質問をしているのかもしれません。

フラットスクリーンで3つのspatial次元をシミュレートしようとすると、常に不完全になり、データの読み取りが困難になります。ただし、D3で3つの異なるdataディメンションをグラフ化するのは非常に簡単です。 2つのデータ変数に水平レイアウトと垂直レイアウトを使用し、3番目の変数にサイズ、形状、色、または網かけを使用します。

3つのデータ変数すべてが連続数で最も適切に表される場合、3つの表示次元が水平位置、垂直位置、およびバブルサイズであるバブル散布図を使用するのが最善のアプローチです。

以下は、オンラインインタラクティブコンポーネントを使用して、モーションを介して表示される4番目の次元を追加する例です。
Bubble Scatterplotバブル散布図-オリジナルをクリックしてください

3つの次元はCustomerProduct、およびcontent。 「コンテンツ」がどのような値(数値またはカテゴリ)であるかはわかりませんが、「顧客」と「製品」はカテゴリであると確信しています。

2つのカテゴリディメンションを使用してテーブルをレイアウトし、テーブルの各セルに3番目の数値ディメンションでサイズ設定された円が含まれる例を次に示します。 3番目の変数がカテゴリの場合、形状を使用して、「コンテンツ」タイプ(存在する場合)が「顧客」と「製品」の各ペアに対応することを示すことができます。
Bubble Matrix
バブルマトリックス-クリックしてオリジナル

もう1つは、3番目の次元がサイズではなく色で表示されるものです。色は連続変数を表しますが、カテゴリを表すためにハイコントラスト色のセットを簡単に選択できます。
Colour Matrixカラーマトリックス-クリックしてオリジナル

もちろん、普通の積み上げ棒グラフは、2つのカテゴリと数量を表示する別の方法です。
Stacked Bar Graphs 積み上げ棒グラフ-オリジナルをクリックしてください

また、3つのデータ変数で停止する必要はありません。 2つのデータ変数がカテゴリまたはカテゴリに分類することを気にかけない数値の場合、「小さな倍数」アプローチで4つの変数をグラフ化できます。この場合、カテゴリ変数を表すテーブルを作成し、各テーブルセル内の他の2つの変数。

このような:
Scatterplot Matrix散布図マトリックス-クリックしてオリジナル

または、これ(週と曜日はデータの2つの次元であり、カテゴリ/金額は他の2つの次元です):
Pie Chart Small Multiples
円グラフスモールマルチプル-クリックしてオリジナル

たくさんのアイデアを与えてくれたことを願っています...

66
AmeliaBR

ある種があなたが求めるものに似ている1つの例は次のとおりです。

D散布図

enter image description here

この例では X3DOM を使用していることに注意してください。これは、HTMLで3Dレンダリングを標準化するかなり新しい試みであり、すべてのブラウザーでサポートされているわけではありません。


X3DOMでD3.jsを使用する場合の追加のテスト例:

コールバックテストのX3DOM

D3 X3DOMイベントテスト

D3 GoogleグループでX3DOMも検索してください。


別の潜在的に興味深いアプローチは、次のようにD3.jsとThree.jsを使用することです。

three.jsおよびd3.jsを使用してGPSトラックを3Dで表示


一般に、D3.jsは科学的な視覚化よりもデータの視覚化を重視しています。つまり、D3.jsは優れた方法でサポートする地理的な3Dデータの表示を除き、3D空間の表示を広範囲にサポートしていませんが、これは必要なものではありません)。

たとえば(この例は例に直接関係していない、単に説明のためだけです):D3は木の2D描画のためのアルゴリズムを提供しますが、木の3D配置とそれに続く2D画面上のそのような配置のための装置を提供しません。


D3.jsに限定されていない場合、おそらくあなたと似た目的のために特別に作成された他のライブラリを使用して、同じ目標をより簡単かつ迅速に達成できます。たとえば、 Pre3D を使用できます。これを見てください 。 Pre3DはX3DOMを使用せず、2DキャンバスでのプレーンHTMLレンダリングのみを使用します。 3Dグラフのアニメーション(回転)は、最初のD3/X3DOMの例よりもスムーズだと思います。

40
VividD

私が見つけた最高の例(どちらも信じられないほどシンプルでした)は次のとおりです。

Highcharts(3dスキャッター)

http://www.highcharts.com/demo/3d-scatter-draggable

Vis.js(バーやドットなどのさまざまな3Dオプション)

http://visjs.org/examples/graph3d/playground/index.html

X、y、z座標を指定し、設定を好きなように設定するだけで、笑っています。

9
David Spence

より適切に言えば「3D」の新しい例が出てきたようです。 http://bl.ocks.org/supereggbert/aff58196188816576af

そして、ここに私が作った適応があります:

http://bl.ocks.org/adrianturcato/cf665b7cca9f6057691a

6
aturc

d3-3d を作成しました。これは、3dデータを視覚化するのに役立つd3-pluginです。うまくいけば、これはあなたの目標を達成するのに役立ちます。

enter image description here

6
Niekes

ここに純粋なjavascript+svgソリューション

enter image description here

let f = (x, z) => Math.cos(z/20)*20 + Math.sin(x/10)*10 + x/3*Math.atan2(z,x);

let cos = Math.cos, sin = Math.sin, xyz = 'xyz'.split(''),
    k = 500, a1 = 0, a2 = 0, far = 300, p, w, h, a,
    points = [], lines = [], s = 100;
    
for (var x = -s; x < s; x += 5) 
for (var z = -s; z < s; z += 5) 
  points.Push({x, z, r:2});

for (var i = 0; i < 6; i++) lines.Push([
  {x:-s, y:-s, z:-s, color:`hsl(${i*120},55%,55%)`, state:{}},
  {x:i%3==0?s:-s, y:i%3==1?s:-s, z:i%3==2?s:-s, state:{}}
]);

points.forEach(d=>d.state={fill:`rgb(${d.x+s},${(d.y=f(d.x,d.z))+s},${d.z+s})`});
pointsGroup.innerHTML=points.map((d,i)=>`<circle ind="${i}"></circle>`).join('');
linesGroup.innerHTML=lines.map(d=>`<path stroke="${d[0].color}"></path>`).join('');
let circles = pointsGroup.querySelectorAll('circle');
let paths = linesGroup.querySelectorAll('path');

function project(p) {
  let x = p.x*cos(a1) + p.z*sin(a1);
  let z = p.z*cos(a1) - p.x*sin(a1);
  let y = p.y*cos(a2) +   z*sin(a2);
  let d =   z*cos(a2) - p.y*sin(a2) + far;
  p.state.cx = (k/d)*x + w/2;
  p.state.cy = (k/d)*y + h/2;
  p.state.r = far/d*p.r;
}

function render() {
  if (a) for (var i=0; i<3; i++) 
    xyz.forEach((c, j) => lines[i][0][c] = i==j ? -s : (lines[i][1]=a)[c]);
  points.forEach(project);      
  points.sort((a, b) => a.state.r - b.state.r);
  lines.forEach(line => line.forEach(project));      
  points.forEach((d, i) => Object.entries(d.state)
      .forEach(e => circles[i].setAttribute(...e)));
  lines.forEach((l, i) => paths[i].setAttribute('d', 
     `M${l[0].state.cx} ${l[0].state.cy} L${l[1].state.cx} ${l[1].state.cy}`));
}

let evt = (t, f) => addEventListener(t, e => render(f(e)));
evt('click', e => a = points[e.target.getAttribute('ind')])
evt('wheel', e => k *= 1 - Math.sign(e.deltaY)*0.1);
evt('mouseup', e => p = null);
evt('mousedown', e => p = {x: e.x, y: e.y, a1, a2});
evt('mousemove', e => p && (a1 = p.a1-(e.x-p.x)/100) + (a2 = p.a2-(e.y-p.y)/100));
evt('resize', e=>svg.setAttribute('viewBox',`0 0 ${w=innerWidth} ${h=innerHeight}`));
dispatchEvent(new Event('resize'));
<svg id="svg" stroke-width="2"><g id="pointsGroup"></g><g id="linesGroup"></g></svg>
1

Stefan Niekeは最近、彼のd3-3dプラグインでいくつかのクールなこともやっています: https://bl.ocks.org/Niekes

1
Cliff Coulter