I try below example to zoom stem plot.axis can be zoomed,the stem lines and circle not zoomed.
var width = 900
var height = 480
var margin = {top:50,left:80,right:50,bottom:50}
var svg = d3.select('body')
.append('svg')
.attr('height',height margin.top margin.bottom)
.attr('width',width margin.left margin.right)
.style('border','2px solid red')
// .on('zoom', (event) => {
// g.attr('transform', event.transform);
// })
var g = svg.append('g')
.attr('transform',`translate(${margin.left},${margin.top})`)
load_csvtext();
//======== done ========//
function load_from_disk() {
Promise.all([
d3.csv('save.csv')
]).then(([data]) => {
process(data)
})
}
function load_csvtext() {
var csvtext = `ts,latitude,longitude
2022-04-06 07:22:01.972,26.145957,-80.254937
2022-04-06 07:22:04.972,26.145958,-80.254936
2022-04-06 07:22:07.973,26.145957,-80.254936
2022-04-06 07:22:10.975,26.145957,-80.254936
2022-04-06 07:22:13.973,26.145956,-80.254935
2022-04-06 07:22:16.977,26.145956,-80.254934
2022-04-06 07:22:19.974,26.145955,-80.254934
2022-04-06 07:22:22.974,26.145955,-80.254935
2022-04-06 07:22:25.969,26.145954,-80.254935
2022-04-06 07:22:28.974,26.145954,-80.254935
2022-04-06 07:22:31.972,26.145954,-80.254936
2022-04-06 07:22:34.978,26.145954,-80.254937
2022-04-06 07:22:37.978,26.145953,-80.254937
2022-04-06 07:22:40.981,26.145953,-80.254937,
2022-04-06 07:22:43.991,26.145953,-80.254938
2022-04-06 07:22:46.973,26.145953,-80.254938
2022-04-06 07:22:49.974,26.145953,-80.254939`
var data = d3.csvParse(csvtext)
process(data)
}
function process(data) {
const tParser = d3.timeParse("%Y-%m-%d %H:%M:%S.%f")
var prevts = 0
var x = 'x'
var y = 'y'
data.map(d => {
d[x] = tParser(d['ts'])
if (prevts == 0) {
prevts = d[x]
d[y] = 0
}else{
d[y] = d[x] - prevts
//prevts = d[x]
}
})
var xmax = d3.max(data,d => d.x)
var xmin = d3.min(data,d => d.x)
var ymin = d3.min(data,d => d.y)
var ymax = d3.max(data,d => d.y)
var xScale = d3.scaleLinear()
.domain([xmin, xmax])
.range([0, width])
var yScale = d3.scaleTime()
.domain([ymin, ymax])
.range([height,0])
var xaxis = g.append("g")
.attr("class", "axis")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom()
.scale(xScale)
.ticks(20)
);
xaxis.selectAll("text")
.attr("transform", "rotate(-30)")
.style("text-anchor", "end");
var yaxis = g.append("g")
.attr("class", "axis")
.attr("transform", `translate(0,0)`)
.call(d3.axisLeft()
.scale(yScale)
.ticks(10)
);
var circles = g.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("fill", "green")
.attr("cx", function(d) { return xScale(d.x); } )
.attr("cy", function(d) { return yScale(d.y); } )
.attr("r", 5)
var lines = g.selectAll(".stem")
.data(data)
.enter()
.append("line")
.attr('class','stem')
.attr("stroke", "black")
.attr("stroke-width", 2)
.attr("x1", function(d) {return xScale(d.x); } )
.attr("x2", function(d) {return xScale(d.x); } )
.attr("y1", function(d) {return yScale(ymin); } )
.attr("y2", function(d) {return yScale(d.y); } )
var zoom = d3.zoom()
.scaleExtent([0.005, 2000])
.extent([[0, 0], [width, height]])
.on('zoom', zoomed);
g.call(zoom)
function zoomed(event) {
var newX = event.transform.rescaleX(xScale);
var newY = event.transform.rescaleY(yScale)
xaxis.call(d3.axisBottom(newX));
xaxis.selectAll("text")
.attr("transform", "rotate(-30)")
.style("text-anchor", "end");
yaxis.call(d3.axisLeft(newY));
lines
.selectAll('line')
.attr("x1", function(d) { return newX(d.x); } )
.attr("x2", function(d) { return newX(d.x); } )
.attr("y1", function(d) { return newY(ymin); } )
.attr("y2", function(d) { return newY(d.y); } )
//.attr("stroke", "red")
circles.selectAll('circle')
.attr('cx', function (d) {
return newX(d.x);
})
.attr('cy', function (d) {
return newY(d.y);
})
}
return
}
<script src="https://unpkg.com/[email protected]/dist/d3.min.js"></script>
CodePudding user response:
Your lines
and circles
are already selections containing lines and circles, no need to select lines and circles inside them (which don't exist by the way). Just do:
lines.attr("x1", etc...
Here's your snippet with that change.
var width = 900
var height = 480
var margin = {
top: 50,
left: 80,
right: 50,
bottom: 50
}
var svg = d3.select('body')
.append('svg')
.attr('height', height margin.top margin.bottom)
.attr('width', width margin.left margin.right)
.style('border', '2px solid red')
// .on('zoom', (event) => {
// g.attr('transform', event.transform);
// })
var g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`)
load_csvtext();
//======== done ========//
function load_from_disk() {
Promise.all([
d3.csv('save.csv')
]).then(([data]) => {
process(data)
})
}
function load_csvtext() {
var csvtext = `ts,latitude,longitude
2022-04-06 07:22:01.972,26.145957,-80.254937
2022-04-06 07:22:04.972,26.145958,-80.254936
2022-04-06 07:22:07.973,26.145957,-80.254936
2022-04-06 07:22:10.975,26.145957,-80.254936
2022-04-06 07:22:13.973,26.145956,-80.254935
2022-04-06 07:22:16.977,26.145956,-80.254934
2022-04-06 07:22:19.974,26.145955,-80.254934
2022-04-06 07:22:22.974,26.145955,-80.254935
2022-04-06 07:22:25.969,26.145954,-80.254935
2022-04-06 07:22:28.974,26.145954,-80.254935
2022-04-06 07:22:31.972,26.145954,-80.254936
2022-04-06 07:22:34.978,26.145954,-80.254937
2022-04-06 07:22:37.978,26.145953,-80.254937
2022-04-06 07:22:40.981,26.145953,-80.254937,
2022-04-06 07:22:43.991,26.145953,-80.254938
2022-04-06 07:22:46.973,26.145953,-80.254938
2022-04-06 07:22:49.974,26.145953,-80.254939`
var data = d3.csvParse(csvtext)
process(data)
}
function process(data) {
const tParser = d3.timeParse("%Y-%m-%d %H:%M:%S.%f")
var prevts = 0
var x = 'x'
var y = 'y'
data.map(d => {
d[x] = tParser(d['ts'])
if (prevts == 0) {
prevts = d[x]
d[y] = 0
} else {
d[y] = d[x] - prevts
//prevts = d[x]
}
})
var xmax = d3.max(data, d => d.x)
var xmin = d3.min(data, d => d.x)
var ymin = d3.min(data, d => d.y)
var ymax = d3.max(data, d => d.y)
var xScale = d3.scaleLinear()
.domain([xmin, xmax])
.range([0, width])
var yScale = d3.scaleTime()
.domain([ymin, ymax])
.range([height, 0])
var xaxis = g.append("g")
.attr("class", "axis")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom()
.scale(xScale)
.ticks(20)
);
xaxis.selectAll("text")
.attr("transform", "rotate(-30)")
.style("text-anchor", "end");
var yaxis = g.append("g")
.attr("class", "axis")
.attr("transform", `translate(0,0)`)
.call(d3.axisLeft()
.scale(yScale)
.ticks(10)
);
var circles = g.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("fill", "green")
.attr("cx", function(d) {
return xScale(d.x);
})
.attr("cy", function(d) {
return yScale(d.y);
})
.attr("r", 5)
var lines = g.selectAll(".stem")
.data(data)
.enter()
.append("line")
.attr('class', 'stem')
.attr("stroke", "black")
.attr("stroke-width", 2)
.attr("x1", function(d) {
return xScale(d.x);
})
.attr("x2", function(d) {
return xScale(d.x);
})
.attr("y1", function(d) {
return yScale(ymin);
})
.attr("y2", function(d) {
return yScale(d.y);
})
var zoom = d3.zoom()
.scaleExtent([0.005, 2000])
.extent([
[0, 0],
[width, height]
])
.on('zoom', zoomed);
g.call(zoom)
function zoomed(event) {
var newX = event.transform.rescaleX(xScale);
var newY = event.transform.rescaleY(yScale)
xaxis.call(d3.axisBottom(newX));
xaxis.selectAll("text")
.attr("transform", "rotate(-30)")
.style("text-anchor", "end");
yaxis.call(d3.axisLeft(newY));
lines.attr("x1", function(d) {
return newX(d.x);
})
.attr("x2", function(d) {
return newX(d.x);
})
.attr("y1", function(d) {
return newY(ymin);
})
.attr("y2", function(d) {
return newY(d.y);
})
//.attr("stroke", "red")
circles.attr('cx', function(d) {
return newX(d.x);
})
.attr('cy', function(d) {
return newY(d.y);
})
}
return
}
<script src="https://unpkg.com/[email protected]/dist/d3.min.js"></script>
You will see that there are several other issues, but those should be addressed in new questions (in order to keep just 1 issue per question).