D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
S-trunk
Full window
Github gist
Tstat
Built with
blockbuilder.org
<!DOCTYPE html> <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