Built with blockbuilder.org
forked from interwebjill's block: Multiple zoomable canvas area charts
xxxxxxxxxx
<head>
<meta charset="utf-8">
<style>
/* to prevent browser overscrolling */
html {
overflow: hidden;
}
/* for retina display */
canvas, #zoom-rectangle {
width: 960px;
height: 500px;
}
#zoom-rectangle {
position: relative;
top: -500px;
}
</style>
</head>
<body>
<canvas width="1920" height="1000"></canvas>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var canvas = document.querySelector("canvas"),
context = canvas.getContext("2d");
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = canvas.width - margin.left - margin.right,
height = canvas.height - margin.top - margin.bottom;
context.translate(margin.left, margin.top);
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 x = d3.scaleTime()
.range([0, width]);
var x2 = d3.scaleTime() // for zooming
.range([0, width]);
var y = d3.scaleLinear()
.range([height, 0]);
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 zoomRect = d3.select(document.body).append("svg")
// .attr("width", this.svgDims.width)
// .attr("height", this.svgDims.height)
.attr("id", "zoom-rectangle");
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;
x.domain(d3.extent(data, function(d) { return d.date; }));
x2.domain(x.domain());
y.domain([
0,
d3.max(sources, function(c) { return d3.max(c.values, function(v) { return v.kW; }); })
]);
color.domain(sources.map(function(c) { return c.id; }));
var zoom = d3.zoom()
.scaleExtent([1, Infinity])
.translateExtent([[0, 0], [width, height]])
.extent([[0, 0], [width, height]])
.on("zoom", zoomed);
zoomRect.call(zoom);
function draw() {
context.clearRect(-margin.left, -margin.top, canvas.width, canvas.height);
context.save();
// 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();
function zoomed() {
var t = d3.event.transform;
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]] = +d[c];
return d;
}
var date = parseDate("2015/02/07 12:00");
var kW = 466.0;
var buttonSVG = zoomRect.append('svg')
.attr("x", x(date))
.attr("y", y(kW));
var button = buttonSVG.append('g')
.html(
`
<circle class="st0 celestial-ring ripple-priority" cx="15" cy="15" r="12" />
<line class="st2" x1="15" y1="10" x2="15" y2="12"/>
<line class="st2" x1="15" y1="20" x2="15" y2="18"/>
<line class="st2" x1="9" y1="15" x2="12" y2="15"/>
<line class="st2" x1="20" y1="15" x2="18" y2="15"/>
<circle class="hit-area" cx="15" cy="15" r="50" />
`
);
// createParentAnnotationContainer() {
// self = this;
// self.pointX = self.xScale(this.date);
// this.$annotationCard = this.$annotationGroup.append('svg')
// .datum(this.data)
// .attr("class", d => { return `annotation ${d.category}`;})
// .attr('x', self.pointX)
// .attr('y',
// d => {
// let kW;
// if (d.yPositionOverride) {
// kW = (d.yPositionOverride === 'consumption') ? this.values.consumption : d.yPositionOverride;
// } else {
// kW = this.values.production;
// }
// self.pointY = this.yScale(kW)
// return this.pointY;
// });
// }
// createIconButton() {
// this.$iconButton = this.$annotationCard.append('g')
// .attr("class", d => { return `iconButton ${d.category}`; })
// .html(d => { return this.pickIcon(d.category); })
// .on("mouseover", () => {
// this.setActive(true, true);
// })
// .on("mouseout", () => {
// this.setActive(false, true);
// })
// .on("mousedown", () => {
// event.stopPropagation();
// if (this.zoomLevel === 0) {
// event.stopPropagation();
// appModel.requestZoomToExtent(this.zoomToExtent[0], this.zoomToExtent[1]);
// if (this.compareCurves) {
// document.getElementById("threshold").style.visibility = 'hidden';
// }
// // this.setActive(!this.isActive, true);
// } else {
// event.stopPropagation();
// appModel.requestZoomOut();
// appModel.setLiquidFunVisibility(false);
// document.getElementById("threshold").style.visibility = 'visible';
// }
// });
// }
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js