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

Zooming out on logarithmic axis clears the chart #153

Closed
RaitzeR opened this issue Jun 7, 2018 · 6 comments
Closed

Zooming out on logarithmic axis clears the chart #153

RaitzeR opened this issue Jun 7, 2018 · 6 comments

Comments

@RaitzeR
Copy link

RaitzeR commented Jun 7, 2018

If you try to zoom out on a logarithmic axis, the chart data will disappear. I think this is because it tries to get a negative value for the scale.
There is no problems with panning though. It correctly gets the new scale.

options: {
              scales: {
                  xAxes: [{
                      type: 'linear',
                      ticks: {
                          userCallback: function(tick) {
                              return timeConverter(tick, false);
                          },
                          autoSkip: false,
                          maxRotation: 20,
                          minRotation: 20
                      },
                      position: 'bottom'
                  }],
                  yAxes: [{
                      type: 'logarithmic',
                      ticks: {
                          userCallback: function(tick) {
                              var remain = tick / (Math.pow(10, Math.floor(Chart.helpers.log10(tick))));
                              if (remain === 1) {
                                  return sanitizeNumber(tick).toString();
                              }
                              return '';
                          },
                      },
                  }]
              },
              tooltips: {
                  callbacks: {
                      label: function(tooltipItem, chartData) {
                          return "Time: "+ timeConverter(tooltipItem.xLabel, true) +" - Price:"+ sanitizeNumber(tooltipItem.yLabel) +""
                      }
                  }
              },
              pan: {
                  enabled: true,
                  mode: 'xy',
              },
              zoom: {
                  enabled: true,
                  mode: 'xy',
              }
@BDominik
Copy link

I have exactly the same problem.
Did you solved this?
I'm using logarithmic scaling on the x axis only.

@BDominik
Copy link

BDominik commented Nov 22, 2018

Actually if you set the zoom and pan ranges, than it's working
rangeMin: { x: 10, y: 0.0193 }, rangeMax: { x: 8640, y: 1.4 }

@jannisgt
Copy link
Contributor

jannisgt commented Feb 4, 2019

Hi,

I found a solution for that problem. This is the actual function for numerical scale zoom.

function zoomNumericalScale(scale, zoom, center, zoomOptions) {
	var range = scale.max - scale.min;
	var newDiff = range * (zoom - 1);

	var cursorPixel = scale.isHorizontal() ? center.x : center.y;
	var minPercent = (scale.getValueForPixel(cursorPixel) - scale.min) / range;
	var maxPercent = 1 - minPercent;

	var minDelta = newDiff * minPercent;
	var maxDelta = newDiff * maxPercent;

	scale.options.ticks.min = rangeMinLimiter(zoomOptions, scale.min + minDelta);
	scale.options.ticks.max = rangeMaxLimiter(zoomOptions, scale.max - maxDelta);
}

The easiest remedy is to add a query if the scale.type is "logarithmic", like:

function zoomNumericalScale(scale, zoom, center, zoomOptions) {
	var tickOpts = scale.options.ticks;
	var range = scale.max - scale.min;
	var newDiff = range * (zoom - 1);

	var cursorPixel = scale.isHorizontal() ? center.x : center.y;
	var minPercent = (scale.getValueForPixel(cursorPixel) - scale.min) / range;
	var maxPercent = 1 - minPercent;

	var minDelta = newDiff * minPercent;
	var maxDelta = newDiff * maxPercent;

	tickOpts.min = scale.min + minDelta;
	tickOpts.max = scale.max - maxDelta;

	if (scale.type === 'logarithmic') {
		if (tickOpts.min < 0) {
			tickOpts.min = 0;
		}
	}

	scale.options.ticks.min = rangeMinLimiter(zoomOptions, scale.min + minDelta);
	scale.options.ticks.max = rangeMaxLimiter(zoomOptions, scale.max - maxDelta);
}

With this solution the lowest scale point in a logarithmic scale can only be 0.

@jledentu
Copy link
Collaborator

jledentu commented Feb 5, 2019

@jannisgt Thanks! Do you want to open a PR?

@jannisgt
Copy link
Contributor

jannisgt commented Feb 5, 2019

@jledentu never done, but I try 👍

@jledentu
Copy link
Collaborator

@benmccann I think we can close this issue since chartjs/Chart.js#6058 was merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants