forked from FergusDevelopmentLLC's block: Tomato Varieties
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://d3js.org/d3.v4.min.js"></script>
<title>Tomato Varieties</title>
<style>
body {
margin: 0px;
}
.tick {
font-size: 12pt;
}
g.tick line {
opacity: 0.4;
}
.axis-label {
fill: black;
font-size: 13pt;
font-family: sans-serif;
}
.title {
fill: black;
font-size: 18pt;
font-weight: bold;
font-family: sans-serif;
}
div.tooltip {
position: absolute;
max-width: 300px;
padding: 3px 6px;
color: grey;
font-family: 'Droid Sans Mono', monospace;
font-size: .7em;
background: whitesmoke;
border: 1px solid grey;
border-radius: 3px;
pointer-events: none;
}
td#legend-wrapper {
padding-top: 220px;
}
</style>
</head>
<body>
<table>
<tr>
<td>
<svg id="chart" width="800" height="500"></svg>
</td>
<td id="legend-wrapper">
<svg width="140" height="152">
<g
id="g5230"
transform="translate(0,0.6779661)">
<g
id="g5246"
transform="translate(-12.881356,-52.20339)">
<g
transform="translate(0,-0.6779661)"
id="g5208">
<circle
style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:1.5;stroke-dasharray:1, 0;stroke-opacity:1"
id="circle3750-7"
r="50"
cy="152.1162"
cx="63.437881" />
<circle
style="fill:#ff0000;fill-opacity:0;stroke:#000000;stroke-width:1.5;stroke-dasharray:1, 0;stroke-opacity:1"
id="circle3764-5"
r="5"
cy="195.90532"
cx="62.63118" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 63.29408,102.21081 58.95904,0"
id="path5002"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 63.29408,190.83651 58.95904,0"
id="path5002-5"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="126.11049"
y="105.75459"
id="text5079"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5081"
x="126.11049"
y="105.75459"
style="font-size:11.25px;line-height:125%">25oz</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="126.11049"
y="193.75459"
id="text5079-6"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5081-2"
x="126.11049"
y="193.75459"
style="font-size:11.25px;line-height:125%">2oz</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:200%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="46.82235"
y="61.246117"
id="text5079-1"
sodipodi:linespacing="200%"><tspan
sodipodi:role="line"
id="tspan5081-27"
x="46.82235"
y="61.246117"
style="font-size:11.25px;line-height:200%">High Yield</tspan><tspan
sodipodi:role="line"
x="46.82235"
y="83.746117"
style="font-size:11.25px;line-height:200%"
id="tspan5204">Heat Tolerant</tspan></text>
<path
style="fill:#ff0000;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m 16.271186,58.915254 23.728814,0"
id="path5159"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 1.5;stroke-dashoffset:0;stroke-opacity:1"
d="M 16.271186,78.91525 40,78.91525"
id="path5159-9"
inkscape:connector-curvature="0" />
</g>
</g></svg>
</td>
</tr>
</table>
<script>
var tooltip;
tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
const title = "Tomato Varieties";
const xValue = d => d.matures_avg_days;
const xLabel = 'Plant Maturity (days)';
const yValue = d => d.height_avg_ft;
const yLabel = 'Plant Height (feet)';
const margin = { left: 100, right: 40, top: 65, bottom: 70 };
const svg = d3.select('#chart');
const width = svg.attr('width');
const height = svg.attr('height');
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const xAxisG = g.append('g')
.attr('transform', `translate(0, ${innerHeight})`);
const yAxisG = g.append('g');
xAxisG.append('text')
.attr('class', 'axis-label')
.attr('x', innerWidth / 2)
.attr('y', 55)
.text(xLabel);
yAxisG.append('text')
.attr('class', 'axis-label')
.attr('x', -innerHeight / 2)
.attr('y', -50)
.attr('transform', `rotate(-90)`)
.style('text-anchor', 'middle')
.text(yLabel);
const xScale = d3.scaleLinear();
const yScale = d3.scaleLinear();
const xAxis = d3.axisBottom()
.scale(xScale)
.tickPadding(15)
.tickSize(-innerHeight);
const yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5)
.tickPadding(15)
.tickSize(-innerWidth);
const row = d => {
d.fruit_size_low_oz = Number(d.fruit_size_low_oz);
d.fruit_size_high_oz = Number(+d.fruit_size_high_oz);
d.fruit_size_avg_oz = Number(+d.fruit_size_avg_oz);
d.matures_low_days = Number(+d.matures_low_days);
d.matures_high_days = Number(+d.matures_high_days);
d.matures_avg_days = Number(+d.matures_avg_days);
d.spacing_low_in = Number(+d.spacing_low_in);
d.spacing_avg_in = Number(+d.spacing_avg_in);
d.spacing_high_in = Number(+d.spacing_high_in);
d.height_low_ft = Number(+d.height_low_ft);
d.height_high_ft = Number(+d.height_high_ft);
d.height_avg_ft = Number(+d.height_avg_ft);
d.yield_num = Number(+d.yield_num);
d.heat_tolerance_num = Number(+d.heat_tolerance_num);
return d;
};
svg.append('text')
.attr('class', 'title')
.attr('x', width / 2)
.attr('y', 40)
.style('text-anchor', 'middle')
.text(title);
d3.csv('tomato_varieties.csv', row, data => {
data = data.sort((a,b) => d3.descending(a.fruit_size_avg_oz, b.fruit_size_avg_oz));
var xDomain = d3.extent(data, xValue)
var xFudge = d3.extent(data, d => d.fruit_size_avg_oz)
xScale
.domain([xDomain[0] - xFudge[0], xDomain[1] + xFudge[1]/2])
.range([0, innerWidth])
.nice();
var yDomain = d3.extent(data, yValue)
yScale
.domain([yDomain[0], yDomain[1] + (yDomain[1] - yDomain[0])/4])
.range([innerHeight, 0])
.nice();
var prev_stroke_color = 'rgb(0, 0, 0)';
g.selectAll('circle').data(data)
.enter().append('circle')
.attr('cx', d => xScale(xValue(d)))
.attr('cy', d => yScale(yValue(d)))
.attr('fill', d => d.color)
.attr('fill-opacity', 0.4)
.attr('stroke', d => getStrokeBasedOnYield(d))
.attr('stroke-width', '1.5')
.attr('stroke-opacity', '1')
.attr('stroke-dasharray', d => getStrokeDashArrayBasedOnHeatTolerance(d))
.attr('r', d => d.fruit_size_avg_oz * 2)
.on('mouseover', function(d) {
prev_stroke_color = d3.select(this).style('stroke');
var tooltip_msg = `Common Name: ${d.common_name}`;
tooltip_msg = tooltip_msg + `<br/>Heat tolerance: ${d.heat_tolerance}`;
tooltip_msg = tooltip_msg + `<br/>Fruit Size: ${d.fruit_size_avg_oz}oz`;
tooltip_msg = tooltip_msg + `<br/>Plant height: ${d.height_avg_ft}ft`;
tooltip_msg = tooltip_msg + `<br/>Maturity: ${d.matures_avg_days} days`;
tooltip_msg = tooltip_msg + `<br/>${d.description}`;
tooltip_msg = tooltip_msg + `<br/><img src='${d.image_url}' width='250' height='225' />`;
tooltip.transition().style("opacity", 1);
tooltip.html(tooltip_msg).style("left", (d3.event.pageX + 15) + "px").style("top", (d3.event.pageY - 28) + "px");
d3.select(this).style("stroke", "green");
d3.select(this).style("stroke-width", "4");
this.parentNode.appendChild(this);
})
.on('mouseout', function(d) {
d3.select(this).style("stroke", prev_stroke_color);
d3.select(this).style("stroke-width", "1.5");
tooltip.style("opacity", 0);
});
xAxisG.call(xAxis);
yAxisG.call(yAxis);
});
function getStrokeBasedOnYield(d) {
returnColor = 'black';
if(d.yield == 'High') { returnColor = 'red'; }
return returnColor;
}
function getStrokeDashArrayBasedOnHeatTolerance(d) {
returnSDA = '1, 0';
if(d.heat_tolerance == 'High') {
returnSDA = '3, 2';
}
return returnSDA;
}
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js