humangeo / leaflet-dvf

Leaflet Data Visualization Framework
MIT License
689 stars 152 forks source link

Problem with Legend/displayOptions/StylesBuilder #106

Closed joakimkejser closed 7 years ago

joakimkejser commented 7 years ago

Hi,

I'm having a few issues with the styles as well as the related legend when using multiple displayOptions and the L.StylesBuilder. In particular, the order in which i specify my displayOptions influence the result I get, where each covers only a portion of what I'm trying to achieve.

I use a L.Graph to map from-to flows. I size the weight of the line by one property (continuous variable), and color the line based on its origin (categorical variable). For the latter, I use the L.StylesBuilder to handle the categorical nature of my variable.

My setup is as follows:

var colorFunction1 = new L.CustomColorFunction(0, _.uniq(_.pluck(data, "from_id")).length - 1, L.ColorBrewer.Qualitative.Dark2[7]);

displayNameFunction = function(index){
    return ["Name1", "Name2"][index];
}

var styles = new L.StylesBuilder(_.uniq(_.pluck(data, "from_id")), {
    color: colorFunction1,
        fillColor: colorFunction1,
        displayName: displayNameFunction
    });

I set the className of legendOptions to 'legend-line' and use the same CSS styles as in the airline example. Given the displayOptions in the following order:

 displayOptions: {
     "from_id": {
       displayName: "From",
       styles: styles.getStyles(),
       excludeFromTooltip: true
     },
     "Gw": {
       weight: new L.LinearFunction([0, 1.25], [_.max(data, function(d){ return d.Gw; }).Gw, 5]),
       displayName: "Gross Weight",
       displayText: function(x) {
         return Math.round(x).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " kg";
       }
     }
 }

I get the legend like this: image

My categorical variable how somehow inherited the displayName from the "Gw" property, and not the displayName I set through the L.StylesBuilder.

Now, if I reverse the order I specify the displayOptions:

 displayOptions: {
     "Gw": {
       weight: new L.LinearFunction([0, 1.25], [_.max(data, function(d){ return d.Gw; }).Gw, 5]),
       displayName: "Gross Weight",
       displayText: function(x) {
         return Math.round(x).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " kg";
       }
     },
     "from_id": {
       displayName: "From",
       styles: styles.getStyles(),
       excludeFromTooltip: true
     }
 }

I get the following, "correct" legend. image

However, now my lines in L.Graph no longer get the weight sized dynamically by the "Gw" property.

Am I doing something wrong? Have I missed something obvious?

joakimkejser commented 7 years ago

Just to clarify, this also happens with a L.DataLayer.

Don't want L.Graph getting any unwarranted blame!

sfairgrieve commented 7 years ago

@joakimkejser Thanks for pointing this out. I'll investigate.

sfairgrieve commented 7 years ago

Still trying to figure this one out. Definitely an interesting one! ;)

sfairgrieve commented 7 years ago

I think I figured it out. I'm still testing the fix to make sure it doesn't affect anything else. When it's at a good point, I'll push the code to a new branch and let you try it out just to make sure it solves your issue.

sfairgrieve commented 7 years ago

@joakimkejser I think the feature/styles-fix branch may fix this problem. Can you take a look when you get a chance and see if it works for you?

joakimkejser commented 7 years ago

@sfairgrieve I'll take a look at it during today. Thanks for spending time on this!

joakimkejser commented 7 years ago

@sfairgrieve This fixes my problem! It does not matter which order I specify my displayOptions, and all "effects" are preserved both ways. Cheers!

When do you expect to merge this and the other fixed issues (tooltips) into 1.0dev?

sfairgrieve commented 7 years ago

Great! I'll merge this/other fixes later today/tonight. Thanks for testing and continuing to help find and resolve these issues.