class BreedingGraph { constructor() { this.rootNode = document.createElement('breeding-graph'); } mount(parentNode) { parentNode.appendChild(this.rootNode); return this; } render(rows, config) { const rootNode = this.rootNode; const {getX, getY, gradientStops, dotRadius, dim} = config; var margin = {top: 10, right: 20, bottom: 20, left: 30}; var width = dim.width - margin.left - margin.right, height = dim.height - margin.top - margin.bottom; // X const [xStart, xEnd] = d3.extent(rows, getX); const xScale = d3.scaleTime() .range([0, width]) .domain([xStart, xEnd]); const xFn = function(d) { return xScale(getX(d)); }; const xAxis = d3.axisBottom() .scale(xScale) .ticks(d3.timeYear.every(2)) .tickFormat(d3.timeFormat("%Y")); // Y const [yStart, yEnd] = d3.extent(rows, getY); const yScale = d3.scaleLinear() .range([height, 0]) .domain([0, yEnd]); const yFn = function(d) { return yScale(getY(d)); }; const yAxis= d3.axisLeft() .scale(yScale) .ticks(5) .tickSize(-width); // Plot var svg = d3.select(rootNode) .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append('g') .attr('class','chart') .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); svg.append("linearGradient") .attr("id", "count-gradient") .attr("gradientUnits", "userSpaceOnUse") .attr("x1", 0).attr("y1", 0 ) .attr("x2", 700).attr("y2", 0 ) .selectAll("stop") .data(gradientStops) .enter().append("stop") .attr("offset", function(d) { return d.offset; }) .attr("stop-color", function(d) { return d.color; }); svg.append('g') .attr('class', 'x axis') .attr('transform', "translate(0," + height + ")") .call(xAxis); svg.append('g') .attr('class', 'y axis') .call(yAxis); d3.select(".y.axis") .append("text") .attr("class", "label"); svg.append("path") .datum(rows) .attr("class", "line") .attr("d", d3.line().x(xFn).y(yFn)); svg.selectAll(".dot") .data(rows) .enter().append("svg:circle") .attr("class", "dot") .attr("cx", xFn ) .attr("cy", yFn ) .attr("r", dotRadius); } }