Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Mouse over of pie charts should "zoom" the pie slice under the cursor #10

Open
johnmccutchan opened this issue Aug 11, 2014 · 4 comments

Comments

@johnmccutchan
Copy link

This is important when you have lots of small pie slices.

Also, a tool tip showing the name & value.

@midoringo8823
Copy link
Contributor

We should have this implemented in the near future.

@kendalharland
Copy link
Contributor

This issue has been open for quite some time so I'm unsure of what progress has been made. I have a behavior implementation of zooming pie slices, which I've posted below. The existing tooltip behavior works fine alongside this behavior, but maybe a tooltip class specifically for pie charts would be helpful. The original tooltip doesn't display the series row labels because other chart renderers usually have the labels on the axes.

Notes

This implementation assumes the original stroke width of a pie chart slice will always be one and that the original stroke color will always be white. I haven't added code to pull these values automatically from the chart theme because pie_chart_renderer.dart hard-codes these values to 1px and #ffffff respectively anyway. If it would be a better idea to pull these values from the chart (just in case the defaults will change in the future) I'll go ahead and add them.

If _magnitude is set too large, the paths don't 'zoom' in a very pretty fashion: their inner corners don't form a nice point even with stroke-linejoin set to miter and stroke-miterlimit set anywhere between 1.0 and any other large value.

Otherwise this seems to work ok. Is this along the lines of what you were thinking of as far as zooming a pie slice goes? I'm not sure if it would be better to have a separate pop-up window to display the larger slice, similar to how the ChartToolTip Popup works.

part of charted.charts;

/**
 * The PieSliceZoomer "zooms" a pie slice when the cursor hovers over a pie 
 * chart column.
 */
class PieSliceZoomer implements ChartBehavior {
  final String orientation;
  ChartArea _area;
  Selection _pieSliceSelection;
  SelectionScope _scope;
  SubscriptionsDisposer _disposer = new SubscriptionsDisposer();
  final int _magnitude = 5;
  int _originalStrokeWidth = 1;

  /**
   * Constructs the PieSliceZoomer
   */
  PieSliceZoomer({this.orientation: ORIENTATION_RIGHT});

  /** Sets up listeners for triggering the zoomer */
  void init(ChartArea area, Element upperRenderPane, Element lowerRenderPane) {
    _area = area;
    _disposer.addAll([
        area.onValueMouseOver.listen(zoomIn),
        area.onValueMouseOut.listen(zoomOut)
    ]);
    _scope = new SelectionScope.element(_area.host);
  }

  void dispose() {
    _disposer.dispose();
  }

  /**
   * 'Zooms' the hovered pie slice by increasing the corresponding path's stroke
   * width and setting its color to the column's fill color. 
   * 
   * In order to make the zoomed pie slice appear in front of all other slices, 
   * it is appened as the topmost path in the chart's svg element.
   * 
   * This also sets the 'stroke-linejoin' attibute to keep joined paths from 
   * looking messy.
   */
  zoomIn(ChartEvent e) {
    var pie = e.source.target.parent.children,
      slice = e.source.target,
      firstNonSlice = pie.firstWhere((Element el) => el.toString() != "path"),
      afterSlices = pie.indexOf(firstNonSlice),
      prevStrokeWidth = double.parse(
          slice.getAttribute("stroke-width").replaceAll("px", "")),
      newStrokeWidth;

    // Don't zoom if the slice hasn't returned to its original size
    if (prevStrokeWidth.round() != _originalStrokeWidth) return;
    newStrokeWidth = (_magnitude*prevStrokeWidth).round();
    pie.insert(afterSlices, slice);
    _pieSliceSelection = _scope.selectElements([slice]);
    _pieSliceSelection.transition()
      ..style("stroke", _area.theme.getColorForKey(e.column+1))
      ..attr("stroke-linejoin", "miter")
      ..attr("stroke-miterlimit", "4.0")
      ..attr("stroke-width", "${newStrokeWidth}px")
      ..duration(_area.theme.transitionDuration);
  }

  zoomOut(ChartEvent e) {
    _pieSliceSelection.transition()
      ..style("stroke", "#fff")
      ..attr("stroke-linejoin", null)
      ..attr("stroke-miterlimit", null)
      ..attr("stroke-width", "${_originalStrokeWidth}px")
      ..duration(_area.theme.transitionDuration);
  }

}

zoomdemo5
zoomdemo4
zoomdemo3
zoomdemo2
zoomdemo1

@midoringo8823
Copy link
Contributor

Hi Kendal, thank you for contributing to charted, this looks great!

We actually missed adding a "CONTRIBUTING" file that has information for individual contributors to contribute to charted. I'll paste the content below. After you sign the CLA you could pack your changes in a pull request where we could review and comment on your change and merge it to the code base.

I think it would be a better idea to pull the stroke and color from the chart because the default 1px and #ffffff could change in the future, or we might at least make it configurable. So it's safer to do that. Other comments are: "orientation" seems to be unused, there should be spaces before and after operator, and we indent 4 spaces when declaring multiple variables with , and line break. It would be great if you can change these before adding the pull request.

Here's the content of the CONTRIBUTING file below:

Want to contribute? Great! First, read this page (including the small print at the end).

Before you contribute

Before we can use your code, you must sign the
Google Individual Contributor License Agreement
(CLA), which you can do online. The CLA is necessary mainly because you own the
copyright to your changes, even after your contribution becomes part of our
codebase, so we need your permission to use and distribute your code. We also
need to be sure of various other things—for instance that you'll tell us if you
know that your code infringes on other people's patents. You don't have to sign
the CLA until after you've submitted your code for review and a member has
approved it, but you must do it before we can put your code into our codebase.
Before you start working on a larger contribution, you should get in touch with
us first through the issue tracker with your idea so that we can help out and
possibly guide you. Coordinating up front makes it much easier to avoid
frustration later on.

Code reviews

All submissions, including submissions by project members, require review. We
use Github pull requests for this purpose.

The small print

Contributions made by corporations are covered by a different agreement than
the one above, the Software Grant and Corporate Contributor License Agreement.

@kendalharland
Copy link
Contributor

Thanks Michael, I'll go ahead and take care of these things.

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

No branches or pull requests

4 participants