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

Using other shapes than "circles" for line points #question #173

Closed
julien opened this issue Oct 19, 2017 · 13 comments
Closed

Using other shapes than "circles" for line points #question #173

julien opened this issue Oct 19, 2017 · 13 comments

Comments

@julien
Copy link
Collaborator

julien commented Oct 19, 2017

Description

This is more a question rather than an issue.

I'd like to be able to use other shapes than svg circle for the "line points" used in Line and Spline charts.

Since circle seems to be hardcoded in many places, I thought using the onafterinit callback to do the following:

  • Select chart lines
  • Get circle positions (is this possible through the API?)
  • Append the "desired shape" (in my case an svg rect) and set it's attributes
  • Remove the circles (or hide them via API)

What do you think of the idea?

Would this be an interesting feature for the library?

Thanks

@netil
Copy link
Member

netil commented Oct 20, 2017

@julien that's a good idea!

But rather than applying using callback, it'll be great if this feature can be implemented as one of the new option.

We already have point option, so maybe adding type to change the shape of the data points.

point: {
	type: "rect",  // default 'circle'
	...
}

And the expected result will be as:
image

What do you think on that?

@julien
Copy link
Collaborator Author

julien commented Oct 20, 2017

@netil sounds like a much better idea indeed.

@julien
Copy link
Collaborator Author

julien commented Oct 20, 2017

Hi again @netil,

I went ahead an started "prototyping" the type option for point, it probably needs to be much improved, and I'd need some advice and thoughts on the direction to be taken to make this feature as usefull as possible without adding too much complexity to the code (which is kind of what I did in the prototype).

The changes made can be seen in the following diff

I have not yet submitted a pull request, because I think some things are missing:

  • The selection also seems to update points (or circles in this case) and would probably need to be updated accordingly.

  • No new tests have been added (I thought it might not be that useful for a prototype), but the changes don't break existing tests.

  • Since this would allow different types to be used, it might make sense to support other SVG shapes.
    At the moment, code that renders these shapes (or points) is not easily customizable and I
    thought that it might be better to allow the developer to specify this in the options and refactor the existing code for rendering "circles" to follow this pattern.

    Something like.

    point: {
      r: 4,
      render(data, options) {
        return some_d3_selection;
      },
      update(selection, data, options) {
        // update existing shape
        return some_d3_selection;
      }
    }

    However, I'm not really sure how to implement these "factory" methods and would appreciate
    your feedback.

I've also gone an updated the demo in my fork, if you're interested.

While I'm at it, I wanted to tell I'd probably want to collaborate on "custom lines" feature and I hope you don't mind.

Please tell me what you think when you have a chance and thanks for your time

@netil
Copy link
Member

netil commented Oct 23, 2017

That's great @julien and apologize for the delay.

Selection

I can't say the selection circle should follow to the data point shape. Even data point is rectangle, I'm not seeing weird having circle around it.

Tests

Well, the test should be added according the final implementation. So, it should have some test code before the PR.

Types

IMO, the reasonable svg shapes to be support will be:

  • circle
  • rect
  • ellipse (there's no big difference with circle. I don't think is useful)
  • polygon (maybe useful)

It'll be great giving some flexibility, but I'm not really sure implementing the factory.
Internally, the rendering of the circle flows from updateCircle() to redrawCircle().

  • updateCircle(): Bind the data and add elements with the basic attr.
  • redrawCircle(): Positioning elements.

To not break(or follow) the current flow, it's necessary (1) set(updateCircle) and (2) positioning(redrawCircle), but adding 2 callback options isn't seem clear and understandable at first glance.

For this moment, I just come up the following.
Make type to handle node reference also, and draw callback to set points' position and style.

point: {
	type: [HTMLElement | SVGElement],
	draw: function(point, x, y) {
		point.attr("cx", x).attr("cy", y);
	}
}

But, I think is fine just supporting rect type only for now.
Adding more functionality can be done after seeing the reactions of the users.

And it seems great about custom lines. :)

@julien
Copy link
Collaborator Author

julien commented Oct 23, 2017

Hi @netil,

Thanks for the reply.

I went along and tried using other shapes in my fork just to try and see what I could come up with.

Selection

Concerning the selection, you made a point, I think using a circle even if the shape is a rect shouldn't be an issue (I've tested this with other shapes and it wasn't a problem).

Tests

Concerning the tests, I will add some to make sure everything is covered, I just wanted to have your thoughts after talking about this idea.

Types

Concerning the types, let me clarify what I meant by "factory" method.

As you mentioned, I see that the shape is appended with updateCircle() and that it's posisition is the updated when redrawCircle(...) is invoked.

My proposal would be to do something like this in shape.line.js:

updateCircle() {
  const $$ = this;

  if (!$$.config.point_show) {
    return;
  }

  $$.mainCircle = $$.main.selectAll(`.${CLASS.circles}`).selectAll(`.${CLASS.circle}`)
    .data($$.lineOrScatterData.bind($$));

  $$.mainCircle.exit().remove();

  /* Call the draw method provided via config to append the element */
  const pointType = $$.config.point_type || "circle";
  $$.mainCircle = $$.config.point_create($$.config.point_type)
}

And then to update the circle:

redrawCircle(cx, cy, withTransition, flow) {
	let selectedCircles = this.main.selectAll(`.${CLASS.selectedCircle}`);
	let mainCircles;

	if (!this.config.point_show) {
		return [];
	}

        /* Call the update method provided via config  to update the element's position */
       mainCircles = this.config.point_update(this.mainCircle, cx, cy, withTransition, flow);

	return [
		mainCircles,
		selectedCircles
			.attr("cx", cx)
			.attr("cy", cy)
	];
},

This seems flexible enough to support various shapes, but we would need to check that both methods are provided (create and update) before invoking them. If no methods are provided, we could just use the default "circle" create and update methods (that billboard.js would provide).

  • Concerning the lines, I will give you and update shortly but I would like to implement this first.

In anycase, tell me what you think, I will prepare a PR with the code changes (and tests).

Thanks again

@julien
Copy link
Collaborator Author

julien commented Oct 23, 2017

Hi again @netil,

Since code might be better to explain the "factory methods", I've pushed a preview of these changes here.

With these changes, you could do something like this:

var chart = bb.generate({
  data: {
    columns: [
      ["data1", 30, 200, 100, 400, 150, 250],
      ["data2", 50, 20, 10, 40, 15, 25]
    ]
  },
  point: {
    create: function(parent, cssClassFn, sizeFn, fillStyle) {
      return parent.enter().append("rect")
        .attr("class", cssClassFn)
        .attr("width", sizeFn)
        .attr("height", sizeFn)
        .style("fill", fillStyle);
    },

    update(element, selectedElements, cx, cy, withTransition, flow, opacityFn, fillStyle) {
      let mainCircles;

      const w = parseFloat(element.attr("width"));
      const h = parseFloat(element.attr("height"));

      mainCircles = element
      .attr("x", d => {
        return cx(d) - (w * 0.5);
      })
      .attr("y", d => {
        return cy(d) - (h * 0.5);
      })
      .style("opacity", opacityFn)
      .style("fill", fillStyle);
    
      return mainCircles;
    }
  },
  bindto: "#chart"
});

And the line would use "rect"s instead of "circles".
Tell me if you think this is still a good idea when you can.

Thanks

@netil
Copy link
Member

netil commented Oct 25, 2017

What a great approach @julien!
I love the idea, but also have some concern on this.

Giving flexibility is really good, but the user should have some kind of knowledge to implement this. I mean, this options are more likely for 'high-end' users.

I think billboard.js is getting popularity because of its simplicity in the implementation and ease usage interface.

What do you think about this? If there is more simplicity way to get on this, will be great.

@julien
Copy link
Collaborator Author

julien commented Oct 27, 2017

Thanks @netil,

I understand you have some concerns about this suggestion, and also agree that in order to implement this feature, the developer should have some idea on how to implement it.
Documenting and providing examples, would make things easier.

I also agree that billboard is popular because of it's simplicity, but I also think that allowing the developer to customize the "look and feel" of the charts is a bonus.

One example of customizing billboard is the possibility to change the "default colors" that are provided by billboard by specifying the color_pattern option.

var chart = bb.generate({
  color: {
    pattern: ['#ff0000', '#00ff00'] // My custom colors
  },
  data: {
    columns: [
      ['data1', 120, 200, 20, 400, 50, 100],
      ['data2', 20, 100, 210, 80, 60, 230]
    ]
  },
  bindto: '#chart'
});

Having the same flexibility for "custom shapes" would be great, so I guess we have several options:

  1. Allow developers to provide code that renders their "custom shapes".
    In this case, if no options are specified, billboard provides some defaults to
    make sure things are rendered correctly, on the other hand if those options are provided,
    it would be the developer's responsibility.

    var chart = bb.generate({
      point: {
        create: function(options) {
          // code provided by the developer
        },
        update: function(x, y) {
          // code provided by the developer
        } 
      },
      data: {
        columns: [
          ['data1', 120, 200, 20, 400, 50, 100],
          ['data2', 20, 100, 210, 80, 60, 230]
        ]
      },
      bindto: '#chart'
    });
  2. Support a set of custom shapes, for example circle and rectangle and
    render the corresponding shape accordingly.

    var chart = bb.generate({
      point: {
        type: 'rectangle' // If no `type` option is provided, default to circles
      },
      data: {
        columns: [
          ['data1', 120, 200, 20, 400, 50, 100],
          ['data2', 20, 100, 210, 80, 60, 230]
        ]
      },
      bindto: '#chart'
    });

Tell me if you think one of these options is a viable solution and thanks again for your time.

@netil
Copy link
Member

netil commented Oct 30, 2017

My opinion is supporting 2 ways of implementation will be more flexible. Just letting user decide which way to approach.

But on implementing this, it needs decide which options are considered first if both options are declared.

@julien
Copy link
Collaborator Author

julien commented Oct 30, 2017

@netil, thanks for the feedback.

I think we could "prioritize" which way of drawing things is used when several options are provided.

I'll try to illustrate this with "pseudo code".

// 1 - Check the `point_type` option to see if
//     it has a valid value (e.g. "circle", "rectangle")
if (isValidPointType(this.config.point_type)) {
} 
// 2 - Check that point_create and point_update are functions
else if (hasValidDrawFunctions(this.config)) {
} 
// 3 -  No option was specified, draw the "default" circles
else {
}

I also the number of arguments passed the point_create and point_update functions could be reduced, and I am updating my example, which I'll give you an update on shortly.

@netil
Copy link
Member

netil commented Oct 31, 2017

I agree with your approach @julien.

We discussed quite a while on it, and I think we made some consensus how to implement.
Now is time to implement it!

@julien
Copy link
Collaborator Author

julien commented Oct 31, 2017

@netil great news!

@julien
Copy link
Collaborator Author

julien commented Nov 2, 2017

Hi agian @netil,

I just opened #184, so I guess we will continue discussing there.

@netil netil closed this as completed in cc2ac8b Nov 9, 2017
netil added a commit that referenced this issue Nov 10, 2017
update description
remove unnecessary definition

Ref #173 
Fix #186
netil pushed a commit that referenced this issue Jun 18, 2019
# 1.0.0 (2019-06-18)

### Bug Fixes

* fallback to __bindto's id attribute when it is not a string ([16a1e6d](16a1e6d))
* regex replaces everything that is not alphanum, - or _ ([1f093dd](1f093dd))
* **tooltip:** Correct tooltip position when is zoomed ([45785ab](45785ab)), closes [#197](#197) [#281](#281) [#431](#431) [#546](#546)
* throw errors instead of alerts ([12cf47d](12cf47d))
* **all:** Re-organize import from d3 ([c11a215](c11a215)), closes [#285](#285) [#313](#313)
* **AMD-module:** updating to enforce the AMD standard ([4f8f63c](4f8f63c))
* **api:** Cancel transitions on destroy. ([7dd287d](7dd287d)), closes [#766](#766) [#765](#765)
* **api:** Change the way of hiding tooltip ([#358](#358)) ([67c8305](67c8305)), closes [#343](#343)
* **api:** Correct .x()/.xs() to work properly ([80d4e1b](80d4e1b)), closes [#634](#634) [#635](#635)
* **api:** Correct on exporting custom points ([f65bcfb](f65bcfb)), closes [#541](#541) [#741](#741)
* **api:** Correct toggle interaction ([#456](#456)) ([3682a83](3682a83)), closes [#454](#454)
* **api:** Fix css encoding in exported svg ([321971e](321971e)), closes [#843](#843) [#844](#844)
* **api:** Fix JSON data loading ([9067138](9067138)), closes [#398](#398) [#400](#400)
* **api:** Fix loading to maintain correct x index ([f3881bc](f3881bc)), closes [#517](#517) [#519](#519)
* **api:** Fix regions.remove() error ([#579](#579)) ([0c0374f](0c0374f)), closes [#529](#529) [#578](#578)
* **api:** Fix to remove instance ([#357](#357)) ([80fdc31](80fdc31)), closes [#347](#347)
* **api:** Remove cached data when .unload() is called ([aa91bab](aa91bab)), closes [#626](#626) [#627](#627)
* **api-load:** Allow false for unload ([e52e5ad](e52e5ad)), closes [#321](#321) [#333](#333)
* **api.zoom, interaction:** fix zoom bug for rects ([b3521c8](b3521c8)), closes [#33](#33) [#46](#46)
* **arc:** Correction on rendering 0 values ([dcfa12c](dcfa12c)), closes [#652](#652) [#656](#656)
* **arc:** Fix to generate arc when data is zero ([04a4dd8](04a4dd8)), closes [#935](#935)
* **arc,api:** Correct on data representation and handling ([#332](#332)) ([3eec8d7](3eec8d7)), closes [#303](#303) [#331](#331)
* **area:** Apply gradient on dynamic data loading ([954c303](954c303)), closes [#855](#855)
* **area-line-range:** Fix working with grouped data ([1546dda](1546dda)), closes [#630](#630) [#644](#644)
* **area-range:** Correct handling null data ([cc1d4ee](cc1d4ee)), closes [#482](#482) [#487](#487)
* **area-range:** Fixed data parsing ([#485](#485)) ([4b78de5](4b78de5)), closes [#481](#481)
* **axis:** Adjust axes range ([0130519](0130519)), closes [#859](#859)
* **axis:** Avoid unnecessary computing char dimension ([3f52827](3f52827)), closes [#399](#399) [#407](#407)
* **axis:** Correct axis label position ([#538](#538)) ([37cca8c](37cca8c)), closes [#519](#519) [#534](#534)
* **axis:** Correct axis transition ([e2bec90](e2bec90)), closes [#759](#759)
* **axis:** Correct not to generate unnecessary ticks ([#560](#560)) ([9346e66](9346e66)), closes [#348](#348)
* **axis:** Correct rotated x axis rendering ([2b02a03](2b02a03)), closes [#230](#230) [#234](#234)
* **axis:** Correct tick's position implementation ([#457](#457)) ([09547be](09547be)), closes [#380](#380)
* **axis:** Correct ticks less than ~0.1 to be shown ([8d14bcb](8d14bcb)), closes [#387](#387) [#409](#409)
* **axis:** Fix indexed x axis order ([#879](#879)) ([df8d385](df8d385)), closes [#714](#714) [#877](#877)
* **axis:** Fix on axis width sizing ([10f27e5](10f27e5)), closes [#920](#920)
* **axis:** fix side-effects from [#717](#717) ([#740](#740)) ([4eba766](4eba766))
* **axis:** Fix x Axis tick fit for timeseries ([9cda54f](9cda54f)), closes [#628](#628)
* **axis:** improve tick label size calculation ([8dc08bd](8dc08bd)), closes [#323](#323) [#324](#324)
* **axis:** Round float numbers from 'binary floating point' ([bd2fbbe](bd2fbbe)), closes [#222](#222) [#320](#320)
* **Axis:** Fix text alignment when legend is not showing ([620d737](620d737)), closes [#25](#25) [#686](#686)
* **Axis:** Fix tick text position ([0ca6b18](0ca6b18)), closes [#672](#672) [#678](#678)
* **bar:** Adjust bar width regardless tick count limit ([8f92d3e](8f92d3e)), closes [#166](#166) [#182](#182)
* **bar:** Fix bar position on width option ([0883588](0883588)), closes [#720](#720) [#832](#832)
* **bar:** Remove new line chars on path string ([#533](#533)) ([1f9db5a](1f9db5a)), closes [#530](#530)
* **bower:** add scss source files to bower package ([945ee66](945ee66))
* **bubble,point:** Fix bubble size change on load API ([#214](#214)) ([d9eb371](d9eb371)), closes [#163](#163)
* **chart:** Correct data label text prop ref ([d9f4477](d9f4477)), closes [#780](#780) [#781](#781)
* **color:** Correct the way on setting pattern value ([#509](#509)) ([164a3f9](164a3f9)), closes [#507](#507)
* **color:** Remove importing schemeCategory10 ([72864c5](72864c5)), closes [#298](#298) [#373](#373)
* **colors:** Fix color method ([8effaad](8effaad)), closes [#233](#233)
* **data:** babel transform bug ([1f8efc2](1f8efc2)), closes [#17](#17) [#18](#18)
* **data:** Correct data label text to be shown on scatter ([#492](#492)) ([f9f0081](f9f0081)), closes [#488](#488)
* **data:** Correct data order to not be altered ([e39db91](e39db91)), closes [#379](#379) [#412](#412)
* **data:** Correct data.onclick calls ([#203](#203)) ([a5fd3fc](a5fd3fc)), closes [#202](#202)
* **data:** Correct onover/out callback on touch ([#769](#769)) ([9ad9817](9ad9817)), closes [#768](#768)
* **data:** Fix data indexing ([2e3010b](2e3010b)), closes [#863](#863)
* **data:** Fix empty label text flickering ([173990b](173990b)), closes [#901](#901)
* **data:** Remove selection on data.onmin/max ([#143](#143)) ([7709c32](7709c32)), closes [#8](#8)
* **data,interaction:** Bar type interaction error on multiple x ([cf49d71](cf49d71)), closes [#178](#178) [#180](#180)
* **data.convert:** allow dots in json properties ([7ff837a](7ff837a)), closes [#14](#14)
* **dev-env:** Update main entry point ([1488232](1488232)), closes [#391](#391) [#525](#525) [#549](#549)
* **domain:** Fix getting Y domain min/max value ([864e112](864e112)), closes [#685](#685) [#690](#690)
* **event:** Correct on resizing all generated charts ([10d6d73](10d6d73)), closes [#404](#404) [#466](#466) [#468](#468)
* **gauge:** Correct background rendering on fullCircle ([#141](#141)) ([7f5fda2](7f5fda2)), closes [#140](#140)
* **grid:** Correct grid position ([5a7a94d](5a7a94d)), closes [#820](#820) [#821](#821)
* **grid:** Correct grid scale on zoom ([2904d41](2904d41)), closes [#799](#799)
* **grid:** Correct updating grid's attributes ([#414](#414)) ([1662a1f](1662a1f)), closes [#389](#389)
* **interaction:** Correct drag selection error ([#493](#493)) ([f38cd24](f38cd24)), closes [#490](#490)
* **interaction:** Correct event binding ([#27](#27)) ([f09d2ed](f09d2ed)), closes [#24](#24)
* **interaction:** Correct mouse event create ([#252](#252)) ([930f74b](930f74b)), closes [#251](#251)
* **interaction:** Correct rect element sizing ([6a09985](6a09985)), closes [#522](#522) [#523](#523)
* **interaction:** Prioritize mouse input ([#280](#280)) ([5cc3442](5cc3442)), closes [#92](#92)
* **internal:** Correct evaluating inputType condition ([#257](#257)) ([4b1f3cc](4b1f3cc)), closes [#92](#92)
* **internal:** Fix on unexpected resize event firing ([#572](#572)) ([dd5af9c](dd5af9c)), closes [#571](#571)
* **label:** Correct newly added texts transition position ([f81d440](f81d440)), closes [#648](#648) [#718](#718)
* **legend:** Correct legend positioning ([51ee8ce](51ee8ce)), closes [#737](#737) [#737](#737) [#752](#752)
* **legend:** Correct to keep the original class value ([46ebf35](46ebf35)), closes [#444](#444)
* **legend:** Fix legend template update for dynamic loading ([#622](#622)) ([1e465ae](1e465ae)), closes [#621](#621)
* **legend:** Fix resize for arc ([#707](#707)) ([89a3ece](89a3ece)), closes [#705](#705)
* **legend:** Fix resizing when legend template is used ([#706](#706)) ([87294dd](87294dd)), closes [#705](#705)
* **Legend:** working with useless transition effect ([676b1e5](676b1e5)), closes [#25](#25) [#41](#41)
* **line:** Correct on rotated step type ([#474](#474)) ([74bd639](74bd639)), closes [#471](#471)
* **line:** Correct zoom with data.regions ([a76000a](a76000a)), closes [#728](#728) [#729](#729)
* **line:** Fix areaGradient for spaced data name ([3fbd4b2](3fbd4b2)), closes [#930](#930)
* **line:** Fix gradient with dataname starting w/no ([fe31102](fe31102)), closes [#936](#936)
* **options:** Correct when bindto element not exist ([448a45d](448a45d)), closes [#743](#743) [#749](#749)
* **pie:** Correct multiline label text ([9bacb9b](9bacb9b)), closes [#784](#784)
* **point:** Check for node.childNodes existance for IE / Edge ([59a5a05](59a5a05)), closes [#601](#601) [#602](#602)
* **point:** Correct point expansion on old IEs ([2e9dbfe](2e9dbfe)), closes [#897](#897)
* **point:** Fix custom point hover position ([2edb82a](2edb82a)), closes [#618](#618) [#700](#700)
* **radar:** Correct on resizing ([#540](#540)) ([f2fdecc](f2fdecc)), closes [#497](#497)
* **radar:** Fix data.onover/out callback ([91c8df2](91c8df2)), closes [#768](#768) [#773](#773)
* **radar:** Fix incorrect rendering ([#738](#738)) ([f8915e2](f8915e2)), closes [#735](#735)
* **readme:** Change broken link about license ([#188](#188)) ([a9a1e09](a9a1e09))
* **regions:** Fix regions resizing on zoom ([#561](#561)) ([c61960d](c61960d)), closes [#483](#483)
* **selection:** Correct multiple callback calls ([#120](#120)) ([f7cae57](f7cae57)), closes [#117](#117)
* **selection:** Correct multiple selection error ([#455](#455)) ([353f809](353f809)), closes [#445](#445)
* **selection:** Correct on data selection ([#113](#113)) ([eb13350](eb13350)), closes [#112](#112)
* **shape:** Correct newly added points transition position ([d9dc75a](d9dc75a)), closes [#648](#648) [#659](#659)
* **shape:** Fix for empty data in normalization ([#649](#649)) ([76f3558](76f3558)), closes [#623](#623)
* **shape:** Fix normalization on hidden data ([#645](#645)) ([aba9496](aba9496)), closes [#643](#643)
* **shape:** line.step.type config not working ([#86](#86)) ([62273bf](62273bf)), closes [#85](#85)
* **shape:** Prevent when non-existed data.hide is given ([#650](#650)) ([6a72602](6a72602)), closes [#623](#623)
* **shape, api.zoom:** fix zoom for barchart ([917384f](917384f)), closes [#16](#16) [#32](#32)
* **shape.line:** Correct getting shape object ([#47](#47)) ([b2a0acf](b2a0acf)), closes [#10](#10)
* **shape.line:** Correct return type ([#148](#148)) ([3317183](3317183)), closes [#147](#147)
* **size:** Correct height increase during resize ([#223](#223)) ([9699a55](9699a55)), closes [#155](#155) [#164](#164)
* **size:** Correct width on resizing ([#189](#189)) ([5a93a19](5a93a19)), closes [#179](#179)
* **subchart:** Correct subchart extent option ([eac3e65](eac3e65)), closes [#142](#142) [#805](#805)
* **subchart:** Maintain subchart selection on resize ([c7d7fa5](c7d7fa5)), closes [#778](#778)
* **subchart:** Maintaion selection for category x axis ([3f46609](3f46609)), closes [#778](#778)
* **tiles:** Fix background tiles id ([c452b43](c452b43)), closes [#225](#225) [#226](#226)
* **tooltip:** Correct interaction on mobile ([23ff1df](23ff1df)), closes [#376](#376) [#377](#377)
* **tooltip:** Correct on toggling data series ([#253](#253)) ([e7d1b19](e7d1b19)), closes [#240](#240)
* **tooltip:** Enhancement for overlapped points ([3ee694d](3ee694d)), closes [#568](#568) [#569](#569)
* **tooltip:** Fix for dynamically loaded data adding column ([009d3b1](009d3b1)), closes [#660](#660) [#661](#661)
* **tooltip:** Fix for mobile environment ([#616](#616)) ([981bc77](981bc77)), closes [#593](#593)
* **tooltip:** Fix handling on color tile ([#875](#875)) ([56c2f99](56c2f99)), closes [#816](#816) [#816](#816)
* **tooltip:** Fix mid value showing for area-range type ([#598](#598)) ([a9d615b](a9d615b)), closes [#597](#597)
* **tooltip:** Fix on ungrouped tooltip showing for custom shape ([#548](#548)) ([9411758](9411758)), closes [#547](#547) [#241](#241)
* **tooltip:** Fix tooltip.show() for multi x axis ([aaa8293](aaa8293)), closes [#785](#785)
* **tooltip:** Make linked tooltip to work based on index ([2df0a38](2df0a38)), closes [#494](#494) [#496](#496)
* **tooltip:** Non linked tooltip exclusion ([feeb536](feeb536)), closes [#393](#393) [#396](#396)
* **ua:** Fix the side-effect by refactoring ([#898](#898)) ([d00d903](d00d903))
* **zoom:** Correct not firing data.onclick callback ([7368446](7368446)), closes [#583](#583) [#584](#584)
* **zoom:** Correct not to re-scale while zoom is disabled ([#273](#273)) ([502d6fd](502d6fd)), closes [#272](#272)
* **zoom:** Correct zoom in rendering on 0 coord. ([f61b792](f61b792)), closes [#169](#169) [#170](#170)
* **zoom:** Correct zoom resizing ([#139](#139)) ([67e863e](67e863e)), closes [#60](#60)
* **zoom:** Correct zoom.range() to work ([6830e5c](6830e5c)), closes [#290](#290) [#291](#291)
* **zoom:** Correct zooming for category axis type ([#441](#441)) ([c8a164a](c8a164a)), closes [#177](#177)
* **zoom:** Fix on .zoom() API  ([cd0d109](cd0d109)), closes [#581](#581) [#582](#582)
* **zoom:** Fix on rotated axis ([#892](#892)) ([983d970](983d970)), closes [#736](#736) [#818](#818)
* **zoom:** Fix on zoom.rescale option ([#566](#566)) ([851ec3e](851ec3e)), closes [#470](#470)
* **zoom:** Fix tooltip pos for bubble/scatter ([1fc9c16](1fc9c16)), closes [#906](#906)
* **zoom:** Fix zoom level reset ([ec24c2c](ec24c2c)), closes [#913](#913)
* **zoom:** Fix zoom rescale by wheel ([585d607](585d607)), closes [#890](#890)
* **zoom:** Maintain zoommed scale on .zoom() ([7b7a274](7b7a274)), closes [#654](#654) [#702](#702)
* **Zoom:** Updated domain values onzoom/onzoomend ([acf3239](acf3239)), closes [#770](#770) [#777](#777)

### Features

* **all:** Add TS definition  ([8b34691](8b34691)), closes [#629](#629) [#682](#682)
* **api:** Intent to ship .config() ([b0dc53a](b0dc53a)), closes [#502](#502) [#545](#545)
* **arc:** Enhance multiline text label ([7e57c67](7e57c67)), closes [#784](#784)
* **Arc:** Implement multiline donut title ([b816dc0](b816dc0)), closes [#71](#71) [#130](#130)
* **area:** Intent to ship area.linearGradient ([0063a4c](0063a4c)), closes [#755](#755) [#800](#800)
* **axis:** Enhancement on tick multiline ([#386](#386)) ([4178e40](4178e40)), closes [#381](#381)
* **axis:** Inten to ship axis.x.tick.tooltip ([94a8650](94a8650)), closes [#236](#236) [#240](#240)
* **axis:** Intent to ship axis clipPath option ([#459](#459)) ([e9fb973](e9fb973)), closes [#458](#458)
* **axis:** Intent to ship multi Axes ([becd3c3](becd3c3)), closes [#98](#98) [#697](#697) [#699](#699)
* **axis:** Intent to ship tick show options ([#746](#746)) ([89c1aa2](89c1aa2)), closes [#737](#737)
* **axis:** Intent to ship tick.text.position ([#426](#426)) ([816ce2a](816ce2a)), closes [#380](#380)
* **axis:** Pass category name param ([#329](#329)) ([7e06851](7e06851)), closes [#327](#327)
* **bar:** Intent to ship bar.radius option ([#476](#476)) ([17e2b41](17e2b41)), closes [#359](#359)
* **bar:** Intent to ship variant width ([ae46c85](ae46c85)), closes [#720](#720) [#724](#724)
* **bubble:** Intent to ship bubble type ([#195](#195)) ([c80d78f](c80d78f)), closes [#163](#163)
* **Chart:** Expose primary node elements ([#511](#511)) ([de3f60c](de3f60c)), closes [#423](#423)
* **ChartInternal,Options:** Add before/after initialization callbacks ([354d7e2](354d7e2)), closes [#55](#55) [#126](#126)
* **ChartInternal,Options:** Add new clipPath option ([6531692](6531692)), closes [#56](#56) [#95](#95)
* **color:** Intent to ship color.onover ([5ec2d9e](5ec2d9e)), closes [#754](#754) [#768](#768) [#772](#772)
* **core:** Intent to ship global config ([1b524e1](1b524e1)), closes [#932](#932)
* **core:** Intent to ship instance property ([#315](#315)) ([d20c68d](d20c68d)), closes [#308](#308)
* **data:** Intent to ship data.labels.centered ([cbe95b7](cbe95b7)), closes [#876](#876)
* **data:** Intent to ship data.labels.colors ([c10c946](c10c946)), closes [#871](#871)
* **data:** Intent to ship data.min()/max() ([e9f1417](e9f1417)), closes [#637](#637) [#638](#638)
* **data,Options:** Implement data.onmin/onmax callback ([6a88a74](6a88a74)), closes [#8](#8) [#125](#125)
* **data.type:** Intent to ship 'area-range' charts ([9fd9577](9fd9577)), closes [#277](#277) [#293](#293)
* **export:** Intent to ship export as an image ([9ad9956](9ad9956)), closes [#78](#78) [#213](#213)
* **gauge:** Enhance display multiline labels ([#516](#516)) ([3a1267e](3a1267e)), closes [#442](#442)
* **gauge:** Intent to ship stack data ([0d7fb3e](0d7fb3e)), closes [#580](#580)
* **grid:** Intent to ship grid.front option ([#385](#385)) ([58621a0](58621a0)), closes [#384](#384)
* **interaction:** Add new inputType.touch.preventDefault option ([baa7a7a](baa7a7a)), closes [#82](#82) [#88](#88)
* **legend:** Add argument to legend template ([2ecab0d](2ecab0d)), closes [#302](#302) [#322](#322)
* **legend:** Add shapes to legend ([a0b6542](a0b6542)), closes [#269](#269) [#289](#289)
* **legend:** Implement legend.contents ([26de147](26de147)), closes [#58](#58) [#134](#134)
* **line:** Ability to hide points for linecharts only ([3d217cc](3d217cc)), closes [#520](#520) [#521](#521)
* **option:** Intent to ship bar.padding option ([#370](#370)) ([6671e63](6671e63)), closes [#335](#335)
* **Options:** Add custom classname for bind element ([#212](#212)) ([22cee47](22cee47)), closes [#201](#201)
* **Options:** Implement color.tile option ([bec92dd](bec92dd)), closes [#193](#193) [#196](#196)
* **Options:** New tooltip onshow/onhidden and linked options ([c96d2dd](c96d2dd)), closes [#341](#341)
* **pie:** Enhance innerRadius option ([1668463](1668463)), closes [#856](#856)
* **pie:** Intent to ship pie's pdding and innerRadius options. ([b04ba3d](b04ba3d)), closes [#301](#301) [#304](#304)
* **plugin:** Add support for Stanford Diagrams ([a162cb7](a162cb7)), closes [#829](#829)
* **point:** Allow grouped custom point ([#565](#565)) ([ee12f96](ee12f96)), closes [#562](#562)
* **point:** Implement alternate markers ([8f1b56f](8f1b56f)), closes [#209](#209) [#219](#219)
* **point,bar:** Intent to ship sensitivity ([ebeb30f](ebeb30f)), closes [#831](#831)
* **radar:** Intent to ship multiline axis ([44198e1](44198e1)), closes [#904](#904)
* **radar:** Intent to ship radar type ([#453](#453)) ([7d0da65](7d0da65)), closes [#59](#59)
* **radar:** Intent to ship radar.direction.clockwise ([#543](#543)) ([f17fa7e](f17fa7e)), closes [#464](#464)
* **regions:** Intent to ship dasharray ([ca94580](ca94580)), closes [#491](#491) [#498](#498)
* **shape:** Intent to ship stack.normalize ([3af15a5](3af15a5)), closes [#623](#623) [#643](#643)
* **shape.line:** Add a line_classes option ([5781b5a](5781b5a)), closes [#181](#181)
* **shape.line:** Allow customization of points ([cc2ac8b](cc2ac8b)), closes [#173](#173) [#184](#184)
* **stats:** Intent to ship stats ([bc163b9](bc163b9)), closes [#928](#928)
* **text,Options:** Add new data.labels.position option ([51b09d7](51b09d7)), closes [#57](#57) [#99](#99)
* **theme:** Add new 'graph' theme ([014537a](014537a)), closes [#631](#631) [#647](#647)
* **theme:** Intent to ship css theme ([e113278](e113278)), closes [#241](#241) [#507](#507)
* **title:** Intent to ship multilined title ([#731](#731)) ([171df89](171df89)), closes [#612](#612) [#727](#727)
* **tooltip:** Implement tooltip.order ([db7d0f8](db7d0f8)), closes [#127](#127) [#131](#131)
* **tooltip:** Intent to ship linked tooltip with name ([ae263a1](ae263a1)), closes [#401](#401) [#402](#402)
* **tooltip:** Intent to ship tooltip.contents.template ([c1af5df](c1af5df)), closes [#813](#813)
* **tooltip:** Intent to ship tooltip.contents.text ([c16ab48](c16ab48)), closes [#826](#826)
* **tooltip:** Intent to ship tooltip.doNotHide ([81e2f09](81e2f09)), closes [#812](#812)
* **zoom:** Add option to zoom by dragging ([da2ce10](da2ce10)), closes [#416](#416) [#508](#508) [#513](#513)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants