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

[FEATURE] Support multi-level (a.k.a hierarchical) category axis #4946

Closed
sarod opened this issue Nov 14, 2017 · 11 comments
Closed

[FEATURE] Support multi-level (a.k.a hierarchical) category axis #4946

sarod opened this issue Nov 14, 2017 · 11 comments

Comments

@sarod
Copy link

sarod commented Nov 14, 2017

Expected Behavior

Add support for displaying hierarchical categories.
An example of hierarchical category could be: Country > City
e.g:

  • USA
    • New York
    • San Francisco
  • Canada
    • Toronto
    • Vancouver

When displaying such hiearchical category on an axis it is interesting to display the axis similarly to what MS Excel does
See https://i.stack.imgur.com/CYp8Y.jpg for instance.

Current Behavior

With current version of chartjs we have to flatten the hierarchy and have category labels like this:

  • USA - New York
  • USA - San Francisco
  • Canada - Toronto
  • Canada - Vancouver

The problems with that solution is that:

  • there is a lot of repetition in the axis so this uses more space to display
  • repetition also prevents user from quickly identify the hierarchical nature of the categories.

Possible Solution

This could be implemented either by supporting this in the existing category axis or by having a dedicated axis.
To support this the configuration API could be modified to support hierarchical labels.
A label would be either a simple string or to supported child categories an object with label and children properties.
e.g.

xAxes: [{
    type: 'category',
	labels: [
          { label: 'USA', children: ['New York', 'San Francisco']}, 
          { label: 'Canada', children: ['Toronto', 'Vancouver']}],
}]

## Context
I originally posted a question on stack overflow for that and some additional context can be found there if needed.

@sarod
Copy link
Author

sarod commented Nov 19, 2017

Hi, I started looking at how this could be implemented as a plug-in.
I looked at the documentation of how to create new axes. http://www.chartjs.org/docs/latest/developers/axes.html

However from what I see in the documentation and in the code the extension point documented for scale are not flexible enough to implement what I need. So the plug-in would need to re-implement lot of what is implemented in Chart.Scale like the draw method right?

Also to get me started I copied the code from the core.category.js and registered it with an alternate name 'categoryHierarchical' however I didn't get the same rendering: the bars were not positioned between ticks but were centered on the ticks. However as soon as I renamed my category to 'category' the chart behaved properly so it seems that the type "category" has some hard coded behaviour attached to it side of the scale itself. Is there some way to fix this?

@etimberg
Copy link
Member

@sarod that's correct about the drawing code. You'll need to re-implement a lot of the draw code since there is so much different between the axes.

To see if there is any category axis hard codings I would try searching for "category" in the codebase. I did a quick search and didn't see much. Did you remember to change the default config for your new axis?

@sarod
Copy link
Author

sarod commented Nov 21, 2017

@etimberg thanks for the answer.

Regarding "category" specific behavior.
I found that configuring my xAxes with offset: true when using my category axis solves my layouting issue.
However when I register my axis I use the same defaults that are used to register the standard axis so I don't understand why I need this additional configuration.
I found that the chart types also declare some defaults so maybe those are the defaults that get applied when I use the built-in "category" axis. However I still don't understand why this chart defaults would be preserved for the standard "category" axis and not for my custom axis.

e.g. defaults declaration from controller.bar.js

defaults._set('bar', {
	hover: {
		mode: 'label'
	},

	scales: {
		xAxes: [{
			type: 'category',

			// Specific to Bar Controller
			categoryPercentage: 0.8,
			barPercentage: 0.9,

			// offset settings
			offset: true,

			// grid line settings
			gridLines: {
				offsetGridLines: true
			}
		}],

		yAxes: [{
			type: 'linear'
		}]
	}
});

Anyway this is certainly not blocking me from implementing the axis.

So thanks again for the answer I'll try to wrap my head around the draw method logic.

@etimberg
Copy link
Member

In terms of the category defaults from a chart default not merging, you might be hitting https://github.com/chartjs/Chart.js/blob/master/src/core/core.helpers.js#L51-L58 which was designed to prevent accidentally using the wrong settings if the axis type changes.

Is there anything I can answer about the draw logic?

@sarod
Copy link
Author

sarod commented Nov 23, 2017

Thanks for the pointer about settings merge.

The draw method is a big piece so I'll need to find time to familiarize before I ask questions. I'll let you know.

@dav-sap
Copy link

dav-sap commented Feb 1, 2018

hey @sarod,
is there any progress with this feature? Iv'e been looking for something like this for some time

@sarod
Copy link
Author

sarod commented Feb 2, 2018

@dav-sap, No I didn't make any progress so far.
Implementing this is more involved than what I initially thought as most of the drawing logic needs to be rewritten.

@sarod
Copy link
Author

sarod commented Mar 13, 2018

FYI I don't use chartjs anymore so I don't plan to work on this anymore.

@sgratzl
Copy link
Contributor

sgratzl commented Jun 27, 2018

our implementation: https://github.com/datavisyn/chartjs-scale-hierarchical

hierarchy

see also https://codepen.io/sgratzl/pen/vrVXae

@kocil
Copy link

kocil commented Jul 10, 2018

Just want to make a compliment,
sgratzl's solution solves this issue and more.

  • stacked bar : yes
  • multiple-level labels : yes
  • interactive : that's more than excel 👍

@etimberg
Copy link
Member

There is a plugin that supports this https://github.com/sgratzl/chartjs-plugin-hierarchical

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

5 participants