Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: update for merge tooltip function #1244

Open
Always-prog opened this issue Mar 17, 2023 · 4 comments
Open

Feature: update for merge tooltip function #1244

Always-prog opened this issue Mar 17, 2023 · 4 comments
Labels
Documentation Issues that require documentation updates

Comments

@Always-prog
Copy link

Hello! Thank you for a good slider!

I needed to merge sliders if they overlapped and found a function in the documentation (https://refreshless.com/nouislider/examples/#section-merging-tooltips) that could help me achieve this. However, I had to set a hardcoded minimum proximity, which was not ideal since my tooltips have different sizes.

To address this issue, I updated the script for merging tooltips. Here's the code I used:

/**
 * @param slider HtmlElement with an initialized slider
 * @param separator String joining tooltips
 */
export function mergeTooltips(slider, separator) {
  var textIsRtl = window.getComputedStyle(slider).direction === "rtl";
  var isRtl = slider.noUiSlider.options.direction === "rtl";
  var isVertical = slider.noUiSlider.options.orientation === "vertical";
  var tooltips = slider.noUiSlider.getTooltips();
  var origins = slider.noUiSlider.getOrigins();

  // Move tooltips into the origin element. The default stylesheet handles this.
  tooltips.forEach(function (tooltip, index) {
    if (tooltip) {
      origins[index].appendChild(tooltip);
    }
  });

  slider.noUiSlider.on("update", function (
    values,
    handle,
    unencoded,
    tap,
    positions
  ) {
    var pools = [[]];
    var poolPositions = [[]];
    var poolValues = [[]];
    var atPool = 0;

    // Assign the first tooltip to the first pool, if the tooltip is configured
    if (tooltips[0]) {
      pools[0][0] = 0;
      poolPositions[0][0] = positions[0];
      poolValues[0][0] = values[0];
    }

    for (var i = 1; i < positions.length; i++) {
     // HERE's MY CODE
      const tooltipLeft = tooltips[i - 1].getBoundingClientRect();
      const tooltipRight = tooltips[i].getBoundingClientRect();
      if (
        !(
          tooltipLeft.x < tooltipRight.x &&
          tooltipLeft.x + tooltipLeft.width > tooltipRight.x
        )
      ) {
        atPool++;
        pools[atPool] = [];
        poolValues[atPool] = [];
        poolPositions[atPool] = [];
      }
      // HERE's MY CODE END

      if (tooltips[i]) {
        pools[atPool].push(i);
        poolValues[atPool].push(values[i]);
        poolPositions[atPool].push(positions[i]);
      }
    }

    pools.forEach(function (pool, poolIndex) {
      var handlesInPool = pool.length;

      for (var j = 0; j < handlesInPool; j++) {
        var handleNumber = pool[j];

        if (j === handlesInPool - 1) {
          var offset = 0;

          poolPositions[poolIndex].forEach(function (value) {
            offset += 1000 - value;
          });

          var direction = isVertical ? "bottom" : "right";
          var last = isRtl ? 0 : handlesInPool - 1;
          var lastOffset = 1000 - poolPositions[poolIndex][last];
          offset =
            (textIsRtl && !isVertical ? 100 : 0) +
            offset / handlesInPool -
            lastOffset;

          // Center this tooltip over the affected handles
          tooltips[handleNumber].innerHTML = poolValues[poolIndex].join(
            separator
          );
          tooltips[handleNumber].style.removeProperty("visibility");

          tooltips[handleNumber].style[direction] = offset + "%";
        } else {
          // Hide this tooltip
          tooltips[handleNumber].style.visibility = "hidden";
        }
      }
    });
  });
}

My approach uses tooltip position and widths to determine which tooltips need to be merged, which I believe is an improvement over a hardcoded percentage.

Thank you for taking the time to read my issue and for any feedback you may have.

@leongersen
Copy link
Owner

Thanks for your feedback! If you want to generalize the example in the documentation, I'd be open for a PR :)

@leongersen leongersen added the Documentation Issues that require documentation updates label Aug 1, 2023
@Always-prog
Copy link
Author

Always-prog commented Aug 2, 2023

@leongersen Of course, here is it! #1256

@Always-prog
Copy link
Author

@leongersen Hello! Just remind you about the PR!

@Always-prog
Copy link
Author

@leongersen Hi! Please take a look at the changed docs in this PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation Issues that require documentation updates
Projects
None yet
Development

No branches or pull requests

2 participants