Fix finance 3D scenario scaling
This commit is contained in:
@@ -1296,20 +1296,20 @@
|
|||||||
if (double.TryParse(Convert.ToString(args.Value, CultureInfo.InvariantCulture), NumberStyles.Number, CultureInfo.InvariantCulture, out var value))
|
if (double.TryParse(Convert.ToString(args.Value, CultureInfo.InvariantCulture), NumberStyles.Number, CultureInfo.InvariantCulture, out var value))
|
||||||
{
|
{
|
||||||
_finance3dScenarioFactor = Math.Clamp(value, 0.5d, 1.5d);
|
_finance3dScenarioFactor = Math.Clamp(value, 0.5d, 1.5d);
|
||||||
await RenderFinance3dAsync();
|
await UpdateFinance3dScenarioFactorAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ResetFinance3dScenarioFactor()
|
private async Task ResetFinance3dScenarioFactor()
|
||||||
{
|
{
|
||||||
_finance3dScenarioFactor = 1d;
|
_finance3dScenarioFactor = 1d;
|
||||||
await RenderFinance3dAsync();
|
await UpdateFinance3dScenarioFactorAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SetFinance3dScenarioFactorPreset(double value)
|
private async Task SetFinance3dScenarioFactorPreset(double value)
|
||||||
{
|
{
|
||||||
_finance3dScenarioFactor = Math.Clamp(value, 0.5d, 1.5d);
|
_finance3dScenarioFactor = Math.Clamp(value, 0.5d, 1.5d);
|
||||||
await RenderFinance3dAsync();
|
await UpdateFinance3dScenarioFactorAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RenderFinance3dAsync()
|
private async Task RenderFinance3dAsync()
|
||||||
@@ -1321,10 +1321,19 @@
|
|||||||
await JsRuntime.InvokeVoidAsync("trafagFinance3d.render", _finance3dCanvas, rows, new
|
await JsRuntime.InvokeVoidAsync("trafagFinance3d.render", _finance3dCanvas, rows, new
|
||||||
{
|
{
|
||||||
indicator = _finance3dIndicator,
|
indicator = _finance3dIndicator,
|
||||||
title = ResolveFinance3dIndicatorLabel(_finance3dIndicator)
|
title = ResolveFinance3dIndicatorLabel(_finance3dIndicator),
|
||||||
|
scenarioFactor = Finance3dScenarioAffectsValue ? _finance3dScenarioFactor : 1d
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task UpdateFinance3dScenarioFactorAsync()
|
||||||
|
{
|
||||||
|
await JsRuntime.InvokeVoidAsync(
|
||||||
|
"trafagFinance3d.updateFactor",
|
||||||
|
_finance3dCanvas,
|
||||||
|
Finance3dScenarioAffectsValue ? _finance3dScenarioFactor : 1d);
|
||||||
|
}
|
||||||
|
|
||||||
private IReadOnlyList<object> BuildFinance3dRows()
|
private IReadOnlyList<object> BuildFinance3dRows()
|
||||||
{
|
{
|
||||||
if (_financeResult is null)
|
if (_financeResult is null)
|
||||||
@@ -1351,8 +1360,8 @@
|
|||||||
{
|
{
|
||||||
Finance3dIndicators.IncludedRows => row.IncludedRows,
|
Finance3dIndicators.IncludedRows => row.IncludedRows,
|
||||||
Finance3dIndicators.ExcludedRows => row.ExcludedRows,
|
Finance3dIndicators.ExcludedRows => row.ExcludedRows,
|
||||||
Finance3dIndicators.Deviation => deviation * (decimal)_finance3dScenarioFactor,
|
Finance3dIndicators.Deviation => deviation,
|
||||||
_ => Math.Abs(row.NetSalesActual) * (decimal)_finance3dScenarioFactor
|
_ => Math.Abs(row.NetSalesActual)
|
||||||
};
|
};
|
||||||
return new
|
return new
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
function createThreeScene(canvas, rows, options) {
|
function createThreeScene(canvas, rows, options) {
|
||||||
const THREE = window.THREE;
|
const THREE = window.THREE;
|
||||||
|
const factor = normalizeFactor(options && options.scenarioFactor);
|
||||||
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: false });
|
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: false });
|
||||||
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
|
||||||
renderer.setClearColor(0xf7f9fb, 1);
|
renderer.setClearColor(0xf7f9fb, 1);
|
||||||
@@ -49,6 +50,7 @@
|
|||||||
root.add(new THREE.LineSegments(new THREE.BufferGeometry().setFromPoints(gridPoints), gridMaterial));
|
root.add(new THREE.LineSegments(new THREE.BufferGeometry().setFromPoints(gridPoints), gridMaterial));
|
||||||
|
|
||||||
const barGeometry = new THREE.BoxGeometry(0.68, 1, 0.68);
|
const barGeometry = new THREE.BoxGeometry(0.68, 1, 0.68);
|
||||||
|
const bars = [];
|
||||||
rows.forEach(row => {
|
rows.forEach(row => {
|
||||||
const countryIndex = Math.max(0, axes.countries.indexOf(String(row.country || "-")));
|
const countryIndex = Math.max(0, axes.countries.indexOf(String(row.country || "-")));
|
||||||
const yearIndex = Math.max(0, axes.years.indexOf(Number(row.year || 0)));
|
const yearIndex = Math.max(0, axes.years.indexOf(Number(row.year || 0)));
|
||||||
@@ -60,8 +62,10 @@
|
|||||||
metalness: 0.05
|
metalness: 0.05
|
||||||
});
|
});
|
||||||
const bar = new THREE.Mesh(barGeometry, material);
|
const bar = new THREE.Mesh(barGeometry, material);
|
||||||
bar.scale.y = height;
|
bar.userData.baseHeight = height;
|
||||||
bar.position.set(xStart + countryIndex * (xStep || 2), height / 2, zStart + yearIndex * (zStep || 2));
|
bar.position.set(xStart + countryIndex * (xStep || 2), 0, zStart + yearIndex * (zStep || 2));
|
||||||
|
applyBarFactor(bar, factor);
|
||||||
|
bars.push(bar);
|
||||||
root.add(bar);
|
root.add(bar);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -81,6 +85,8 @@
|
|||||||
targetX: previous ? previous.targetX : 0,
|
targetX: previous ? previous.targetX : 0,
|
||||||
targetY: previous ? previous.targetY : 2.8,
|
targetY: previous ? previous.targetY : 2.8,
|
||||||
targetZ: previous ? previous.targetZ : 0,
|
targetZ: previous ? previous.targetZ : 0,
|
||||||
|
factor,
|
||||||
|
bars,
|
||||||
dragging: false,
|
dragging: false,
|
||||||
dragMode: "rotate",
|
dragMode: "rotate",
|
||||||
lastX: 0,
|
lastX: 0,
|
||||||
@@ -91,6 +97,18 @@
|
|||||||
resizeAndRender(canvas);
|
resizeAndRender(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeFactor(value) {
|
||||||
|
const factor = Number(value);
|
||||||
|
if (!Number.isFinite(factor)) return 1;
|
||||||
|
return Math.max(0.5, Math.min(1.5, factor));
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyBarFactor(bar, factor) {
|
||||||
|
const height = Math.max(0.02, Number(bar.userData.baseHeight || 0.08) * factor);
|
||||||
|
bar.scale.y = height;
|
||||||
|
bar.position.y = height / 2;
|
||||||
|
}
|
||||||
|
|
||||||
function addCanvasLabel(scene, THREE, text, x, y, z, scale) {
|
function addCanvasLabel(scene, THREE, text, x, y, z, scale) {
|
||||||
const labelCanvas = document.createElement("canvas");
|
const labelCanvas = document.createElement("canvas");
|
||||||
labelCanvas.width = 512;
|
labelCanvas.width = 512;
|
||||||
@@ -247,6 +265,13 @@
|
|||||||
renderFallback(canvas, normalizedRows, options || {});
|
renderFallback(canvas, normalizedRows, options || {});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
updateFactor: function (canvas, factor) {
|
||||||
|
const state = stateByCanvas.get(canvas);
|
||||||
|
if (!state || !state.bars) return;
|
||||||
|
state.factor = normalizeFactor(factor);
|
||||||
|
state.bars.forEach(bar => applyBarFactor(bar, state.factor));
|
||||||
|
renderState(state, canvas);
|
||||||
|
},
|
||||||
resize: resizeAndRender,
|
resize: resizeAndRender,
|
||||||
pixelProbe: function (canvas) {
|
pixelProbe: function (canvas) {
|
||||||
const ctx = canvas && canvas.getContext ? canvas.getContext("2d", { willReadFrequently: true }) : null;
|
const ctx = canvas && canvas.getContext ? canvas.getContext("2d", { willReadFrequently: true }) : null;
|
||||||
|
|||||||
Reference in New Issue
Block a user