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

Problems when displaying tooltips of multiple series #65

Open
vitorbaptista opened this issue Mar 3, 2014 · 10 comments · Fixed by #66 · May be fixed by #152
Open

Problems when displaying tooltips of multiple series #65

vitorbaptista opened this issue Mar 3, 2014 · 10 comments · Fixed by #66 · May be fixed by #152

Comments

@vitorbaptista
Copy link
Contributor

Hi,

This is the problem I'm facing:

animation

Note that, even though there're two bars: Foo and Bar, the tooltip calls them Foo in both cases.

I reproduced this in a fiddle at http://jsfiddle.net/vitorbaptista/vPGH6/1/. It basically creates two series:

var values1 = [ ["Foo", 5] ];
var values2 = [ ["Bar", 10] ];

var options = {
  // Set up bars, set mode as category, etc. Nothing special.
};

var plotObj = $.plot( $("#bars"),
  [
      { data: values1, label: "Series 1"},
      { data: values2, label: "Series 2"}      
  ],
  options );

The problem comes from FlotTooltip.stringFormat, specially from https://github.com/krzysu/flot.tooltip/blob/master/js/jquery.flot.tooltip.js#L225-L229

// change x from number to given label, if given
if(typeof item.series.xaxis.ticks !== 'undefined') {
  if(item.series.xaxis.ticks.length > item.dataIndex && !this.isTimeMode('xaxis', item))
    content = content.replace(xPattern, item.series.xaxis.ticks[item.dataIndex].label);
}

What this does, AFAIK, is get the tick indexed at item.dataIndex's label and replace it at %x. The problem is that, in this case, item.dataIndex is always 0, because both values have a single data array. As the label at the tick indexed at 0 is Foo, this is what we get.

I couldn't understand why this code exists. At that point, the correct label is already in the x and y variables, configured in https://github.com/krzysu/flot.tooltip/blob/master/js/jquery.flot.tooltip.js#L175-L182.

Is this the expected behavior? Am I doing something wrong?

Thanks!

@krzysu
Copy link
Owner

krzysu commented Mar 6, 2014

Hi, that feature was written by one of the contributors (see v0.6.4 https://github.com/krzysu/flot.tooltip#v064), so I don't quite know what is that about.
Maybe here you can find some more info #18 or just ask @Lukindo or @LoicUV

@lmacko
Copy link
Contributor

lmacko commented Mar 6, 2014

The multiBar chart doesn't check whether you use same indexes on x-axis. It doesn't reorder the values or adds missing. That's why the plugin shows wrong labels.

The solutions I suggest:
-merge series to one [ ["Foo", 5],["Bar", 10] ]
-add missing elements to both series
var values1=[ ["Foo", 5],["Bar", 0] ]; var values1=[ ["Foo", 0],["Bar", 0] ]

ad Why that code exists,
yes, you're right the label is in x and y, however you have to somehow transfer the label value to format string (to the place where user want it to be shown)

@krzysu
Copy link
Owner

krzysu commented Mar 6, 2014

thank you @Lukindo for the answer!

@vitorbaptista
Copy link
Contributor Author

Hi all,

Thanks for your comments! They were very useful.

I think I might have found the solution. Basically, the problem is that we're using only item.dataIndex to find the current item. That works if there's a single series plotted, but will break apart if there're multiple series. The problem is that item.dataIndex is the index relative to the item's data only, which may (or may not) be all that's on the graph.

But the item also have item.seriesIndex. As far as I can see, to get the item's tick, we should be doing item.seriesIndex + item.dataIndex, and not only item.dataIndex.

In my previous example, we had two series:

var values1 = [ ["Foo", 5] ];
var values2 = [ ["Bar", 10] ];

The Foo item will end up with { dataIndex: 0, seriesIndex: 0, ... }, and Bar will have { dataIndex: 0, seriesIndex: 1, ... }, and the ticks array will be [ { label: "Foo", v: 0 }, { label: "Bar", v: 1 } ].

So, if we change the code to use item.dataIndex + item.seriesIndex, as in:

if(typeof item.series.xaxis.ticks !== 'undefined') {
    var index = item.dataIndex + item.seriesIndex;
    if(item.series.xaxis.ticks.length > index && !this.isTimeMode('xaxis', item))
        content = content.replace(xPattern, item.series.xaxis.ticks[index].label);
}

Everything works as expected.

I tested the same code but using the data from #18:

data: [ [0, 450], [1, 550], [2, 320], [3, 700] ],
xaxis: {
     ticks: [
       [0, "great"],
       [1, "greater"],
       [2, "greatest"]
     ]
}   

And everything worked fine as well. In this case, as there's only one series, every item's seriesIndex is 0.

Does it sound right? I'd be happy to submit a pull request with these changes if you agree.

@vitorbaptista
Copy link
Contributor Author

Ah! If that helps to debug this proposal, there's a jsfiddle with the updated code at http://jsfiddle.net/vitorbaptista/vPGH6/3/

@krzysu
Copy link
Owner

krzysu commented Mar 9, 2014

Hi, if you tested that both use cases work good, then just send pull request. Thanks!

vitorbaptista added a commit to vitorbaptista/flot.tooltip that referenced this issue Mar 10, 2014
We replace the "%x" in the tooltip string with the corresponding item tick's
label. We do so by looking at the item's index in the chart's data array
(dataIndex), and getting the tick in the same index in the ticks' array.
That works fine if you have a single series, but doesn't work with multiple
ones.

In that case, you have multiple data arrays, one for each series, but you still
have a single ticks array. For example, if you have the plot's data as:

[
  { data: [ ["Foo", 5] ] },
  { data: [ ["Bar", 10] ] }
]

Both item's dataIndex will be 0, because each one is the first element on its
series' data array. But the ticks array is something like:

["Foo", "Bar"]

If you use only dataIndex, you'll get the tick "Foo" for both items. What we
need is an offset which tells us which series the current item is in: that's
seriesIndex. The ticks' index is then calculated as ```seriesIndex +
dataIndex```.

That solves our problem. In our example, even though the dataIndex for both
items is 0, the seriesIndex for "Foo" is 0, and for "Bar" is 1. Everything
works as expected.

This fixes krzysu#65.
@Roundaround
Copy link
Collaborator

Reopened this issue because of the discussion on pull request #66.

@Roundaround Roundaround reopened this Aug 6, 2014
@michpetrov
Copy link

The fix expects the ticks of n-th series to be offset by n, that can work with series that form triangular matrices but not it in general. The code should be reverted and instead user should be required to supply series that are aligned into a matrix, e.g.

var values1 = [ ["Foo", 5], null ];
var values2 = [ null, ["Bar", 10] ];

@vitorbaptista
Copy link
Contributor Author

@michpetrov Could you create a jsfiddle showing an example where the current code breaks? You could edit http://jsfiddle.net/vitorbaptista/vPGH6/1/, but you'll need to update flot.tooltip's code there (as it's from before this patch was applied)

@michpetrov
Copy link

@vitorbaptista http://jsfiddle.net/vPGH6/17/

with a set of

var values1 = [ ["Foo", 5], ["Foobar", 6] ];
var values2 = [ ["Bar", 10] ];

the tickIndex for the last bar would have to be 2, but it is only 1.

Or maybe a better example would be

var values1 = [ ["Foo", 5], ["Bar", 6] ];
var values2 = [ ["Foo", 2], ["Bar", 3] ];

In this case item.dataIndex + item.seriesIndex doesn't make sense, since the series have no offset.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants