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

Xrange, partialFill and zoom/pan #7617

Closed
Rob-DM1CM opened this Issue Jan 5, 2018 · 3 comments

Comments

Projects
None yet
3 participants
@Rob-DM1CM

Rob-DM1CM commented Jan 5, 2018

Expected behaviour

I have a x-range chart, where I'm also using zoom (in X) and pan. When the chart is not zoomed, the partialFill's look fine, and when the chart is zoomed or panned such that some of the horizontal bars stretch beyond the chart boundaries, the partialFills should still represent the correct percentage of the total bar length, even though some of the bar is no longer visible (beyond the chart area).

Actual behaviour

In actual fact, when the chart is zoomed or panned such that some of the horizontal bars stretch beyond the chart boundaries, the partialFills no longer represent the correct percentage of the total bar length, but now show the percentage of the VISIBLE part of the bar. This is neither useful, nor correct behaviour.

I had the idea of replacing partialFill with another option which would simply set the start- and end-stops of the portion of the bar (in X-values) to be shaded, rather than the percentage of total bar length. In this way, your code would simply have to read those start/end stop values and shade the correct area, regardless of whether the chart had been zoomed/panned. And it would be simpler to do on the developer/user's side, since he wouldn't have to keep calculating percentages. Or does such a thing already exist?

Live demo with steps to reproduce

Some screenshots: https://forum.highcharts.com/highcharts-usage/x-range-partialfill-and-zoom-pan-t40043/#p138694

The actual webpage I'm working on :

http://codetest.iotamaps.org/dxpeditions - click on the "IOTA DXpeditions timeline" tab...

Affected browser(s)

All

@pawelfus

This comment has been minimized.

Show comment
Hide comment
@pawelfus

pawelfus Jan 5, 2018

Contributor

Hi @Rob-DM1CM

Thank you for reporting this issue. It looks like partialFill is miscalculated. Simplified demo with predefined extremes has the same issue: http://jsfiddle.net/8gzpst3x/1/

Workaround:
Replace clipping the rect and render the shape with direct values: http://jsfiddle.net/s0e020zd/1/ Snippet:

Highcharts.wrap(Highcharts.seriesTypes.xrange.prototype, 'translatePoint', function(p, point) {
  var endX, endPlotX, partial;

  p.apply(this, Array.prototype.slice.call(arguments, 1));

  if (point.partialFill) {

    partial = Highcharts.isObject(point.partialFill) ?
    	point.partialFill.amount : point.partialFill;

    endX = Highcharts.pick(
      point.x2, point.x + (point.len || 0)
    );

    endPlotX = this.xAxis.toPixels(
      point.x + partial * (endX - point.x),
      true
    );

    point.clipRectArgs.width = point.partShapeArgs.width;

    point.partShapeArgs.x = point.plotX;
    point.partShapeArgs.width = Math.max(
      endPlotX - point.plotX,
      0
    );
  }
});

Internal note:
Why calculations use clip-path to display the partial, not the partial element itself? Is that connected to the rounded corners or to simplicity of calculations?

Contributor

pawelfus commented Jan 5, 2018

Hi @Rob-DM1CM

Thank you for reporting this issue. It looks like partialFill is miscalculated. Simplified demo with predefined extremes has the same issue: http://jsfiddle.net/8gzpst3x/1/

Workaround:
Replace clipping the rect and render the shape with direct values: http://jsfiddle.net/s0e020zd/1/ Snippet:

Highcharts.wrap(Highcharts.seriesTypes.xrange.prototype, 'translatePoint', function(p, point) {
  var endX, endPlotX, partial;

  p.apply(this, Array.prototype.slice.call(arguments, 1));

  if (point.partialFill) {

    partial = Highcharts.isObject(point.partialFill) ?
    	point.partialFill.amount : point.partialFill;

    endX = Highcharts.pick(
      point.x2, point.x + (point.len || 0)
    );

    endPlotX = this.xAxis.toPixels(
      point.x + partial * (endX - point.x),
      true
    );

    point.clipRectArgs.width = point.partShapeArgs.width;

    point.partShapeArgs.x = point.plotX;
    point.partShapeArgs.width = Math.max(
      endPlotX - point.plotX,
      0
    );
  }
});

Internal note:
Why calculations use clip-path to display the partial, not the partial element itself? Is that connected to the rounded corners or to simplicity of calculations?

@pawelfus pawelfus added the Bug label Jan 5, 2018

@Rob-DM1CM

This comment has been minimized.

Show comment
Hide comment
@Rob-DM1CM

Rob-DM1CM Jan 6, 2018

Hi Pawel,

Thanks for attending to this. The workaround works very nicely!

Cheers, Rob

Rob-DM1CM commented Jan 6, 2018

Hi Pawel,

Thanks for attending to this. The workaround works very nicely!

Cheers, Rob

@TorsteinHonsi

This comment has been minimized.

Show comment
Hide comment
@TorsteinHonsi

TorsteinHonsi Jan 8, 2018

Collaborator

Thanks for the workaround Pawel! Will you prepare a PR with this fix?

Why calculations use clip-path to display the partial, not the partial element itself?

Yes, I believe this is because of the rounded corners.

Collaborator

TorsteinHonsi commented Jan 8, 2018

Thanks for the workaround Pawel! Will you prepare a PR with this fix?

Why calculations use clip-path to display the partial, not the partial element itself?

Yes, I believe this is because of the rounded corners.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment