mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
burg temperature graph - corrections
This commit is contained in:
parent
ccb75570da
commit
5f0be0401e
3 changed files with 253 additions and 209 deletions
100
index.html
100
index.html
|
|
@ -1799,7 +1799,7 @@
|
||||||
<span data-tip="Set curve profile">Curve:
|
<span data-tip="Set curve profile">Curve:
|
||||||
<select id="epCurve">
|
<select id="epCurve">
|
||||||
<option>Linear</option>
|
<option>Linear</option>
|
||||||
<option selected>Basis spline</option>
|
<option selected>Basis spline</option>
|
||||||
<option>Bundle</option>
|
<option>Bundle</option>
|
||||||
<option>Cubic Catmull-Rom</option>
|
<option>Cubic Catmull-Rom</option>
|
||||||
<option>Monotone X</option>
|
<option>Monotone X</option>
|
||||||
|
|
@ -1990,61 +1990,62 @@
|
||||||
<div id="burgBody" style="padding-bottom: .3em">
|
<div id="burgBody" style="padding-bottom: .3em">
|
||||||
<div style="display: flex; align-items: center">
|
<div style="display: flex; align-items: center">
|
||||||
<svg data-tip="Burg emblem. Click to edit" class="pointer" viewBox="0 0 200 200" width="13em" height="13em"><use id="burgEmblem"></use></svg>
|
<svg data-tip="Burg emblem. Click to edit" class="pointer" viewBox="0 0 200 200" width="13em" height="13em"><use id="burgEmblem"></use></svg>
|
||||||
<div>
|
<div style="display: grid; grid-auto-rows: minmax(1.6em, auto)">
|
||||||
<div id="burgProvinceAndState" style="font-style: italic; max-width: 16em"></div>
|
<div id="burgProvinceAndState" style="font-style: italic; max-width: 16em"></div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="label">Name:</div>
|
<div class="label">Name:</div>
|
||||||
<input id="burgName" data-tip="Type to rename the burg" autocorrect="off" spellcheck="false" style="width: 8em">
|
<input id="burgName" data-tip="Type to rename the burg" autocorrect="off" spellcheck="false" style="width: 8em">
|
||||||
<span data-tip="Speak the name. You can change voice and language in options" class="speaker">🔊</span>
|
<span data-tip="Speak the name. You can change voice and language in options" class="speaker">🔊</span>
|
||||||
<span id="burgNameReRandom" data-tip="Generate random name for the burg" class="icon-globe pointer"></span>
|
<span id="burgNameReRandom" data-tip="Generate random name for the burg" class="icon-globe pointer"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-tip="Select burg type. Type slightly affects emblem generation">
|
<div data-tip="Select burg type. Type slightly affects emblem generation">
|
||||||
<div class="label">Type:</div>
|
<div class="label">Type:</div>
|
||||||
<select id="burgType" style="width: 8em">
|
<select id="burgType" style="width: 8em">
|
||||||
<option value="Generic">Generic</option>
|
<option value="Generic">Generic</option>
|
||||||
<option value="River">River</option>
|
<option value="River">River</option>
|
||||||
<option value="Lake">Lake</option>
|
<option value="Lake">Lake</option>
|
||||||
<option value="Naval">Naval</option>
|
<option value="Naval">Naval</option>
|
||||||
<option value="Nomadic">Nomadic</option>
|
<option value="Nomadic">Nomadic</option>
|
||||||
<option value="Hunting">Hunting</option>
|
<option value="Hunting">Hunting</option>
|
||||||
<option value="Highland">Highland</option>
|
<option value="Highland">Highland</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-tip="Select dominant culture">
|
<div data-tip="Select dominant culture">
|
||||||
<div class="label">Culture:</div>
|
<div class="label">Culture:</div>
|
||||||
<select id="burgCulture" style="width: 8em"></select>
|
<select id="burgCulture" style="width: 8em"></select>
|
||||||
<span id="burgNameReCulture" data-tip="Generate culture-specific name for the burg" class="icon-book pointer"></span>
|
<span id="burgNameReCulture" data-tip="Generate culture-specific name for the burg" class="icon-book pointer"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-tip="Set burg population">
|
<div data-tip="Set burg population">
|
||||||
<div class="label">Population:</div>
|
<div class="label">Population:</div>
|
||||||
<input id="burgPopulation" type="number" min=0 step=1 style="width: 8em">
|
<input id="burgPopulation" type="number" min=0 step=1 style="width: 8em">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="label">Features:</div>
|
<div class="label">Features:</div>
|
||||||
<span id="burgCapital" data-tip="Shows whether the burg is a state capital. Click to toggle" data-feature="capital" class="burgFeature icon-star"></span>
|
<span id="burgCapital" data-tip="Shows whether the burg is a state capital. Click to toggle" data-feature="capital" class="burgFeature icon-star"></span>
|
||||||
<span id="burgPort" data-tip="Shows whether the burg is a port. Click to toggle" data-feature="port" class="burgFeature icon-anchor"></span>
|
<span id="burgPort" data-tip="Shows whether the burg is a port. Click to toggle" data-feature="port" class="burgFeature icon-anchor"></span>
|
||||||
<span id="burgCitadel" data-tip="Shows whether the burg has a citadel (castle). Click to toggle" data-feature="citadel" class="burgFeature icon-chess-rook" style="font-size: 1.1em"></span>
|
<span id="burgCitadel" data-tip="Shows whether the burg has a citadel (castle). Click to toggle" data-feature="citadel" class="burgFeature icon-chess-rook" style="font-size: 1.1em"></span>
|
||||||
<span id="burgWalls" data-tip="Shows whether the burg is walled. Click to toggle" data-feature="walls" class="burgFeature icon-fort-awesome"></span>
|
<span id="burgWalls" data-tip="Shows whether the burg is walled. Click to toggle" data-feature="walls" class="burgFeature icon-fort-awesome"></span>
|
||||||
<span id="burgPlaza" data-tip="Shows whether the burg is a trade center (has big marketplace). Click to toggle" data-feature="plaza" class="burgFeature icon-store" style="font-size: 1em"></span>
|
<span id="burgPlaza" data-tip="Shows whether the burg is a trade center (has big marketplace). Click to toggle" data-feature="plaza" class="burgFeature icon-store" style="font-size: 1em"></span>
|
||||||
<span id="burgTemple" data-tip="Shows whether the burg is a religious center. Click to toggle" data-feature="temple" class="burgFeature icon-chess-bishop" style="font-size: 1.1em; margin-left: 3px"></span>
|
<span id="burgTemple" data-tip="Shows whether the burg is a religious center. Click to toggle" data-feature="temple" class="burgFeature icon-chess-bishop" style="font-size: 1.1em; margin-left: 3px"></span>
|
||||||
<span id="burgShanty" data-tip="Shows whether the burg has a shanty town. Click to toggle" data-feature="shanty" class="burgFeature icon-campground" style="font-size: 1em"></span>
|
<span id="burgShanty" data-tip="Shows whether the burg has a shanty town. Click to toggle" data-feature="shanty" class="burgFeature icon-campground" style="font-size: 1em"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-tip="Burg mean annual temperature and real-world city for comparison">
|
<div data-tip="Burg mean annual temperature and real-world city for comparison">
|
||||||
<div class="label">Temperature:</div>
|
<div class="label">Temperature:</div>
|
||||||
<span id="burgTemperature"></span>, like in
|
<span id="burgTemperature"></span>, like in
|
||||||
<span id="burgTemperatureLikeIn"></span>
|
<span id="burgTemperatureLikeIn"></span>
|
||||||
</div>
|
<i id="burgTemperatureGraph" data-tip="Show temperature graph for the burg" class="icon-chart-area pointer"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div data-tip="Burg height above mean sea level">
|
<div data-tip="Burg height above mean sea level">
|
||||||
<div class="label">Elevation:</div>
|
<div class="label">Elevation:</div>
|
||||||
<span id="burgElevation"></span> above sea level
|
<span id="burgElevation"></span> above sea level
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -2085,7 +2086,6 @@
|
||||||
<button id="burglLegend" data-tip="Edit free text notes (legend) for this burg" class="icon-edit"></button>
|
<button id="burglLegend" data-tip="Edit free text notes (legend) for this burg" class="icon-edit"></button>
|
||||||
<button id="burgLock" class="icon-lock-open" onmouseover="showElementLockTip(event)"></button>
|
<button id="burgLock" class="icon-lock-open" onmouseover="showElementLockTip(event)"></button>
|
||||||
<button id="burgRemove" data-tip="Remove non-capital burg. Shortcut: Delete" class="icon-trash fastDelete"></button>
|
<button id="burgRemove" data-tip="Remove non-capital burg. Shortcut: Delete" class="icon-trash fastDelete"></button>
|
||||||
<button id="burgTemperatureGraph" data-tip="Shows the temperature graph in the burg" class="icon-chart-area"></button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ function editBurg(id) {
|
||||||
document.getElementById("burglLegend").addEventListener("click", editBurgLegend);
|
document.getElementById("burglLegend").addEventListener("click", editBurgLegend);
|
||||||
document.getElementById("burgLock").addEventListener("click", toggleBurgLockButton);
|
document.getElementById("burgLock").addEventListener("click", toggleBurgLockButton);
|
||||||
document.getElementById("burgRemove").addEventListener("click", removeSelectedBurg);
|
document.getElementById("burgRemove").addEventListener("click", removeSelectedBurg);
|
||||||
document.getElementById("burgTemperatureGraph").addEventListener("click", showTemperatureGraphs);
|
document.getElementById("burgTemperatureGraph").addEventListener("click", showTemperatureGraph);
|
||||||
|
|
||||||
function updateBurgValues() {
|
function updateBurgValues() {
|
||||||
const id = +elSelected.attr("data-id");
|
const id = +elSelected.attr("data-id");
|
||||||
|
|
@ -543,11 +543,11 @@ function editBurg(id) {
|
||||||
const name = elSelected.text();
|
const name = elSelected.text();
|
||||||
editNotes("burg" + id, name);
|
editNotes("burg" + id, name);
|
||||||
}
|
}
|
||||||
function showTemperatureGraphs() {
|
|
||||||
const id = elSelected.attr("data-id");
|
|
||||||
showTGForBurg(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
function showTemperatureGraph() {
|
||||||
|
const id = elSelected.attr("data-id");
|
||||||
|
showBurgTemperatureGraph(id);
|
||||||
|
}
|
||||||
|
|
||||||
function removeSelectedBurg() {
|
function removeSelectedBurg() {
|
||||||
const id = +elSelected.attr("data-id");
|
const id = +elSelected.attr("data-id");
|
||||||
|
|
|
||||||
|
|
@ -1,161 +1,208 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function showTGForBurg(id) {
|
function showBurgTemperatureGraph(id) {
|
||||||
const b = pack.burgs[id];
|
const b = pack.burgs[id];
|
||||||
const lat = mapCoordinates.latN - (b.y / graphHeight) * mapCoordinates.latT;
|
const lat = mapCoordinates.latN - (b.y / graphHeight) * mapCoordinates.latT;
|
||||||
const temperature = grid.cells.temp[pack.cells.g[b.cell]];
|
const temperature = grid.cells.temp[pack.cells.g[b.cell]];
|
||||||
const prec = grid.cells.prec[pack.cells.g[b.cell]];
|
const prec = grid.cells.prec[pack.cells.g[b.cell]];
|
||||||
|
|
||||||
const weights = [
|
|
||||||
[//Layer0
|
|
||||||
//IN0 IN1
|
|
||||||
[10.782752257744338, 2.7100404240962126],
|
|
||||||
[-2.8226802110591462, 51.62920138583541],
|
|
||||||
[-6.6250956268643835, 4.427939197315455],
|
|
||||||
[-59.64690518541339, 41.89084162654791],
|
|
||||||
[-1.3302059550553835, -3.6964487738450913],
|
|
||||||
[-2.5844898544535497, 0.09879268612455298],
|
|
||||||
[-5.58528252533573, -0.23426224364501905],
|
|
||||||
[26.94531337690372, 20.898158905988907],
|
|
||||||
[3.816397481634785, -0.19045424064580757],
|
|
||||||
[-4.835697931609101, -10.748232783636434]
|
|
||||||
],
|
|
||||||
[//Layer1
|
|
||||||
[-2.478952081870123, 0.6405800134306895, -7.136785640930911, -0.2186529024764509, 3.6568435212735424, 31.446026153530838, -19.91005187482281, 0.2543395274783306, -7.036924569659988, -0.7721371621651565],
|
|
||||||
[-197.10583739743538, 6.889921141533474, 0.5058941504631129, 7.7667203434606416, -53.74180550086929, -15.717331715167001, -61.32068414155791, -2.259728220978728, 35.84049189540032, 94.6157364730977],
|
|
||||||
[-5.312011591880851, -0.09923148954215096, -1.7132477487917586, -22.55559652066422, 0.4806107280554336, -26.5583974109492, 2.0558257347014863, 25.815645234787432, -18.569029876991156, -2.6792003366730035],
|
|
||||||
[20.706518520569514, 18.344297403881875, 99.52244671131733, -58.53124969563653, -60.74384321042212, -80.57540534651835, 7.884792406540866, -144.33871131678563, 80.134199744324, 20.50745285622448],
|
|
||||||
[-52.88299538575159, -15.782505343805528, 16.63316001054924, 88.09475330556671, -17.619552086641818, -19.943999528182427, -120.46286026828177, 19.354752020806302, 43.49422099308949, 28.733924806541363],
|
|
||||||
[-2.4621368711159897, -1.2074759925679757, -1.5133898639835084, 2.173715352424188, -5.988707597991683, 3.0234147182203843, 3.3284199340000797, -1.8805161326360575, 5.151910934121654, -1.2540553911612116]
|
|
||||||
],
|
|
||||||
[//Layer2
|
|
||||||
[-0.3357437479474717, 0.01430651794222215, -0.7927524256670906, 0.2121636229648523, 1.0587803023358318, -3.759288325505095],
|
|
||||||
[-1.1988028704442968, 1.3768997508052783, -3.8480086358278816, 0.5289387340947143, 0.5769459339961177, -1.2528318145750772],
|
|
||||||
[1.0074966649240946, 1.155301164699459, -2.974254371052421, 0.47408176553219467, 0.5939042688615264, -0.7631976947131744]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
//From (-∞,∞) to ~[-1,1]
|
|
||||||
const In1 = [(Math.abs(lat) - 26.950680212887473)/48.378128506956,(prec - 12.229929140832644)/29.94402033696607];
|
|
||||||
|
|
||||||
let lastIn = In1;
|
|
||||||
let lstOut = [];
|
|
||||||
for (let levelN = 0; levelN < weights.length ; levelN++) {
|
|
||||||
let layerN = weights[levelN];
|
|
||||||
for (let i = 0; i < layerN.length ; i++) {
|
|
||||||
lstOut[i] = 0;
|
|
||||||
for (let j = 0; j < layerN[i].length ; j++)
|
|
||||||
lstOut[i] = lstOut[i] + lastIn[j]*layerN[i][j] ;
|
|
||||||
//Sigmoid
|
|
||||||
lstOut[i] = 1/(1+Math.exp(-lstOut[i]));
|
|
||||||
}
|
|
||||||
lastIn = lstOut.slice(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//From [0,1] to [min,max]
|
|
||||||
//Standard deviation for average temperature for the year
|
|
||||||
const yearSig = lstOut[0]*62.9466411977018+0.28613807855649165;
|
|
||||||
//Standard deviation for the difference between the minimum and maximum temperatures for the year
|
|
||||||
const yearDelTmpSig = (lstOut[1]*13.541688670361175+0.1414213562373084) > yearSig ? yearSig : (lstOut[1]*13.541688670361175+0.1414213562373084);
|
|
||||||
//Expected value for the difference between the minimum and maximum temperatures for the year
|
|
||||||
const yearDelTmpMu = lstOut[2]*15.266666666666667+0.6416666666666663;
|
|
||||||
|
|
||||||
//Temperature change shape
|
|
||||||
//const formTmp = -Math.cos(data*2*Math.PI) / 2;
|
|
||||||
const delT = yearDelTmpMu/2+0.5*yearDelTmpSig/2;
|
|
||||||
const minT = temperature - ((yearSig+delT) > 15 ? (yearSig+delT) : 15);
|
|
||||||
const maxT = temperature + (temperature - minT);
|
|
||||||
|
|
||||||
const chartWidth = window.innerWidth/2,
|
// prettier-ignore
|
||||||
chartHeight = 300; // height of our land/sea profile, excluding the biomes data below
|
const weights = [
|
||||||
const xOffset = 80,
|
[// Layer0
|
||||||
yOffset = 10; // this is our drawing starting point from top-left (y = 0) of SVG
|
[10.782752257744338, 2.7100404240962126],
|
||||||
|
[-2.8226802110591462, 51.62920138583541],
|
||||||
const xscale = d3.scaleLinear().domain([0,360]).range([0, chartWidth]);
|
[-6.6250956268643835, 4.427939197315455],
|
||||||
const xscale_inv = d3.scaleLinear().domain([0, chartWidth]).range([0,360]);
|
[-59.64690518541339, 41.89084162654791],
|
||||||
const yscale = d3.scaleLinear().domain([minT, maxT]).range([chartHeight, 0]);
|
[-1.3302059550553835, -3.6964487738450913],
|
||||||
const yscale_inv = d3.scaleLinear().domain([chartHeight, 0]).range([minT, maxT]);
|
[-2.5844898544535497, 0.09879268612455298],
|
||||||
|
[-5.58528252533573, -0.23426224364501905],
|
||||||
const dataAverTmp = [];
|
[26.94531337690372, 20.898158905988907],
|
||||||
const dataMinTmp = [];
|
[3.816397481634785, -0.19045424064580757],
|
||||||
const dataMaxTmp = [];
|
[-4.835697931609101, -10.748232783636434]
|
||||||
for (let i = 0; i < 360 ; i++) {
|
],
|
||||||
let formTmp = Math.cos(i/360*2*Math.PI) / 2;
|
[// Layer1
|
||||||
if(lat > 0) formTmp = -formTmp;
|
[-2.478952081870123, 0.6405800134306895, -7.136785640930911, -0.2186529024764509, 3.6568435212735424, 31.446026153530838, -19.91005187482281, 0.2543395274783306, -7.036924569659988, -0.7721371621651565],
|
||||||
const averT = formTmp * yearSig + temperature;
|
[-197.10583739743538, 6.889921141533474, 0.5058941504631129, 7.7667203434606416, -53.74180550086929, -15.717331715167001, -61.32068414155791, -2.259728220978728, 35.84049189540032, 94.6157364730977],
|
||||||
const delT = yearDelTmpMu/2+formTmp*yearDelTmpSig/2;
|
[-5.312011591880851, -0.09923148954215096, -1.7132477487917586, -22.55559652066422, 0.4806107280554336, -26.5583974109492, 2.0558257347014863, 25.815645234787432, -18.569029876991156, -2.6792003366730035],
|
||||||
dataAverTmp.push({x:xscale(i) + xOffset,y:yscale(averT) + yOffset});
|
[20.706518520569514, 18.344297403881875, 99.52244671131733, -58.53124969563653, -60.74384321042212, -80.57540534651835, 7.884792406540866, -144.33871131678563, 80.134199744324, 20.50745285622448],
|
||||||
dataMinTmp.push({x:xscale(i) + xOffset,y:yscale(averT-delT) + yOffset});
|
[-52.88299538575159, -15.782505343805528, 16.63316001054924, 88.09475330556671, -17.619552086641818, -19.943999528182427, -120.46286026828177, 19.354752020806302, 43.49422099308949, 28.733924806541363],
|
||||||
dataMaxTmp.push({x:xscale(i) + xOffset,y:yscale(averT+delT) + yOffset});
|
[-2.4621368711159897, -1.2074759925679757, -1.5133898639835084, 2.173715352424188, -5.988707597991683, 3.0234147182203843, 3.3284199340000797, -1.8805161326360575, 5.151910934121654, -1.2540553911612116]
|
||||||
}
|
],
|
||||||
|
[// Layer2
|
||||||
document.getElementById("epControls").style.visibility = "hidden";
|
[-0.3357437479474717, 0.01430651794222215, -0.7927524256670906, 0.2121636229648523, 1.0587803023358318, -3.759288325505095],
|
||||||
|
[-1.1988028704442968, 1.3768997508052783, -3.8480086358278816, 0.5289387340947143, 0.5769459339961177, -1.2528318145750772],
|
||||||
|
[1.0074966649240946, 1.155301164699459, -2.974254371052421, 0.47408176553219467, 0.5939042688615264, -0.7631976947131744]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
// From (-∞,∞) to ~[-1,1]
|
||||||
|
const In1 = [(Math.abs(lat) - 26.950680212887473) / 48.378128506956, (prec - 12.229929140832644) / 29.94402033696607];
|
||||||
|
|
||||||
$("#elevationProfile").dialog({
|
let lastIn = In1;
|
||||||
title: "Seasonal temperature schedule",
|
let lstOut = [];
|
||||||
resizable: false,
|
|
||||||
width: window.width,
|
|
||||||
close: closeTGForBurg,
|
|
||||||
position: {my: "left top", at: "left+20 bottom-500", of: window, collision: "fit"}
|
|
||||||
});
|
|
||||||
|
|
||||||
draw();
|
for (let levelN = 0; levelN < weights.length; levelN++) {
|
||||||
|
const layerN = weights[levelN];
|
||||||
|
for (let i = 0; i < layerN.length; i++) {
|
||||||
|
lstOut[i] = 0;
|
||||||
|
for (let j = 0; j < layerN[i].length; j++) {
|
||||||
|
lstOut[i] = lstOut[i] + lastIn[j] * layerN[i][j];
|
||||||
|
}
|
||||||
|
// sigmoid
|
||||||
|
lstOut[i] = 1 / (1 + Math.exp(-lstOut[i]));
|
||||||
|
}
|
||||||
|
lastIn = lstOut.slice(0);
|
||||||
|
}
|
||||||
|
|
||||||
function draw() {
|
// Standard deviation for average temperature for the year from [0,1] to [min,max]
|
||||||
|
const yearSig = lstOut[0] * 62.9466411977018 + 0.28613807855649165;
|
||||||
|
// Standard deviation for the difference between the minimum and maximum temperatures for the year
|
||||||
|
const yearDelTmpSig = lstOut[1] * 13.541688670361175 + 0.1414213562373084 > yearSig ? yearSig : lstOut[1] * 13.541688670361175 + 0.1414213562373084;
|
||||||
|
// Expected value for the difference between the minimum and maximum temperatures for the year
|
||||||
|
const yearDelTmpMu = lstOut[2] * 15.266666666666667 + 0.6416666666666663;
|
||||||
|
|
||||||
document.getElementById("elevationGraph").innerHTML = "";
|
// Temperature change shape
|
||||||
const legendSize = 60;
|
const delT = yearDelTmpMu / 2 + (0.5 * yearDelTmpSig) / 2;
|
||||||
|
const minT = temperature - (yearSig + delT > 15 ? yearSig + delT : 15);
|
||||||
|
const maxT = temperature + (temperature - minT);
|
||||||
|
|
||||||
|
// height of land/sea profile, excluding the biomes data below
|
||||||
|
const chartWidth = window.innerWidth / 2;
|
||||||
|
const chartHeight = 300;
|
||||||
|
|
||||||
|
// drawing starting point from top-left (y = 0) of SVG
|
||||||
|
const xOffset = 80;
|
||||||
|
const yOffset = 10;
|
||||||
|
|
||||||
|
const xscale = d3.scaleLinear().domain([0, 360]).range([0, chartWidth]);
|
||||||
|
const xscale_inv = d3.scaleLinear().domain([0, chartWidth]).range([0, 360]);
|
||||||
|
const yscale = d3.scaleLinear().domain([minT, maxT]).range([chartHeight, 0]);
|
||||||
|
const yscale_inv = d3.scaleLinear().domain([chartHeight, 0]).range([minT, maxT]);
|
||||||
|
|
||||||
|
const dataAverTmp = [];
|
||||||
|
const dataMinTmp = [];
|
||||||
|
const dataMaxTmp = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < 360; i++) {
|
||||||
|
let formTmp = Math.cos((i / 360) * 2 * Math.PI) / 2;
|
||||||
|
if (lat > 0) formTmp = -formTmp;
|
||||||
|
const averT = formTmp * yearSig + temperature;
|
||||||
|
const delT = yearDelTmpMu / 2 + (formTmp * yearDelTmpSig) / 2;
|
||||||
|
dataAverTmp.push({x: xscale(i) + xOffset, y: yscale(averT) + yOffset});
|
||||||
|
dataMinTmp.push({x: xscale(i) + xOffset, y: yscale(averT - delT) + yOffset});
|
||||||
|
dataMaxTmp.push({x: xscale(i) + xOffset, y: yscale(averT + delT) + yOffset});
|
||||||
|
}
|
||||||
|
|
||||||
|
drawGraph();
|
||||||
|
$("#alert").dialog({title: "Anual temperature in " + b.name, position: {my: "center", at: "center", of: "svg"}});
|
||||||
|
|
||||||
|
function drawGraph() {
|
||||||
|
alertMessage.innerHTML = "";
|
||||||
|
|
||||||
|
const legendSize = 60;
|
||||||
const chart = d3
|
const chart = d3
|
||||||
.select("#elevationGraph")
|
.select("#alertMessage")
|
||||||
.append("svg")
|
.append("svg")
|
||||||
.attr("width", chartWidth + 120)
|
.attr("width", chartWidth + 120)
|
||||||
.attr("height", chartHeight + yOffset + legendSize)
|
.attr("height", chartHeight + yOffset + legendSize)
|
||||||
.attr("id", "elevationSVG")
|
.attr("id", "elevationSVG")
|
||||||
.attr("class", "epbackground");
|
.attr("class", "epbackground");
|
||||||
|
|
||||||
// arrow-head definition
|
// arrow-head definition
|
||||||
chart.append("defs").append("marker").attr("id", "arrowhead").attr("orient", "auto").attr("markerWidth", "2").attr("markerHeight", "4").attr("refX", "0.1").attr("refY", "2");
|
chart
|
||||||
|
.append("defs")
|
||||||
|
.append("marker")
|
||||||
|
.attr("id", "arrowhead")
|
||||||
|
.attr("orient", "auto")
|
||||||
|
.attr("markerWidth", "2")
|
||||||
|
.attr("markerHeight", "4")
|
||||||
|
.attr("refX", "0.1")
|
||||||
|
.attr("refY", "2");
|
||||||
|
|
||||||
let Gen = d3.line().curve(d3.curveBasis).x((p) => p.x).y((p) => p.y);
|
let Gen = d3
|
||||||
|
.line()
|
||||||
|
.curve(d3.curveBasis)
|
||||||
|
.x(p => p.x)
|
||||||
|
.y(p => p.y);
|
||||||
|
|
||||||
|
//print graphs
|
||||||
|
chart
|
||||||
|
.append("g")
|
||||||
|
.append("path")
|
||||||
|
.attr("d", Gen(dataAverTmp))
|
||||||
|
.attr("fill", "none")
|
||||||
|
.attr("stroke", "orange")
|
||||||
|
.on("mousemove", printVal)
|
||||||
|
.style("stroke-width", "2");
|
||||||
|
chart
|
||||||
|
.append("g")
|
||||||
|
.append("path")
|
||||||
|
.attr("d", Gen(dataMinTmp))
|
||||||
|
.attr("fill", "none")
|
||||||
|
.attr("stroke", "blue")
|
||||||
|
.on("mousemove", printVal)
|
||||||
|
.style("stroke-width", "2");
|
||||||
|
chart.append("g").append("path").attr("d", Gen(dataMaxTmp)).attr("fill", "none").attr("stroke", "red").on("mousemove", printVal).style("stroke-width", "2");
|
||||||
|
|
||||||
|
//print legend
|
||||||
|
chart
|
||||||
|
.append("circle")
|
||||||
|
.attr("cx", (chartWidth * 1) / 4)
|
||||||
|
.attr("cy", chartHeight + yOffset + legendSize * 0.8)
|
||||||
|
.attr("r", 4)
|
||||||
|
.style("fill", "red");
|
||||||
|
chart
|
||||||
|
.append("text")
|
||||||
|
.attr("x", (chartWidth * 1) / 4 + 20)
|
||||||
|
.attr("y", chartHeight + yOffset + legendSize * 0.8)
|
||||||
|
.text("Day temperature")
|
||||||
|
.style("font-size", "10px")
|
||||||
|
.attr("alignment-baseline", "middle");
|
||||||
|
chart
|
||||||
|
.append("circle")
|
||||||
|
.attr("cx", (chartWidth * 2) / 4)
|
||||||
|
.attr("cy", chartHeight + yOffset + legendSize * 0.8)
|
||||||
|
.attr("r", 4)
|
||||||
|
.style("fill", "orange");
|
||||||
|
chart
|
||||||
|
.append("text")
|
||||||
|
.attr("x", (chartWidth * 2) / 4 + 20)
|
||||||
|
.attr("y", chartHeight + yOffset + legendSize * 0.8)
|
||||||
|
.text("Average daily temperature")
|
||||||
|
.style("font-size", "10px")
|
||||||
|
.attr("alignment-baseline", "middle");
|
||||||
|
chart
|
||||||
|
.append("circle")
|
||||||
|
.attr("cx", (chartWidth * 3) / 4)
|
||||||
|
.attr("cy", chartHeight + yOffset + legendSize * 0.8)
|
||||||
|
.attr("r", 4)
|
||||||
|
.style("fill", "blue");
|
||||||
|
chart
|
||||||
|
.append("text")
|
||||||
|
.attr("x", (chartWidth * 3) / 4 + 20)
|
||||||
|
.attr("y", chartHeight + yOffset + legendSize * 0.8)
|
||||||
|
.text("Night temperature")
|
||||||
|
.style("font-size", "10px")
|
||||||
|
.attr("alignment-baseline", "middle");
|
||||||
|
|
||||||
|
//print title
|
||||||
|
let timerId = setTimeout(() => chart.attr("data-tip", "Seasonal temperature schedule"), 1000);
|
||||||
|
|
||||||
|
const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
||||||
|
//Val under line
|
||||||
|
function printVal() {
|
||||||
|
let m = d3.mouse(this);
|
||||||
|
let tmp = convertTemperature(yscale_inv(m[1] - yOffset).toFixed(1));
|
||||||
|
let month = months[parseInt((xscale_inv(m[0] - xOffset) / 360) * 12)];
|
||||||
|
chart.attr("data-tip", tmp + " in " + month);
|
||||||
|
clearTimeout(timerId);
|
||||||
|
timerId = setTimeout(() => chart.attr("data-tip", "Seasonal temperature schedule"), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
//print graphs
|
|
||||||
chart.append("g").append("path").attr("d", Gen(dataAverTmp))
|
|
||||||
.attr("fill", "none").attr("stroke", "orange").on("mousemove", printVal).style("stroke-width", "2");
|
|
||||||
chart.append("g").append("path").attr("d", Gen(dataMinTmp))
|
|
||||||
.attr("fill", "none").attr("stroke", "blue").on("mousemove", printVal).style("stroke-width", "2");
|
|
||||||
chart.append("g").append("path").attr("d", Gen(dataMaxTmp))
|
|
||||||
.attr("fill", "none").attr("stroke", "red").on("mousemove", printVal).style("stroke-width", "2");
|
|
||||||
|
|
||||||
//print legend
|
|
||||||
chart.append("circle").attr("cx",chartWidth*1/4).attr("cy",chartHeight + yOffset + legendSize*0.8).attr("r", 4).style("fill", "red")
|
|
||||||
chart.append("text").attr("x", chartWidth*1/4+20).attr("y", chartHeight + yOffset + legendSize*0.8)
|
|
||||||
.text("Day temperature").style("font-size", "10px").attr("alignment-baseline","middle")
|
|
||||||
chart.append("circle").attr("cx",chartWidth*2/4).attr("cy",chartHeight + yOffset + legendSize*0.8).attr("r", 4).style("fill", "orange")
|
|
||||||
chart.append("text").attr("x", chartWidth*2/4+20).attr("y", chartHeight + yOffset + legendSize*0.8)
|
|
||||||
.text("Average daily temperature").style("font-size", "10px").attr("alignment-baseline","middle")
|
|
||||||
chart.append("circle").attr("cx",chartWidth*3/4).attr("cy",chartHeight + yOffset + legendSize*0.8).attr("r", 4).style("fill", "blue")
|
|
||||||
chart.append("text").attr("x", chartWidth*3/4+20).attr("y", chartHeight + yOffset + legendSize*0.8)
|
|
||||||
.text("Night temperature").style("font-size", "10px").attr("alignment-baseline","middle")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//print title
|
|
||||||
let timerId = setTimeout(() => chart.attr("data-tip", "Seasonal temperature schedule"), 1000);
|
|
||||||
|
|
||||||
const months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
|
|
||||||
//Val under line
|
|
||||||
function printVal(){
|
|
||||||
let m = d3.mouse(this);
|
|
||||||
let tmp = convertTemperature(yscale_inv(m[1]-yOffset).toFixed(1));
|
|
||||||
let month = months[parseInt(xscale_inv(m[0]-xOffset)/360*12)];
|
|
||||||
chart.attr("data-tip", tmp + " in " + month);
|
|
||||||
clearTimeout(timerId);
|
|
||||||
timerId = setTimeout(() => chart.attr("data-tip", "Seasonal temperature schedule"), 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
const xAxis = d3
|
const xAxis = d3
|
||||||
.axisBottom(xscale)
|
.axisBottom(xscale)
|
||||||
.ticks(10)
|
.ticks(10)
|
||||||
.tickFormat(function (d) {
|
.tickFormat(function (d) {
|
||||||
return months[parseInt(d/360*12)];
|
return months[parseInt((d / 360) * 12)];
|
||||||
});
|
});
|
||||||
const yAxis = d3
|
const yAxis = d3
|
||||||
.axisLeft(yscale)
|
.axisLeft(yscale)
|
||||||
|
|
@ -192,16 +239,18 @@ function showTGForBurg(id) {
|
||||||
.attr("stroke-dasharray", "4 1")
|
.attr("stroke-dasharray", "4 1")
|
||||||
.attr("transform", "translate(" + xOffset + "," + parseInt(chartHeight + +yOffset) + ")")
|
.attr("transform", "translate(" + xOffset + "," + parseInt(chartHeight + +yOffset) + ")")
|
||||||
.call(xGrid);
|
.call(xGrid);
|
||||||
|
|
||||||
if(minT < 0 && maxT > 0){
|
if (minT < 0 && maxT > 0) {
|
||||||
//add zero lv
|
//add zero lv
|
||||||
chart.append("g").append("line")
|
chart
|
||||||
.attr("x1", xscale(0) + xOffset)
|
.append("g")
|
||||||
.attr("y1", yscale(0) + yOffset)
|
.append("line")
|
||||||
.attr("x2", xscale(360) + xOffset)
|
.attr("x1", xscale(0) + xOffset)
|
||||||
.attr("y2", yscale(0) + yOffset)
|
.attr("y1", yscale(0) + yOffset)
|
||||||
.attr("stroke", "black");
|
.attr("x2", xscale(360) + xOffset)
|
||||||
}
|
.attr("y2", yscale(0) + yOffset)
|
||||||
|
.attr("stroke", "black");
|
||||||
|
}
|
||||||
|
|
||||||
// add the Y gridlines
|
// add the Y gridlines
|
||||||
chart
|
chart
|
||||||
|
|
@ -212,9 +261,4 @@ function showTGForBurg(id) {
|
||||||
.attr("transform", "translate(" + xOffset + "," + yOffset + ")")
|
.attr("transform", "translate(" + xOffset + "," + yOffset + ")")
|
||||||
.call(yGrid);
|
.call(yGrid);
|
||||||
}
|
}
|
||||||
function closeTGForBurg() {
|
}
|
||||||
document.getElementById("epControls").style.visibility = "visible";
|
|
||||||
document.getElementById("elevationGraph").innerHTML = "";
|
|
||||||
modules.elevation = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue