I am trying to create a scatterplot with a zooming. The following code I have used in my angular application and its working till a certain extent when I run it in my local server. However putting the same code in Stackblitz, the zooming is not working. I want to achieve a zooming where the zooming is limited to just the values on the graph. There should be no zooming of the axis accept the value changes in both the axis. Something exactly like : http://bl.ocks.org/peterssonjonas/4a0e7cb8d23231243e0e .
Here in the example, on zooming, only the values are zoomed and the axis values changed correspondingly. It doesn't zoom the whole graph plot area. How do I achieve it? Here is my Stackblitz code: https://stackblitz.com/edit/angular-hu2thj
ANSWER : Finally I figure out the graph for this problem in case of any future reference:
import { Component, OnInit, Input, ViewChild, ElementRef } from '@angular/core';
import * as d3 from 'd3';
@Component({
selector: 'app-scatterplot',
templateUrl: './scatterplot.component.html',
styleUrls: ['./scatterplot.component.css']
})
export class ScatterplotComponent implements OnInit {
@ViewChild('chart1') private chartContainer: ElementRef;
dataValue = [{ x: "67", y: "188", },
{ x: "200", y: "163" },
{ x: "254", y: "241" },
{ x: "175", y: "241" },
];
ngOnInit() {
this.graph();
}
graph() {
const element = this.chartContainer.nativeElement;
var svgWidth = 400;
var svgHeight = 400;
var margin = { top: 30, right: 40, bottom: 50, left: 60 };
var width = svgWidth - margin.left - margin.right;
var height = svgHeight - margin.top - margin.bottom;
var originalCircle = {
"cx": -150,
"cy": -15,
"r": 20
};
var svgViewport = d3.select(element)
.append('svg')
.attr('width', svgWidth)
.attr('height', svgHeight)
// create scale objects
var x = d3.scaleLinear()
.domain([1, 500])
.range([0, width]);
var y = d3.scaleLinear()
.domain([1, 500])
.range([height, 0]);
// create axis objects
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
// Zoom Function
var zoom = d3.zoom()
.on("zoom", zoomFunction);
// Inner Drawing Space
var innerSpace = svgViewport.append("g")
.attr("class", "inner_space")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(zoom);
// append some dummy data
var data = innerSpace.selectAll("circle")
.data(this.dataValue)
.enter().append("circle")
.attr("class", "dot")
.attr("cx", function (d) {
return x(d.x)
;
})
.attr("cy", function (d) {
return y(d.y);
})
.attr("r", 2);
// Draw Axis
var gX = innerSpace.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, " + height + ")")
.call(xAxis);
var gY = innerSpace.append("g")
.attr("class", "axis axis--y")
.call(yAxis);
// append zoom area
var view = innerSpace.append("rect")
.attr("class", "zoom")
.attr("width", width)
.attr("height", height - 10)
.attr("fill", "transparent")
.attr("fill-opacity", 0.1)
.call(zoom)
function zoomFunction() {
// create new scale ojects based on event
var new_xScale = d3.event.transform.rescaleX(x)
var new_yScale = d3.event.transform.rescaleY(y)
console.log(d3.event.transform)
// update axes
gX.call(xAxis.scale(new_xScale));
gY.call(yAxis.scale(new_yScale));
// update circle
data.attr("transform", d3.event.transform)
};
}
}