Skip to content

Commit 114886c

Browse files
committed
Update line examples
1 parent 2f1df2e commit 114886c

5 files changed

Lines changed: 81 additions & 5 deletions

File tree

docs/anu-examples/areaChartStacked.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,8 @@ export function areaChartStacked(engine){
8282
//Adjust the legend position
8383
legend.position(new BABYLON.Vector3(1.5, -1, 0));
8484

85+
//Shift the entire chart to the left to center it in the default camera view
86+
chart.positionX(-0.25)
87+
8588
return scene;
8689
}

docs/anu-examples/linechart2D.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function linechart2D(engine){
1515
new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 10, -5), scene);
1616
//Add a camera that rotates around the origin and adjust its properties
1717
const camera = new BABYLON.ArcRotateCamera('Camera', 0, 0, 0, new BABYLON.Vector3(0, 0, 0), scene);
18-
camera.position = new BABYLON.Vector3(0, 0, -1.75);
18+
camera.position = new BABYLON.Vector3(0, 0, -3);
1919
camera.wheelPrecision = 20;
2020
camera.minZ = 0;
2121
camera.attachControl(true);
@@ -25,12 +25,13 @@ export function linechart2D(engine){
2525
let dateFormat = d3.timeFormat('%Y');
2626

2727
//Create the D3 functions that we will use to scale our data dimensions to desired output ranges for our visualization
28-
let scaleX = d3.scaleTime().domain(d3.extent(data.map((d) => parseTime(d.date)))).range([-0.5, 0.5]);
29-
let scaleY = d3.scaleLinear().domain([0, Math.max(...data.map(d => d.price))]).range([-0.5, 0.5]).nice();
30-
//Do the same for color, using Anu helper functions map scale outputs to Color4 objects based on the 'schemecategory10' palette from D3
31-
let scaleC = d3.scaleOrdinal(anu.ordinalChromatic('d310').toColor4());
28+
let scaleX = d3.scaleTime().domain(d3.extent(data.map((d) => parseTime(d.date)))).range([-1, 1]);
29+
let scaleY = d3.scaleLinear().domain([0, Math.max(...data.map(d => d.price))]).range([-1, 1]).nice();
30+
//Do the same for color, using Anu helper functions map scale outputs to Color3 objects based on the 'schemecategory10' palette from D3
31+
let scaleC = d3.scaleOrdinal(anu.ordinalChromatic('d310').toColor3());
3232

3333
//Create an array of arrays where each sub-array is an ordered list of Vector3 corresponding to the timeseries for each stock symbol
34+
//These Vectors will be the actual positional values for our lines
3435
let paths = Object.values(data.reduce((acc, d) => {
3536
let position = new BABYLON.Vector3(scaleX(parseTime(d.date)), scaleY(d.price), 0);
3637
(acc[d.symbol] = acc[d.symbol] || []).push(position);
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright : J.P. Morgan Chase & Co.
3+
4+
import * as anu from '@jpmorganchase/anu';
5+
import * as BABYLON from '@babylonjs/core';
6+
import * as d3 from 'd3';
7+
import data from './data/stocks.csv';
8+
9+
//Create and export a function that takes a Babylon engine and returns a Babylon Scene
10+
export function linechart2DTubes(engine){
11+
12+
//Create an empty Scene
13+
const scene = new BABYLON.Scene(engine);
14+
//Add some lighting
15+
new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 10, -5), scene);
16+
//Add a camera that rotates around the origin and adjust its properties
17+
const camera = new BABYLON.ArcRotateCamera('Camera', 0, 0, 0, new BABYLON.Vector3(0, 0, 0), scene);
18+
camera.position = new BABYLON.Vector3(0, 0, -3);
19+
camera.wheelPrecision = 20;
20+
camera.minZ = 0;
21+
camera.attachControl(true);
22+
23+
//Create D3 functions to parse the time and date
24+
let parseTime = d3.timeParse('%b %d %Y');
25+
let dateFormat = d3.timeFormat('%Y');
26+
27+
//Create the D3 functions that we will use to scale our data dimensions to desired output ranges for our visualization
28+
let scaleX = d3.scaleTime().domain(d3.extent(data.map((d) => parseTime(d.date)))).range([-1, 1]);
29+
let scaleY = d3.scaleLinear().domain([0, Math.max(...data.map(d => d.price))]).range([-1, 1]).nice();
30+
//Do the same for color, using Anu helper functions map scale outputs to Color3 objects based on the 'schemecategory10' palette from D3
31+
let scaleC = d3.scaleOrdinal(anu.ordinalChromatic('d310').toColor3());
32+
33+
//Create an array of arrays where each sub-array is an ordered list of Vector3 corresponding to the timeseries for each stock symbol
34+
//These Vectors will be the actual positional values for our lines
35+
let paths = Object.values(data.reduce((acc, d) => {
36+
let position = new BABYLON.Vector3(scaleX(parseTime(d.date)), scaleY(d.price), 0);
37+
(acc[d.symbol] = acc[d.symbol] || []).push(position);
38+
return acc;
39+
}, {} ));
40+
41+
//Create a Center of Transform TransformNode that serves the parent node for all our meshes that make up our chart
42+
let CoT = anu.create('cot', 'cot');
43+
//Select our CoT so that we have it as a Selection object
44+
let chart = anu.selectName('cot', scene);
45+
46+
//Create tubes as children of our CoT that will render the paths we had defined, one tube for each path
47+
let lines = chart.bind('tube', { path: (d) => d, radius: 0.0075 }, paths)
48+
.material((d,n,i) => {
49+
//Set a material for each tube which is what determines its color
50+
const material = new BABYLON.StandardMaterial('LineMaterial' + i);
51+
material.diffuseColor = scaleC(i); //Set base color
52+
material.emissiveColor = scaleC(i).multiplyByFloats(0.25, 0.25, 0.25); //Make a bit brighter, using full values will blow out the color
53+
material.specularColor = BABYLON.Color3.Black(); //Disable reflections
54+
return material;
55+
});
56+
57+
//Use the axes prefab with our two D3 scales with additional customizations
58+
anu.createAxes('myAxes', { scale: { x: scaleX, y: scaleY },
59+
parent: CoT,
60+
domainMaterialOptions: { width: 0.01 },
61+
labelTicks: { x: scaleX.ticks(d3.timeYear) },
62+
labelFormat: { x: dateFormat, y: (text) => '$' + text }
63+
});
64+
65+
return scene;
66+
}

docs/examples/line_chart_2D.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@ aside: false
44

55
<script setup>
66
import { linechart2D } from '../anu-examples/linechart2D.js'
7+
import { linechart2DTubes } from '../anu-examples/linechart2DTubes.js'
78
</script>
89

910
# 2D Line Chart
1011
Basic 2D timeseries using [LineSystem](https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param/line_system/) of five stocks and their prices between 2000 and 2010.
1112

1213
<singleView :scene="linechart2D" />
1314

15+
Alternatively, [Tubes](https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param/tube/) can be used to provide further visual control over each line. In particular, the radius of each Tube can be set (LineSystem does not support this), making the lines easier to see from long distances.
16+
17+
<singleView :scene="linechart2DTubes" />
18+
1419
::: code-group
1520
<<< @/./anu-examples/linechart2D.js
21+
<<< @/./anu-examples/linechart2DTubes.js
1622
:::
4.46 KB
Loading

0 commit comments

Comments
 (0)