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

Add donut chart pattern #200

Merged
merged 9 commits into from Nov 30, 2017
Merged

Add donut chart pattern #200

merged 9 commits into from Nov 30, 2017

Conversation

jiekang
Copy link
Contributor

@jiekang jiekang commented Nov 22, 2017

This adds the donut chart pattern addressing one half of issue #180

The patterns closely follow the angularJS versions:
http://www.patternfly.org/angular-patternfly/#/api/patternfly.charts.component:pfDonutChart

Notable differences:

  • similar to the patternfly-ng sparkline pattern, previously stand-alone options like chartHeight are moved under the config as for example config.chartHeight or config.centerLabel

A demo via rawgit is available via:
http://rawgit.com/jiekang/patternfly-ng/donut-chart-dist/dist-demo/#/donut

Thoughts?

@joshuawilson
Copy link
Member

I think a lot of those commits can/should be squashed. A commit should be a change, if it takes you several commits to get it right but they are all the same thing then condense them. It keeps the change atomic.

@jiekang jiekang changed the title Add donut and donut-pct chart patterns Add donut chart pattern Nov 22, 2017
@jiekang
Copy link
Contributor Author

jiekang commented Nov 22, 2017

Okay. I've squashed the commits and following comments in #180 only included the donut chart pattern for this PR.

@dlabrecq
Copy link
Member

dlabrecq commented Nov 22, 2017

Ideally, these components should be separate PRs -- it's a bit much to review at once.

If there are two components, they should have their own examples. Tabs can be used to show variations of that example.

Please include a link to a working example. A screenshot is also very helpful. I can download and build your code, but others (designers) will need to review.

There are instructions in the contribution guide for how to setup Travis to generate an example for you.

@jiekang
Copy link
Contributor Author

jiekang commented Nov 22, 2017

I'd like to setup Travis to generate an example for me. The contribution guide states:

You will also need to add an AUTH_TOKEN variable to Travis generated in your GitHub account to allow Travis to connect to your fork.

Do you have more detailed instructions on how to accomplish this? My Travis build fails as it's not authorized to push to my repository.

In the meantime I've attached a link to a screenshot of the donut example page:

Screenshot

@sahil143
Copy link
Member

@jiekang
Travis Build
You can follow this step by step guide to add AUTH_TOKEN to Travis. Remember, you need to do this for Patternfly-ng instead of Patternfly-webcomponents.

@jiekang
Copy link
Contributor Author

jiekang commented Nov 23, 2017

@sahil143 Thank you!

@jiekang
Copy link
Contributor Author

jiekang commented Nov 23, 2017

@dlabrecq
Copy link
Member

Does the donut chart provide the ability to add horizontal and vertical labels like the Angular PatternFly example?

@jiekang
Copy link
Contributor Author

jiekang commented Nov 24, 2017

@dlabrecq
I don't see any mention of horizontal or vertical labels in the API [1] or source [2] for donut charts.
[1] http://www.patternfly.org/angular-patternfly/#/api/patternfly.charts.component:pfDonutChart
[2] https://github.com/patternfly/angular-patternfly/blob/master/src/charts/donut/donut-chart-component.js

For context, the code is as close to a 1 to 1 transform of js to ts and angularjs to angular that tries to follow the style of the sparkline chart that's already in patternfly-ng. The only major differences are:

  • Does not have dataAvailable html guard to switch display to pf-empty-chart. I don't think this element exists yet in patternfly-ng
  • Uses the EventEmitter provided by ChartBase to access chart when it's available. The angularjs version accesses chart directly.
  • Merges defaults on config and config.donut as the defaults function is not recursive and donut contains default configuration that we'd like to keep. Otherwise a user setting the title via donut.title will lose all default configuration in config.donut. In angularjs it seems the merge is recursive as this problem isn't seen with the exact same example.

In general, there should be no functional difference between the angular and angularjs versions of the donut chart. At least that's what I intended.

I see a labelConfig in the donut-pct API [3]. Is that what you are referring to? It is not available in the donut chart.
[3] http://www.patternfly.org/angular-patternfly/#/api/patternfly.charts.component:pfDonutPctChart

@dlabrecq
Copy link
Member

The labels I'm referring to in the Angular PatternFly donut chart example below are; Cats, Hamsters, Fish, and Dogs.

screen shot 2017-11-25 at 12 03 13 am

@jiekang
Copy link
Contributor Author

jiekang commented Nov 27, 2017

Ah, yes users can add a legend. In general, users can add c3 configuration in the same manner as before (which is how the legend is added in the angularjs example).

@dlabrecq Would you like me to modify the angular example to include exactly the two that you showed?

@dlabrecq
Copy link
Member

Yes, please do. Need to ensure the examples can demonstrate feature parity with APF.

@jiekang
Copy link
Contributor Author

jiekang commented Nov 27, 2017

@dlabrecq Okay, done.

Looks like the rawgit has automatically updated and the result can be viewed there.

Copy link
Member

@dlabrecq dlabrecq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the example to show tooltips like Angular PatternFly.

/**
* An optional function to customize the text of the center label
*/
centerLabelFn?: any;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, we want to stay away from callback functions. Instead, this can be a simple centerLabel property.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to centerLabel property.

/**
* An optional function to handle when donut is clicked
*/
onClickFn?: any;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a callback function, we would like to have an onClick event in the component.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This onClickFn mirrors angular-patternfly and would be an API difference between angular-patternfly and patternfly-ng if changed, is that okay? My approach was to keep things one to one such that anyone deciding to port from one to the other would not have to make any config changes due to incompatibilities. However I realize angularjs and angular are completely different projects so this might not be a concern for this project.

I don't understand what an "onClick event in the component" means, could you elaborate?

Copy link
Member

@dlabrecq dlabrecq Nov 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's ok to be different from APF. This is our opportunity to clean things up.

Instead of calling a function when the donut is clicked, we emit an event. A developer can easily subscript to the event like so:

<pfng-donut-chart (onClick)="myFunction($event)"...

Then, in the component we would have something like this:

/**
 * The event emitted when an item has been clicked
 */
@output('onClick') onClick = new EventEmitter();

And some method to handle the click:

handleClick($event: MouseEvent): void {
  this.onClick.emit({
    item: item
  } as ListEvent);
}

/**
* C3 inherited configuration for colors
*/
colors?: any;
Copy link
Member

@dlabrecq dlabrecq Nov 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear what "colors" is. Please add an example to the comments? For example:

'colors' : {
  'Cats': '#0088ce', // blue
  'Hamsters': '#3f9c35', // green
  'Fish': '#ec7a08', // orange
  'Dogs': '#cc0000' // red
}

I wonder if a typed object may help here?

colors?: Color;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the comment with an example. I'm reluctant to add a typed object for c3 inherited configuration as it mimics c3 configuration exactly. Maybe a link to the c3 API that it's intended to match would work for all c3 inherited configuration?

@@ -0,0 +1 @@
<div #chartElement id="{{donutChartId}}"></div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to create the pf-empty-chart for the no data available use case. This is an integral part of the component HTML layout in Angular Patternfly. It should be a very simple component -- please let me know if you need help with that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it('should setup onclick correctly', () => {
expect(typeof(comp.config.data.onclick)).toBe('function');
});
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are a great start.

In addition to these tests, I would like to see a couple tests ported from donut-pct.spec.js. For example, anything that tests the label would be very useful here. The donut-pct tests seem to share a lot in common with donut.

@@ -20,6 +20,7 @@ import { SearchHighlightExampleComponent }
import { SortExampleComponent } from '../app/sort/examples/sort-example.component';
import { SortArrayExampleComponent } from '../app/pipe/sort-array/examples/sort-array-example.component';
import { SparklineExampleComponent } from '../app/chart/sparkline/examples/sparkline-example.component';
import { DonutExampleComponent } from '../app/chart/donut/examples/donut-example.component';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alphabetical order please

Copy link
Contributor Author

@jiekang jiekang Nov 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Thoughts on adding ordered-imports and the like to enforce tslinting of alphabetical order as a separate issue/PR? Also I noticed tslint was updated from 4.x to 5.x and the tslint config file contains unsupported configuration for member-ordering. It doesn't seem to break anything but I think a fix would be good for those using editors that read from the config file to show tslint warnings.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it would be good to fix this. A separate PR would probably be best.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The member-ordering seems to be working; for example, if I add a private method before a public one. Although, it's possible that config could be deprecated?

Unfortunately, none of that enforces import ordering, just fields, methods, and constructors. However, I did find adding this does the trick:

"ordered-imports": true,

@@ -85,6 +86,9 @@ const routes: Routes = [{
}, {
path: 'sparkline',
component: SparklineExampleComponent
}, {
path: 'donut',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alphabetical order please

@@ -37,6 +37,9 @@ <h3>Components</h3>
<li>
<a routerLink="/sparkline" routerLinkActive="active">Sparkline</a>
</li>
<li>
<a routerLink="/donut" routerLinkActive="active">Donut</a>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alphabetical order please

@@ -55,6 +56,7 @@ import { NavigationExampleModule } from '../app/navigation/examples/navigation-e
SortArrayExampleModule,
SortExampleModule,
SparklineExampleModule,
DonutExampleModule,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alphabetical order please

@@ -27,6 +27,7 @@ import { SearchHighlightExampleModule } from '../app/pipe/search-highlight/examp
import { SortArrayExampleModule } from '../app/pipe/sort-array/examples/sort-array-example.module';
import { SortExampleModule } from '../app/sort/examples/sort-example.module';
import { SparklineExampleModule } from '../app/chart/sparkline/examples/sparkline-example.module';
import { DonutExampleModule } from '../app/chart/donut/examples/donut-example.module';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alphabetical order please

Observable
.timer(0, 5000)
.map(() => Math.floor(Math.random() * 100) + 100)
.subscribe(val => this.config2.chartHeight = val);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very cool, but can we add this as a separate example? For example, have a "Basic" and "Dynamic" tabs similar to other component examples.

Sometimes my tooltip disappears as I'm attempting to hover and the data changes under me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an example, we could have examples named donut-basic-example.component.ts and donut-dynamic-example.component.ts...

Copy link
Member

@dlabrecq dlabrecq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dlabrecq dlabrecq merged commit be620bf into patternfly:master Nov 30, 2017
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 this pull request may close these issues.

None yet

4 participants