Skip to content

Unable to customize datetime format on hover info labels. #469

@jmussett

Description

@jmussett

We have a requirement to display sub-second timestamps in the hover info labels that are displayed on the plots. Unfortunately DateTimeConverter.cs has no way of changing the datetime format.

Currently, we're having to use reflection to override the JsonSerializerOptions used for plotting by doing the following:

public static class PlotlyExtensions
{
    public static async Task NewPlot(this PlotlyChart plotlyChart, JsonSerializerOptions serializerOptions)
    {
        var interopProperty = typeof(PlotlyChart)
            .GetProperty("Interop", BindingFlags.NonPublic | BindingFlags.Instance)
            ?? throw new InvalidOperationException("Could not find 'Interop' on PlotlyChart.");

        var plotlyInterop = interopProperty.GetValue(plotlyChart)!;

        var moduleTaskField = plotlyInterop
            .GetType()
            .GetField("moduleTask", BindingFlags.NonPublic | BindingFlags.Instance)
            ?? throw new InvalidOperationException("Could not find 'moduleTask' on PlotlyJsInterop.");

        var moduleTaskValue = (Lazy<Task<IJSObjectReference>>) moduleTaskField.GetValue(plotlyInterop)!;

        var jsRuntime = await moduleTaskValue.Value.ConfigureAwait(false);

        await jsRuntime.InvokeVoidAsync(
            "newPlot",
            plotlyChart.Id,
            plotlyChart.Data?.Select(trace => trace?.PrepareJsInterop(serializerOptions)),
            plotlyChart.Layout?.PrepareJsInterop(serializerOptions),
            plotlyChart.Config?.PrepareJsInterop(serializerOptions),
            plotlyChart.Frames?.PrepareJsInterop(serializerOptions)
        );
    }

    // Addition extensions for PrepareJsInterop and PrepareJsonElement, which are also internal.

}

Our solution is very brittle as it can potentially break following any subsequent version of Plotly.Blazor that is released.

My recommendation is to move the SerializationOptions from PlotlyJsInterop to PlotlyChart exposing it publically, allowing it to be overriden. You could then access those options in PlotlyJsInterop via the PlotlyChart object reference.

Passing the serialization options as an optional parameter into NewPlot() could also be an option, but you may have to extend that to other methods that also use those settings.

Let me know your thoughts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions