xxxxxxxxxx
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
.axis .domain {
display: none;
}
.axis line {
stroke: rgb(155, 155, 155);
stroke-opacity: .3;
}
</style>
</head>
<body>
<svg></svg>
<script>
let maxWidth = window.innerWidth - 25;
let maxHeight = window.innerHeight - 25;
const svg = d3.select("svg")
.attr("width", maxWidth)
.attr("height", maxHeight);
const margin = { top:10, left:40, bottom:30, right:20 };
let width = +svg.attr("width") - margin.left - margin.right;
let height = +svg.attr("height") - margin.top - margin.bottom;
const g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const x = d3.scaleTime().rangeRound([0, width]);
const y = d3.scaleLinear().rangeRound([height, 0]);
const parseTime = d3.timeParse("%Y %m %d %H %M %S");
const displayTime = d3.timeFormat("%Hh%M");
const line = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.temp); })
.curve(d3.curveBasis);
const tooltip = g.append("g")
.attr("class", "mark")
.style("opacity", 0);
tooltip.append("circle").attr("r", 7)
.style("fill", "none")
.style("stroke-width", "1.5px");
tooltip.append("text")
.attr("x", 10)
.attr("y", -7.5)
.style("font", "10px sans-serif")
.attr("dy", "0.35em")
.text("");
let xAxis, yAxis, path, pathLine;
let data;
d3.queue()
.defer(d3.json, "data.json")
.await(process);
window.onresize = resize;
function process(error, json) {
for(let o of json.datas)
o.date = parseTime(o.date);
data = json.datas.slice(json.datas.length-50);
// La dernière valeur était nulle
data.pop();
console.log("DATA : %O", data);
draw();
}
function draw() {
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.temp; })]);
// X Axis
xAxis = g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, " + height + ")")
.call(d3.axisBottom(x).tickFormat(function(d) { return displayTime(d); }));
// Y Axis
yAxis = g.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y).tickSize(-width).tickFormat(function(d) { return d; }));
path = g.append("g")
.attr("class", "path")
.data([data]);
pathLine = path.append("path")
.attr("fill", "none")
.attr("stroke", "rgb(31, 119, 180)")
.attr("stroke-width", 2)
.attr("d", line)
.on("mouseover", function(d, i) {
tooltip.style("opacity", 1);
})
.on("mousemove", function(d) {
const mouse = d3.mouse(this);
const mouseXValue = x.invert(mouse[0]);
const mouseYValue = y.invert(mouse[1]);
tooltip.attr("transform", "translate(" + mouse[0] + "," + mouse[1] + ")");
tooltip.selectAll("circle").style("stroke", "rgb(31, 119, 180)");
tooltip.selectAll("text").style("fill", "rgb(31, 119, 180)")
.text(displayTime(mouseXValue) + " : " + Math.round(mouseYValue));
})
.on("mouseleave", function(d) {
tooltip.style("opacity", 0);
});
path.selectAll("circle")
.data(function(d) { return d; })
.enter()
.append("circle")
.attr("class", ".dot")
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.temp); })
.attr("r", 1)
.style("fill", "blue");
}
d3.interval(function() {
console.log("maj");
// TODO Update data + update graph
}, 60000);
function resize() {
maxWidth = window.innerWidth - 25;
maxHeight = window.innerHeight - 25;
svg.attr("width", maxWidth);
svg.attr("height", maxHeight);
width = +svg.attr("width") - margin.left - margin.right;
height = +svg.attr("height") - margin.top - margin.bottom;
x.rangeRound([0, width]);
y.rangeRound([height, 0]);
// X Axis
xAxis.transition().duration(100)
.attr("transform", "translate(0, " + height + ")")
.call(d3.axisBottom(x).tickFormat(function(d) { return displayTime(d); }));
// Y Axis
yAxis.transition().duration(100)
.call(d3.axisLeft(y).tickSize(-width).tickFormat(function(d) { return d; }));
pathLine.transition().duration(100)
.attr("d", line);
path.selectAll("circle")
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.temp); });
}
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js