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.

+3


source to share


1 answer


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>
      

Run codeHide result


+1


source







All Articles