forked from interwebjill's block: Line bar chart generator
forked from interwebjill's block: Line bar chart generator with time series
forked from interwebjill's block: Line bar chart generator with time series and zoom
xxxxxxxxxx
<meta charset="utf-8">
<style>
.PVkW {
stroke: rgba(249, 208, 87, 0.5);
}
.TBLkW {
stroke: rgba(54, 174, 175, 0.3);
}
.lineBar {
clip-path: url(#clip);
}
</style>
<body>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
// shape generator
d3.functor = function functor(v) {
return typeof v === "function" ? v : function() {
return v;
};
};
function lineBarGenerator() {
//set defaults
var x1 = function(d) { return d.x; },
y1 = height,
y2 = function(d) { return d.y-height; };
//returned function to generate lineBar path
function lineBar(d) {
var line_x1 = d3.functor(x1).call(this, d),
line_y2 = d3.functor(y2).call(this, d);
return `M ${line_x1}, ${y1} v ${line_y2-height}`;
}
//getter-setter methods
lineBar.x1 = function(value) {
if (!arguments.length) return x1; x1 = value; return lineBar;
};
lineBar.y1 = function(value) {
if (!arguments.length) return y1; y1 = value; return lineBar;
};
lineBar.y2 = function(value) {
if (!arguments.length) return y2; y2 = value; return lineBar;
};
return lineBar;
}
// end shape generator
var margin = {
top: 100,
right: 100,
left: 100,
bottom: 100
};
var svg = d3.select("svg");
var width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var parseDate = d3.timeParse("%Y/%m/%d %H:%M");
// scales and axes
var x = d3.scaleTime()
.range([0, width]),
y = d3.scaleLinear()
.range([height, 0]);
var xAxis = d3.axisBottom(x),
yAxis = d3.axisLeft(y);
var xGroup = g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
var yGroup = g.append("g")
.attr("class", "axis axis--y")
.call(yAxis);
// end scales and axes
// generator
var lineBar = lineBarGenerator()
.x1(function(d) { return x(d.date); })
.y2(function(d) { return y(d.kW); });
// zoom
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("class", "zoom-area")
.attr("fill", "none")
.attr("pointer-events", "all")
.call(zoom);
// svg defs
var defs = svg.append("defs");
defs.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
// data call
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 max = 1300;
var xExtent = d3.extent(data, function(d) { return d.date; });
x.domain(xExtent);
y.domain([
0,
max
]);
xGroup.call(xAxis);
yGroup.call(yAxis);
var i, len=sources.length;
for (i=0; i<len; i++) {
g.append("g")
.attr("class", `source${i}`)
.selectAll("g")
.data(sources[i].values)
.enter()
.append("path")
.attr("class", d => `lineBar ${sources[i].id}`)
.attr("d", lineBar)
.attr("strokeWidth", 1);
}
});
function type(d) {
d.date = parseDate(d.date);
d.value = +Math.round(d.PVkW); // changed data value to match new data and rounded to integer values to optimize
return d;
}
function zoomed() {
var xz = d3.event.transform.rescaleX(x);
xGroup.call(xAxis.scale(xz));
g.selectAll("path.lineBar").attr("d", lineBar.x1(function(d) { return xz(d.date); }));
}
</script>
Modified http://d3js.org/d3.v4.min.js to a secure url
https://d3js.org/d3.v4.min.js