Scaling using d3.scalePoint ()
So, I changed these examples so that I can use scalePoint to xAxis (instead of scaleLinear, I also changed the code so you can only scale up xAxis, I don't care about yAxis scaling):
https://bl.ocks.org/mbostock/db6b4335bf1662b413e7968910104f0f
Everything seems to work except scaling, I am getting an error undefined is not a function
on this line:gX.call(xAxis.scale(d3.event.transform.rescaleX(x)));
Any idea on how to make scaling work with scalePoint?
Here's the code:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<style>
text {
fill: black;
}
rect {
fill: steelblue;
}
path.chart__line {
fill: green;
opacity: .3;
stroke: green;
stroke-width: 1.5px;
}
</style>
<svg id="my-svg" width="960" height="500">
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0.0%" stop-color="#2c7bb6"></stop>
<stop offset="12.5%" stop-color="#00a6ca"></stop>
<stop offset="25.0%" stop-color="#00ccbc"></stop>
<stop offset="37.5%" stop-color="#90eb9d"></stop>
<stop offset="50.0%" stop-color="#ffff8c"></stop>
<stop offset="62.5%" stop-color="#f9d057"></stop>
<stop offset="75.0%" stop-color="#f29e2e"></stop>
<stop offset="87.5%" stop-color="#e76818"></stop>
<stop offset="100.0%" stop-color="#d7191c"></stop>
</linearGradient>
</defs>
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
let xDomain = ['A', 'B', 'C'];
let zoomed = () => {
view.attr("transform", d3.event.transform);
gX.call(xAxis.scale(d3.event.transform.rescaleX(x)));
// gY.call(yAxis.scale(d3.event.transform.rescaleY(y))); // I don't care about yAxis
};
let resetted = () => {
svg.transition()
.duration(750)
.call(zoom.transform, d3.zoomIdentity);
};
let svg = d3.select("#my-svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
let zoom = d3.zoom()
.scaleExtent([1, 40])
.translateExtent([[0, 0], [width, height]])
.on("zoom", zoomed);
let x = d3.scalePoint()
.domain(xDomain)
.range([0, width]);
let y = d3.scaleLinear()
.domain([0, height])
.range([0, height]);
let xAxis = d3.axisBottom(x)
.ticks(xDomain.length)
.tickSize(height)
.tickPadding(8 - height);
let yAxis = d3.axisRight(y)
.ticks(10)
.tickSize(width)
.tickPadding(8 - width);
let view = svg.append("rect")
.attr("class", "view")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height);
let gX = svg.append("g")
.attr("class", "axis axis--x")
.call(xAxis);
let gY = svg.append("g")
.attr("class", "axis axis--y")
.call(yAxis);
d3.select("button")
.on("click", resetted);
svg.call(zoom);
</script>
</body>
</html>
Thank you for your time.
source to share
You need to use continuous scale if you want to use the function transformX
. It uses a scale function invert
that only provides continuous scales.
Although you mentioned that you don't want to use it scaleLinear
, I tested it and it seems to work fine. (I had to activate y scaling to check this)
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<style>
text {
fill: black;
}
rect {
fill: steelblue;
}
path.chart__line {
fill: green;
opacity: .3;
stroke: green;
stroke-width: 1.5px;
}
</style>
<svg id="my-svg" width="960" height="500">
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0.0%" stop-color="#2c7bb6"></stop>
<stop offset="12.5%" stop-color="#00a6ca"></stop>
<stop offset="25.0%" stop-color="#00ccbc"></stop>
<stop offset="37.5%" stop-color="#90eb9d"></stop>
<stop offset="50.0%" stop-color="#ffff8c"></stop>
<stop offset="62.5%" stop-color="#f9d057"></stop>
<stop offset="75.0%" stop-color="#f29e2e"></stop>
<stop offset="87.5%" stop-color="#e76818"></stop>
<stop offset="100.0%" stop-color="#d7191c"></stop>
</linearGradient>
</defs>
</svg>
<script src="https://d3js.org/d3.v4.js"></script>
<script>
let xDomain = ['A', 'B', 'C'];
let zoomed = () => {
view.attr("transform", d3.event.transform);
gX.call(xAxis.scale(d3.event.transform.rescaleX(x)));
gY.call(yAxis.scale(d3.event.transform.rescaleY(y))); // I don't care about yAxis
};
let resetted = () => {
svg.transition()
.duration(750)
.call(zoom.transform, d3.zoomIdentity);
};
let svg = d3.select("#my-svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
let zoom = d3.zoom()
.scaleExtent([1, 40])
.translateExtent([
[0, 0],
[width, height]
])
.on("zoom", zoomed);
let x = d3.scaleLinear()
.domain(xDomain)
.range([0, width]);
let y = d3.scaleLinear()
.domain([0, height])
.range([0, height]);
let xAxis = d3.axisBottom(x)
.ticks(xDomain.length)
.tickSize(height)
.tickPadding(8 - height);
let yAxis = d3.axisRight(y)
.ticks(10)
.tickSize(width)
.tickPadding(8 - width);
let view = svg.append("rect")
.attr("class", "view")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height);
let gX = svg.append("g")
.attr("class", "axis axis--x")
.call(xAxis);
let gY = svg.append("g")
.attr("class", "axis axis--y")
.call(yAxis);
d3.select("button")
.on("click", resetted);
svg.call(zoom);
</script>
</body>
</html>
source to share