Built with blockbuilder.org
xxxxxxxxxx
<meta charset="utf-8">
<style>
.grid line {
fill: none;
stroke: grey;
stroke-width: 0.5;
shape-rendering: crispEdges; }
.area { fill: lightgrey;}
.text {
font: 15px sans-serif;}
.labels {
font: 10px sans-serif;
text-anchor: middle;
font-family": sans-serif;
font-weight: bold;}
.names {
font: 10px sans-serif;
text-anchor: middle;
font-family": sans-serif;
font-weight: bold;}
</style>
<body>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script>
var margin = {top: 20, right: 100, bottom: 40, left: 50},
width = 1040 - margin.left - margin.right,
height = 540 - margin.top - margin.bottom;
var xtimerange = 1500;
var ytemprange = 150;
var tstattol = 3.5;
var x = d3.scaleLinear().range([0, width]); // used for grid
var y = d3.scaleLinear().range([height, 0]); // used for grid
var x_scale = d3.scaleLinear()
.domain([0,xtimerange])
.range([0, width]);
var y_scale = d3.scaleLinear()
.domain([0,ytemprange])
.range([height,0]);
var format = d3.format(",d");
// BUTTONS
d3.select("body").append("button").attr("id","Move1").text("Run1")
d3.select("body").append("button").attr("id","Move2").text("Run2")
d3.select("body").append("button").attr("id","Move3").text("Reset")
//objects arrays xs = xstart, ys = ystart, yL = yLimit
var dataset = [
{key: "Thermostat", xs: 100, ys: 70, yn: 80, ye: 96.3, slope: 1.8, c:"lightgray", filter: "y"},
{key: "Flue spipe", xs: 00, ys: 75, yn: 90, ye: 120, slope: 2, c: "lightblue", filter: "n"},
{key: "SBend", xs: 10, ys: 86, yn: 100, ye: 110, slope: 2, c: "orange", filter: "n"},
{key: "Collector", xs: 0, ys: 100, yn: 130, ye: 145, slope: 2, c: "pink", filter: "n"},
];
// determine the x stop point for the thermostat (in time no scaled!)
var Tstatstop = (dataset[0].ye-dataset[0].ys)/(dataset[0].slope/60)+dataset[0].xs
// COLOUR SCALE
var cScale = d3.scaleLinear()
.domain([60,120])
.range([0,1]);
// determine end xpoint of normal section
function xn (d) {
return x_scale((d.yn-d.ys)/(d.slope/60)+d.xs)};
// determine the tstat start x value
function xts (d) {
return x_scale(((d.ye-tstattol)-d.ys)/(d.slope/60)+d.xs)};
// determine the tstart end x value
function xte (d) {
return x_scale(((d.ye+tstattol)-d.ys)/(d.slope/60)+d.xs)};
// function to determine the y end point for the continues line
function yend (d) {
return y_scale((d.slope/60)*(xtimerange-d.xs)+d.ys)};
// determine the xs of the limit section
function xe (d) {
return x_scale(((d.ye-d.ys)/(d.slope/60))+d.xs)};
// function to determine the x end point for the Tstat (and others!!)
function yendatTstatstop (d) {
return y_scale((d.slope/60)*(Tstatstop-d.xs)+d.ys)};
function yendatTstatstop2 (d) {
return y_scale((d.slope/60)*(Tstatstop-d.xs)+d.ys-1)};
// xaxis generator
var xAxis = d3.axisBottom()
.scale(x_scale)
.ticks(12);
// yaxis generator
var yAxis = d3.axisLeft()
.scale(y_scale)
.ticks(5);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// call the xaxis
svg.append("g")
.attr("transform", "translate(0," + (height) + ")")
.call(xAxis);
// add xaxis label
svg.append("text")
.attr("text-anchor", "middle")
.attr("x", width / 2)
.attr("y", height + 30)
.text("time [s]");
// call the yaxis
svg.append("g")
.attr("transform", "translate(" + 0 + ",0)")
.call(yAxis);
// add yaxis label
svg.append("text")
.attr("class", "y label")
.attr("text-anchor", "middle")
.attr("x", -height/2)
.attr("y", -40)
.attr("dy", ".75em")
.attr("transform", "rotate(-90)")
.text("Temperature [C]");
// FULL LINE
svg.selectAll("lines")
.data(dataset)
.enter()
.append("line")
.style("stroke", "gray")
.attr("stroke-width",0.5)
.attr("x1",function (d) { return x_scale(d.xs)})
.attr("x2",width)
.attr("y1",function (d) { return y_scale(d.ys)})
.attr("y2", yend);
// NORMAL LINES
svg.selectAll("lines")
.data(dataset)
.enter()
.append("line")
.filter( function (d) { return d.filter === "n"})
.style("stroke", "green")
.attr("stroke-width",2)
.attr("x1",function (d) { return x_scale(d.xs)})
.attr("x2", xn)
.attr("y1",function (d) { return y_scale(d.ys)})
.attr("y2",function (d) { return y_scale(d.yn)});
// LIMIT LINES
svg.selectAll("lines")
.data(dataset)
.enter()
.append("line")
.filter( function (d) { return d.filter === "n"})
.style("stroke", "red")
.attr("stroke-width",2)
.attr("x1", xe)
.attr("x2", width)
.attr("y1",function (d) { return y_scale(d.ye)})
.attr("y2", yend);
// TSTAT LINE
svg.selectAll("lines")
.data(dataset)
.enter()
.append("line")
.filter( function (d) { return d.filter === "y"})
.style("stroke", "black")
.attr("stroke-width",4)
.attr("x1", xts)
.attr("x2", xte)
.attr("y1", function (d) { return y_scale(d.ye - tstattol)})
.attr("y2", function (d) { return y_scale(d.ye + tstattol)})
// CIRCLES
svg.selectAll("points")
.data(dataset)
.enter()
.append("circle")
.style("stroke","black")
.attr("fill", function (d) {return d3.rgb(d3.interpolateCool(cScale(d.ys)))})
.attr("cx",function (d) { return x_scale(d.xs)})
.attr("cy",function (d) { return y_scale(d.ys)})
.attr("r", 10)
// LIMIT SQUARES
svg.selectAll("limits")
.data(dataset)
.enter()
.append("rect")
.filter( function (d) { return d.filter === "n"})
.style("stroke","black")
.style("fill-opacity", 0.2)
.attr("rect-anchor", "middle")
.attr("fill", "red")
.attr("x", function (d) {
return x_scale(((d.ye-d.ys)/(d.slope/60))+d.xs)-5})
.attr("y",function (d) { return y_scale(d.ye)-5})
.attr("width", 10)
.attr("height", 10);
// NORMAL SQUARES
svg.selectAll("normals")
.data(dataset)
.enter()
.append("rect")
.filter( function (d) { return d.filter === "n"})
.style("stroke","black")
.style("fill-opacity", 0.2)
.attr("rect-anchor", "middle")
.attr("fill", "green")
.attr("x", function (d) {
return x_scale((d.yn-d.ys)/(d.slope/60)+d.xs-6)
})
.attr("y",function (d) { return y_scale(d.yn)-5})
.attr("width", 10)
.attr("height", 10);
// TSTAT TEXT ANGULAR
svg.append("text")
.attr("class","text")
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("transform", "translate("+ x_scale(Tstatstop) +"," + y_scale(dataset[0].ye-5) + ") rotate (-8)")
.text("Switch Range")
.append("r");
// NAMES
svg.selectAll("names")
.data(dataset)
.enter()
.append("text")
.attr("class","text")
.style("fill", function (d){
return d.c
})
.attr("x", function(d){return width})
.attr("y", yend)
.text(function (d){return d.key})
.attr("fill", "black")
;
// LABELS,
svg.selectAll("labels")
.data(dataset)
.enter()
.append("text")
.attr("class", "labels")
.attr("x", function(d){return x_scale(d.xs)})
.attr("y", function(d){return y_scale(d.ys-1)})
.text(function (d){return d.ys})
.attr("fill", "black")
;
//ACTION TIME
d3.select("#Move1")
.on("click", function() {
svg.selectAll("circle")
.data(dataset)
.transition()
.ease(d3.easeLinear)
.delay(function (d){
return (d.xs/Tstatstop)*10000
})
.duration( function (d) {
return 10000*((Tstatstop-d.xs)/Tstatstop)})
.attr("cx", x_scale(Tstatstop))
.attr("cy", yendatTstatstop)
.attr("r",10)
.attr("fill", function (d) {return d3.rgb(d3.interpolateCool(cScale(d.ye)))})
svg.selectAll(".labels")
.data(dataset)
.transition()
.ease(d3.easeLinear)
.delay(function (d){return (d.xs/Tstatstop)*10000})
.duration( function (d) {return 10000*((Tstatstop-d.xs)/Tstatstop)})
.attr("x", x_scale(Tstatstop))
.attr("y", yendatTstatstop2)
.tween("text", function(d) {
var that = d3.select(this),
i = d3.interpolateNumber(d.ys, ((d.slope/60)*(Tstatstop-d.xs)+d.ys));
return function(t) { that.text(format(i(t))); };
})
});
d3.select("#Move3")
.on("click", function() {
svg.selectAll("circle")
.data(dataset)
.transition()
.ease(d3.easeLinear)
.delay(function (d){
return (d.xs/Tstatstop)*1000
})
.duration( function (d) {
return 1000*((Tstatstop-d.xs)/Tstatstop)})
.attr("fill", function (d) {return d3.rgb(d3.interpolateCool(cScale(d.ys)))})
.attr("cx",function (d) { return x_scale(d.xs)})
.attr("cy",function (d) { return y_scale(d.ys)})
.attr("r", 10)
svg.selectAll(".labels")
.data(dataset)
.transition()
.ease(d3.easeLinear)
.delay(function (d){return (d.xs/Tstatstop)*1000})
.duration( function (d) {return 1000*((Tstatstop-d.xs)/Tstatstop)})
.attr("x", function(d){return x_scale(d.xs)})
.attr("y", function(d){return y_scale(d.ys-1)})
.tween("text", function(d) {
var that = d3.select(this),
i = d3.interpolateNumber(((d.slope/60)*(Tstatstop-d.xs)+d.ys),d.ys );
return function(t) { that.text(format(i(t))); };})
});
</script>
</body>
https://d3js.org/d3.v4.min.js