dygraphs
dygraphs copied to clipboard
"connectSeparatedPoints:true" produces "undefined" in legend for missing values.
The example "Connect-Separated" displays this problem very clearly: http://dygraphs.com/tests/connect-separated.html
If you click the toggles at the bottom to set them to "true," you get "undefined" for any point that is missing data in the graph.
I am seeing this on my own pages using the 2.0.0 version (same as here). However, my own pages work fine if I go back to the 1.1.1 code.
Repro: https://jsfiddle.net/eM2Mg/9541/
The JSFiddle (above) shows the problem. Line 3 of the data has a missing (null) "Z" data point. Moving the mouse over the graph at that point shows "undefined" in the legend for the "Z" value. Previously, it just wouldn't display anything for a null value.
I reported this bug almost 2 months ago, but there has been no acknowledgement of the bug yet.
The bug has been acknowledged. There's generally no SLA for volunteer-driven open source projects.
I've stumbled into this problem too. I've realized that the problem is present only when the datasource is a js obj, not in case the graph is populated via CSV.
Any news about a workaround?
I've stumbled into this problem too. I've realized that the problem is present only when the datasource is a js obj, not in case the graph is populated via CSV.
This is happening to me but with a CSV source as well. For example:
2019-02-21 21:34:29,,99.62,
2019-02-21 22:24:28,87.49,,
If you have a valueFormatter
it's not even being called, so apparently you cannot manually fix this.
I had the same problem. I could work around it by filling up my input data to not contain any null
values. I did this by filling up the missing values with the last "known" value, i.e. creating a stair function but interpolation will work as well. However, I am not plotting the original data anymore but this was fine for the project.
I just also had the exact same problem and couldn't workaround it. A fix would be very welcome. Why not just calling valueFormatter in any case, maybe with a separate option 'callValueFormatterForUndefinedValues' defaulting to false for backwards compatibility?
*** English version below ***
Sehr geehrte Damen und Herren,
ich bin bis einschließlich zum 11. September 2019 nur eingeschränkt per E-Mail und Telefon erreichbar. Ihre E-Mails werden nicht weiter geleitet. In dringenden Fällen kontaktieren Sie bitte meinen Kollegen Daniel Rech ([email protected] , +491626477725).
Vielen Dank für Ihr Verständnis.
Mit freundlichen Grüßen
Michael Kreim
*** English ***
Dear Sir or Madam,
Thank you for your message.
I am currently out of the office and will be back on 12th September 2019. Your e-mail will not be forwarded. In urgent cases please contact my colleague Daniel Rech ([email protected] , +491626477725). Thank you very much.
Kind regards,
Michael Kreim
This is fairly easy to solve using legendFormatter. Check for missing values in your callback and handle them how you see fit.
Based on what CameronSinclair84 said, I did some test and indeed that function is what renders the whole legend line, instead of just each series' value. So if you overwrite it, you will have to include several lines of code to achieve the exact same default output. I wouldn't call that 'fairly easy'. ;)
I took a look at the code in http://dygraphs.com/2.1.0/dygraph.js and found where the problem lies. In the Legend.defaultFormatter
function, near the end, you have to replace + series.yHTML +
with + (series.yHTML || "") +
(or whatever you want to be displayed instead of "undefined").
So you either fix the source JS file, or copy the whole function, fix it and add it in options.legendFormatter
.
I also tried to find a fix where yHTML
is set instead (function Legend.generateLegendHTML
), which theoretically is a call to valueFormatter
, but that function is indeed not called in this scenario, so I'm not sure what's going on there.
PS: You have a very short (and probably buggy) version for legendFormatter
here, where this feature was requested.
What I mean is you can pass in a callback function as an option in the options block to handle this.
Read here under legendFormatter: http://dygraphs.com/options.html#Legend
My callback looks like this:
legendFormatter(data: any) { if (data.x == null) { return data.series.map(element => { return '<span style="font-weight:bold; color:' + element.color + ';">' + '<div class="dygraph-legend-line" style="border-bottom-color:' + element.color + ';"></div>' + ' ' + element.labelHTML + '</span><br>'; }).join(' '); } else { return data.xHTML + '<br>' + data.series.map(element => { if (element.yHTML) { return '<span style="font-weight:bold; color:' + element.color + ';">' + '<div class="dygraph-legend-line" style="border-bottom-color:' + element.color + ';"></div>' + ' ' + element.labelHTML + ': ' + element.yHTML + '</span><br>'; } }).join(' '); } }
Or if you would rather replace the undefined with a dash for example:
legendFormatter(data: any) { if (data.x == null) { return data.series.map(element => { return '<span style="font-weight:bold; color:' + element.color + ';">' + '<div class="dygraph-legend-line" style="border-bottom-color:' + element.color + ';"></div>' + ' ' + element.labelHTML + '</span><br>'; }).join(' '); } else { return data.xHTML + '<br>' + data.series.map(element => { return '<span style="font-weight:bold; color:' + element.color + ';">' + '<div class="dygraph-legend-line" style="border-bottom-color:' + element.color + ';"></div>' + ' ' + element.labelHTML + ': ' + (element.yHTML ? element.yHTML : '-') + '</span><br>'; }).join(' '); } }
Well, I was also talking about specifying a function in options.legendFormatter
to override the default one. I like your approach with the lines in the legend. Here is my simplified (improved?) version:
// options go here. See http://dygraphs.com/options.html
{
legend: 'always',
animatedZooms: true,
title: 'dygraphs chart template',
connectSeparatedPoints: true,
legendFormatter: function(data) {
return data.series.map(element => {
return `<span style="font-weight:bold; color:${element.color};"><div class="dygraph-legend-line"></div> ${element.labelHTML}: ${element.yHTML || '-'}</span>`;
}).join('<br/>');
}
});
You can see it in action here: https://jsfiddle.net/6q3wkna4/
PR was merged