prographs 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -1
- package/README.md +6 -4
- package/dist/AutoGraph-PDPEAIXL.cjs +145 -0
- package/dist/GraphType.js +19 -0
- package/dist/autograph/chartIndex.js +521 -0
- package/dist/autograph/chartModules.js +2 -1
- package/dist/autograph/index.cjs +98 -93
- package/dist/catalog-DI4XZ46L.cjs +142 -0
- package/dist/catalog.js +2 -1
- package/dist/charts/biologycharts/BiologySamples.js +59 -0
- package/dist/charts/biologycharts/PunnettSquare.js +342 -0
- package/dist/charts/biologycharts/biologyEnums.js +22 -1
- package/dist/charts/biologycharts/index.js +5 -3
- package/dist/charts/doecharts/DoeSamples.js +78 -0
- package/dist/charts/doecharts/SipocDiagram.js +453 -0
- package/dist/charts/doecharts/index.js +4 -2
- package/dist/charts/fieldcharts/SpeciesAccumulationCurve.js +350 -0
- package/dist/charts/fieldcharts/fieldEnums.js +8 -1
- package/dist/charts/fieldcharts/index.js +5 -3
- package/dist/charts/signals/AntennaPatternChart.js +492 -0
- package/dist/charts/signals/SignalSamples.js +17 -0
- package/dist/charts/signals/index.js +5 -3
- package/dist/charts/softwarediagrams/ComponentDiagram.js +504 -0
- package/dist/charts/softwarediagrams/DeploymentDiagram.js +419 -0
- package/dist/charts/softwarediagrams/SoftwareSamples.js +283 -1
- package/dist/charts/softwarediagrams/index.js +7 -3
- package/dist/charts/softwarediagrams/softwareEnums.js +45 -1
- package/dist/charts/sportscharts/PowerDurationCurve.js +301 -0
- package/dist/charts/sportscharts/SportsSamples.js +102 -0
- package/dist/charts/sportscharts/TrainingLoadChart.js +325 -0
- package/dist/charts/sportscharts/index.js +6 -2
- package/dist/charts/strategycharts/BassDiffusionChart.js +362 -0
- package/dist/charts/strategycharts/BassModel.js +96 -0
- package/dist/charts/strategycharts/BurnRunwayChart.js +284 -0
- package/dist/charts/strategycharts/CapTableChart.js +366 -0
- package/dist/charts/strategycharts/KanbanBoard.js +324 -0
- package/dist/charts/strategycharts/OkrTree.js +339 -0
- package/dist/charts/strategycharts/StrategyPane.js +27 -0
- package/dist/charts/strategycharts/StrategySamples.js +251 -0
- package/dist/charts/strategycharts/index.js +15 -3
- package/dist/charts/threefields/BsfcMap3DChart.js +231 -0
- package/dist/charts/threefields/CompressorMap3DChart.js +217 -0
- package/dist/charts/threefields/FieldGrid.js +50 -0
- package/dist/charts/threefields/LossLandscape3DChart.js +201 -0
- package/dist/charts/threefields/MapSheet.js +77 -0
- package/dist/charts/threefields/TerrainRoute3DChart.js +201 -0
- package/dist/charts/threefields/TerrainRouteMath.js +40 -0
- package/dist/charts/threefields/ThreeFieldBase.js +117 -0
- package/dist/charts/threefields/ThreeFieldsSamples.js +80 -0
- package/dist/charts/threefields/WaferMap3DChart.js +218 -0
- package/dist/charts/threefields/index.js +19 -0
- package/dist/charts/threesurfaces/index.js +2 -2
- package/dist/charts/tradingcharts/KeltnerChannelChart.js +171 -0
- package/dist/charts/tradingcharts/TradingMath.js +20 -0
- package/dist/charts/tradingcharts/index.js +4 -2
- package/dist/{chunk-ZL6XDXMK.cjs → chunk-26PSLEP4.cjs} +8 -8
- package/dist/{chunk-W3US6EFP.cjs → chunk-2BO5DZUP.cjs} +12 -12
- package/dist/{chunk-5DP7OUSE.cjs → chunk-2GG5YYSC.cjs} +6 -6
- package/dist/{chunk-7FG4JSVO.cjs → chunk-2GL2VNJU.cjs} +253 -33
- package/dist/{chunk-LCWMRCLF.cjs → chunk-2PYOI7OY.cjs} +21 -21
- package/dist/{chunk-JFWJAEBD.cjs → chunk-3U4MCSKI.cjs} +4 -4
- package/dist/{chunk-CUPLHZRR.cjs → chunk-3ZMM3FSK.cjs} +4 -4
- package/dist/{chunk-L2AV62DP.cjs → chunk-4767WQJ7.cjs} +6 -6
- package/dist/{chunk-DA2EYIIP.cjs → chunk-4E7FSSBF.cjs} +1210 -168
- package/dist/{chunk-VS5LQEZB.cjs → chunk-526STI2S.cjs} +5 -5
- package/dist/{chunk-RXIMEK6C.cjs → chunk-55767YPI.cjs} +20 -20
- package/dist/{chunk-JXLSKIUV.cjs → chunk-5FBQOMMT.cjs} +26 -26
- package/dist/{chunk-27PZV5BR.cjs → chunk-5N4Z7MTS.cjs} +4 -4
- package/dist/{chunk-KEWCUIQA.cjs → chunk-5WEV6YWA.cjs} +22 -22
- package/dist/chunk-5XOVVC5X.cjs +3281 -0
- package/dist/{chunk-HK5J7Q2W.cjs → chunk-6HLXVWXU.cjs} +9 -9
- package/dist/{chunk-7JG47RW4.cjs → chunk-6LQT4WJ5.cjs} +25 -25
- package/dist/{chunk-OCVTI6X4.cjs → chunk-6YTWOUFD.cjs} +329 -36
- package/dist/{chunk-W7IQCAVN.cjs → chunk-7F6W6HKL.cjs} +11 -11
- package/dist/{chunk-F2DCJXDM.cjs → chunk-7L6KYU5A.cjs} +21 -21
- package/dist/{chunk-GTGR6LPR.cjs → chunk-A4GIN4FE.cjs} +17 -17
- package/dist/{chunk-B2CETSR6.cjs → chunk-A4US7SA7.cjs} +5 -5
- package/dist/{chunk-3DIF2YYW.cjs → chunk-AOXPBLPW.cjs} +10 -10
- package/dist/{chunk-7TTR4UF5.cjs → chunk-ATI45Z4M.cjs} +2 -2
- package/dist/{chunk-5BFCIX2V.cjs → chunk-CPPMO4IQ.cjs} +434 -148
- package/dist/{chunk-AYZZQ6AC.cjs → chunk-CZ5KGF6Q.cjs} +9 -9
- package/dist/{chunk-7THJ3ZBK.cjs → chunk-D4I35MCE.cjs} +2 -2
- package/dist/{chunk-MCPPFRLN.cjs → chunk-DCGAAN3Z.cjs} +2 -2
- package/dist/{chunk-VABL6CVX.cjs → chunk-DEY36N37.cjs} +21 -21
- package/dist/{chunk-RNCKGJCC.cjs → chunk-DXHXD3DK.cjs} +3 -3
- package/dist/{chunk-A56ZGMVZ.cjs → chunk-E7B45DBZ.cjs} +11 -11
- package/dist/{chunk-DOR6L4MT.cjs → chunk-EJC6EAC5.cjs} +18 -18
- package/dist/{chunk-UPGNM7MA.cjs → chunk-EULJOOMA.cjs} +11 -11
- package/dist/{chunk-G4AZL4GO.cjs → chunk-EYM6LEIF.cjs} +474 -70
- package/dist/{chunk-NJ4X6XGV.cjs → chunk-EZTYX2GH.cjs} +5 -5
- package/dist/chunk-FDD4UP73.cjs +521 -0
- package/dist/{chunk-WJ3VH2Q4.cjs → chunk-GEAIGM3J.cjs} +110 -615
- package/dist/{chunk-P3SBHF43.cjs → chunk-GRUYVXTS.cjs} +2 -2
- package/dist/{chunk-NX4Z5LMS.cjs → chunk-H3SZXND5.cjs} +5 -5
- package/dist/{chunk-EE4S4TOE.cjs → chunk-HS45TOFJ.cjs} +21 -21
- package/dist/chunk-INGOG6OV.cjs +899 -0
- package/dist/{chunk-UDKA6DGT.cjs → chunk-J3CDXZHF.cjs} +4 -4
- package/dist/{chunk-YO6G7TKI.cjs → chunk-JAU5ADEU.cjs} +11 -11
- package/dist/{chunk-22LBK4GA.cjs → chunk-JQEBSHX3.cjs} +4 -4
- package/dist/{chunk-RXX3U7VQ.cjs → chunk-KLXGLMFU.cjs} +10 -10
- package/dist/chunk-KVOX36J3.cjs +327 -0
- package/dist/chunk-L6BGNHFL.cjs +139 -0
- package/dist/{chunk-GMER35L3.cjs → chunk-L7TB7PU5.cjs} +20 -20
- package/dist/{chunk-AFXYNBL2.cjs → chunk-LBTRYEM2.cjs} +4 -4
- package/dist/{chunk-WYYCKIOD.cjs → chunk-LLULNJSP.cjs} +11 -11
- package/dist/{chunk-J27XOSLP.cjs → chunk-LSO46AFV.cjs} +8 -8
- package/dist/{chunk-5XJO45ES.cjs → chunk-LZ2KJ7ZX.cjs} +11 -11
- package/dist/chunk-M4IQ5LIZ.cjs +422 -0
- package/dist/{chunk-Y2KIUKJF.cjs → chunk-MPDHDKYZ.cjs} +11 -11
- package/dist/{chunk-4EMPKRZU.cjs → chunk-MRQ42ZJE.cjs} +3 -3
- package/dist/{chunk-EU5D2MF4.cjs → chunk-MYV4KZWP.cjs} +9 -9
- package/dist/{chunk-XD7KN4UN.cjs → chunk-MZXVLC24.cjs} +6 -6
- package/dist/{chunk-PPSONARU.cjs → chunk-NLBVDFIR.cjs} +41 -2
- package/dist/{chunk-L3PEGMGM.cjs → chunk-NY3TBZY4.cjs} +33 -33
- package/dist/{chunk-6YNYXXB6.cjs → chunk-OGVVSFAR.cjs} +3 -3
- package/dist/{chunk-MLV7QLB6.cjs → chunk-OMTQIQMN.cjs} +6 -6
- package/dist/{chunk-BEEOSNK7.cjs → chunk-PEJJ6TXJ.cjs} +15 -144
- package/dist/{chunk-SOKOWUF5.cjs → chunk-PPGWHIU7.cjs} +2 -2
- package/dist/{chunk-IELWOM2J.cjs → chunk-PPO6SDAN.cjs} +6 -6
- package/dist/{chunk-6JTZZCSL.cjs → chunk-PUMKX5F2.cjs} +3 -3
- package/dist/{chunk-RFOXFY2U.cjs → chunk-PXBYWCNB.cjs} +190 -799
- package/dist/{chunk-3BYXOISI.cjs → chunk-Q3HB3IX6.cjs} +4 -4
- package/dist/{chunk-RXCOVONX.cjs → chunk-RBMUOIXE.cjs} +289 -34
- package/dist/{chunk-MSBNHCSE.cjs → chunk-RJHGCUUD.cjs} +6 -6
- package/dist/{chunk-I6VG7F6Z.cjs → chunk-RSONDMYW.cjs} +708 -141
- package/dist/{chunk-GZDNPHMT.cjs → chunk-SHMPFCUE.cjs} +19 -19
- package/dist/{chunk-ZIBVCOW6.cjs → chunk-SN4FCXFC.cjs} +19 -19
- package/dist/{chunk-7KM52NMN.cjs → chunk-SN5T7WYO.cjs} +2 -2
- package/dist/{chunk-7MSZR65Z.cjs → chunk-SQJZGVDR.cjs} +7 -7
- package/dist/chunk-SYABFMD7.cjs +633 -0
- package/dist/{chunk-2RRFEYFH.cjs → chunk-TICB3MAC.cjs} +16 -16
- package/dist/{chunk-AOOKHUV5.cjs → chunk-U7Z7XYR2.cjs} +5 -5
- package/dist/{chunk-JEWQAXVG.cjs → chunk-UA2THQFV.cjs} +6 -6
- package/dist/{chunk-LHZPAHU3.cjs → chunk-VIK4L2YF.cjs} +112 -521
- package/dist/{chunk-4YWMAQ4J.cjs → chunk-VM2Y6BDY.cjs} +4 -4
- package/dist/{chunk-IRRKE2ZE.cjs → chunk-VMS3KWYI.cjs} +21 -21
- package/dist/{chunk-4SLARW6F.cjs → chunk-VU5NUD46.cjs} +17 -17
- package/dist/{chunk-XHY6TVYG.cjs → chunk-VV5CVOF7.cjs} +13 -13
- package/dist/{chunk-CCIBPGPZ.cjs → chunk-VYSAWPSS.cjs} +57 -57
- package/dist/{chunk-TTNEMQ2A.cjs → chunk-W7YRWEWQ.cjs} +22 -22
- package/dist/{chunk-C7MUOGEW.cjs → chunk-X7R5SY62.cjs} +6 -6
- package/dist/{chunk-ILR5KBMB.cjs → chunk-XOK3KTSS.cjs} +6 -6
- package/dist/{chunk-2CZM2I3T.cjs → chunk-XUIX45VU.cjs} +19 -19
- package/dist/{chunk-TGRMPS3A.cjs → chunk-XWH46PVJ.cjs} +165 -43
- package/dist/{chunk-WQYXXECR.cjs → chunk-Y5XVMK3K.cjs} +6 -6
- package/dist/{chunk-AK4TX2WG.cjs → chunk-YCNKEDTG.cjs} +13 -13
- package/dist/{chunk-PJJB24DU.cjs → chunk-YEF7SE3X.cjs} +20 -20
- package/dist/{chunk-RVLV4XW6.cjs → chunk-YMTVPMU3.cjs} +22 -22
- package/dist/data/index.cjs +2 -2
- package/dist/entries/autograph-lazy.cjs +2 -2
- package/dist/entries/charts/acoustictransport.cjs +3 -3
- package/dist/entries/charts/analysischarts.cjs +3 -3
- package/dist/entries/charts/astrocharts.cjs +3 -3
- package/dist/entries/charts/bars.cjs +3 -3
- package/dist/entries/charts/bayesiancharts.cjs +3 -3
- package/dist/entries/charts/biocharts.cjs +3 -3
- package/dist/entries/charts/biologycharts.cjs +11 -3
- package/dist/entries/charts/biologycharts.d.ts +1 -1
- package/dist/entries/charts/biologycharts.js +3 -2
- package/dist/entries/charts/business.cjs +3 -3
- package/dist/entries/charts/carecharts.cjs +3 -3
- package/dist/entries/charts/chemistrycharts.cjs +3 -3
- package/dist/entries/charts/civicscharts.cjs +3 -3
- package/dist/entries/charts/clinicalcharts.cjs +3 -3
- package/dist/entries/charts/comparison.cjs +3 -3
- package/dist/entries/charts/demography.cjs +3 -3
- package/dist/entries/charts/density.cjs +3 -3
- package/dist/entries/charts/diagrams.cjs +3 -3
- package/dist/entries/charts/distribution.cjs +3 -3
- package/dist/entries/charts/doecharts.cjs +13 -3
- package/dist/entries/charts/doecharts.d.ts +1 -1
- package/dist/entries/charts/doecharts.js +2 -1
- package/dist/entries/charts/earthscience.cjs +3 -3
- package/dist/entries/charts/economicscharts.cjs +3 -3
- package/dist/entries/charts/energycharts.cjs +3 -3
- package/dist/entries/charts/engineering.cjs +3 -3
- package/dist/entries/charts/fieldcharts.cjs +7 -3
- package/dist/entries/charts/fieldcharts.d.ts +1 -1
- package/dist/entries/charts/fieldcharts.js +3 -2
- package/dist/entries/charts/financial.cjs +3 -3
- package/dist/entries/charts/flow.cjs +3 -3
- package/dist/entries/charts/frameworks.cjs +3 -3
- package/dist/entries/charts/genomics.cjs +3 -3
- package/dist/entries/charts/geoflows.cjs +3 -3
- package/dist/entries/charts/geomaps.cjs +3 -3
- package/dist/entries/charts/geosciencecharts.cjs +3 -3
- package/dist/entries/charts/hierarchy.cjs +3 -3
- package/dist/entries/charts/indicators.cjs +3 -3
- package/dist/entries/charts/inferencecharts.cjs +3 -3
- package/dist/entries/charts/layoutcharts.cjs +3 -3
- package/dist/entries/charts/lifescience.cjs +4 -4
- package/dist/entries/charts/linesareas.cjs +3 -3
- package/dist/entries/charts/logisticscharts.cjs +3 -3
- package/dist/entries/charts/machinecharts.cjs +7 -3
- package/dist/entries/charts/machinecharts.d.ts +1 -1
- package/dist/entries/charts/machinecharts.js +2 -1
- package/dist/entries/charts/massive.cjs +3 -3
- package/dist/entries/charts/mathematical.cjs +3 -3
- package/dist/entries/charts/matrix.cjs +3 -3
- package/dist/entries/charts/medicalcharts.cjs +4 -4
- package/dist/entries/charts/mlcharts.cjs +4 -4
- package/dist/entries/charts/modelcharts.cjs +6 -5
- package/dist/entries/charts/multivariate.cjs +3 -3
- package/dist/entries/charts/musiccharts.cjs +3 -3
- package/dist/entries/charts/network.cjs +3 -3
- package/dist/entries/charts/physicscharts.cjs +3 -3
- package/dist/entries/charts/pictorial.cjs +4 -4
- package/dist/entries/charts/portfoliocharts.cjs +3 -3
- package/dist/entries/charts/productcharts.cjs +3 -3
- package/dist/entries/charts/proportion.cjs +3 -3
- package/dist/entries/charts/qualitycharts.cjs +3 -3
- package/dist/entries/charts/radial.cjs +3 -3
- package/dist/entries/charts/reliabilitycharts.cjs +5 -3
- package/dist/entries/charts/scatter.cjs +3 -3
- package/dist/entries/charts/scientific.cjs +3 -3
- package/dist/entries/charts/seriescharts.cjs +3 -3
- package/dist/entries/charts/signals.cjs +7 -3
- package/dist/entries/charts/signals.d.ts +1 -1
- package/dist/entries/charts/signals.js +2 -1
- package/dist/entries/charts/softwarediagrams.cjs +21 -3
- package/dist/entries/charts/softwarediagrams.d.ts +1 -1
- package/dist/entries/charts/softwarediagrams.js +4 -2
- package/dist/entries/charts/sportscharts.cjs +13 -3
- package/dist/entries/charts/sportscharts.d.ts +1 -1
- package/dist/entries/charts/sportscharts.js +3 -1
- package/dist/entries/charts/statistics.cjs +6 -6
- package/dist/entries/charts/strategycharts.cjs +30 -3
- package/dist/entries/charts/strategycharts.d.ts +1 -1
- package/dist/entries/charts/strategycharts.js +6 -1
- package/dist/entries/charts/structure.cjs +3 -3
- package/dist/entries/charts/surveycharts.cjs +3 -3
- package/dist/entries/charts/systemscharts.cjs +3 -3
- package/dist/entries/charts/textcharts.cjs +5 -5
- package/dist/entries/charts/thematicmaps.cjs +4 -4
- package/dist/entries/charts/threebars.cjs +3 -3
- package/dist/entries/charts/threefields.cjs +53 -0
- package/dist/entries/charts/threefields.d.ts +1 -0
- package/dist/entries/charts/threefields.js +6 -0
- package/dist/entries/charts/threeglobe.cjs +3 -3
- package/dist/entries/charts/threenetwork.cjs +3 -3
- package/dist/entries/charts/threestrata.cjs +3 -3
- package/dist/entries/charts/threesurfaces.cjs +7 -3
- package/dist/entries/charts/threesurfaces.d.ts +1 -1
- package/dist/entries/charts/threesurfaces.js +2 -1
- package/dist/entries/charts/threevolume.cjs +4 -4
- package/dist/entries/charts/timeline.cjs +3 -3
- package/dist/entries/charts/tracecharts.cjs +3 -3
- package/dist/entries/charts/trackscharts.cjs +3 -3
- package/dist/entries/charts/tradingcharts.cjs +6 -4
- package/dist/entries/charts/tradingcharts.d.ts +1 -1
- package/dist/entries/charts/tradingcharts.js +2 -1
- package/dist/entries/three.cjs +60 -20
- package/dist/entries/three.d.ts +1 -1
- package/dist/entries/three.js +7 -1
- package/dist/index.cjs +258 -97
- package/dist/index.d.cts +1953 -10
- package/dist/index.d.ts +1953 -10
- package/dist/index.js +26 -5
- package/dist/page/index.cjs +2 -2
- package/dist/react/components.js +58 -1
- package/dist/react/index.cjs +135 -92
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +2 -2
- package/package.json +1 -1
- package/dist/AutoGraph-XLBJQDRB.cjs +0 -140
- package/dist/catalog-O7XGDD2H.cjs +0 -137
- package/dist/chunk-77K2HTRC.cjs +0 -3220
- package/dist/chunk-XEK47TVD.cjs +0 -323
- /package/dist/{chunk-UMEKIIHJ.cjs → chunk-LNWTC72Y.cjs} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SampleData } from "../../data/SampleData.js";
|
|
2
|
+
import { BassModel } from "./BassModel.js";
|
|
2
3
|
import { KanoCategory, KanoCurve } from "./KanoCurve.js";
|
|
3
4
|
// src/charts/strategycharts/StrategySamples.ts
|
|
4
5
|
var round = (value, digits = 1) => +value.toFixed(digits);
|
|
@@ -468,6 +469,190 @@ var TEAMS = [
|
|
|
468
469
|
"Product",
|
|
469
470
|
"Operations"
|
|
470
471
|
];
|
|
472
|
+
/** Each round's buyers and the share of the company after the round that each buys. */
|
|
473
|
+
var ROUNDS = [
|
|
474
|
+
["Founding", []],
|
|
475
|
+
["Seed", [["Angel investors", .05], ["Halden Seed Fund", .14]]],
|
|
476
|
+
["Series A", [
|
|
477
|
+
["Northquill Ventures", .2],
|
|
478
|
+
["Halden Seed Fund", .03],
|
|
479
|
+
["Employee pool", .06]
|
|
480
|
+
]],
|
|
481
|
+
["Series B", [
|
|
482
|
+
["Pellmoor Capital", .15],
|
|
483
|
+
["Northquill Ventures", .03],
|
|
484
|
+
["Employee pool", .03]
|
|
485
|
+
]]
|
|
486
|
+
];
|
|
487
|
+
var STAGES = [
|
|
488
|
+
["Backlog", null],
|
|
489
|
+
["Ready", 4],
|
|
490
|
+
["In progress", 3],
|
|
491
|
+
["Review", 2],
|
|
492
|
+
["Done", null]
|
|
493
|
+
];
|
|
494
|
+
var CARDS = [
|
|
495
|
+
[
|
|
496
|
+
"Gift card balance",
|
|
497
|
+
0,
|
|
498
|
+
"Checkout",
|
|
499
|
+
"Feature"
|
|
500
|
+
],
|
|
501
|
+
[
|
|
502
|
+
"Search by ingredient",
|
|
503
|
+
0,
|
|
504
|
+
"Search",
|
|
505
|
+
"Feature"
|
|
506
|
+
],
|
|
507
|
+
[
|
|
508
|
+
"Archive old orders",
|
|
509
|
+
0,
|
|
510
|
+
"Platform",
|
|
511
|
+
"Chore"
|
|
512
|
+
],
|
|
513
|
+
[
|
|
514
|
+
"Split shipments",
|
|
515
|
+
0,
|
|
516
|
+
"Checkout",
|
|
517
|
+
"Feature"
|
|
518
|
+
],
|
|
519
|
+
[
|
|
520
|
+
"Retry failed payments",
|
|
521
|
+
1,
|
|
522
|
+
"Checkout",
|
|
523
|
+
"Bug"
|
|
524
|
+
],
|
|
525
|
+
[
|
|
526
|
+
"Typo-tolerant search",
|
|
527
|
+
1,
|
|
528
|
+
"Search",
|
|
529
|
+
"Feature"
|
|
530
|
+
],
|
|
531
|
+
[
|
|
532
|
+
"Rotate signing keys",
|
|
533
|
+
1,
|
|
534
|
+
"Platform",
|
|
535
|
+
"Chore"
|
|
536
|
+
],
|
|
537
|
+
[
|
|
538
|
+
"Saved carts sync",
|
|
539
|
+
2,
|
|
540
|
+
"Checkout",
|
|
541
|
+
"Feature"
|
|
542
|
+
],
|
|
543
|
+
[
|
|
544
|
+
"Slow results on mobile",
|
|
545
|
+
2,
|
|
546
|
+
"Search",
|
|
547
|
+
"Bug"
|
|
548
|
+
],
|
|
549
|
+
[
|
|
550
|
+
"Move queues to new cluster",
|
|
551
|
+
2,
|
|
552
|
+
"Platform",
|
|
553
|
+
"Chore"
|
|
554
|
+
],
|
|
555
|
+
[
|
|
556
|
+
"Address lookup",
|
|
557
|
+
2,
|
|
558
|
+
"Checkout",
|
|
559
|
+
"Feature"
|
|
560
|
+
],
|
|
561
|
+
[
|
|
562
|
+
"Tax rounding error",
|
|
563
|
+
3,
|
|
564
|
+
"Checkout",
|
|
565
|
+
"Bug"
|
|
566
|
+
],
|
|
567
|
+
[
|
|
568
|
+
"Filter by dietary need",
|
|
569
|
+
3,
|
|
570
|
+
"Search",
|
|
571
|
+
"Feature"
|
|
572
|
+
],
|
|
573
|
+
[
|
|
574
|
+
"One-page checkout",
|
|
575
|
+
4,
|
|
576
|
+
"Checkout",
|
|
577
|
+
"Feature"
|
|
578
|
+
],
|
|
579
|
+
[
|
|
580
|
+
"Synonym dictionary",
|
|
581
|
+
4,
|
|
582
|
+
"Search",
|
|
583
|
+
"Feature"
|
|
584
|
+
],
|
|
585
|
+
[
|
|
586
|
+
"Upgrade database",
|
|
587
|
+
4,
|
|
588
|
+
"Platform",
|
|
589
|
+
"Chore"
|
|
590
|
+
],
|
|
591
|
+
[
|
|
592
|
+
"Empty results page",
|
|
593
|
+
4,
|
|
594
|
+
"Search",
|
|
595
|
+
"Bug"
|
|
596
|
+
]
|
|
597
|
+
];
|
|
598
|
+
var OBJECTIVES = [
|
|
599
|
+
["Make setup quick for new teams", [
|
|
600
|
+
[
|
|
601
|
+
"Median setup time under 10 minutes",
|
|
602
|
+
72,
|
|
603
|
+
.8
|
|
604
|
+
],
|
|
605
|
+
[
|
|
606
|
+
"Activation rate from 41% to 55%",
|
|
607
|
+
48,
|
|
608
|
+
.6
|
|
609
|
+
],
|
|
610
|
+
[
|
|
611
|
+
"Halve setup support tickets",
|
|
612
|
+
85,
|
|
613
|
+
.9
|
|
614
|
+
]
|
|
615
|
+
]],
|
|
616
|
+
["Earn the trust of larger customers", [
|
|
617
|
+
[
|
|
618
|
+
"Pass the security audit",
|
|
619
|
+
90,
|
|
620
|
+
.9
|
|
621
|
+
],
|
|
622
|
+
[
|
|
623
|
+
"Uptime of 99.95% for the quarter",
|
|
624
|
+
64,
|
|
625
|
+
.7
|
|
626
|
+
],
|
|
627
|
+
[
|
|
628
|
+
"Sign 6 customers over 500 seats",
|
|
629
|
+
33,
|
|
630
|
+
.3
|
|
631
|
+
],
|
|
632
|
+
[
|
|
633
|
+
"Launch single sign-on",
|
|
634
|
+
55,
|
|
635
|
+
.5
|
|
636
|
+
]
|
|
637
|
+
]],
|
|
638
|
+
["Grow revenue from existing accounts", [
|
|
639
|
+
[
|
|
640
|
+
"Net revenue retention of 112%",
|
|
641
|
+
40,
|
|
642
|
+
.5
|
|
643
|
+
],
|
|
644
|
+
[
|
|
645
|
+
"Launch usage-based pricing",
|
|
646
|
+
20,
|
|
647
|
+
.3
|
|
648
|
+
],
|
|
649
|
+
[
|
|
650
|
+
"Expansion pipeline of 1.8M",
|
|
651
|
+
68,
|
|
652
|
+
.7
|
|
653
|
+
]
|
|
654
|
+
]]
|
|
655
|
+
];
|
|
471
656
|
/** SYNTHETIC rows for the strategy diagrams: every company, product, person and number here is invented. */
|
|
472
657
|
var StrategySamples = class {
|
|
473
658
|
/** `{ technology, position, years }`: place on the cycle from 0 to 100, and years to the plateau or the word Obsolete. */
|
|
@@ -593,5 +778,71 @@ var StrategySamples = class {
|
|
|
593
778
|
tenure: round(.5 + u() * 9)
|
|
594
779
|
}));
|
|
595
780
|
}
|
|
781
|
+
/** `{ round, holder, shares }`: the fully diluted shares each holder of an invented company has after each funding round. */
|
|
782
|
+
static capTable(seed = 1) {
|
|
783
|
+
const { u } = SampleData.rng(seed);
|
|
784
|
+
const held = /* @__PURE__ */ new Map([["Founders", 8e6], ["Employee pool", 1e6]]);
|
|
785
|
+
return ROUNDS.flatMap(([round, buyers]) => {
|
|
786
|
+
const stakes = buyers.map(([holder, stake]) => [holder, stake * (.85 + u() * .3)]);
|
|
787
|
+
const before = [...held.values()].reduce((sum, shares) => sum + shares, 0), sold = stakes.reduce((sum, [, stake]) => sum + stake, 0);
|
|
788
|
+
for (const [holder, stake] of stakes) held.set(holder, (held.get(holder) ?? 0) + Math.round(before * stake / (1 - sold) / 1e3) * 1e3);
|
|
789
|
+
return [...held].map(([holder, shares]) => ({
|
|
790
|
+
round,
|
|
791
|
+
holder,
|
|
792
|
+
shares
|
|
793
|
+
}));
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
/** `{ month, balance, burn }`: an invented company's month-end cash and net burn over a year, with one month of net inflow. */
|
|
797
|
+
static burn(seed = 1) {
|
|
798
|
+
const { u, n } = SampleData.rng(seed);
|
|
799
|
+
let balance = Math.round(4600 + u() * 600) * 1e3;
|
|
800
|
+
return Array.from({ length: 12 }, (_, i) => {
|
|
801
|
+
const burn = i === 4 ? -Math.round(40 + u() * 60) * 1e3 : Math.round(175 + 11 * i + n() * 22) * 1e3;
|
|
802
|
+
balance -= burn;
|
|
803
|
+
return {
|
|
804
|
+
month: `${i < 2 ? 2025 : 2026}-${String((i + 10) % 12 + 1).padStart(2, "0")}`,
|
|
805
|
+
balance,
|
|
806
|
+
burn
|
|
807
|
+
};
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
/** `{ task, stage, lane, kind, owner, limit }`: an invented shop team's board, each card carrying its stage's work-in-progress limit. A few cards move on a stage by seed. */
|
|
811
|
+
static kanban(seed = 1) {
|
|
812
|
+
const { u } = SampleData.rng(seed);
|
|
813
|
+
return CARDS.map(([task, stage, lane, kind], i) => ({
|
|
814
|
+
task,
|
|
815
|
+
at: Math.min(STAGES.length - 1, stage + (u() < .2 ? 1 : 0)),
|
|
816
|
+
lane,
|
|
817
|
+
kind,
|
|
818
|
+
owner: PEOPLE[i % PEOPLE.length]
|
|
819
|
+
})).sort((a, b) => a.at - b.at).map(({ at, ...card }) => ({
|
|
820
|
+
...card,
|
|
821
|
+
stage: STAGES[at][0],
|
|
822
|
+
limit: STAGES[at][1]
|
|
823
|
+
}));
|
|
824
|
+
}
|
|
825
|
+
/** `{ objective, keyResult, progress, confidence }` for an invented software firm's quarter: progress 0 to 100, confidence 0 to 1. */
|
|
826
|
+
static okr(seed = 1) {
|
|
827
|
+
const { u } = SampleData.rng(seed);
|
|
828
|
+
return OBJECTIVES.flatMap(([objective, results]) => results.map(([keyResult, progress, confidence]) => ({
|
|
829
|
+
objective,
|
|
830
|
+
keyResult,
|
|
831
|
+
progress: clamp(Math.round(progress + (u() - .5) * 16), 0, 100),
|
|
832
|
+
confidence: round(clamp(confidence + (u() - .5) * .2, 0, 1))
|
|
833
|
+
})));
|
|
834
|
+
}
|
|
835
|
+
/** `{ period, adopters }`: households taking up an invented product in each of its first eight years, drawn from a Bass curve with noise. */
|
|
836
|
+
static bass(seed = 1) {
|
|
837
|
+
const { u, n } = SampleData.rng(seed);
|
|
838
|
+
return BassModel.run({
|
|
839
|
+
p: .02 + u() * .012,
|
|
840
|
+
q: .38 + u() * .1,
|
|
841
|
+
m: Math.round(110 + u() * 40) * 1e3
|
|
842
|
+
}, 8).map((period) => ({
|
|
843
|
+
period: 2018 + period.t,
|
|
844
|
+
adopters: Math.max(0, Math.round(period.adopters * (1 + n() * .035)))
|
|
845
|
+
}));
|
|
846
|
+
}
|
|
596
847
|
};
|
|
597
848
|
export { StrategySamples };
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BassModel } from "./BassModel.js";
|
|
2
|
+
import { StrategyPane } from "./StrategyPane.js";
|
|
2
3
|
import { StrategyRows } from "./StrategyRows.js";
|
|
3
4
|
import { KanoCategory, KanoCurve } from "./KanoCurve.js";
|
|
4
5
|
import { StrategySamples } from "./StrategySamples.js";
|
|
5
6
|
import { StrategyWords } from "./StrategyWords.js";
|
|
7
|
+
import { BassDiffusionChart, BassDiffusionView } from "./BassDiffusionChart.js";
|
|
8
|
+
import { BurnRunwayBalance, BurnRunwayChart, BurnRunwayLayout } from "./BurnRunwayChart.js";
|
|
9
|
+
import { StrategyNotes } from "./StrategyNotes.js";
|
|
6
10
|
import { BusinessModelCanvas, BusinessModelCanvasKind, BusinessModelCanvasNotes } from "./BusinessModelCanvas.js";
|
|
11
|
+
import { CapTableBasis, CapTableChart, CapTableView } from "./CapTableChart.js";
|
|
7
12
|
import { CustomerJourneyEmotionMark, CustomerJourneyEmotionPlace, CustomerJourneyMap, CustomerJourneyStageMark } from "./CustomerJourneyMap.js";
|
|
8
13
|
import { EisenhowerLayout, EisenhowerMatrix, EisenhowerQuadrant, EisenhowerTaskMark } from "./EisenhowerMatrix.js";
|
|
9
14
|
import { FiveForcesArrows, FiveForcesDiagram, FiveForcesForce, FiveForcesRating } from "./FiveForcesDiagram.js";
|
|
10
15
|
import { FootballFieldChart, FootballFieldMark, FootballFieldOrder } from "./FootballFieldChart.js";
|
|
11
16
|
import { StrategyLabels } from "./StrategyLabels.js";
|
|
12
17
|
import { HypeCycleChart, HypeCycleLabels, HypeCycleMarker, HypeCyclePhases } from "./HypeCycleChart.js";
|
|
18
|
+
import { KanbanBoard, KanbanCardDetail } from "./KanbanBoard.js";
|
|
13
19
|
import { KanoAxes, KanoCurveSet, KanoMarker, KanoModelChart, KanoPlacement } from "./KanoModelChart.js";
|
|
14
20
|
import { NineBoxGrid, NineBoxPlacement } from "./NineBoxGrid.js";
|
|
21
|
+
import { OkrTree, OkrTreeLayout, OkrTreeRollup } from "./OkrTree.js";
|
|
15
22
|
import { StrategyCanvasChart, StrategyCanvasOrder } from "./StrategyCanvasChart.js";
|
|
16
23
|
import { TechnologyAdoptionCurve, TechnologyAdoptionSegments } from "./TechnologyAdoptionCurve.js";
|
|
17
24
|
import { WardleyAxis, WardleyMap, WardleyStages } from "./WardleyMap.js";
|
|
@@ -27,6 +34,11 @@ var strategychartsCatalog = [
|
|
|
27
34
|
CustomerJourneyMap,
|
|
28
35
|
EisenhowerMatrix,
|
|
29
36
|
FootballFieldChart,
|
|
30
|
-
NineBoxGrid
|
|
37
|
+
NineBoxGrid,
|
|
38
|
+
CapTableChart,
|
|
39
|
+
BurnRunwayChart,
|
|
40
|
+
KanbanBoard,
|
|
41
|
+
OkrTree,
|
|
42
|
+
BassDiffusionChart
|
|
31
43
|
];
|
|
32
|
-
export { BusinessModelCanvas, BusinessModelCanvasKind, BusinessModelCanvasNotes, CustomerJourneyEmotionMark, CustomerJourneyEmotionPlace, CustomerJourneyMap, CustomerJourneyStageMark, EisenhowerLayout, EisenhowerMatrix, EisenhowerQuadrant, EisenhowerTaskMark, FiveForcesArrows, FiveForcesDiagram, FiveForcesForce, FiveForcesRating, FootballFieldChart, FootballFieldMark, FootballFieldOrder, HypeCycleChart, HypeCycleLabels, HypeCycleMarker, HypeCyclePhases, KanoAxes, KanoCategory, KanoCurve, KanoCurveSet, KanoMarker, KanoModelChart, KanoPlacement, NineBoxGrid, NineBoxPlacement, StrategyCanvasChart, StrategyCanvasOrder, StrategyLabels, StrategyNotes, StrategyRows, StrategySamples, StrategyWords, TechnologyAdoptionCurve, TechnologyAdoptionSegments, WardleyAxis, WardleyMap, WardleyStages, strategychartsCatalog };
|
|
44
|
+
export { BassDiffusionChart, BassDiffusionView, BassModel, BurnRunwayBalance, BurnRunwayChart, BurnRunwayLayout, BusinessModelCanvas, BusinessModelCanvasKind, BusinessModelCanvasNotes, CapTableBasis, CapTableChart, CapTableView, CustomerJourneyEmotionMark, CustomerJourneyEmotionPlace, CustomerJourneyMap, CustomerJourneyStageMark, EisenhowerLayout, EisenhowerMatrix, EisenhowerQuadrant, EisenhowerTaskMark, FiveForcesArrows, FiveForcesDiagram, FiveForcesForce, FiveForcesRating, FootballFieldChart, FootballFieldMark, FootballFieldOrder, HypeCycleChart, HypeCycleLabels, HypeCycleMarker, HypeCyclePhases, KanbanBoard, KanbanCardDetail, KanoAxes, KanoCategory, KanoCurve, KanoCurveSet, KanoMarker, KanoModelChart, KanoPlacement, NineBoxGrid, NineBoxPlacement, OkrTree, OkrTreeLayout, OkrTreeRollup, StrategyCanvasChart, StrategyCanvasOrder, StrategyLabels, StrategyNotes, StrategyPane, StrategyRows, StrategySamples, StrategyWords, TechnologyAdoptionCurve, TechnologyAdoptionSegments, WardleyAxis, WardleyMap, WardleyStages, strategychartsCatalog };
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { ChartFamily, DataShape, Dimension } from "../../core/enums.js";
|
|
2
|
+
import { Scales } from "../../core/Scales.js";
|
|
3
|
+
import { BsfcMath } from "../machinecharts/BsfcMath.js";
|
|
4
|
+
import { MachineChart } from "../machinecharts/MachineChart.js";
|
|
5
|
+
import { MachineMesh } from "../machinecharts/MachineMesh.js";
|
|
6
|
+
import { MachineSamples } from "../machinecharts/MachineSamples.js";
|
|
7
|
+
import { ColorRamp } from "../threesurfaces/ColorRamp.js";
|
|
8
|
+
import { SurfaceGeometry } from "../threesurfaces/SurfaceGeometry.js";
|
|
9
|
+
import { CEIL, FLOOR } from "../threesurfaces/SurfaceSpace.js";
|
|
10
|
+
import { TubeBatch } from "../threesurfaces/TubeBatch.js";
|
|
11
|
+
import { MapSheet } from "./MapSheet.js";
|
|
12
|
+
import { ThreeFieldBase } from "./ThreeFieldBase.js";
|
|
13
|
+
import { max, range, scaleLinear, ticks } from "d3";
|
|
14
|
+
// src/charts/threefields/BsfcMap3DChart.ts
|
|
15
|
+
/** Lines of equal consumption laid on the surface, drawn flat on the floor, or left out. */
|
|
16
|
+
var BsfcMap3DContours = /* @__PURE__ */ function(BsfcMap3DContours) {
|
|
17
|
+
BsfcMap3DContours["Draped"] = "draped-contours";
|
|
18
|
+
BsfcMap3DContours["Floor"] = "floor-contours";
|
|
19
|
+
BsfcMap3DContours["None"] = "no-contours";
|
|
20
|
+
return BsfcMap3DContours;
|
|
21
|
+
}({});
|
|
22
|
+
/** The full-load curve as a wall down to the floor, or as a rail along the edge with its trace on the floor. */
|
|
23
|
+
var BsfcMap3DBoundary = /* @__PURE__ */ function(BsfcMap3DBoundary) {
|
|
24
|
+
BsfcMap3DBoundary["Wall"] = "full-load-wall";
|
|
25
|
+
BsfcMap3DBoundary["Rail"] = "full-load-rail";
|
|
26
|
+
return BsfcMap3DBoundary;
|
|
27
|
+
}({});
|
|
28
|
+
/** `Point` pins the lowest BSFC measured, `Line` joins the most economical point at each power. */
|
|
29
|
+
var BsfcMap3DOptimum = /* @__PURE__ */ function(BsfcMap3DOptimum) {
|
|
30
|
+
BsfcMap3DOptimum["Point"] = "best-point";
|
|
31
|
+
BsfcMap3DOptimum["Line"] = "economy-line";
|
|
32
|
+
BsfcMap3DOptimum["None"] = "no-optimum";
|
|
33
|
+
return BsfcMap3DOptimum;
|
|
34
|
+
}({});
|
|
35
|
+
var BSFC = "BSFC";
|
|
36
|
+
var ECONOMY = "Best economy line";
|
|
37
|
+
/**
|
|
38
|
+
* An engine's fuel map as a bowl: consumption per unit of work as height over speed and torque, cut off by the full-load
|
|
39
|
+
* curve, with the lowest point pinned. Use it to show how wide and how deep the economical region is; the 2D BSFC map
|
|
40
|
+
* takes the same rows and reads the contours more exactly.
|
|
41
|
+
*/
|
|
42
|
+
var BsfcMap3DChart = class BsfcMap3DChart extends ThreeFieldBase {
|
|
43
|
+
static meta = {
|
|
44
|
+
id: "bsfc-map-3d",
|
|
45
|
+
name: "3D engine BSFC map",
|
|
46
|
+
family: ChartFamily.Scientific,
|
|
47
|
+
dimension: Dimension.Three,
|
|
48
|
+
shape: DataShape.Table,
|
|
49
|
+
description: "Raises brake specific fuel consumption into a surface over engine speed and torque, bounded by the full-load curve, with the minimum pinned and constant-power lines across it.",
|
|
50
|
+
tags: [
|
|
51
|
+
"engine map",
|
|
52
|
+
"fuel consumption",
|
|
53
|
+
"fuel island",
|
|
54
|
+
"torque curve",
|
|
55
|
+
"automotive",
|
|
56
|
+
"powertrain",
|
|
57
|
+
"full load"
|
|
58
|
+
],
|
|
59
|
+
sample: (seed) => MachineSamples.bsfcMap(seed),
|
|
60
|
+
variants: {
|
|
61
|
+
contours: Object.values(BsfcMap3DContours),
|
|
62
|
+
boundary: Object.values(BsfcMap3DBoundary),
|
|
63
|
+
power: [true, false],
|
|
64
|
+
optimum: Object.values(BsfcMap3DOptimum)
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
defaults() {
|
|
68
|
+
return {
|
|
69
|
+
...super.defaults(),
|
|
70
|
+
x: "speed",
|
|
71
|
+
y: "torque",
|
|
72
|
+
bsfc: "bsfc",
|
|
73
|
+
contours: "draped-contours",
|
|
74
|
+
boundary: "full-load-wall",
|
|
75
|
+
power: true,
|
|
76
|
+
optimum: "best-point",
|
|
77
|
+
xLabel: "Engine speed (rpm)",
|
|
78
|
+
yLabel: "Torque (N·m)",
|
|
79
|
+
zLabel: "BSFC (g/kWh)"
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
get sweeps() {
|
|
83
|
+
const { data, x, y, bsfc } = this.options;
|
|
84
|
+
return BsfcMath.sweeps((Array.isArray(data) ? data : []).filter((row) => row !== null && typeof row === "object"), x, y, bsfc);
|
|
85
|
+
}
|
|
86
|
+
table() {
|
|
87
|
+
const { x, y, bsfc } = this.options;
|
|
88
|
+
return {
|
|
89
|
+
columns: [
|
|
90
|
+
x,
|
|
91
|
+
y,
|
|
92
|
+
bsfc
|
|
93
|
+
],
|
|
94
|
+
rows: this.sweeps.flat().map((node) => [
|
|
95
|
+
node.x,
|
|
96
|
+
node.y,
|
|
97
|
+
node.z
|
|
98
|
+
])
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/** BSFC at a speed and torque, read off the mesh the surface is drawn from. NaN outside the operating range. */
|
|
102
|
+
static consumption(mesh, speed, torque) {
|
|
103
|
+
const rows = mesh.nodes, last = rows.length - 1;
|
|
104
|
+
if (last < 1 || !(speed >= rows[0][0].x && speed <= rows[last][0].x)) return NaN;
|
|
105
|
+
let j = 0;
|
|
106
|
+
while (j < last - 1 && rows[j + 1][0].x < speed) j++;
|
|
107
|
+
const t = (speed - rows[j][0].x) / (rows[j + 1][0].x - rows[j][0].x || 1);
|
|
108
|
+
const sweep = rows[j].map((node, i) => ({
|
|
109
|
+
y: node.y + (rows[j + 1][i].y - node.y) * t,
|
|
110
|
+
z: node.z + (rows[j + 1][i].z - node.z) * t
|
|
111
|
+
}));
|
|
112
|
+
if (!(torque >= sweep[0].y && torque <= sweep[sweep.length - 1].y)) return NaN;
|
|
113
|
+
let i = 0;
|
|
114
|
+
while (i < sweep.length - 2 && sweep[i + 1].y < torque) i++;
|
|
115
|
+
return sweep[i].z + (sweep[i + 1].z - sweep[i].z) * (torque - sweep[i].y) / (sweep[i + 1].y - sweep[i].y || 1);
|
|
116
|
+
}
|
|
117
|
+
/** A uniform cubic B-spline through `points`, held at both ends: the smoothing the 2D map gives its economy line. */
|
|
118
|
+
static eased(points, pieces = 4) {
|
|
119
|
+
if (points.length < 3) return points.map(([x, y]) => [x, y]);
|
|
120
|
+
const knots = [
|
|
121
|
+
points[0],
|
|
122
|
+
points[0],
|
|
123
|
+
...points,
|
|
124
|
+
points[points.length - 1],
|
|
125
|
+
points[points.length - 1]
|
|
126
|
+
];
|
|
127
|
+
return [...knots.slice(0, -3).flatMap((_, i) => Array.from({ length: pieces }, (_, piece) => {
|
|
128
|
+
const t = piece / pieces, weights = [
|
|
129
|
+
(1 - t) ** 3,
|
|
130
|
+
3 * t ** 3 - 6 * t * t + 4,
|
|
131
|
+
-3 * t ** 3 + 3 * t * t + 3 * t + 1,
|
|
132
|
+
t ** 3
|
|
133
|
+
];
|
|
134
|
+
return [0, 1].map((axis) => weights.reduce((sum, weight, k) => sum + weight * knots[i + k][axis], 0) / 6);
|
|
135
|
+
})), [points[points.length - 1][0], points[points.length - 1][1]]];
|
|
136
|
+
}
|
|
137
|
+
build(ctx) {
|
|
138
|
+
const { contours, boundary, power, optimum } = this.options, { theme, palette } = ctx;
|
|
139
|
+
const sweeps = this.sweeps, measured = sweeps.flat();
|
|
140
|
+
const mesh = new MachineMesh(sweeps, 24, 4), sheet = new MapSheet(mesh, measured, true, [FLOOR + (contours === "floor-contours" ? .55 : .3), CEIL]);
|
|
141
|
+
const ramp = new ColorRamp(palette.sequential), [low, high] = sheet.z;
|
|
142
|
+
const paint = (value) => ramp.at(.08 + .85 * (high - value) / (high - low));
|
|
143
|
+
const tone = palette.color(BSFC);
|
|
144
|
+
const kwh = (value) => `${MachineChart.short(value, 4)} g/kWh`;
|
|
145
|
+
const told = (node, title) => ({
|
|
146
|
+
title,
|
|
147
|
+
rows: [
|
|
148
|
+
["BSFC", kwh(node.z)],
|
|
149
|
+
["Speed", `${Math.round(node.x).toLocaleString("en")} rpm`],
|
|
150
|
+
["Torque", `${MachineChart.short(node.y)} N·m`],
|
|
151
|
+
["Power", `${MachineChart.short(BsfcMath.power(node.x, node.y))} kW`]
|
|
152
|
+
]
|
|
153
|
+
});
|
|
154
|
+
this.box(ctx, {
|
|
155
|
+
x: this.ticks(sheet.x, sheet.across),
|
|
156
|
+
y: this.ticks(sheet.y, sheet.depth),
|
|
157
|
+
z: measured.length ? scaleLinear(sheet.z, [0, 1]).ticks(4).map((value) => [sheet.level(value), Scales.format(value, high - low)]) : []
|
|
158
|
+
});
|
|
159
|
+
if (!measured.length) return;
|
|
160
|
+
const lift = this.rise(ctx);
|
|
161
|
+
if (!mesh.rows) {
|
|
162
|
+
this.dots(ctx, measured.map((node) => sheet.place(node)), .02, (k) => paint(measured[k].z), lift, (k) => told(measured[k]));
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
this.solid(ctx, sheet.geometry(paint), lift, (k) => told(mesh.nodes[Math.floor(k / mesh.columns)][k % mesh.columns]));
|
|
166
|
+
const full = mesh.nodes.map((row) => row[row.length - 1]), edge = full.map((node) => sheet.place(node, .01));
|
|
167
|
+
this.tubes(new TubeBatch(.011).add(edge), lift, theme.ink);
|
|
168
|
+
if (boundary === "full-load-wall") this.solid(ctx, SurfaceGeometry.curtain(full.map((node) => sheet.place(node)), FLOOR + .002, (k) => paint(full[k].z), () => paint(high)), lift);
|
|
169
|
+
else this.tubes(new TubeBatch(.006).add(full.map((node) => sheet.floor(node, .007))), ctx.root, theme.ink);
|
|
170
|
+
const [mx, my, mz] = edge[Math.floor(edge.length / 2)];
|
|
171
|
+
this.tag(ctx, "Full load", [
|
|
172
|
+
mx,
|
|
173
|
+
(my + FLOOR) / 2,
|
|
174
|
+
mz + .02
|
|
175
|
+
], lift);
|
|
176
|
+
const levels = contours === "no-contours" ? [] : sheet.contours(mesh.levels(10));
|
|
177
|
+
const draped = contours === "draped-contours", isolines = new TubeBatch(.004);
|
|
178
|
+
for (const { value, paths } of levels) for (const path of paths) isolines.add(path.map((node) => draped ? sheet.place(node, .004) : sheet.floor(node, .006)), draped ? void 0 : paint(value));
|
|
179
|
+
if (draped) this.tubes(isolines, lift, theme.ink, .55);
|
|
180
|
+
else this.tubes(isolines, ctx.root);
|
|
181
|
+
const peak = max(full, (node) => BsfcMath.power(node.x, node.y)) ?? 0, [first, last] = [full[0].x, full[full.length - 1].x];
|
|
182
|
+
const on = (speed, torque) => ({
|
|
183
|
+
x: speed,
|
|
184
|
+
y: torque,
|
|
185
|
+
z: BsfcMap3DChart.consumption(mesh, speed, torque)
|
|
186
|
+
});
|
|
187
|
+
const lay = (nodes, lifted) => nodes.map((node) => Number.isFinite(node.z) ? sheet.place(node, lifted) : [
|
|
188
|
+
NaN,
|
|
189
|
+
NaN,
|
|
190
|
+
NaN
|
|
191
|
+
]);
|
|
192
|
+
const speeds = range(0, 81).map((i) => first + (last - first) * i / 80);
|
|
193
|
+
const hyperbolas = new TubeBatch(.004);
|
|
194
|
+
for (const kw of power && peak > 0 ? ticks(0, peak, 4).filter((value) => value > 0) : []) {
|
|
195
|
+
const nodes = speeds.map((speed) => on(speed, BsfcMath.torque(speed, kw))), end = nodes.findLast((node) => Number.isFinite(node.z));
|
|
196
|
+
if (nodes.filter((node) => Number.isFinite(node.z)).length < 2 || !end) continue;
|
|
197
|
+
hyperbolas.add(lay(nodes, .006));
|
|
198
|
+
const [x, y, z] = sheet.place(end);
|
|
199
|
+
ctx.label(`${kw} kW`, [
|
|
200
|
+
x + .11,
|
|
201
|
+
y + .02,
|
|
202
|
+
z
|
|
203
|
+
], "muted", 10, lift);
|
|
204
|
+
}
|
|
205
|
+
this.tubes(hyperbolas, lift, theme.surface, .85);
|
|
206
|
+
if (optimum === "economy-line") {
|
|
207
|
+
const economy = BsfcMap3DChart.eased(BsfcMath.economy(mesh, range(1, 25).map((i) => peak * i / 25))).map(([speed, torque]) => on(speed, torque));
|
|
208
|
+
const tube = this.tubes(new TubeBatch(.009).add(lay(economy, .012)), lift, palette.color(ECONOMY));
|
|
209
|
+
if (tube) ctx.pick(tube, () => ({
|
|
210
|
+
title: ECONOMY,
|
|
211
|
+
color: palette.color(ECONOMY),
|
|
212
|
+
rows: [["Joins", "the lowest BSFC at each power"]]
|
|
213
|
+
}));
|
|
214
|
+
}
|
|
215
|
+
const best = optimum === "best-point" ? measured.reduce((lowest, node) => node.z < lowest.z ? node : lowest) : null;
|
|
216
|
+
if (!best) return;
|
|
217
|
+
const drawn = BsfcMap3DChart.consumption(mesh, best.x, best.y);
|
|
218
|
+
this.pins(ctx, [{
|
|
219
|
+
at: sheet.place({
|
|
220
|
+
...best,
|
|
221
|
+
z: Number.isFinite(drawn) ? drawn : best.z
|
|
222
|
+
}, .004),
|
|
223
|
+
text: `Lowest ${kwh(best.z)}`,
|
|
224
|
+
pick: () => ({
|
|
225
|
+
...told(best, "Lowest BSFC"),
|
|
226
|
+
color: tone
|
|
227
|
+
})
|
|
228
|
+
}], lift);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
export { BsfcMap3DBoundary, BsfcMap3DChart, BsfcMap3DContours, BsfcMap3DOptimum };
|