class TriangleSingleRisk extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
let ball_0 = document.getElementById("ball_0")
let ball_1 = document.getElementById("ball_1")
let ball_2 = document.getElementById("ball_2")
let x_start = parseInt(window.getComputedStyle(ball_0).left, 10) + 45
let y_start = parseInt(window.getComputedStyle(ball_0).top, 10) + 12.5
let x_end = parseInt(window.getComputedStyle(ball_1).left, 10)
let y_end = parseInt(window.getComputedStyle(ball_1).top, 10) + 25
var newLine = document.createElementNS('http://www.w3.org/2000/svg','line');
newLine.setAttribute('id','line1');
newLine.setAttribute('x1',x_start );
newLine.setAttribute('y1',y_start);
newLine.setAttribute('x2',x_end);
newLine.setAttribute('y2',y_end);
newLine.setAttribute("stroke", "black")
$("#lineSVG").append(newLine);
x_start = parseInt(window.getComputedStyle(ball_0).left, 10) + 46
y_start = parseInt(window.getComputedStyle(ball_0).top, 10) + 37.5
x_end = parseInt(window.getComputedStyle(ball_2).left, 10)
y_end = parseInt(window.getComputedStyle(ball_2).top, 10) + 20
newLine = document.createElementNS('http://www.w3.org/2000/svg','line');
newLine.setAttribute('id','line2');
newLine.setAttribute('x1',x_start );
newLine.setAttribute('y1',y_start);
newLine.setAttribute('x2',x_end);
newLine.setAttribute('y2',y_end);
newLine.setAttribute("stroke", "black")
$("#lineSVG").append(newLine);
}
render() {
const upTick = this.props.upTick
const downTick = (this.props.downTick || -this.props.upTick) // Use downTick only if supplied
return (
<>
>
)
}
}
class DecisionTree extends React.Component {
constructor(props) {
super(props);
this.componentDidMount = this.componentDidMount.bind(this);
this.drawLines = this.drawLines.bind(this);
}
componentDidMount() {
let round = this.props.currentRound
let lastID = this.props.drawn[round]
let submittedContinuation = [-500, -500] // Initialize with nonsensical values
if (this.props.continuationDec) {
submittedContinuation = this.props.continuationDec.slice(0,this.props.currentRound + 1)
}
let submittedStop = submittedContinuation.findIndex(element => element == "Stop")
if (this.props.pulse && lastID >= 0 && round <5 && submittedStop == -1) {
// Make current ball pulse
document.getElementById("ball_"+lastID).classList.add("pulse")
}
// Draw lines
if (round >= 1) {
// Clear canvas before painting
$("#lineSVG").empty();
for (let i = 1; i <= round; i++) {
let ele1 = this.props.drawn[i-1]
let ele2 = this.props.drawn[i]
if (!(i > submittedStop && submittedStop != -1)) {
this.drawLines(ele1, ele2, i)
}
}
}
}
drawLines(id1, id2, layer) {
let start = document.getElementById("ball_"+ id1)
let end = document.getElementById("ball_" + id2)
let x_start = parseInt(window.getComputedStyle(start).left, 10) + 25
let y_start = 0
let x_end = parseInt(window.getComputedStyle(end).left, 10)
let y_end = 0
let color = "black"
if (id2-id1 == layer) {
//Up move
y_start = parseInt(window.getComputedStyle(start).top, 10) + 8
y_end = parseInt(window.getComputedStyle(end).top, 10) + 18
color = "#0f5132"
} else if (id2-id1 == layer + 1) {
// Down mode
y_start = parseInt(window.getComputedStyle(start).top, 10) + 18
y_end = parseInt(window.getComputedStyle(end).top, 10) + 8
color = "#842029"
}
if (window.getComputedStyle(start).left.indexOf('%') >= 0) {
// Need to overwrite values
let bg = document.getElementById("lineSVG")
let width = parseInt(bg.style.width)
let height = parseInt(bg.style.height)
x_start = (parseInt(window.getComputedStyle(start).left, 10) * width / 100) + 25
x_end = (parseInt(window.getComputedStyle(end).left, 10) * width / 100)
if (id2-id1 == layer) {
y_start = (parseInt(window.getComputedStyle(start).top, 10) * height / 100) + 8
y_end = (parseInt(window.getComputedStyle(end).top, 10) * height / 100) + 18
} else if (id2-id1 == layer + 1) {
// Down move
y_start = (parseInt(window.getComputedStyle(start).top, 10) * height / 100) + 18
y_end = (parseInt(window.getComputedStyle(end).top, 10) * height / 100) + 8
}
}
var newLine = document.createElementNS('http://www.w3.org/2000/svg','line');
newLine.setAttribute('id',"line_"+layer);
newLine.setAttribute('x1',x_start );
newLine.setAttribute('y1',y_start);
newLine.setAttribute('x2',x_end);
newLine.setAttribute('y2',y_end);
newLine.setAttribute("stroke", color)
newLine.setAttribute("stroke-width", 2)
$("#lineSVG").append(newLine);
}
render() {
const upTick = this.props.upTick
const downTick = (this.props.downTick || this.props.upTick) // Use downTick only if supplied
// Find stop decision
let submittedContinuation = [-500, -500] // Initialize with nonsensical values
if (this.props.continuationDec) {
submittedContinuation = this.props.continuationDec.slice(0,this.props.currentRound + 1)
}
let submittedStop = submittedContinuation.findIndex(element => element == "Stop")
let stopIndex = 200
if (submittedStop >= 0) {
stopIndex = this.props.drawn[submittedStop]
}
else if (this.props.currentRound == 5 ) {
stopIndex = this.props.drawn[this.props.currentRound]
}
let arrButtons = []
let index = -1
for (let layer = 1; layer <= 5; layer++) {
for (let i =0; i < layer; i++) {
index ++ // Increase index by one
arrButtons.push(
)
}
}
let layer = 6
for (let i =0; i < layer; i++) {
index ++ // Increase index by one
arrButtons.push(
)
}
return (
{arrButtons} {/*Very important to wrap the buttons inside a div*/}
)
}
}
// Ball designs
function BallSingleRisk(props) {
let style = {
flex : 1,
// MARK
width: "50px", // Note: 30 would also work
height: "50px",
// marginLeft: "20px",
// marginTop: "50px",
borderRadius: "50%",
border: "0.5px solid black",
display: "block",
position: 'absolute',
// MARK change 7 to change no of layers
top: "45%",
left: (100 / 3 * (props.layer) - 1 - 15).toString() + '%',
fontSize: 10,
color: "white", // Do not show content
padding: "0px",
}
let idName = "ball_" + props.index;
// Background depends on clicked or not
if (props.currentNode == props.index) {
style.background = "darkblue"
} else if (props.isClicked[props.index]) {
(props.prob[props.index] === 0) ? (style.background = "black")
: (props.prob[props.index] === 100) ? (style.background = "transparent")
: (props.prob[props.index] === -100) ? style.background = ("linear-gradient(to right, white, black)")
: style.background = "url('/static/img/questionmark_s.png') center center" // Use questionmark picture)
} else {
// Has not been clicked
style.background = props.initialColor
}
let textShown = ""
let greyScheme = {
0 : "#F5F5F5",
10: "#E8E8E8",
20: "#DCDCDC",
30: "#D3D3D3",
40: "#C0C0C0",
50: "#BEBEBE",
60: "#A9A9A9",
70: "#989898",
80: "#808080",
90: "#696969",
100: "#606060",
}
if (0< props.prob[props.index] && props.prob[props.index] < 100 && !(props.currentNode == props.index)) {
textShown = 100-props.prob[props.index]
let greyIndex = Math.round((100-props.prob[props.index])/10) * 10;
style.background = greyScheme[greyIndex]
if (greyIndex >= 80) {
style.color = "white"
} else {
style.color = "black" // Show probability inside node
}
}
// Only for instructions
if (props.prob[props.index] === -200 && !(props.currentNode == props.index)) {
style.background = "url('/static/img/questionmark_s.png') center center"
}
return <>
>
}
function DisabledBallSingleRisk(props) {
//defines the properties of the circle as a button
let style = {
background: "black",
width: "50px",
height: "50px",
borderRadius: "50%",
border: "0.5px solid black",
display: "block",
position: 'absolute',
// MARK change 7 to change no of layers
top: (25 + ((props.inlayer-1) * 40) // offset für Elemente in Layer
).toString() + '%',
left: (100 / 3 * (props.layer) - 1 - 15).toString() + '%'
}
let containerstyle = {
height: "50px",
width: "100px",
position: 'absolute',
// MARK change 7 to change no of layers
top: (25 + ((props.inlayer-1) * 40) // offset für Elemente in Layer
).toString() + '%',
left: (100 / 3 * (props.layer) - 1 + 5).toString() + '%'
}
let idName = "ball_" + props.index;
let text = ""
if (props.inlayer == 1) {
text = "W = £" + (js_vars.upTick).toFixed(2)
} else {
text = "L = -£" + (js_vars.upTick).toFixed(2)
}
if (props.drawn == props.index) {
//style.background = "blue"
if (props.drawn == 1) {
style.border = "1px solid #0f5132"
style.background = "#d1e7dd"
} else if (props.drawn == 2) {
style.border = "1px solid #842029"
style.background = "#f8d7da"
}
}
style.color = "white"
style.textAlign = "center"
return <>
{text}
>
}
function BallDecision(props) {
let style = {
flex : 1,
width: "25px", // Note: 30 would also work
height: "25px",
borderRadius: "50%",
border: "0.5px solid black",
display: "block",
position: 'absolute',
// MARK change 7 to change no of layers
top: ((props.inlayer * (100 / 7) + 40) // offset für Elemente in Layer
- (props.layer * 0.5 * (100 / 7)) // offset nach Layer
- (0.06 * props.pay_up * (props.layer * 0.5 * (100 / 7))) // Versetzung nach payoff differenz
- (0.06 * props.pay_down * (props.layer * 0.5 * (100 / 7)))
).toString() + '%',
left: (100 / 7 * (props.layer) - 5).toString() + '%',
fontSize: 10,
color: "transparent", // Do not show content
padding: "0px",
}
let idName = "ball_" + props.index;
// Background depends on clicked or not
if (props.currentNode == props.index) {
style.background = "darkblue" // Instructions currently given
} else if (props.isClicked[props.index]) {
(props.prob[props.index] === 0) ? (style.background = "black")
: (props.prob[props.index] === 100) ? (style.background = "transparent")
: (props.prob[props.index] === -100) ? style.background = ("linear-gradient(to right, white, black)")
: style.background = "url('/static/img/questionmark_s.png') center center" // Use questionmark picture)
} else {
// Has not been clicked
style.background = props.initialColor
}
let textShown = ""
let greyScheme = {
0 : "#F5F5F5",
10: "#E8E8E8",
20: "#DCDCDC",
30: "#D3D3D3",
40: "#C0C0C0",
50: "#BEBEBE",
60: "#A9A9A9",
70: "#989898",
80: "#808080",
90: "#696969",
100: "#606060",
}
if (0< props.prob[props.index] && props.prob[props.index] < 100 && !(props.currentNode == props.index)) {
textShown = 100-props.prob[props.index]
let greyIndex = Math.round((100-props.prob[props.index])/10) * 10;
style.background = greyScheme[greyIndex]
if (greyIndex >= 80) {
style.color = "white"
} else {
style.color = "black" // Show probability inside node
}
}
if (props.index == props.stopIndex) {
style.background = '#FFD700'
textShown = "B"
style.fontSize = 15
style.color = "black"
style.border= "0.5px solid black"
}
else if (props.drawn[props.layer - 1] == props.index && props.index < props.stopIndex) {
if (props.initialColor) {
style.background = props.initialColor
}
style.border = "3px solid #2E8BC0"
}
// Only for instructions
if (props.prob[props.index] === -200 && !(props.currentNode == props.index)) {
//style.background = "url('/static/img/questionmark_s.png') center center"
textShown = "N"
style.color = "black"
style.fontSize = 15
}
return
}
function DisabledBallDecision(props) {
//defines the properties of the circle as a button
let style = {
background: "black",
width: "25px",
height: "25px",
borderRadius: "50%",
border: "none",
display: "block",
position: 'absolute',
// MARK change 7 to change no of layers
top: ((props.inlayer * (100 / 7) + 40) // offset für Elemente in Layer
- (props.layer * 0.5 * (100 / 7)) // offeset nach Layer
- (0.06 * props.pay_up * (props.layer * 0.5 * (100 / 7))) // Versetzung nach payoff differenz
- (0.06 * props.pay_down * (props.layer * 0.5 * (100 / 7)))
).toString() + '%', left: (100 / 7 * (props.layer) - 5).toString() + '%'
}
let idName = "ball_" + props.index;
let textShown = ""
if (props.index == props.stopIndex) {
style.background = '#FFD700'
textShown = "B"
style.fontSize = 15
style.color = "black"
style.border= "0.5px solid black"
}
return
}