Source: plot/templates/PlotlyTimeLinePlot.js

import { merge, mergeWith } from "lodash";

import { PlotlyVefPlot } from "./PlotlyVefPlot.js";
import { LodashCustomizer } from "../utils.js";
export { PlotlyTimeLinePlot };


/**
 * Represents a plot configuration using Plotly with additional features for filtering.
 * @extends PlotlyVefPlot
 */
class PlotlyTimeLinePlot extends PlotlyVefPlot {

    /**
     * Constructs a new time line plot object.
     * @param {HTMLElement} graphDiv - The HTML element representing the graph container.
     * @param {Array} [data=[]] - The data to be plotted.
     * @param {Object} [layout={}] - The layout configuration for the plot.
     * @param {Object} [config={}] - The configuration options for the plot.
     */
    constructor(graphDiv, data = [], layout = {}, config = {}) {
        // Default values for data, layout, and config specific for time series plot
        const textColor = PlotlyVefPlot.getCssVariable('--text-color');
        const gridColor = PlotlyVefPlot.getCssVariable('--dark-surface-color');
        const tickColor = gridColor;
        const zeroLineColor = gridColor;
        const markerColorSelected = PlotlyVefPlot.getCssVariable('--secondary-color');
        const markerColorUnselected = '#676767';//'#333';
        const selectionColor = 'gray';

        const data2DTimeSeriesFilterDefault = [{
            mode: 'markers',
            marker: {
                color: markerColorSelected,
                size: 50, //use default size and symbol for best performance
                symbol: 'line-ns', //https://plotly.com/javascript/reference/scatter/#scatter-marker-symbol
                //maxdisplayed: 10, //no impact
            },
            type: 'scattergl',
            hoverinfo: 'x',
            unselected: {
                marker: {
                    color: markerColorUnselected,
                    opacity: 0.5,
                }
            }
        }];

        const layout2DTimeSeriesFilterDefault = {
            font: {
                color: textColor,
                family: 'PT Sans", sans-serif',
                size: '14px'
            },
            dragmode: 'select',
            selectdirection: 'h',
            height: 150,
            margin: {
                l: 0,
                r: 0,
                t: 50,
                b: 75
            },
            xaxis: {
                spikemode: 'across',
                //spikecolor: 'purple',
                tickwidth: 2,
                tickcolor: tickColor,
                //ticks: "inside",
                showgrid: true,
                showline: false,
                gridwidth: 2,
                gridcolor: gridColor
            },
            yaxis: {
                showspikes: false,
                showgrid: false,
                zeroline: true,
                zerolinecolor: zeroLineColor,
                zerolinewidth: 2,
                fixedrange: true,
            },
            newselection: {
                line: {
                    color: selectionColor,
                    dash: 'dash',
                    width: 2
                }
            }
        };

        const config2DTimeSeriesFilterDefault = {
            //scrollZoom: true,
            modeBarButtonsToAdd: ['select2d'],
            modeBarButtonsToRemove: ['toImage', 'Change Mode'], //'pan2d'
        };

        // Merge provided data, layout, and config with defaults
        const dataPreMerged = merge(data2DTimeSeriesFilterDefault, data);
        const layoutPreMerged = merge(layout2DTimeSeriesFilterDefault, layout);
        const configPreMerged = mergeWith(config2DTimeSeriesFilterDefault, config, LodashCustomizer.concatArrays);

        super(graphDiv, dataPreMerged, layoutPreMerged, configPreMerged);

        this.graphDiv.classList.add("vef-plot-filter");
    }

    /**
     * Filter the data based on the selected points inside the plot.
     * @param {Function} callback - Callback that is applied on data selection and deselection. 
     */
    filterData(callback) {
        this.getElement().on('plotly_selected', callback);
        this.getElement().on('plotly_deselect', callback);
    }
}