Kis*_*ish 48 javascript 3d svg graph d3.js
我正在搜索具有3维(x,y和z)并使用D3.js的图.请告诉我,如果有任何数据可视化网站,我可以找到这样的图表,或者如果d3js.org上有一个我错过了某种方式.
Ame*_*aBR 66
由VividD和Lars Kotthoff联系起来的3D散点图可能是你所要求的最好的例子,但我会反对并暗示你可能会提出错误的问题.
试图在平面屏幕上模拟三个空间维度总是不完美的,并且难以读取数据.但是,在D3中绘制三个不同的数据维度非常容易.您可以为两个数据变量使用水平和垂直布局,然后为第三个变量使用大小,形状,颜色或阴影.
如果所有三个数据变量最好用连续数字表示,那么最好的方法是使用气泡散点图,其中三个显示尺寸是水平位置,垂直位置和气泡大小.
这是一个示例,它还使用在线交互式组件添加通过运动显示的第四个维度:
Bubble Scatterplot - 点击原图
您说过您的三个维度是客户,产品和内容.我不知道"内容"是什么样的价值(数量或类别),但我很确定"客户"和"产品"是类别.
下面是一个示例,其中使用两个分类维度来布置表格,然后表格的每个单元格都包含一个按第三个数字维度调整大小的圆圈.如果您的第三个变量是一个类别,您可以使用一个形状来指示哪个"内容"类型(如果有)与"customer"和"product"的每个配对一起使用:
泡泡矩阵 - 单击原始
这是另一个,其中第三个维度是按颜色而不是按大小显示的.颜色代表连续变量,但您可以轻松选择一组高对比度颜色来表示类别:
彩色矩阵 - 单击原始
当然,一个普通的堆积条形图是显示两个类别和数量的另一种方式:
堆积条形图 - 单击原始
而且您不必停止三个数据变量.如果两个数据变量是您不介意分类到类别中的类别或数字,您可以使用"小多重"方法绘制四个变量,在其中创建表示分类变量的表,然后重复一个图表.每个表格单元格中的其他两个变量.
像这样:
散点图矩阵 - 单击原始
或者这(周和星期几是数据的两个维度,类别/金额是另外两个):
饼图小倍数 - 点击原始
我希望能给你很多想法......
Viv*_*idD 40
一个类似于你所寻求的例子是:
请注意,此示例使用X3DOM,这是一种相当新的尝试,用于标准化HTML中的3D呈现,并非所有浏览器都支持.
关于在X3DOM中使用D3.js的一些其他测试示例:
在D3 Google上搜索X3DOM.
另一种可能有趣的方法是使用D3.js和Three.js,就像这里:
一般来说,D3.js更倾向于数据可视化而不是科学可视化,这意味着它没有广泛支持显示3D空间(除了显示地理3D数据,D3.js支持的方式很好,但是这不是什么需要).
例如(此示例与您的示例无直接关系,仅用于解释):D3提供了用于树木的2D绘制的算法,但是没有提供用于树木的3D放置以及随后在2D屏幕上呈现这种放置的任何装置.
如果您不仅限于D3.js,也许您可以使用其他库来更轻松,更快地实现相同的目标,这些库是专为与您类似的目的而编写的.例如,您可以使用Pre3D.看看这个例子.Pre3D不使用X3DOM,只是2D画布上的纯HTML渲染.我认为它的3D图形的动画(旋转)比第一个D3/X3DOM示例中的那些更平滑.
希望这个答案可以帮到你.
我能找到的最好的例子(非常简单)是:
Highcharts(三维散点图)
http://www.highcharts.com/demo/3d-scatter-draggable
Vis.js(各种3d选项,如条形和点)
http://visjs.org/examples/graph3d/playground/index.html
只需提供x,y和z坐标,设置你喜欢的配置,然后你就笑了.
这是纯javascript + svg解决方案
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'));
Run Code Online (Sandbox Code Playgroud)
<svg id="svg" stroke-width="2"><g id="pointsGroup"></g><g id="linesGroup"></g></svg>
Run Code Online (Sandbox Code Playgroud)
它看起来像一个更恰当的说"3D"的新例子已经出现. http://bl.ocks.org/supereggbert/aff58196188816576af0
这是我做的改编:
http://bl.ocks.org/adrianturcato/cf665b7cca9f6057691a
归档时间: |
|
查看次数: |
55001 次 |
最近记录: |