myChart={
const div = html`<div style='max-width: 900px; overflow-x: auto; padding: 0px; margin: 0px;'></div>`;
const svg = d3.select(div)
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
svg.append('defs').append('marker')
.attr("id",'arrowhead')
.attr('viewBox','-0 -5 10 10')
.attr('refX',23)
.attr('refY',0)
.attr('orient','auto')
.attr('markerWidth',13)
.attr('markerHeight',13)
.attr('xoverflow','visible')
.append('svg:path')
.attr('d', 'M 0,-5 L 10 ,0 L 0,5')
.attr('fill', '#999')
.style('stroke','none');
const dataset = {
nodes: [
{id: 74, name: 'Calculus - single variable', group: 'Team A', runtime: 10},
{id: 1, name: 'Limits and continuity', group: 'Team B', runtime: 10},
{id: 2, name: 'Motivational applications', group: 'Team C', runtime: 60},
{id: 3, name: 'Finding limits using graphs', group: 'Team C', runtime: 30},
{id: 4, name: 'Rules of limits', group: 'Team C', runtime: 40},
{id: 5, name: 'Evaluating limits', group: 'Team C', runtime: 20},
{id: 6, name: 'factoring', group: 'Team D', runtime: 60},
{id: 7, name: 'rationalizing', group: 'Team D', runtime: 60},
{id: 8, name: 'rational expressions', group: 'Team D', runtime: 100},
{id: 9, name: 'trigonometric', group: 'Team D', runtime: 80},
{id: 10, name: 'Squeeze theorem', group: 'Team C', runtime: 20},
{id: 11, name: 'One-sided limits', group: 'Team C', runtime: 240},
{id: 12, name: 'Continuity', group: 'Team C', runtime: 30},
{id: 13, name: 'classifying discontinuities', group: 'Team D', runtime: 40},
{id: 14, name: 'intermediate value theorem', group: 'Team D', runtime: 20},
{id: 15, name: 'Infinite limits and vertical asymptotes', group: 'Team C', runtime: 60},
{id: 16, name: 'Limits at infinity, horizontal and oblique asymptotes', group: 'Team C', runtime: 30},
{id: 17, name: 'Estimating limits numerically', group: 'Team C', runtime: 40},
{id: 18, name: 'Applications', group: 'Team C', runtime: 20},
{id: 19, name: 'instantaneous rate of change', group: 'Team D', runtime: 60},
{id: 20, name: 'tangent lines and slopes', group: 'Team D', runtime: 60},
{id: 21, name: 'finding all asymptotes', group: 'Team D', runtime: 100},
{id: 22, name: 'Definitions and existence (conceptual)', group: 'Team C', runtime: 80},
//-----Differentiation-----
{id: 23, name: 'Differentiation', group: 'Team B', runtime: 10},
{id: 24, name: 'Definition of the derivative', group: 'Team C', runtime: 60},
{id: 25, name: 'Conceptual understanding of derivatives', group: 'Team C', runtime: 30},
{id: 26, name: 'polynomials and power functions', group: 'Team D', runtime: 40},
{id: 27, name: 'Product rule', group: 'Team C', runtime: 20},
{id: 28, name: 'without trigonometric functions', group: 'Team D', runtime: 60},
{id: 29, name: 'with trigonometric functions', group: 'Team D', runtime: 60},
{id: 30, name: 'Quotient rule', group: 'Team C', runtime: 100},
{id: 31, name: 'Derivatives', group: 'Team C', runtime: 80},
{id: 32, name: 'exponential functions', group: 'Team D', runtime: 20},
{id: 33, name: 'logarithmic functions', group: 'Team D', runtime: 240},
{id: 34, name: 'inverse functions', group: 'Team D', runtime: 30},
{id: 35, name: 'inverse trigonometric functions', group: 'Team D', runtime: 40},
{id: 36, name: 'Hyperbolic functions', group: 'Team C', runtime: 30},
{id: 37, name: 'Chain rule', group: 'Team C', runtime: 60},
{id: 38, name: 'Higher-order derivatives', group: 'Team C', runtime: 30},
{id: 39, name: 'Derivatives involving multiple rules', group: 'Team C', runtime: 40},
{id: 40, name: 'no product, quotient, or chain rule', group: 'Team D', runtime: 20},
{id: 41, name: 'no chain rule', group: 'Team D', runtime: 60},
{id: 42, name: 'all rules', group: 'Team D', runtime: 60},
{id: 43, name: 'Logarithmic differentiation', group: 'Team C', runtime: 100},
{id: 44, name: 'Implicit differentiation', group: 'Team C', runtime: 80},
//-----Application of differentiation-----
{id: 45, name: 'Applications of differentiation', group: 'Team B', runtime: 10},
{id: 46, name: 'Mean value theorem', group: 'Team C', runtime: 60},
{id: 47, name: 'Rates of change', group: 'Team C', runtime: 30},
{id: 48, name: 'general', group: 'Team D', runtime: 40},
{id: 49, name: 'business and economics', group: 'Team D', runtime: 20},
{id: 50, name: 'engineering and physics', group: 'Team D', runtime: 60},
{id: 51, name: 'natural and social sciences', group: 'Team D', runtime: 60},
{id: 52, name: 'Increasing/decreasing functions and local extrema', group: 'Team C', runtime: 100},
{id: 53, name: 'Concavity and points of inflection', group: 'Team C', runtime: 80},
{id: 54, name: 'Global extrema', group: 'Team C', runtime: 20},
{id: 55, name: 'Summary of curve sketching', group: 'Team C', runtime: 240},
{id: 56, name: 'Optimization', group: 'Team C', runtime: 30},
{id: 57, name: 'general', group: 'Team D', runtime: 40},
{id: 58, name: 'business and economics', group: 'Team D', runtime: 20},
{id: 59, name: 'engineering and physics', group: 'Team D', runtime: 60},
{id: 60, name: 'natural and social sciences', group: 'Team D', runtime: 30},
{id: 61, name: 'Linear approximation and differentials', group: 'Team C', runtime: 40},
{id: 62, name: 'Related rates', group: 'Team C', runtime: 20},
{id: 63, name: 'Indeterminate forms and L Hopital rule', group: 'Team C', runtime: 60},
{id: 64, name: 'Newton method', group: 'Team C', runtime: 60},
{id: 65, name: 'Elasticity of demand', group: 'Team C', runtime: 100},
//-----Integrals-----
{id: 66, name: 'Integrals', group: 'Team B', runtime: 10},
{id: 67, name: 'Conceptual understanding of integration', group: 'Team C', runtime: 60},
{id: 68, name: 'Antiderivatives', group: 'Team C', runtime: 30},
{id: 69, name: 'Indefinite integrals', group: 'Team C', runtime: 40},
{id: 70, name: 'Riemann sums', group: 'Team C', runtime: 20},
{id: 71, name: 'Definite integrals', group: 'Team C', runtime: 60},
{id: 72, name: 'Fundamental theorem of calculus', group: 'Team C', runtime: 60},
{id: 73, name: 'Improper integrals', group: 'Team C', runtime: 100},
//-----Techniques of integration-----
{id: 84, name: 'Techniques of integration', group: 'Team B', runtime: 100},
{id: 75, name: 'Substitution', group: 'Team C', runtime: 10},
{id: 76, name: 'Integration by parts', group: 'Team C', runtime: 60},
{id: 77, name: 'Trigonometric integrals', group: 'Team C', runtime: 30},
{id: 78, name: 'Partial fractions', group: 'Team C', runtime: 40},
{id: 79, name: 'Trigonometric substitution', group: 'Team C', runtime: 20},
{id: 80, name: 'Computer algebra system', group: 'Team C', runtime: 60},
{id: 81, name: 'Mixed techniques', group: 'Team C', runtime: 60},
{id: 82, name: 'Challenging integrals', group: 'Team C', runtime: 100},
{id: 83, name: 'Approximation', group: 'Team C', runtime: 100},
//-----Applications of integration-----
{id: 85, name: 'Applications of integration', group: 'Team B', runtime: 100},
{id: 86, name: 'Average value of a function', group: 'Team C', runtime: 10},
{id: 87, name: 'Areas between curves', group: 'Team C', runtime: 60},
{id: 88, name: 'Volumes', group: 'Team C', runtime: 30},
{id: 89, name: 'by slices', group: 'Team D', runtime: 40},
{id: 90, name: 'by disks', group: 'Team D', runtime: 20},
{id: 91, name: 'by washers', group: 'Team D', runtime: 60},
{id: 92, name: 'by cylindrical shells', group: 'Team D', runtime: 60},
{id: 93, name: 'by multiple methods', group: 'Team D', runtime: 100},
{id: 94, name: 'Arc length', group: 'Team C', runtime: 100},
{id: 95, name: 'Surfaces of revolution', group: 'Team C', runtime: 60},
{id: 96, name: 'Distance, velocity, acceleration', group: 'Team C', runtime: 60},
{id: 97, name: 'Work', group: 'Team C', runtime: 100},
{id: 98, name: 'Hydrostatic pressure', group: 'Team C', runtime: 100},
{id: 99, name: 'Center of gravity', group: 'Team C', runtime: 60},
{id: 100, name: 'Other physics and engineering applications', group: 'Team C', runtime: 100},
{id: 101, name: 'Economics', group: 'Team C', runtime: 100},
{id: 102, name: 'Biology', group: 'Team C', runtime: 60},
{id: 103, name: 'Probability and statistics', group: 'Team C', runtime: 60},
//-----Infinite sequences and series-----
{id: 104, name: 'Infinite sequences and series', group: 'Team B', runtime: 100},
{id: 105, name: 'Limit of a sequence', group: 'Team C', runtime: 10},
{id: 106, name: 'Series notation', group: 'Team C', runtime: 60},
{id: 107, name: 'Partial sums', group: 'Team C', runtime: 30},
{id: 108, name: 'Taylor polynomials', group: 'Team C', runtime: 40},
{id: 109, name: 'Geometric', group: 'Team C', runtime: 20},
{id: 110, name: 'Test for divergence', group: 'Team C', runtime: 60},
{id: 111, name: 'Comparison tests', group: 'Team D', runtime: 60},
{id: 112, name: 'Integral test', group: 'Team D', runtime: 100},
{id: 113, name: 'Ratio test', group: 'Team D', runtime: 100},
{id: 114, name: 'Root test', group: 'Team D', runtime: 60},
{id: 115, name: 'Alternating series test', group: 'Team D', runtime: 60},
{id: 116, name: 'Absolute and conditional convergence', group: 'Team C', runtime: 100},
{id: 117, name: 'Strategy for testing series', group: 'Team C', runtime: 100},
{id: 118, name: 'Interval of convergence of a power series', group: 'Team D', runtime: 60},
{id: 119, name: 'Maclaurin series', group: 'Team D', runtime: 100},
{id: 120, name: 'Taylor series', group: 'Team D', runtime: 100},
{id: 121, name: 'Power series', group: 'Team D', runtime: 60},
{id: 122, name: 'Representations of functions as series', group: 'Team D', runtime: 60},
{id: 123, name: 'Fourier series', group: 'Team D', runtime: 60},
{id: 124, name: 'Applications of Taylor polynomials', group: 'Team C', runtime: 60},
],
links: [
//-----Calculus - single variable-----
{source: 1, target: 74, type: ''},
{source: 23, target: 74, type: ''},
{source: 45, target: 74, type: ''},
{source: 66, target: 74, type: ''},
{source: 84, target: 74, type: ''},
{source: 85, target: 74, type: ''},
{source: 104, target: 74, type: ''},
{source: 45, target: 23, type: 'based on'},
{source: 84, target: 66, type: 'based on'},
{source: 85, target: 66, type: 'based on'},
//-----Limits and continuity-----
{source: 2, target: 1, type: ''},
{source: 3, target: 1, type: ''},
{source: 4, target: 1, type: ''},
{source: 5, target: 4, type: ''},
{source: 6, target: 5, type: ''},
{source: 7, target: 5, type: ''},
{source: 8, target: 5, type: ''},
{source: 9, target: 5, type: ''},
{source: 10, target: 1, type: ''},
{source: 11, target: 1, type: ''},
{source: 12, target: 1, type: ''},
{source: 13, target: 12, type: ''},
{source: 14, target: 12, type: ''},
{source: 15, target: 1, type: ''},
{source: 16, target: 1, type: ''},
{source: 17, target: 1, type: ''},
{source: 18, target: 1, type: ''},
{source: 19, target: 18, type: ''},
{source: 20, target: 18, type: ''},
{source: 21, target: 18, type: ''},
{source: 22, target: 1, type: ''},
//-----Differentiation-----
{source: 24, target: 23, type: ''},
{source: 25, target: 23, type: ''},
{source: 26, target: 31, type: ''},
{source: 27, target: 23, type: ''},
{source: 28, target: 27, type: ''},
{source: 28, target: 30, type: ''},
{source: 28, target: 37, type: ''},
{source: 29, target: 27, type: ''},
{source: 29, target: 30, type: ''},
{source: 29, target: 37, type: ''},
{source: 29, target: 31, type: ''},
{source: 30, target: 23, type: ''},
{source: 31, target: 23, type: ''},
{source: 32, target: 31, type: ''},
{source: 33, target: 31, type: ''},
{source: 34, target: 31, type: ''},
{source: 35, target: 31, type: ''},
{source: 36, target: 31, type: ''},
{source: 36, target: 23, type: ''},
{source: 37, target: 23, type: ''},
{source: 38, target: 23, type: ''},
{source: 39, target: 23, type: ''},
{source: 40, target: 39, type: ''},
{source: 41, target: 39, type: ''},
{source: 42, target: 39, type: ''},
{source: 43, target: 23, type: ''},
{source: 44, target: 23, type: ''},
//-----Application of differentiation-----
{source: 46, target: 45, type: ''},
{source: 47, target: 45, type: ''},
{source: 48, target: 47, type: ''},
{source: 49, target: 47, type: ''},
{source: 50, target: 47, type: ''},
{source: 51, target: 47, type: ''},
{source: 52, target: 45, type: ''},
{source: 53, target: 45, type: ''},
{source: 54, target: 45, type: ''},
{source: 55, target: 45, type: ''},
{source: 56, target: 45, type: ''},
{source: 57, target: 56, type: ''},
{source: 58, target: 56, type: ''},
{source: 59, target: 56, type: ''},
{source: 60, target: 56, type: ''},
{source: 61, target: 45, type: ''},
{source: 62, target: 45, type: ''},
{source: 63, target: 45, type: ''},
{source: 64, target: 45, type: ''},
{source: 65, target: 45, type: ''},
//-----Integrals-----
{source: 67, target: 66, type: ''},
{source: 68, target: 66, type: ''},
{source: 69, target: 66, type: ''},
{source: 70, target: 66, type: ''},
{source: 71, target: 66, type: ''},
{source: 72, target: 66, type: ''},
{source: 73, target: 66, type: ''},
{source: 28, target: 68, type: ''},
{source: 28, target: 69, type: ''},
{source: 28, target: 71, type: ''},
{source: 29, target: 68, type: ''},
{source: 29, target: 69, type: ''},
{source: 29, target: 71, type: ''},
//-----Techniques of integration-----
{source: 75, target: 84, type: ''},
{source: 76, target: 84, type: ''},
{source: 77, target: 84, type: ''},
{source: 78, target: 84, type: ''},
{source: 79, target: 84, type: ''},
{source: 80, target: 84, type: ''},
{source: 81, target: 84, type: ''},
{source: 82, target: 84, type: ''},
{source: 83, target: 84, type: ''},
{source: 36, target: 84, type: ''},
{source: 28, target: 75, type: ''},
{source: 28, target: 76, type: ''},
{source: 29, target: 75, type: ''},
{source: 29, target: 76, type: ''},
//-----Applications of integration-----
{source: 86, target: 85, type: ''},
{source: 87, target: 85, type: ''},
{source: 88, target: 85, type: ''},
{source: 89, target: 88, type: ''},
{source: 90, target: 88, type: ''},
{source: 91, target: 88, type: ''},
{source: 92, target: 88, type: ''},
{source: 93, target: 88, type: ''},
{source: 94, target: 85, type: ''},
{source: 95, target: 85, type: ''},
{source: 96, target: 85, type: ''},
{source: 97, target: 85, type: ''},
{source: 98, target: 85, type: ''},
{source: 99, target: 85, type: ''},
{source: 100, target: 85, type: ''},
{source: 101, target: 85, type: ''},
{source: 102, target: 85, type: ''},
{source: 103, target: 85, type: ''},
//-----Infinite sequences and series-----
{source: 105, target: 104, type: ''},
{source: 106, target: 104, type: ''},
{source: 107, target: 104, type: ''},
{source: 108, target: 104, type: ''},
{source: 109, target: 104, type: ''},
{source: 110, target: 104, type: ''},
{source: 111, target: 110, type: ''},
{source: 112, target: 110, type: ''},
{source: 113, target: 110, type: ''},
{source: 114, target: 110, type: ''},
{source: 115, target: 110, type: ''},
{source: 116, target: 104, type: ''},
{source: 117, target: 104, type: ''},
{source: 118, target: 117, type: ''},
{source: 119, target: 117, type: ''},
{source: 120, target: 117, type: ''},
{source: 121, target: 117, type: ''},
{source: 122, target: 117, type: ''},
{source: 123, target: 117, type: ''},
{source: 124, target: 104, type: ''},
]
};
console.log("dataset is ...",dataset);
// Initialize the links
const link = svg.selectAll(".links")
.data(dataset.links)
.enter()
.append("line")
.attr("class", "links")
.attr('marker-end','url(#arrowhead)') //The marker-end attribute defines the arrowhead or polymarker that will be drawn at the final vertex of the given shape.
//The <title> element provides an accessible, short-text description of any SVG container element or graphics element.
//Text in a <title> element is not rendered as part of the graphic, but browsers usually display it as a tooltip.
link.append("title")
.text(d => d.type);
const edgepaths = svg.selectAll(".edgepath") //make path go along with the link provide position for link labels
.data(dataset.links)
.enter()
.append('path')
.attr('class', 'edgepath')
.attr('fill-opacity', 0)
.attr('stroke-opacity', 0)
.attr('id', function (d, i) {return 'edgepath' + i})
.style("pointer-events", "none");
const edgelabels = svg.selectAll(".edgelabel")
.data(dataset.links)
.enter()
.append('text')
.style("pointer-events", "none")
.attr('class', 'edgelabel')
.attr('id', function (d, i) {return 'edgelabel' + i})
.attr('font-size', 10)
.attr('fill', '#aaa');
edgelabels.append('textPath') //To render text along the shape of a <path>, enclose the text in a <textPath> element that has an href attribute with a reference to the <path> element.
.attr('xlink:href', function (d, i) {return '#edgepath' + i})
.style("text-anchor", "middle")
.style("pointer-events", "none")
.attr("startOffset", "50%")
.text(d => d.type);
// Initialize the nodes
const node = svg.selectAll(".nodes")
.data(dataset.nodes)
.enter()
.append("g")
.attr("class", "nodes")
.call(d3.drag() //sets the event listener for the specified typenames and returns the drag behavior.
.on("start", dragstarted) //start - after a new pointer becomes active (on mousedown or touchstart).
.on("drag", dragged) //drag - after an active pointer moves (on mousemove or touchmove).
//.on("end", dragended) //end - after an active pointer becomes inactive (on mouseup, touchend or touchcancel).
);
node.append("circle")
.attr("r", d=> 17)//+ d.runtime/20 )
.style("stroke", "grey")
.style("stroke-opacity",0.3)
.style("stroke-width", d => d.runtime/10)
.style("fill", d => colorScale(d.group))
node.append("title")
.text(d => d.id + ": " + d.label + " - " + d.group +", runtime:"+ d.runtime+ "min");
node.append("text")
.attr("dy", 4)
.attr("dx", -15)
.text(d => d.name);
node.append("text")
.attr("dy",12)
.attr("dx", -8)
.text(d=> d.runtime);
//Listen for tick events to render the nodes as they update in your Canvas or SVG.
simulation
.nodes(dataset.nodes)
.on("tick", ticked);
simulation.force("link")
.links(dataset.links);
// This function is run at each iteration of the force algorithm, updating the nodes position (the nodes data array is directly manipulated).
function ticked() {
link.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
node.attr("transform", d => `translate(${d.x},${d.y})`);
edgepaths.attr('d', d => 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y);
}
//When the drag gesture starts, the targeted node is fixed to the pointer
//The simulation is temporarily “heated” during interaction by setting the target alpha to a non-zero value.
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();//sets the current target alpha to the specified number in the range [0,1].
d.fy = d.y; //fx - the node’s fixed x-position. Original is null.
d.fx = d.x; //fy - the node’s fixed y-position. Original is null.
}
//When the drag gesture starts, the targeted node is fixed to the pointer
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
//the targeted node is released when the gesture ends
// function dragended(d) {
// if (!d3.event.active) simulation.alphaTarget(0);
// d.fx = null;
// d.fy = null;
// console.log("dataset after dragged is ...",dataset);
// }
//drawing the legend
const legend_g = svg.selectAll(".legend")
.data(colorScale.domain())
.enter().append("g")
.attr("transform", (d, i) => `translate(${width},${i * 20})`);
legend_g.append("circle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", 5)
.attr("fill", colorScale);
legend_g.append("text")
.attr("x", 10)
.attr("y", 5)
.text(d => d);
//drawing the second legend
const legend_g2 = svg.append("g")
//.attr("transform", (d, i) => `translate(${width},${i * 20})`);
.attr("transform", `translate(${width}, 120)`);
legend_g2.append("circle")
.attr("r", 5)
.attr("cx", 0)
.attr("cy", 0)
.style("stroke", "grey")
.style("stroke-opacity",0.3)
.style("stroke-width", 15)
.style("fill", "black")
legend_g2.append("text")
.attr("x",15)
.attr("y",0)
.text("long runtime");
legend_g2.append("circle")
.attr("r", 5)
.attr("cx", 0)
.attr("cy", 20)
.style("stroke", "grey")
.style("stroke-opacity",0.3)
.style("stroke-width", 2)
.style("fill", "black")
legend_g2.append("text")
.attr("x",15)
.attr("y",20)
.text("short runtime");
return div
}