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

Line Chart - Data series without label for each point #12

Closed
prodatacon opened this issue Mar 18, 2013 · 96 comments
Closed

Line Chart - Data series without label for each point #12

prodatacon opened this issue Mar 18, 2013 · 96 comments
Assignees
Milestone

Comments

@prodatacon
Copy link

From the Line Chart documentation,

"The line chart requires an array of labels for each of the data points. This is show on the X axis."

I would like to be able to add a large set of data points to a line chart, but not have a label for each data point. For instance, showing the months of the year on the x axis but having several data points between January and February. I know the project is young, but would you agree this is a good direction to go? I feel the x axis labels and data set should be decoupled.

@ChrisAlvares
Copy link

Yes, or chart.js should have a way to hide data points based on width, kind of what like google charts does. For instance, displaying data for Jan 1-30, but the graph is only x pixels wide, it shows Jan 1-30, but skips every other date.

@ChrisAlvares
Copy link

@humdedum That is a pretty stupid comment. There is nothing wrong with feature enhancements, they should not be taken negatively, but positively by people being interested in @nnnick's projects. It gives him a good idea of what to improve for his users.

I plan on trying to contribute to this project, and reading some of these issues/feature enhancements gives me a good idea of what other people are thinking as well.

As for using "" as a label, that might work right now, but I am sure user interaction/tooltips will come soon, and that will not work when displaying default tooltip information.

@prodatacon
Copy link
Author

@humdedum I was suggesting decoupling x axis labels from data points because for a line chart, I imagine a greater percentage of use cases not requiring labels for each point than those that do. It seems inefficient from that regard. Since the project is young, I am trying to raise thought rather than rush to find a workaround.

@TheGAFF
Copy link

TheGAFF commented Mar 22, 2013

@humdedum but this suggestion will definitely improve this project. People pull data from databases all the time to draw these charts and the last thing they want to do is have to determine which labels stay and which labels go.

For example, if I pull an integer column for my data points and a date column for my labels in the database, I'm not going to want to have to filter out those date columns based on the width of the canvas and the number of points on my chart.

Not everyone creates static HTML pages. " :-)".

@r043v
Copy link

r043v commented Aug 13, 2013

i added a skipLabels option on .Line

r043v@6b2a9fd

@JonDum
Copy link

JonDum commented Feb 21, 2014

@r043v Looks good. Did you ever form a PR for that?

@nurpis
Copy link

nurpis commented Jun 23, 2014

@r043v This is definitely a welcome improvement, but how is skipLabels used? Adding "skipLabels : [int]" as an option does not make any change to the line chart or it's labels. Maybe I misunderstood your idea, documentation about it would be helpful.

@nnnick
Copy link
Member

nnnick commented Jun 29, 2014

Line charts are simply indexed across the x axis, so they need a label for each point.

A potentially better solution would be to create a .Series chart (maybe extending from Chart.types.Line) as an extension to the core library.

@nnnick nnnick closed this as completed Jun 29, 2014
@djensen47
Copy link

Is there an open issue for creating such "Series" chart?

@nnnick
Copy link
Member

nnnick commented Jul 26, 2014

Not as of yet, it is something I made a very brief start on in the past though.

I think it should probably live in it's own repo rather than this repo, so perhaps creating an issue here isn't the best idea. That way there could be alternate community run variants etc.

@hay-wire
Copy link

hay-wire commented Aug 6, 2014

I added showXLabels option for .Line and .Bar. A pull request has been raised at: #521 [ @nnnick ]

With it, you can set the number of labels to display on the X-Axis by passing the option {showXLabels: 10} where 10 is roughly the number of labels to be displayed.

Original Graph:
err-graph

Modified Graph with {showXLabels: 10} option:
great-graph

@loganfuller
Copy link

@humdedum I feel like you're missing the entire point of open source software. If contributors were silenced and "good enough" was accepted as the norm, we'd still be using Linus Torvald's (wonderful at the time) Linux 1.0. Hell, Github wouldn't even have a reason for existing.

As I'm dealing with very large numbers of data points (500+), a graphing library that requires labels is unusable as shown by @hay-wire's first graph above. I love the look of this library, and may try my hand at a PR as well.

@hay-wire
Copy link

hay-wire commented Aug 9, 2014

@loganfuller you can use skip-xlabels branch from my fork of Chart.js with showXLabels option:
https://github.com/hay-wire/Chart.js/tree/skip-xlabels
Hope it solves your problem.
However, I am thinking of fixing the label rotation as well when showXLabels is passed. I shall post an update here if I do it anytime around!

@nnnick
Copy link
Member

nnnick commented Aug 9, 2014

I think this isn't the right solution to this problem. The line charts in Chart.js are designed to handle index data, so just skipping the render of certain labels feels like a hacky solution.

What I propose as a better solution would be to define an x/y value for a point, then have Chart.js dynamically generate the x scale, similar to how the y scale is generated dynamically currently.

It'd require data in slightly different format, so that's why I propose another chart type for this. I think a lot of the base classes for points/bars/whatever could be reused, with an extension to/a new scale class providing this dynamic x/y functionality.

What do you guys think?

@ghost ghost mentioned this issue Sep 9, 2014
@larryb82
Copy link

If you want to hide the labels when there are too many, you can use the following extension. It just pushes the x-labels off the canvas so they are painted but not visible.

  Chart.types.Line.extend({
     name : "AltLine",

     initialize : function(data) {
        Chart.types.Line.prototype.initialize.apply(this, arguments);
        this.scale.draw = function() {
           if (this.display && (this.xLabelRotation > 90)) {
              this.endPoint = this.height - 5;
           }
           Chart.Scale.prototype.draw.apply(this, arguments);
        };
     }
  });

  // then
  new Chart(ctx).AltLine(data, options);

@sicktastic
Copy link

Love this chart.js. How can I configure it so the label is alway on by default without hovering it?

@trufa
Copy link

trufa commented Nov 4, 2014

There is a great hack here.

I quote:

For concreteness, let's say your original list of labels looks like:

["0", "1", "2", "3", "4", "5", "6", "7", "8"]

If you only want to display every 4th label, filter your list of labels so that every 4th label is filled in, and all others are the empty string (e.g. ["0", "", "", "", "4", "", "", "", "8"]).

@thealexbaron
Copy link

@nnnick, any news on this feature? I think a lot of people need it as it's pretty common to have a lot of data on your x-axis.

@luisrudge
Copy link

👍 i need this too

@kingharrison
Copy link

Very interested in this feature. I have a a graph I need to create with 1,000+ points across X. Do I use one of the hacked modules or is this coming into the main branch? Thanks for great software!

@luisrudge
Copy link

I'm using '' as labels

@sisou
Copy link

sisou commented Nov 21, 2014

The problem with using '' as labels is, that Graph.js still 'renders' them (although invisible). This means that the other, visible, labels are still angled against the axis, even though there is now enough room to render them horizontally (see @hay-wire comment and graphs above).
I would much rather prefer to define skipped labels as false and have the remaining labels render normally?

@sepehrooo
Copy link

screen shot 2014-11-26 at 3 55 14 pm

This is google analytics line chart. as you can see all the days are not labeled in the x axis but the data of each day is in the line chart, and if you hover on each Dot a tooltip will show the date & the Y value.
I think this is the best solution, if anyone can implement it. Other solutions like using '' as labels or skip labels are kinda hacky solutions.
@nnnick I think it's exactly what you were saying about this feature request.

Thanks again for your great project.

@r043v
Copy link

r043v commented Nov 27, 2014

@sepehr-y this is exactly what my skipLabels option do
skip labels

@kingharrison
Copy link

And can you skip labels altogether?

On Thursday, November 27, 2014, Sören Schwert notifications@github.com
wrote:

But can you still see the correct labels when you hover over a data point
whose label is skipped?
Sent using CloudMagic
On Thu, Nov 27, 2014 at 2:25 pm, noferi mickaël <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');>
wrote:@sepehr-y this is exactly what my skipLabels option do

—Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub
#12 (comment).

King Harrison IV

Executive Vice President
king4@k3s.com
Linkedin Profile https://www.linkedin.com/in/kingharrison/
877.725.1305 ext: 504
www.k3s.com

@davis
Copy link
Contributor

davis commented Dec 3, 2014

@r043v how do you use your skipLabels option? I'm also interested in this!

@saintedlama
Copy link

Fully agree with @nnnick that a Scale is the right solution and not a skip labels option to avoid chart.js growing to complex.

@saintedlama
Copy link

I created a gist that shows how to implement a series chart. The implementation is not perfect but working!

https://gist.github.com/saintedlama/05cc1663f3e38e06e2d7

@ehajri
Copy link

ehajri commented Jun 7, 2015

@etimberg, how do I specify the number of displayed X labels?

@etimberg
Copy link
Member

etimberg commented Jun 7, 2015

@ehajri We don't have a hard count on the number of labels. If you use a line chart in v2.0 it should behave exactly as a line chart in v1.0. We created the scatter chart that has a different x axis which dynamically adjusts the number of labels (not user settable at the moment). At the moment the x axis of the scatter chart only supports numerical data. We're going to write a date/time scale before 2.0 releases but it has not been done yet,

What kind of labels do you have? In the v2.0 config you can specify a user callback for each axis as

config: {
    scales: {
        xAxes: [{
            labels: {
                userCallback: function(tickValue, index, tickArray) { return "label string"},
           }
        }],
    }
}

You could return an empty string for no label. Does this help? Can you create a jsfiddle of your use case and I can try and give some better advice.

@ravau
Copy link

ravau commented Jul 14, 2015

Guys It was sa irritating I did it using two solutions and adding my hack ;)

  1. get @hay-wire solution Chart.js
  2. modify @qiaorancho solution like this:

Replace
//Allow 3 pixels x2 padding either side for label readability
var xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;

With:

if(this.showXLabels === true || this.showXLabels === false)
var xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;
else{
var gap = Math.floor(this.xLabels.length/this.showXLabels);
var _leftIndex = -1;
var _rightIndex = -1;
for (var i = 0; i < this.xLabels.length; i=i+gap) {//dynamic gap between labels based on labels/showxlabels
if (_leftIndex < 0 && this.xLabels[i]) {
_leftIndex = i;
continue;
}
if (_leftIndex >= 0 && this.xLabels[i]) {
_rightIndex = i;
break;
}
}
var xGridWidth = Math.floor(this.calculateX(_rightIndex) - this.calculateX(_leftIndex)) - 6;
}

Now pass the option:

showXLabels,

to get requested nr of labels! Or you can leave it false and it works original way

@yegong
Copy link

yegong commented Sep 14, 2015

The following snippet will hide labels automatically. By modify xLabels with empty string before invoke draw() and restore them after then. Even more, re-rotating x labels can be applied as there's more space after hiding.

var axisFixedDrawFn = function() {
    var self = this
    var widthPerXLabel = (self.width - self.xScalePaddingLeft - self.xScalePaddingRight) / self.xLabels.length
    var xLabelPerFontSize = self.fontSize / widthPerXLabel
    var xLabelStep = Math.ceil(xLabelPerFontSize)
    var xLabelRotationOld = null
    var xLabelsOld = null
    if (xLabelStep > 1) {
        var widthPerSkipedXLabel = (self.width - self.xScalePaddingLeft - self.xScalePaddingRight) / (self.xLabels.length / xLabelStep)
        xLabelRotationOld = self.xLabelRotation
        xLabelsOld = clone(self.xLabels)
        self.xLabelRotation = Math.asin(self.fontSize / widthPerSkipedXLabel) / Math.PI * 180
        for (var i = 0; i < self.xLabels.length; ++i) {
            if (i % xLabelStep != 0) {
                self.xLabels[i] = ''
            }
        }
    }
    Chart.Scale.prototype.draw.apply(self, arguments);
    if (xLabelRotationOld != null) {
        self.xLabelRotation = xLabelRotationOld
    }
    if (xLabelsOld != null) {
        self.xLabels = xLabelsOld
    }
};

Chart.types.Bar.extend({
    name : "AxisFixedBar",
    initialize : function(data) {
        Chart.types.Bar.prototype.initialize.apply(this, arguments);
        this.scale.draw = axisFixedDrawFn;
    }
});

Chart.types.Line.extend({
    name : "AxisFixedLine",
    initialize : function(data) {
        Chart.types.Line.prototype.initialize.apply(this, arguments);
        this.scale.draw = axisFixedDrawFn;
    }
});

Please notice that clone is an external dependency.

http://stackoverflow.com/a/32569127/837697

@mciparelli
Copy link

Any ideas when v2 will be out with this feature?

@tannerlinsley
Copy link
Contributor

v2.0-dev already has multiple ways of achieving this. Primarily, there is a built in auto-skip feature that will reduce labels as they overlap in most circumstances. You can also override the labels via a userCallback function that is used in the core scale class, or even override the entire scale.ticks array with whatever you want in a hook function. We're working on documentation for these new features right now.

@heisian
Copy link

heisian commented Oct 29, 2015

how??

@PixelAtLarge
Copy link

For those who are trying to get rid of the x-axis labels altogether, while retaining y-axis labels, I was able to achieve this with the following:

  • In chart data: labels: [""]
  • In chart options, add object.label = "ToolTipTitle"; before the line specifying the values that should be returned

@kelpycreek
Copy link

Any word on where the documentation for this can be found?

@piesrtasty
Copy link

Can you make the x axis time / date data with a scatter chart? I don't see anything in the docs about it.

@alexciesielski
Copy link

+1, docs pls

@FMolinan
Copy link

If it's of any help, I get the desired effect of reducing the numbers of objects in the X label by adding the following line:

Chart.defaults.scale.ticks.autoSkipPadding = X;

Where X is the padding you want between the values (and it will create an empty space accordingly), try adjusting the X value so it suits your needs.

@gentisaliu
Copy link

+1 It's a shame this feature request has been around for so long and nothing has been done.

@etimberg
Copy link
Member

@gentisaliu this is supported in v2 out of the box. See https://github.com/chartjs/Chart.js/blob/master/samples/scatter.html

@gentisaliu
Copy link

gentisaliu commented Aug 11, 2016

Thanks, I missed that. I tested it and it works, however is there a way to control the number of displayed labels/ticks in the X axis?

I want to display for instance at most 4 labels in the X axis, since any more than that they overlap and they get difficult to read.

@brianheilig
Copy link

Awesome job and thank you all. Is this also supported on bar charts for a series of dates? I can't seem to make this work.

@danielbronder
Copy link

This question is now a couple of years old. Is there in the current version a better solution to achieve this? I can not seem to make this work. Or is there some documentation where I can find this?

@sassomedia
Copy link
Contributor

What is the exact question? This is quite a thread with many questions/answers. As for the original question, you have a lot of control over labels in v2.x.x. Check out the callbacks in the scales documentation, afterTickToLabelConversion would probably best work or add a callback directly into the ticks configuration.

@pranjalrajputmf
Copy link

Use highcharts. i ended up doing the same.

@imran7404
Copy link

I have the same problem. I am creating a chart by dynamically assigning value to both labels and dataset. But at certain point, label are not showing. label data is generating but not showing.

@Tohnmeister
Copy link

Tohnmeister commented Jul 12, 2017

The use case I'm having (and I don't really see solved with any of the mentioned changes), is the following:

I have a dataset of 255 data samples. On my X axis though I only want to show 0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90%, 100% as the labels. And, obviously, these labels don't really match an exact sample in my data array. They're somewhere in between. E.g. 0% = 0, 10% = 25.5, etc.

The simplest solution would be if chart.js would not match the labels with the samples in case of a line chart, but simply would draw the lines and then draw the labels independently below the chart.

E.g. it would help if I could simply specify:
labels = ['0%', '50%', '100%'];
datasets = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]];

and chart.js would automatically divide the labels linearly through the data instead of matching them to the first three samples in my data.

@Hypenate
Copy link

+1
An suggestion can be that you place each unequal label a bit lower?

Like so:
L | L | L | L
L L L

@george-viaud
Copy link

A good solution would be if each data-point could be an object or array and contain an optional label

Example:

datasets: [{
    data: [1,2,3,4,5,[6,'Special Label'],7,8,9,10,[11,'Yet another labeled point']
}]

Or somesuch.

@nicholasess
Copy link

@george-viaud you need close expression with ]

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

No branches or pull requests