javascript - How to plot svg circles on curved line in d3 js? -
i coding software in draw svg circles positioned side side, user can adjust position, changing line coordinates. desired result this
right circles disposed space not correct, making circles go left
code
function curve(val){ var w = d3.select("#new_row_1").attr("width"); var numlines = 1, linespacing = 18, parabdepth = -30; var row_spacing = 18; if(val == 0){ parabdepth = -18; } else if(val == 1){ parabdepth = 0; } else if(val == 2){ parabdepth = 20; } else if(val == 3){ parabdepth = 30; } else if(val == 4){ parabdepth = 40; } else if(val == 5){ parabdepth = 50; // row_spacing = 18.41; } else if(val == 6){ // row_spacing = 18.5; parabdepth = 60; } else if(val == 7){ // row_spacing = 18.6; parabdepth = 70; } else if(val == 8){ // row_spacing = 18.62; parabdepth = 80; } else if(val == 9){ parabdepth = 90; } else if(val == 10){ parabdepth = 100; } else if(val == 11){ parabdepth = 110; } else if(val == 12){ parabdepth = 120; } else if(val == 13){ parabdepth = 130; } else if(val == 14){ parabdepth = 140; } else if(val == 15){ parabdepth = 150; row_spacing = 20; } width = w ; var curvedata = []; curvedata.push([0,0]); curvedata.push([width/3 * 1, linespacing + parabdepth ]); curvedata.push([width/3 * 2, linespacing + parabdepth ]); curvedata.push([width/3 * 3, 1]); var line = d3.line() .x(function(d) { return d[0]; }) .y(function(d) { return d[1] + 8; }) .curve(d3.curvecardinal); var svg = d3.select("#new_row_1").attr("height", (numlines * linespacing) + linespacing + parabdepth + row_spacing).attr("width", width); var g = svg.selectall(".line") .data(d3.range(numlines)) .enter() .append("g") .attr("class", "line") .attr("transform", function(d){ return "translate(7," + (d*linespacing) + ")"; }); var path = g.append("path") .attr("d", line(curvedata)) .style("fill", "none") .style("stroke", "pink") .style("stroke-width","4") .each(function(){ var g = d3.select(this.parentnode), self = d3.select(this), pathlength = width; g.selectall("circle") .data(d3.range(1, width, row_spacing)) .enter() .append("circle") .attr("transform", (d,i) => { var p = this.getpointatlength(d); return "translate(" + p.x + "," + p.y + ")"; }) .attr("r", 7) .style("fill", function(d,i){ if(i == quant_col2 - 1){ return "red"; }else if(i == quant_col2/2){ return "yellow"; } else if(i == quant_col2 - 2){ return "green"; } else{ return "white"; } }) .attr("stroke","black") .attr("stroke-width","1"); }); } settimeout(function(){ curve(1) },2000) <script src="https://d3js.org/d3.v4.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg width="252" height="18" id="new_row_1" class="new_row" style="top: 150px; left: 302px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><g><circle cx="8" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="3" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">1</text></g><g><circle cx="26" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="21" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">2</text></g><g><circle cx="44" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="39" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">3</text></g><g><circle cx="62" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="57" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">4</text></g><g><circle cx="80" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="75" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">5</text></g><g><circle cx="98" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="93" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">6</text></g><g><circle cx="116" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="111" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">7</text></g><g><circle cx="134" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="129" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">8</text></g><g><circle cx="152" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="147" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">9</text></g><g><circle cx="170" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="165" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">10</text></g><g><circle cx="188" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="183" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">11</text></g><g><circle cx="206" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="201" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">12</text></g><g><circle cx="224" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="219" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">13</text></g><g><circle cx="242" cy="8" r="7" style="fill: white; stroke: black; stroke-width: 1;"></circle><text dx="237" dy="11" class="label" style="font-size: 10px; font-weight: 500; display: none;">14</text><g class="label" style="display: none;"><rect x="126" y="1" width="14" height="14" style="fill: black;"></rect><text dx="130" dy="11" style="font-size: 9px; font-weight: 400; fill: white;">a</text></g></g></svg> the value controlled user, meaning change dynamically. want evenly dispose them through line. how can done?
you using getpointatlength() find x,y coordinates of point @ distance along curve. obvoiously that's wrong. want find y coord given x.
there no built-in svg function that. going have calculate yourself. need polynomial form of bezier equation, not trivial.
since making parabola, better avoid using bezier curves @ all, , calculate curve using normal simple quadratic equation (ax^2 + bx + c).
aside: if decide stick bezier curves, should use quadratic bezier, instead of cbic one. quadratic beziers have property form segmnt of parabola.


Comments
Post a Comment