julia_svg = {
let w = width / 2;
const xScale = d3
.scaleLinear()
.domain([-2, 2])
.range([0, w]);
const yScale = d3
.scaleLinear()
.domain([-2, 2])
.range([w, 0]);
const rScale = d3
.scaleLinear()
.domain([0, 4])
.range([0, w]);
const pts_to_path = d3
.line()
.x(function(d) {
return xScale(d[0]);
})
.y(function(d) {
return yScale(d[1]);
});
let svg = d3
.create("svg")
.attr('width', w)
.attr('height', w);
if (!svg.attr('c')) {
svg.attr('c', '-1,0');
}
const mapbg = DOM.uid('mapbg');
svg
.append("defs")
.append('pattern')
.attr('id', mapbg.id)
.attr('patternUnits', 'userSpaceOnUse')
.attr('width', w)
.attr('height', w)
.append("image")
.attr("xlink:href", generate_julia_im_url({ re: -1, im: 0 }))
.attr('width', w)
.attr('height', w);
svg
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", w)
.attr("height", w)
.attr("fill", mapbg);
svg
.on('mousemove', function() {
svg.selectAll('.orbit').remove();
let c = svg
.attr('c')
.split(',')
.map(parseFloat);
let xy = ij_to_xy(d3.mouse(this), -2, 2, -2, 2, w);
let orbit = compute_orbit(c, xy);
for (let i = 0; i < orbit.length; i++) {
svg
.append("path")
.attr('class', 'orbit')
.attr("d", pts_to_path(orbit.slice(i, i + 2)))
.attr("stroke", "#8888FF")
.attr("stroke-width", 2)
.attr("fill", "none")
.style('opacity', 0.5);
svg
.append("circle")
.attr("class", 'orbit')
.attr("cx", xScale(orbit[i][0]))
.attr("cy", yScale(orbit[i][1]))
.attr("r", 4)
.attr("fill", "red")
.attr("stroke", "none")
.attr('fill-opacity', 0.03);
}
svg
.append("circle")
.attr("class", 'orbit')
.attr("cx", xScale(orbit[0][0]))
.attr("cy", yScale(orbit[0][1]))
.attr("r", 4)
.attr("fill", "green")
.attr("stroke", "black")
.attr("stroke-width", 1);
})
.on('mouseleave', function() {
svg.selectAll('.orbit').remove();
});
return svg.node();
}