Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<style>
/* to prevent browser overscrolling */
html {
overflow: hidden;
}
body {
margin: 0; /* or else canvas alignment is off */
box-sizing: border-box;
}
/* for retina display */
canvas {
width: 880px;
height: 450px;
}
.chart {
position: absolute;
}
#chart-canvas {
margin: 20px 0 0 60px;
z-index: 1;
}
#axis-svg {
z-index: 2;
}
.area {
clip-path: url(#clip);
}
.zoom {
cursor: move;
fill: none;
pointer-events: all;
}
.PVkW {
fill: #f29e2e;
}
.TBLkW {
fill: #36aeaf;
}
</style>
</head>
<body>
<canvas width="1760" height="900" id="chart-canvas" class="chart"></canvas>
<svg width="960" height="500" id="axis-svg" class="chart"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script><script>
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 60},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var canvas = document.querySelector("canvas"),
context = canvas.getContext("2d"),
canvasScale = canvas.width / width;
var parseDate = d3.timeParse("%Y/%m/%d %H:%M");
var color = d3.scaleOrdinal()
.domain(["PVkW", "TBLkW"])
.range(["rgba(249, 208, 87, 1.0)", "rgba(54, 174, 175, 0.6)"]);
var xSVG = d3.scaleTime()
.range([0, width]);
var x = d3.scaleTime()
.range([0, width]);
var x2 = d3.scaleTime() // for zooming
.range([0, width]);
var ySVG = d3.scaleLinear()
.range([height, 0]);
var y = d3.scaleLinear()
.range([height, 0]);
var xAxisSVG = d3.axisBottom(xSVG);
var yAxisSVG = d3.axisLeft(ySVG);
var area = d3.area()
.x(function(d) { return x(d.date); })
.y0(y(0))
.y1(function(d) { return y(d.kW); })
.curve(d3.curveStep)
.context(context);
var yGroupSVG = g.append("g")
.attr("class", "y-axis");
var xGroupSVG = g.append("g")
.attr("transform", "translate(0," + height + ")")
.attr("class", "x-axis");
var defs = svg.append("defs");
defs.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
d3.csv("kW.csv", type, function(error, data) {
if (error) throw error;
var sources = data.columns.slice(1).map(function(id) {
return {
id: id,
values: data.map(function(d) {
return {date: d.date, kW: d[id]};
})
};
});
var len = sources.length;
var xExtent = d3.extent(data, function(d) { return d.date; });
xSVG.domain(xExtent);
x.domain(xExtent);
x2.domain(x.domain());
ySVG.domain([
0,
d3.max(sources, function(c) { return d3.max(c.values, function(v) { return v.kW; }); })
]);
y.domain([
0,
d3.max(sources, function(c) { return d3.max(c.values, function(v) { return v.kW; }); })
]);
yGroupSVG.call(yAxisSVG);
xGroupSVG.call(xAxisSVG);
color.domain(sources.map(function(c) { return c.id; }));
function draw() {
context.save();
context.scale(canvasScale, canvasScale);
context.clearRect(0, 0, width, height);
// clip path
context.beginPath()
context.rect(0, 0, width, height);
context.clip();
for (i=0; i<len; i++) {
context.beginPath();
area(sources[i].values);
context.fillStyle = color(sources[i].id);
context.fill();
}
context.restore();
}
draw();
var zoom = d3.zoom()
.scaleExtent([1, Infinity])
.translateExtent([[0, 0], [width, height]])
.extent([[0, 0], [width, height]])
.on("zoom", zoomed);
var zoomRect = svg.append("rect")
.attr("width", width)
.attr("height", height)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("fill", "none")
.attr("pointer-events", "all")
.call(zoom)
.on("dblclick.zoom", null);
function zoomed() {
var t = d3.event.transform;
var xz = t.rescaleX(xSVG);
xGroupSVG.call(xAxisSVG.scale(xz));
x = t.rescaleX(x2);
draw();
}
});
function type(d, _, columns) {
d.date = parseDate(d.date);
for (var i = 1, n = columns.length, c; i < n; ++i) d[c = columns[i]] = +Math.round(d[c]);
return d;
}
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js