Skip to content

Instantly share code, notes, and snippets.

@Andrew-Reid
Created January 1, 2020 05:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Andrew-Reid/5fa05044f281748580d01ffd52e59da0 to your computer and use it in GitHub Desktop.
Save Andrew-Reid/5fa05044f281748580d01ffd52e59da0 to your computer and use it in GitHub Desktop.
D3 line module test w/Canvas
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3'], factory) :
(global = global || self, factory(global.d3 = global.d3 || {}, global.d3$1));
}(this, function (exports, d3$1) { 'use strict';
function funkyLine(context) {
var referenceMargin = 10;
var interval = 10;
function line(context) {
let custom = d3.curveLinear(context);
custom._context = context;
custom.point = function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0:
this._point = 1;
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y);
this.x0 = x;
this.y0 = y;
break;
case 1:
this._point = 2;
default:
var dx = this.x0 - x;
var dy = this.y0 - y;
//var interval = 10;//referenceInterval;
var margin = referenceMargin;
var r = dx * dx + dy * dy;
r = Math.sqrt(r);
var number = Math.round((r - margin * 2) / interval);
if (number % 4 > 0) number -= number % 4;
margin = (r - number * interval) / 2;
var m = (y - this.y0) / (x - this.x0);
m = -1 / m;
var start = margin / r;
var percentage = (r - margin * 2) / r;
for (var i = 0; i < number; i++) {
var mag = Math.min(i / number, 1 - i / number) * 50;
var x1 = x * (i / number * percentage + start) + this.x0 * (1 - (i / number * percentage + start));
var y1 = y * (i / number * percentage + start) + this.y0 * (1 - (i / number * percentage + start));
if (m == Infinity || m == -Infinity) {
if (i % 2 == 0) this._context.lineTo(x1, y1 + mag);
else this._context.lineTo(x1, y1 - mag);
} else {
var k = mag / Math.sqrt(1 + (m * m));
if (i % 2 == 0) this._context.lineTo(x1 + k, y1 + (m * k));
else this._context.lineTo(x1 - k, y1 - (m * k));
}
}
var x1 = x * (1 - start) + this.x0 * (start);
var y1 = y * (1 - start) + this.y0 * (start);
this._context.lineTo(x1, y1);
this._context.lineTo(x, y);
this.x0 = x;
this.y0 = y;
break;
}
};
return custom;
}
line.interval = function(_) {
return arguments.length ? (interval = _, line) : interval;
};
line.margin = function(_) {
return arguments.length ? (referenceMargin = _, line) : referenceMargin;
};
return line;
}
exports.funkyline = funkyLine;
Object.defineProperty(exports, '__esModule', { value: true });
}));
<!DOCTYPE html>
<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="funkyline.js"></script>
<canvas width="960" height="500"></canvas>
<script>
var svg = d3.create("svg");
var canvas = d3.select("canvas")
var context = canvas.node().getContext("2d");
var line = d3.line()
.curve(d3.funkyline().interval(10))
.context(context);
var data1 = [[100,200],[300,200]];
var data2 = [[100,200],[860,200]];
var data = [data1,data2]
var circles = svg.selectAll(null)
.data(data1)
.enter()
.append("circle")
.attr("cx", function(d) { return d[0]; })
.attr("cy", function(d) { return d[1] + 100; })
.attr("r", 5);
context.beginPath();
line(data1);
context.stroke();
var j = 0;
function transition() {
j++;
circles
.data(data[j%2])
.filter(function(d,i) { return i == 1; })
.transition()
.attr("cx", function(d) { return d[0]; })
.tween("attr.anything", function(d) {
var that = d3.select(this);
var interpolate = j%2 ? d3.interpolateNumber(data1[1][0],data2[1][0]) : d3.interpolateNumber(data2[1][0],data1[1][0]);
return function(t) {
var datum = [[100,300],[interpolate(t),300]];
context.clearRect(0,0,960,500);
context.beginPath();
line(datum);
context.stroke();
}
})
.duration(2000)
.on("end",transition);
}
transition();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment