D3 X Domain shifting unexpectedly after panning - javascript
I am trying to create a plot that is pannable/zoomable only in the x and is responsive to the page resizes. I am running into an issue where the domain of the x-axis works properly at the original zoomTransform. Code snippet is below. I would suggest opening in a different window to test. Notice that the domain stays the same when the window is resized at the original state. Once the plot is panned any amount (the further you pan the more prominent the issue) the domain will shift on page resize.
I have tested trying to adjust the domain on x_ax to the value of the vd axis but that does not seem to help.
window.addEventListener("resize", redraw);
let parentRect = $("#i3061007142472").parent()[0].getBoundingClientRect();
let pWidth = parentRect.width;
let pHeight = parentRect.height;
var margin = {
'top': 10,
'right': 30,
'bottom': 30,
'left': 60
},
width = pWidth - margin.left - margin.right,
height = pHeight - margin.top - margin.bottom;
var svg = d3.select("#i3061007142472")
.attr("width", width)
.attr("height", height + 20);
var zoom = d3.zoom();
zoom.on("zoom", zoom_handler_dataplot);
d3.select("#i3061007142472").call(zoom);
var x_ax = d3.scaleTime()
.domain([new Date('0'), new Date('10')])
.range([60, width]);
x_ax.type = "time";
var svg_gX = svg.append("g")
.attr("class", "xAxis dataplot")
.attr("transform", `translate(0, ${height})`)
svg_gX.call(d3.axisBottom(x_ax).ticks(5));
var y_ax = d3.scaleLinear()
.domain([0, 10])
.range([height, 0]);
y_ax.type = "linear";
let vd_xaxis_ax = x_ax.copy();
let vd_yaxis_ax = y_ax.copy();
var svg_gY = svg.append("g")
.attr("class", "yAxis dataplot")
.style("padding-left", "50px")
.attr("transform", "translate(" + 60 + ", 0)")
.call(d3.axisLeft(y_ax).ticks(5));
allow_pan_dir = "x";
domain = x_ax.domain();
function zoom_handler_dataplot() {
if (allow_pan_dir != "none") {
if (allow_pan_dir == "x" || allow_pan_dir == "both") {
vd_xaxis_ax = d3.event.transform.rescaleX(x_ax);
domain = vd_xaxis_ax.domain()
svg_gX.call(d3.axisBottom(vd_xaxis_ax));
} else {
vd_xaxis_ax = x_ax;
}
if (allow_pan_dir == "y" || allow_pan_dir == "both") {
vd_yaxis_ax = d3.event.transform.rescaleY(y_ax);
svg_gY.call(d3.axisLeft(vd_yaxis_ax));
} else {
vd_yaxis_ax = y_ax;
}
}
}
function redraw() {
console.warn("calling redraw");
console.warn(allow_pan_dir);
chartWidth = parseInt(d3.select(".dataplot_i3061007142472").style("width"));
chartHeight = parseInt(d3.select(".dataplot_i3061007142472").style("height"));
height = chartHeight - margin.top - margin.bottom + 20;
x_ax.range([60, chartWidth]);
y_ax.range([chartHeight - 30 - 10 + 20, 0]);
if (allow_pan_dir == "x" || allow_pan_dir == "both") {
vd_xaxis_ax = d3.zoomTransform(d3.select("#i3061007142472").node()).rescaleX(x_ax);
svg_gX.call(d3.axisBottom(vd_xaxis_ax));
} else {
vd_xaxis_ax = x_ax;
}
if (allow_pan_dir == "y" || allow_pan_dir == "both") {
vd_yaxis_ax = d3.zoomTransform(d3.select("#i3061007142472").node()).rescaleY(y_ax);
svg_gY.call(d3.axisLeft(vd_yaxis_ax));
} else {
vd_yaxis_ax = y_ax;
}
let currTransform = d3.zoomTransform(d3.select('#i3061007142472').node());
d3.select("#i3061007142472").call(zoom.transform, currTransform);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./styles.css ">
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.0.0/d3.min.js" integrity="sha512-il/oXcqETt5LGGmWWbOZLxrDgQQXlr7+ZI37ksA//3e9mxFloAOzlkF8SqtMOlWL6zTCk8hPYUQnreiQvT4elQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
</head>
<body>
<div id="my_plot" style="display: flex; flex: 1;">
<svg id="i3061007142472" class="dataplot_i3061007142472 dataplot"></svg>
</div>
<script src="./app.js"></script>
</body>
</html>
Related
D3 axisBottom scale domain issue when resizing after transform
I am trying to create a simple plot that is zoomable, pannable, and dynamically resizes with the window. In this case I only want it be to zoomable and pannable on the x axis. I'm using d3 v4. The main issue I have run into is that the domain of the bottom axis will shift/slide when the page is being resized after the plot has been transformed. On resizing without having first transformed the plot, the bottom axis behaves as desired and maintains its domain, just "compressing" and "expanding" on resize. To see the desired behavior, you can resize the plot without first transforming the plot by zooming or panning, and you'll see that the bottom axis maintains its domain. To see the undesirable behavior, you can pan or zoom the plot and then resize the page. You will notice that the domain of the bottom axis will slide/shift. I suspect there is something I'm doing wrong with setting my scales, however I am quite stuck. The snippet below is a minimum working example of what I am working with: window.addEventListener("resize", redraw); let parentRect = $("#i3061007142472").parent()[0].getBoundingClientRect(); let pWidth = parentRect.width; let pHeight = parentRect.height; var margin = { 'top': 10, 'right': 30, 'bottom': 30, 'left': 60 }, width = pWidth - margin.left - margin.right, height = pHeight - margin.top - margin.bottom; var svg = d3.select("#i3061007142472") .attr("width", width) .attr("height", height + 20); var zoom = d3.zoom(); zoom.on("zoom", zoom_handler_dataplot); d3.select("#i3061007142472").call(zoom); var x_i3061007142472 = d3.scaleTime() .domain([new Date('0'), new Date('10')]) .range([60, width]); x_i3061007142472.type = "time"; var svg_gX = svg.append("g") .attr("class", "xAxis dataplot") .attr("transform", `translate(0, ${height})`) svg_gX.call(d3.axisBottom(x_i3061007142472).ticks(5)); var y_i3061007142472 = d3.scaleLinear() .domain([0, 10]) .range([height, 0]); y_i3061007142472.type = "linear"; let vd_xaxis_i3061007142472 = x_i3061007142472.copy(); let vd_yaxis_i3061007142472 = y_i3061007142472.copy(); var svg_gY = svg.append("g") .attr("class", "yAxis dataplot") .style("padding-left", "50px") .attr("transform", "translate(" + 60 + ", 0)") .call(d3.axisLeft(y_i3061007142472).ticks(5)); allow_pan_dir = "x"; domain = x_i3061007142472.domain(); function zoom_handler_dataplot() { if (allow_pan_dir != "none") { if (allow_pan_dir == "x" || allow_pan_dir == "both") { vd_xaxis_i3061007142472 = d3.event.transform.rescaleX(x_i3061007142472); domain = vd_xaxis_i3061007142472.domain() svg_gX.call(d3.axisBottom(vd_xaxis_i3061007142472)); } else { vd_xaxis_i3061007142472 = x_i3061007142472; } if (allow_pan_dir == "y" || allow_pan_dir == "both") { vd_yaxis_i3061007142472 = d3.event.transform.rescaleY(y_i3061007142472); svg_gY.call(d3.axisLeft(vd_yaxis_i3061007142472)); } else { vd_yaxis_i3061007142472 = y_i3061007142472; } } } function redraw() { console.warn("calling redraw"); console.warn(allow_pan_dir); chartWidth = parseInt(d3.select(".dataplot_i3061007142472").style("width")); chartHeight = parseInt(d3.select(".dataplot_i3061007142472").style("height")); height = chartHeight - margin.top - margin.bottom + 20; x_i3061007142472.range([60, chartWidth]); y_i3061007142472.range([chartHeight - 30 - 10 + 20, 0]); if (allow_pan_dir == "x" || allow_pan_dir == "both") { vd_xaxis_i3061007142472 = d3.zoomTransform(d3.select("#i3061007142472").node()).rescaleX(x_i3061007142472); svg_gX.call(d3.axisBottom(vd_xaxis_i3061007142472)); } else { vd_xaxis_i3061007142472 = x_i3061007142472; } if (allow_pan_dir == "y" || allow_pan_dir == "both") { vd_yaxis_i3061007142472 = d3.zoomTransform(d3.select("#i3061007142472").node()).rescaleY(y_i3061007142472); svg_gY.call(d3.axisLeft(vd_yaxis_i3061007142472)); } else { vd_yaxis_i3061007142472 = y_i3061007142472; } let currTransform = d3.zoomTransform(d3.select('#i3061007142472').node()); d3.select("#i3061007142472").call(zoom.transform, currTransform); } <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="./styles.css "> <title>Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.0.0/d3.min.js" integrity="sha512-il/oXcqETt5LGGmWWbOZLxrDgQQXlr7+ZI37ksA//3e9mxFloAOzlkF8SqtMOlWL6zTCk8hPYUQnreiQvT4elQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script> </head> <body> <div id="my_plot" style="display: flex; flex: 1;"> <svg id="i3061007142472" class="dataplot_i3061007142472 dataplot"></svg> </div> <script src="./app.js"></script> </body> </html> I tried changing the domain on resize to match the transformed, tried using an intermediary scale, tried modifying the reference scale.
d3 contour Observable to Vanilla JS
I am converting the d3 contour example https://observablehq.com/#d3/volcano-contours?collection=#d3/d3-contour to vanilla js for a stand alone application. I am new to observable and JS. <html> <head> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> <meta content="utf-8" http-equiv="encoding"> <script src="https://d3js.org/d3.v6.min.js"></script> <script src="https://d3js.org/d3-contour.v2.min.js"></script> <script src="https://d3js.org/d3-hsv.v0.1.min.js"></script> </head> <body> <div class="container"></div> <script> function vChart(container){ const data = FileAttachment("volcano.json").json(); const height = data.height; const width = data.width; const contours = d3.contours().size([width, height]); const path = d3.geoPath(); function interpolateTerrain() { const i0 = d3.interpolateHsvLong(d3.hsv(120, 1, 0.65), d3.hsv(60, 1, 0.90)); const i1 = d3.interpolateHsvLong(d3.hsv(60, 1, 0.90), d3.hsv(0, 0, 0.95)); return t => t < 0.5 ? i0(t * 2) : i1((t - 0.5) * 2); } const color = d3.scaleSequential(interpolateTerrain).domain(d3.extent(data.values)).nice(); const thresholds = color.ticks(20); const wide = Generators.observe(notify => { let wide; function resized() { let w = innerWidth > 640; if (w !== wide) notify(wide = w); } resized(); addEventListener("resize", resized); return () => removeEventListener("resize", resized); }) const svg = d3.select(container).append('svg') .attr("viewBox", wide ? [0, 0, width, height] : [0, 0, height, width]) .style("display", "block") .style("margin", "0 -14px") .style("width", "calc(100% + 28px)") .style("height", "auto"); const g = svg.append("g") .attr("transform", wide ? null : ` rotate(90 ${width/2},${height/2}) translate(${(width - height) / 2},${(width - height) / 2}) `) .attr("stroke", "white") .attr("stroke-width", 0.03); for (const threshold of thresholds) { g.append("path") .attr("d", path(contours.contour(data.values, threshold))) .attr("fill", color(threshold)); yield svg.node(); } } vChart('.container') </script> </body> </html> This results in two errors Uncaught ReferenceError: Fileattachment is not defined Uncaught ReferenceError: Generators is not defined I am not able to recreate the generator function, Fileattachment function I guess it is related to observable.
How to create progress bars?
I want to create a waveform with progress bars that fill with another color from left to right. Right now it looks: I want it to look like this. Yellow is buffered audio, orange is playing right now. I already have these values. The main question is how do I fill each rect with color by currentTime of audio? Here's my code: const elementWidth = 1100 const elementHeight = 64 const duration = 160 const currentTime = 20 const buffered = 140 // here's data that i get from web audio api // bar length in seconds would be: // duration / renderData = how much seconds in one bar const renderData = [ [-0.015067690176936956, 0.015065840696712662], [-0.009963374263646985, 0.009960838406137254], [-0.0329772714073922, 0.032922178973984494], [-0.02010780853750818, 0.020192897509204638], [-0.029141768346505944, 0.02913273608186522], [-0.03390369982419367, 0.033888949138664096], [-0.05309944789682607, 0.053106191954295334], [-0.017992382356680794, 0.0179506794436456], [-0.04118192967225779, 0.04120773269527067], [-0.032132343283569134, 0.03223372926977138], [-0.04340663941189386, 0.043317410948806916], [-0.026866048759920942, 0.02695383570549558], [-0.041548487297645216, 0.04142889765358134], [-0.0512541217270734, 0.05128097373670754], [-0.02645596673127562, 0.026461825339764114], [-0.03276659370022165, 0.032869462727325334], [-0.02983164709570332, 0.02965126735342542], [-0.06186988270590101, 0.06228762507639405], [-0.037202475771159274, 0.03684529067849468], [-0.04496168984286248, 0.044984343262096924], [-0.02961698097048877, 0.029580527280458145], [-0.06637895360455075, 0.06584970915134748], [-0.03966561332234608, 0.04028105442218536], [-0.04888827685580639, 0.04879637577182824], [-0.034440279218927505, 0.03448690299802526], [-0.04076603383847427, 0.04087949817166488], [-0.03422100968150345, 0.03407137586231854], [-0.03420552026962888, 0.034233479991186845], [-0.06124921943975816, 0.06133406711072517], [-0.08080063612343565, 0.08052139740352077], [-0.052296123826832304, 0.05245498821828788], [-0.07728568068325997, 0.0772439557897976], [-0.04070025960953707, 0.04072465208052425], [-0.016598400103531252, 0.01673240062886387], [-0.0495708419979178, 0.04952405213368158], [-0.03402468183819489, 0.03404496946468417], [-0.04719791564971553, 0.04716565090961255], [-0.024305039710776202, 0.024425998358774473], [-0.04539290174457686, 0.0453603392364138], [-0.04291280211166326, 0.042803252613569195], [-0.03237617188947045, 0.032430479168267405], [-0.046939414609483046, 0.046991124408919255], [-0.037727014544829074, 0.03756628029896137], [-0.05813820211592722, 0.058137499737658825], [-0.03306609736616569, 0.03332803022833292], [-0.03706343131822335, 0.03699838219166897], [-0.031640843865570666, 0.03150685332686255], [-0.07978720110560034, 0.07982405111308474], [-0.04565408283291298, 0.04548542047551325], [-0.03838929844552628, 0.0386080775422541], [-0.0349069030273341, 0.03516624962570975], [-0.05791808093217102, 0.057646960595115364], [-0.040111244425499945, 0.040190047578908046], [-0.0421531094659709, 0.04210734133509555], [-0.04358563889018587, 0.043380678911277275], [-0.024025454017633886, 0.024179111399202893], [-0.039038574013751944, 0.03889745017750074], [-0.02962543563292595, 0.02975662299643922], [-0.07215596460653108, 0.07225534620830149], [-0.0845103969948925, 0.08417566858032748], [-0.05029865141667644, 0.05110349428845409], [-0.06766253837563593, 0.06680008803627584], [-0.05413748268128195, 0.054261121431710246], [-0.04702217202288801, 0.04710783667779247], [-0.047177278676382065, 0.047241381909344966], [-0.04949906253183499, 0.049358880485210296], [-0.06384145451618915, 0.06398437795989458], [-0.0532812223855561, 0.05336013656088595], [-0.055032831282645335, 0.055131815418379866], [-0.05771727930777607, 0.05743980672281111], [-0.06865421948220482, 0.06896493506959074], [-0.05163944571854085, 0.05129081551014095], [-0.04546664828758613, 0.04549366890782257], [-0.02196073923070452, 0.022119579288034315], [-0.026824862238895183, 0.026915318981447094], [-0.04771898452983383, 0.04768769589918763], [-0.05221904154341058, 0.05202229643239835], [-0.04034726803191834, 0.040288317010035164], [-0.04252634158686052, 0.04275796625513488], [-0.055381424446109724, 0.05515857756430962], [-0.06160043085044191, 0.06143890271068376], [-0.04579617210990365, 0.04612433751815954], [-0.039244869887493206, 0.03927668403684328], [-0.03426885260996771, 0.03423936180141113], [-0.03516869910983574, 0.035127711830890515], [-0.026964357386084752, 0.02699723933039285], [-0.03816966714682839, 0.03778890745758835], [-0.04777519168041681, 0.04824239079542675], [-0.07617805358108933, 0.07612545525147858], [-0.047140552370394925, 0.04744151736320112], [-0.05137018378775051, 0.051114804207469784], [-0.03259493948312707, 0.0325308332802452], [-0.05715909221362399, 0.05709963073119724], [-0.04835633252739353, 0.04849600527981289], [-0.0433886628912617, 0.04331087342221564], [-0.05191740499328957, 0.05183144200010501], [-0.022690824730811025, 0.02281282548488598], [-0.021657892287654815, 0.02160585204290785], [-0.019911292276869504, 0.01990373441321122], [-0.05252214322669061, 0.052514338488489534], [-0.045757900781809524, 0.04581189437809006], [-0.02396372548560904, 0.023788207356191405], [-0.053426097224355276, 0.05348064888976746], [-0.05394891160261981, 0.05421456735805457], [-0.05251658416178273, 0.05238904616093791], [-0.04774168806444406, 0.047755594530669916], [-0.03506924339896615, 0.035076784816174336], [-0.044288649573623336, 0.044337743067559894], [-0.05109649028135573, 0.050986769978167874], [-0.03986396401411081, 0.03992226520835857], [-0.06271544843396921, 0.0628629998182233], [-0.060325113831802425, 0.06014867491287253], [-0.06409607265208252, 0.06426716029136537], [-0.02890807357828784, 0.02879981209701445], [-0.0579076968762734, 0.058055472378755635], [-0.0788244096514242, 0.07889209396389751], [-0.05489594835332056, 0.054304463238473114], [-0.05066376350430718, 0.051136225666937284], [-0.04324084422009672, 0.043106921303429975], [-0.03618639085199314, 0.03630391952984575], [-0.03229893887218463, 0.032254130211298596], [-0.040388961018727465, 0.04034166483632292], [-0.06891322548088202, 0.06894551548689337], [-0.05708462516274434, 0.05713687370165375], [-0.0908320094478539, 0.09053809343169553], [-0.06997210675874246, 0.07036387396569341], [-0.027676689451677956, 0.02757377175784071], [-0.02882633060378825, 0.029207481257562274], [-0.0414701765332311, 0.04136630655327525], [-0.05308296364144847, 0.0526747543606357], [-0.02724146501450132, 0.027406581699254588], [-0.04265844625269343, 0.04270290902986972], [-0.03899306746018118, 0.038745252551468795], [-0.0552804734553083, 0.05535944558193926], [-0.02309096284644189, 0.023040044134232315], [-0.0507964500028555, 0.05096013747702334], [-0.04123972706510699, 0.041359046982264745], [-0.03236153261658939, 0.032179960855430505], [-0.02858521671477931, 0.028570736354436077], [-0.03515761112679279, 0.03513507691850391], [-0.049852204843317816, 0.04984858000374448], [-0.038280519845162314, 0.038365751907998916], [-0.05489151074836156, 0.054958999808454506], [-0.02552547302215947, 0.025555844960312334], [-0.06393766191228746, 0.0638978766928521], [-0.04140103340243134, 0.04113465467714282], [-0.04647459357809104, 0.04654619117779597], [-0.03293849813553063, 0.03301029011724379], [-0.04428244235309984, 0.04433992273438912], [-0.047489538949244604, 0.04755256034371833], [-0.047176763166566854, 0.04719291045558167], [-0.06353201748860114, 0.06380784207550017], [-0.07775209195691819, 0.0773872824070752], [-0.054300174262817344, 0.054476381979975085], [-0.08808678703605805, 0.0879414485377677], [-0.04016286323725983, 0.04007725752721749], [-0.01889086923709467, 0.018989486049242103] ] const height = d3.scaleLinear() .domain(d3.extent(renderData.map(e => e[1] - e[0]))) .range([0, elementHeight]) d3.select(document.getElementById('app')) .append('svg') .attr('class', 'd3') .attr('width', elementWidth) .attr('height', elementHeight) .selectAll('.bar') .data(renderData) .enter() .append('rect') .attr('class', 'bar') .attr('fill', '#E0E0E0') .attr('x', (d, i) => (i * 2 + i)) .attr('y', d => elementHeight - height(d[1] - d[0])) .transition() .duration(300) .ease(d3.easeLinear) .attr('width', 2) .attr('height', d => height(d[1] - d[0])) <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div id='app' /> </body> </html>
Its really fun to play with svg :) This is what i made, have a look. const elementWidth = 1100 const elementHeight = 64 var audioTotalTime = 120.0000; // in secound var currentTime = 0; var currentBuffer = 0; const renderData = [ [-0.015067690176936956, 0.015065840696712662], [-0.009963374263646985, 0.009960838406137254], [-0.0329772714073922, 0.032922178973984494], [-0.02010780853750818, 0.020192897509204638], [-0.029141768346505944, 0.02913273608186522], [-0.03390369982419367, 0.033888949138664096], [-0.05309944789682607, 0.053106191954295334], [-0.017992382356680794, 0.0179506794436456], [-0.04118192967225779, 0.04120773269527067], [-0.032132343283569134, 0.03223372926977138], [-0.04340663941189386, 0.043317410948806916], [-0.026866048759920942, 0.02695383570549558], [-0.041548487297645216, 0.04142889765358134], [-0.0512541217270734, 0.05128097373670754], [-0.02645596673127562, 0.026461825339764114], [-0.03276659370022165, 0.032869462727325334], [-0.02983164709570332, 0.02965126735342542], [-0.06186988270590101, 0.06228762507639405], [-0.037202475771159274, 0.03684529067849468], [-0.04496168984286248, 0.044984343262096924], [-0.02961698097048877, 0.029580527280458145], [-0.06637895360455075, 0.06584970915134748], [-0.03966561332234608, 0.04028105442218536], [-0.04888827685580639, 0.04879637577182824], [-0.034440279218927505, 0.03448690299802526], [-0.04076603383847427, 0.04087949817166488], [-0.03422100968150345, 0.03407137586231854], [-0.03420552026962888, 0.034233479991186845], [-0.06124921943975816, 0.06133406711072517], [-0.08080063612343565, 0.08052139740352077], [-0.052296123826832304, 0.05245498821828788], [-0.07728568068325997, 0.0772439557897976], [-0.04070025960953707, 0.04072465208052425], [-0.016598400103531252, 0.01673240062886387], [-0.0495708419979178, 0.04952405213368158], [-0.03402468183819489, 0.03404496946468417], [-0.04719791564971553, 0.04716565090961255], [-0.024305039710776202, 0.024425998358774473], [-0.04539290174457686, 0.0453603392364138], [-0.04291280211166326, 0.042803252613569195], [-0.03237617188947045, 0.032430479168267405], [-0.046939414609483046, 0.046991124408919255], [-0.037727014544829074, 0.03756628029896137], [-0.05813820211592722, 0.058137499737658825], [-0.03306609736616569, 0.03332803022833292], [-0.03706343131822335, 0.03699838219166897], [-0.031640843865570666, 0.03150685332686255], [-0.07978720110560034, 0.07982405111308474], [-0.04565408283291298, 0.04548542047551325], [-0.03838929844552628, 0.0386080775422541], [-0.0349069030273341, 0.03516624962570975], [-0.05791808093217102, 0.057646960595115364], [-0.040111244425499945, 0.040190047578908046], [-0.0421531094659709, 0.04210734133509555], [-0.04358563889018587, 0.043380678911277275], [-0.024025454017633886, 0.024179111399202893], [-0.039038574013751944, 0.03889745017750074], [-0.02962543563292595, 0.02975662299643922], [-0.07215596460653108, 0.07225534620830149], [-0.0845103969948925, 0.08417566858032748], [-0.05029865141667644, 0.05110349428845409], [-0.06766253837563593, 0.06680008803627584], [-0.05413748268128195, 0.054261121431710246], [-0.04702217202288801, 0.04710783667779247], [-0.047177278676382065, 0.047241381909344966], [-0.04949906253183499, 0.049358880485210296], [-0.06384145451618915, 0.06398437795989458], [-0.0532812223855561, 0.05336013656088595], [-0.055032831282645335, 0.055131815418379866], [-0.05771727930777607, 0.05743980672281111], [-0.06865421948220482, 0.06896493506959074], [-0.05163944571854085, 0.05129081551014095], [-0.04546664828758613, 0.04549366890782257], [-0.02196073923070452, 0.022119579288034315], [-0.026824862238895183, 0.026915318981447094], [-0.04771898452983383, 0.04768769589918763], [-0.05221904154341058, 0.05202229643239835], [-0.04034726803191834, 0.040288317010035164], [-0.04252634158686052, 0.04275796625513488], [-0.055381424446109724, 0.05515857756430962], [-0.06160043085044191, 0.06143890271068376], [-0.04579617210990365, 0.04612433751815954], [-0.039244869887493206, 0.03927668403684328], [-0.03426885260996771, 0.03423936180141113], [-0.03516869910983574, 0.035127711830890515], [-0.026964357386084752, 0.02699723933039285], [-0.03816966714682839, 0.03778890745758835], [-0.04777519168041681, 0.04824239079542675], [-0.07617805358108933, 0.07612545525147858], [-0.047140552370394925, 0.04744151736320112], [-0.05137018378775051, 0.051114804207469784], [-0.03259493948312707, 0.0325308332802452], [-0.05715909221362399, 0.05709963073119724], [-0.04835633252739353, 0.04849600527981289], [-0.0433886628912617, 0.04331087342221564], [-0.05191740499328957, 0.05183144200010501], [-0.022690824730811025, 0.02281282548488598], [-0.021657892287654815, 0.02160585204290785], [-0.019911292276869504, 0.01990373441321122], [-0.05252214322669061, 0.052514338488489534], [-0.045757900781809524, 0.04581189437809006], [-0.02396372548560904, 0.023788207356191405], [-0.053426097224355276, 0.05348064888976746], [-0.05394891160261981, 0.05421456735805457], [-0.05251658416178273, 0.05238904616093791], [-0.04774168806444406, 0.047755594530669916], [-0.03506924339896615, 0.035076784816174336], [-0.044288649573623336, 0.044337743067559894], [-0.05109649028135573, 0.050986769978167874], [-0.03986396401411081, 0.03992226520835857], [-0.06271544843396921, 0.0628629998182233], [-0.060325113831802425, 0.06014867491287253], [-0.06409607265208252, 0.06426716029136537], [-0.02890807357828784, 0.02879981209701445], [-0.0579076968762734, 0.058055472378755635], [-0.0788244096514242, 0.07889209396389751], [-0.05489594835332056, 0.054304463238473114], [-0.05066376350430718, 0.051136225666937284], [-0.04324084422009672, 0.043106921303429975], [-0.03618639085199314, 0.03630391952984575], [-0.03229893887218463, 0.032254130211298596], [-0.040388961018727465, 0.04034166483632292], [-0.06891322548088202, 0.06894551548689337], [-0.05708462516274434, 0.05713687370165375], [-0.0908320094478539, 0.09053809343169553], [-0.06997210675874246, 0.07036387396569341], [-0.027676689451677956, 0.02757377175784071], [-0.02882633060378825, 0.029207481257562274], [-0.0414701765332311, 0.04136630655327525], [-0.05308296364144847, 0.0526747543606357], [-0.02724146501450132, 0.027406581699254588], [-0.04265844625269343, 0.04270290902986972], [-0.03899306746018118, 0.038745252551468795], [-0.0552804734553083, 0.05535944558193926], [-0.02309096284644189, 0.023040044134232315], [-0.0507964500028555, 0.05096013747702334], [-0.04123972706510699, 0.041359046982264745], [-0.03236153261658939, 0.032179960855430505], [-0.02858521671477931, 0.028570736354436077], [-0.03515761112679279, 0.03513507691850391], [-0.049852204843317816, 0.04984858000374448], [-0.038280519845162314, 0.038365751907998916], [-0.05489151074836156, 0.054958999808454506], [-0.02552547302215947, 0.025555844960312334], [-0.06393766191228746, 0.0638978766928521], [-0.04140103340243134, 0.04113465467714282], [-0.04647459357809104, 0.04654619117779597], [-0.03293849813553063, 0.03301029011724379], [-0.04428244235309984, 0.04433992273438912], [-0.047489538949244604, 0.04755256034371833], [-0.047176763166566854, 0.04719291045558167], [-0.06353201748860114, 0.06380784207550017], [-0.07775209195691819, 0.0773872824070752], [-0.054300174262817344, 0.054476381979975085], [-0.08808678703605805, 0.0879414485377677], [-0.04016286323725983, 0.04007725752721749], [-0.01889086923709467, 0.018989486049242103] ] const height = d3.scaleLinear() .domain(d3.extent(renderData.map(e => e[1] - e[0]))) .range([0, elementHeight]) d3.select(document.getElementById('app')) .append('svg') .attr('class', 'd3') .attr('width', elementWidth) .attr('height', elementHeight) .selectAll('.bar') .data(renderData) .enter() .append('rect') .attr('class', 'bar') .attr('fill', '#E0E0E0') .attr('x', (d, i) => (i * 2 + i)) .attr('y', d => elementHeight - height(d[1] - d[0])) .transition() .duration(300) .ease(d3.easeLinear) .attr('width', 2) .attr('height', d => height(d[1] - d[0])) var svg = $(".d3"); var lng = svg.find("rect").length; function update(){ var selectedRect = Math.floor(((currentTime ) / ( lng )) * (audioTotalTime + 86)); var selectedBufferRect = Math.floor(((currentBuffer ) / ( lng )) * (audioTotalTime + 86)); // this is the best i could do, but you understand the ide var playingColor = "red"; var bufferColor = "green"; // buffer Progress $.each (svg.find("rect"), function(index, i){ // buffer if (index<= selectedBufferRect &&$(this).attr("fill") != playingColor ) $(this).attr("fill", bufferColor); }); // Playing Progress $.each (svg.find("rect"), function(index, i){ // Playing if (index<= selectedRect) $(this).attr("fill", playingColor); }); } function PlayingSimulator(){ currentTime += 1 currentBuffer +=3; if (currentTime>= audioTotalTime){ update(); return false; } update(); setTimeout(PlayingSimulator, 60); } PlayingSimulator(); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div id='app' /> </body> </html>
Just add some simple logic in function paint() to determine the fill color. Then you need need to decide how often to re-render (I guess at least once every second for updating currentTime). const elementWidth = 1100; const elementHeight = 64; const duration = 160; let currentTime = 0; const buffered = 140; const renderData = [[-0.015067690176936956, 0.015065840696712662],[-0.009963374263646985, 0.009960838406137254],[-0.0329772714073922, 0.032922178973984494],[-0.02010780853750818, 0.020192897509204638],[-0.029141768346505944, 0.02913273608186522],[-0.03390369982419367, 0.033888949138664096],[-0.05309944789682607, 0.053106191954295334],[-0.017992382356680794, 0.0179506794436456],[-0.04118192967225779, 0.04120773269527067],[-0.032132343283569134, 0.03223372926977138],[-0.04340663941189386, 0.043317410948806916],[-0.026866048759920942, 0.02695383570549558],[-0.041548487297645216, 0.04142889765358134],[-0.0512541217270734, 0.05128097373670754],[-0.02645596673127562, 0.026461825339764114],[-0.03276659370022165, 0.032869462727325334],[-0.02983164709570332, 0.02965126735342542],[-0.06186988270590101, 0.06228762507639405],[-0.037202475771159274, 0.03684529067849468],[-0.04496168984286248, 0.044984343262096924],[-0.02961698097048877, 0.029580527280458145],[-0.06637895360455075, 0.06584970915134748],[-0.03966561332234608, 0.04028105442218536],[-0.04888827685580639, 0.04879637577182824],[-0.034440279218927505, 0.03448690299802526],[-0.04076603383847427, 0.04087949817166488],[-0.03422100968150345, 0.03407137586231854],[-0.03420552026962888, 0.034233479991186845],[-0.06124921943975816, 0.06133406711072517],[-0.08080063612343565, 0.08052139740352077],[-0.052296123826832304, 0.05245498821828788],[-0.07728568068325997, 0.0772439557897976],[-0.04070025960953707, 0.04072465208052425],[-0.016598400103531252, 0.01673240062886387],[-0.0495708419979178, 0.04952405213368158],[-0.03402468183819489, 0.03404496946468417],[-0.04719791564971553, 0.04716565090961255],[-0.024305039710776202, 0.024425998358774473],[-0.04539290174457686, 0.0453603392364138],[-0.04291280211166326, 0.042803252613569195],[-0.03237617188947045, 0.032430479168267405],[-0.046939414609483046, 0.046991124408919255],[-0.037727014544829074, 0.03756628029896137],[-0.05813820211592722, 0.058137499737658825],[-0.03306609736616569, 0.03332803022833292],[-0.03706343131822335, 0.03699838219166897],[-0.031640843865570666, 0.03150685332686255],[-0.07978720110560034, 0.07982405111308474],[-0.04565408283291298, 0.04548542047551325],[-0.03838929844552628, 0.0386080775422541],[-0.0349069030273341, 0.03516624962570975],[-0.05791808093217102, 0.057646960595115364],[-0.040111244425499945, 0.040190047578908046],[-0.0421531094659709, 0.04210734133509555],[-0.04358563889018587, 0.043380678911277275],[-0.024025454017633886, 0.024179111399202893],[-0.039038574013751944, 0.03889745017750074],[-0.02962543563292595, 0.02975662299643922],[-0.07215596460653108, 0.07225534620830149],[-0.0845103969948925, 0.08417566858032748],[-0.05029865141667644, 0.05110349428845409],[-0.06766253837563593, 0.06680008803627584],[-0.05413748268128195, 0.054261121431710246],[-0.04702217202288801, 0.04710783667779247],[-0.047177278676382065, 0.047241381909344966],[-0.04949906253183499, 0.049358880485210296],[-0.06384145451618915, 0.06398437795989458],[-0.0532812223855561, 0.05336013656088595],[-0.055032831282645335, 0.055131815418379866],[-0.05771727930777607, 0.05743980672281111],[-0.06865421948220482, 0.06896493506959074],[-0.05163944571854085, 0.05129081551014095],[-0.04546664828758613, 0.04549366890782257],[-0.02196073923070452, 0.022119579288034315],[-0.026824862238895183, 0.026915318981447094],[-0.04771898452983383, 0.04768769589918763],[-0.05221904154341058, 0.05202229643239835],[-0.04034726803191834, 0.040288317010035164],[-0.04252634158686052, 0.04275796625513488],[-0.055381424446109724, 0.05515857756430962],[-0.06160043085044191, 0.06143890271068376],[-0.04579617210990365, 0.04612433751815954],[-0.039244869887493206, 0.03927668403684328],[-0.03426885260996771, 0.03423936180141113],[-0.03516869910983574, 0.035127711830890515],[-0.026964357386084752, 0.02699723933039285],[-0.03816966714682839, 0.03778890745758835],[-0.04777519168041681, 0.04824239079542675],[-0.07617805358108933, 0.07612545525147858],[-0.047140552370394925, 0.04744151736320112],[-0.05137018378775051, 0.051114804207469784],[-0.03259493948312707, 0.0325308332802452],[-0.05715909221362399, 0.05709963073119724],[-0.04835633252739353, 0.04849600527981289],[-0.0433886628912617, 0.04331087342221564],[-0.05191740499328957, 0.05183144200010501],[-0.022690824730811025, 0.02281282548488598],[-0.021657892287654815, 0.02160585204290785],[-0.019911292276869504, 0.01990373441321122],[-0.05252214322669061, 0.052514338488489534],[-0.045757900781809524, 0.04581189437809006],[-0.02396372548560904, 0.023788207356191405],[-0.053426097224355276, 0.05348064888976746],[-0.05394891160261981, 0.05421456735805457],[-0.05251658416178273, 0.05238904616093791],[-0.04774168806444406, 0.047755594530669916],[-0.03506924339896615, 0.035076784816174336],[-0.044288649573623336, 0.044337743067559894],[-0.05109649028135573, 0.050986769978167874],[-0.03986396401411081, 0.03992226520835857],[-0.06271544843396921, 0.0628629998182233],[-0.060325113831802425, 0.06014867491287253],[-0.06409607265208252, 0.06426716029136537],[-0.02890807357828784, 0.02879981209701445],[-0.0579076968762734, 0.058055472378755635],[-0.0788244096514242, 0.07889209396389751],[-0.05489594835332056, 0.054304463238473114],[-0.05066376350430718, 0.051136225666937284],[-0.04324084422009672, 0.043106921303429975],[-0.03618639085199314, 0.03630391952984575],[-0.03229893887218463, 0.032254130211298596],[-0.040388961018727465, 0.04034166483632292],[-0.06891322548088202, 0.06894551548689337],[-0.05708462516274434, 0.05713687370165375],[-0.0908320094478539, 0.09053809343169553],[-0.06997210675874246, 0.07036387396569341],[-0.027676689451677956, 0.02757377175784071],[-0.02882633060378825, 0.029207481257562274],[-0.0414701765332311, 0.04136630655327525],[-0.05308296364144847, 0.0526747543606357],[-0.02724146501450132, 0.027406581699254588],[-0.04265844625269343, 0.04270290902986972],[-0.03899306746018118, 0.038745252551468795],[-0.0552804734553083, 0.05535944558193926],[-0.02309096284644189, 0.023040044134232315],[-0.0507964500028555, 0.05096013747702334],[-0.04123972706510699, 0.041359046982264745],[-0.03236153261658939, 0.032179960855430505],[-0.02858521671477931, 0.028570736354436077],[-0.03515761112679279, 0.03513507691850391],[-0.049852204843317816, 0.04984858000374448],[-0.038280519845162314, 0.038365751907998916],[-0.05489151074836156, 0.054958999808454506],[-0.02552547302215947, 0.025555844960312334],[-0.06393766191228746, 0.0638978766928521],[-0.04140103340243134, 0.04113465467714282],[-0.04647459357809104, 0.04654619117779597],[-0.03293849813553063, 0.03301029011724379],[-0.04428244235309984, 0.04433992273438912],[-0.047489538949244604, 0.04755256034371833],[-0.047176763166566854, 0.04719291045558167],[-0.06353201748860114, 0.06380784207550017],[-0.07775209195691819, 0.0773872824070752],[-0.054300174262817344, 0.054476381979975085],[-0.08808678703605805, 0.0879414485377677],[-0.04016286323725983, 0.04007725752721749],[-0.01889086923709467, 0.018989486049242103]]; const height = d3 .scaleLinear() .domain(d3.extent(renderData.map(e => e[1] - e[0]))) .range([0, elementHeight]); const svg = d3 .select("#app") .append("svg") .attr("class", "d3") .attr("width", elementWidth) .attr("height", elementHeight); const bar = svg.selectAll(".bar").data(renderData); const barEnter = bar .enter() .append("rect") .attr("class", "bar") .attr("fill", (d, i) => { return paint(i); }) .attr("x", (d, i) => i * 2 + i) .attr("y", d => elementHeight - height(d[1] - d[0])) .attr("width", 2) .attr("height", d => height(d[1] - d[0])); function reRender() { currentTime += 1 barEnter.attr("fill", (d, i) => { return paint(i); }) } window.setInterval(function () { reRender() }, 1000); function paint(i) { barPos = i / renderData.length * duration; if (barPos <= currentTime) { return "red"; } else if (barPos <= buffered) { return "orange"; } else { return "grey"; } } <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div id='app' /> </body> </html> Codepen
How can I display tooltips from multiple maps when mousover on one of the maps in D3js
I have a dashboard with two separate maps of a state showing different data based on years 2014 and 2012. The map when hovered over show the name of area individually. What I need to do is display both 2012 and 2014 maps's tooltips at the same time over the respective maps when I mouseover any one of the two maps. How can I display both at the same time. I would appreciate any help with this. Thanks. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Test dashboard</title> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" > <style> #gujarat-viz-2017, #buttons { border-right: 1px solid #ccc } .container { background-color: #d5e8ec; } .const0 { display: none; } .emptyparty { fill:#f9f9f1; } .emptyparty:hover, .constituency:hover { fill:#ccc; } .hidden { display: none; } .showtooltip { position: absolute; z-index: 10000; background-color: #333; border-radius: 10px; color: #fff; padding: 5px; } /*Party colors*/ .bjp{ fill: #f88101;} .inc{ fill: #6da736;} .ncp{ fill: #076598;} .gpp{ fill: #5a469d;} .ind{ fill: #25a29a;} .jdu{ fill: #eb4d4c;} </style> </head> <body> <div class="container"> <div class="row"> <div id="gujarat-viz-2014" class="col-md-6"> <h2>2014</h2> </div> <div id="gujarat-viz-2012" class="col-md-6"> <h2>2012</h2> </div> </div> <!-- .row --> </div> <script src="http://www.thehindu.com/static/js/jquery-1.10.2.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.js"></script> <script src="https://d3js.org/topojson.v2.min.js"></script> <script> function map_function(map_settings){ // Global variables var margin = { top: 50, left:50, right:50, bottom:50 }, height = 400 - margin.top - margin.bottom, width = 500 - margin.left - margin.right; // Create SVG canvas with responsive resizing var svg = d3.select(map_settings["htmlelement"]) .append("svg") .attr("viewBox", "0 0 " + width + " " + height) .attr("preserveAspectRatio", "xMinYMin") .append("g") .attr("class", "data"+map_settings["year"]) // Add a tooltip to visualization var tooltip = d3.select('body').append('div') .attr('class', 'hidden showtooltip') .attr('id', "tooltip"+map_settings["year"]) // queue and read the topojson, json data file d3.queue() .defer(d3.json, "https://api.myjson.com/bins/17m3if") .defer(d3.json, map_settings.data) .await(render_map) var projection = d3.geoMercator() .scale(3000) .center([71.5, 22.3]) .translate([width / 2, height / 2]) var geoPath = d3.geoPath() .projection(projection) function render_map(error, mapshape, mapdata){ var constituency = topojson.feature(mapshape, mapshape.objects.collection).features; dataMap = {}; mapdata.forEach(function(d){ dataMap[d.constNo] = d; }) var fill_function = function(d) { // d3.select(this).attr('fill', "white") } // end of mousemove_function var mousemove_function = function(d) { var constinfo = dataMap[d.properties.AC_NO]; // console.log(constinfo.constituencyName) // console.log(d3.select(this).data()[0].properties) var html = "<p>"+constinfo.constituencyName+"</p>" tooltip.classed('hidden', false) .html(html) .style("left", (d3.event.clientX - 10) + "px") .style("top", (d3.event.clientY - 45) + "px"); } // end of mousemove_function var class_function = function(d) { var constinfo = dataMap[d.properties.AC_NO]; var className = "constituency "; if(constinfo !== undefined) { className += ("c"+constinfo.constNo+" ") className += constinfo.leadingParty.replace(/[^a-zA-Z ]/g, "").toLowerCase() } else { className += "emptyparty" className += " const" className += d.properties.AC_NO } return className; } // end of class_function var mouseout_function = function(d) { tooltip.classed('hidden', true) } // end of mousemove_function svg.selectAll(".constituency") .data(constituency) .enter().append("path") .attr("d", geoPath) .attr('class', class_function) .attr('fill', "white") .attr('stroke', "#e8e8e8") .attr('stroke-width', "0.5") .on('mouseover', mousemove_function) .on('mouseout', mouseout_function) } // render_map } // map_function var gujarat_data_2014 = { htmlelement: "#gujarat-viz-2014", data: "https://api.myjson.com/bins/yolfr", year: "2014" }; var gujarat_data_2012 = { htmlelement: "#gujarat-viz-2012", data: "https://api.myjson.com/bins/19ztxj", year: "2012" }; map_function(gujarat_data_2014); map_function(gujarat_data_2012); </script> </body> </html>
I'd modify your mousemove and mouseout to operate on both maps at the same time: var mousemove_function = function(d) { var constinfo = dataMap[d.properties.AC_NO]; var html = "<p>" + constinfo.constituencyName + "</p>" var tooltips = d3.selectAll('.showtooltip'); // get paths from all maps d3.selectAll('.c' + constinfo.constNo) .each(function(d,i){ var pos = this.getBoundingClientRect(); // operate on appropriate tooltip d3.select(tooltips.nodes()[i]).classed('hidden', false) .html(html) .style("left", (pos.x + pos.width/2) + "px") .style("top", (pos.y - pos.height/2) + "px"); }); } // end of mousemove_function var mouseout_function = function(d) { d3.selectAll('.showtooltip').classed('hidden', true); } // end of mousemove_function Running code here.
D3 behave weird when I do a drag act which also trigger unexpected zoom function
I am yet a noob for d3 and javascript,while I was writing some code to deal with drag the dots and zoom the coordinate, something weird happened, the dots call the drag function,an outer group() element call the zoom, but when I dragging the dot, the outer group change its translate attribute.Code comes below: <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>zoom test</title> </head> <body></body> <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"> </script> <script type="text/javascript" charset="utf-8"> function addElem(container,elem){ return container.append(elem); } function createLinearScale(dx,dy,rx,ry){ return d3.scale.linear() .domain([dx,dy]) .range([rx,ry]) } function appendWithData(container,selector,type,id,classed,dataset){ var result = container.selectAll(selector) .data(dataset) .enter() .append(type); if(id) result.attr("id",id); if(classed) result.classed(classed,true); return result; } function getElem(selector){ return d3.select(selector); } function getAxis(){ return d3.svg.axis(); } function drag(){ return d3.behavior.drag(); } function getThis(){ return d3.select("this"); } function zoom(){ return d3.behavior.zoom(); } function arrayDelete(array,target,condition){ for (var i = 0, l = array.length; i < l; i ++) { var v = arr[i]; if((target = v) && condition){ array.splice(i,1); } } } </script> <script type="text/javascript" charset="utf-8"> /** * Set frame for page * */ var body = getElem("body"); var svg = addElem(body,"svg"); var outer = addElem(svg,"g"); var target = addElem(outer,"g"); var x_axis = addElem(target,"g"); var y_axis = addElem(target,"g"); var dots = addElem(target,"g"); var data = [ [ 5, 20 ], [ 480, 90 ], [ 250, 50 ], [ 100, 33 ], [ 330, 95 ], [ 410, 12 ], [ 475, 44 ], [ 25, 67 ], [ 85, 21 ], [ 220, 88 ] ]; /** * Add axis to chart * */ var height = 500; var width = 960; var x_scale = createLinearScale(0, d3.max(data,function(d){return d[0];}) + 50, 0, width - 10); var y_scale = createLinearScale(0, d3.max(data, function(d){return d[1];}) + 50, height - 10, 0); var ax_scale = createLinearScale(0, width - 10, 0, d3.max(data,function(d){return d[0];}) + 50); var ay_scale = createLinearScale(height -10, 0, 0, d3.max(data, function(d){ return d[1];}) + 50); var xaxis = getAxis().scale(x_scale).orient("bottom").ticks(30); var yaxis = getAxis().scale(y_scale).orient("right").ticks(10); x_axis.attr("transform",function(d){return "translate(0," + (height - 10) + ")"}).call(xaxis); y_axis.attr("transform",function(d){return "translate(0,0)"}).call(yaxis); /** * Add dots * */ var dot = appendWithData(dots,"circle","circle","","datum",data); var text = appendWithData(dots,"text","text","","index",data); dot.data(data).attr({ "id" : function(d,i){return "datum" +i;}, "tag": function(d,i){return i + "";}, "cx" : function(d){return x_scale(d[0]).toFixed(0)}, "cy" : function(d){return y_scale(d[1]).toFixed(0)}, "fill" : function(d){return "rgb(0," + (d[1] * 5) % 255 + ",53)"}, "r" : 10 }); text.data(data).attr({ "id" : function(d,i){return "index" + i;}, "tag": function(d,i){return i + ""}, "y" : function(d){return y_scale(d[1]).toFixed(0)}, "x" : function(d){return x_scale(d[0]).toFixed(0)}, "transform" : "translate(15,-15)" }) .text(function(d){return d[0] + "," + d[1]}); var flag = 1; var drag = drag(); function dragstart(){ console.log("dragstart") var cur = d3.select(this); console.log("drag"); cur.transition().ease("elastc").attr({ "r" : 15 }); } function dragging(){ flag = 0; var cur = d3.select(this); var tag = cur.attr("tag"); cir = d3.select("circle[tag='" + tag + "']"); txt = d3.select("text[tag='" + tag + "']"); console.log(cur); console.log(txt); var cur_x = d3.event.x; var cur_y = d3.event.y; //target.attr("transform","translate(0,0)"); cir.attr({ "cx" : function(d){return cur_x.toFixed(0)}, "cy" : function(d){return cur_y.toFixed(0)}, //"fill" : function(d){return "rgb(0," + (y_scale(cur_y) * 5) % 255 + ",53)"}, }); txt.attr({ "x" : function(d){return cur_x.toFixed(0)}, "y" : function(d){return cur_y.toFixed(0)}, }) .text(new Number(ax_scale(cur_x)).toFixed(0) + "," + new Number(ay_scale(cur_y)).toFixed(0)); } function dragged(){ var cur = d3.select(this); cur.transition().ease("elastc").attr({ "r" : 10 }); flag = 1; } drag.on("dragstart",dragstart) .on("drag",dragging) .on("dragend",dragged); dot.call(drag);; var zoom = zoom(); function zoomed(){ //if(flag){ console.log("zoomed"); outer.attr("transform","translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")"); //} } zoom.on("zoom",zoomed); outer.call(zoom); </script> </html> As you see, I set a toggle(the variable called flag) to solve the trigger problem,but it cause a new problem, I can't zoom with wheel when the mouse is aloft a blank space.
If I understand the question correctly, you want the zooming on the outer while you want dragging on the dots. In that case, there were two problems with your program: Empty g as the outer: A g element is just an empty container and is unable to capture events inside itself. If you want to capture mouse actions anywhere inside the g, you need to include an invisible background rect inside it with pointer-events: all. Also, you want this element to appear before all other elements in the DOM so that it is indeed in the background: var bgRect = addElem(outer, "rect"); bgRect.attr('fill', 'none') .attr('stroke', 'none') .attr('width', width) .attr('height', height); var target = addElem(outer, "g"); // ... Update: See this question as well: d3.js - mouseover event not working properly on svg group Transitioning on zooming: The "expected" zoom behavior is that the point under the mouse pointer stays static while everything around the pointer zooms in/out. Hence, the container needs to both scale and transition. function zoomed(){ console.log("zoomed"); outer.attr("transform","translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")"); } However, in your case, you do not want the container to transition so that the axis stays firmly rooted at the origin (0, 0). So: function zoomed(){ console.log("zoomed"); outer.attr("transform","translate(" + [0,0] + ") scale(" + d3.event.scale + ")"); } Working demo with these changes: http://jsfiddle.net/S3GsC/