How to determine the best Plotly chart type programmatically based on dataset characteristics?

Discussão em 'Angular' iniciado por Alphonsa John, Fevereiro 4, 2025.

  1. import { Directive, ElementRef, Input, OnInit, Renderer2 } from '@angular/core';
    import { UtilsService } from '../services/utils.service';
    import Plotly from 'plotly.js-dist-min';

    @Directive({
    selector: '[appDynamicPlotly]'
    })
    export class DynamicPlotlyDirective implements OnInit {
    @Input() public data: any;
    @Input() public group: string = 'Month';
    protected plot: any;
    private currentType: string = 'bar'; // Default plot type
    private currentMode: string = ''; // Default plot type

    constructor(private elementRef: ElementRef, private utilsService: UtilsService, private renderer: Renderer2) {}

    ngOnInit() {
    this.plot = this.elementRef.nativeElement;
    this.renderPlot();
    }

    private renderPlot() {
    const trace: any = this.getTrace();

    const layout: Partial<Plotly.Layout> = this.getLayout();

    const config: Partial<Plotly.Config> = {
    responsive: true,
    displayModeBar: false,
    displaylogo: false
    };

    Plotly.react(this.plot, trace, layout, config);
    }

    private getTrace() {
    switch (this.currentType) {
    case 'pie':
    return [
    {
    labels: this.data[this.group], // Grouped data as labels
    values: this.data.storage_state_kg, // Corresponding values
    type: 'pie',
    // textinfo: 'label+percent',
    textposition: 'outside',
    automargin: true,
    marker: { colors: ['#046CC4', '#F066AC', '#3C8454', '#64323A', '#182D44'] },
    hovertemplate: '%{label}<br>H₂ Production: %{value}<extra></extra>'
    }
    ];
    case 'line':
    return [
    {
    x: this.data[this.group],
    y: this.data.storage_state_kg,
    type: 'scatter',
    mode: 'lines',
    name: 'H₂',
    line: { color: '#046CC4', width: 2 },
    hovertemplate: '%{x}<br>H₂ Production: %{y}<extra></extra>'
    }
    ];
    case 'scatter':
    return [
    {
    x: this.data[this.group],
    y: this.data.storage_state_kg,
    type: 'scatter',
    mode: 'markers',
    name: 'H₂',
    marker: { color: '#046CC4', size: 8 },
    hovertemplate: '%{x}<br>H₂ Production: %{y}<extra></extra>'
    }
    ];
    case 'waterfall':
    return [
    {
    x: this.data[this.group],
    y: this.data.storage_state_kg,
    type: 'waterfall',
    name: 'H₂',
    measure: Array(this.data.storage_state_kg.length).fill('relative'),
    connector: { line: { color: '#7F7F7F' } },
    hovertemplate: '%{x}<br>H₂ Production: %{y}<extra></extra>',
    increasing: { marker: { color: '#046CC4' } },
    decreasing: { marker: { color: '#E74C3C' } },
    totals: { marker: { color: '#2ECC71' } }
    }
    ];
    case 'bar':
    default:
    return [
    {
    x: this.data[this.group],
    y: this.data.storage_state_kg,
    type: 'bar',
    name: 'H₂',
    marker: { color: '#046CC4' },
    hovertemplate: '%{x}<br>H₂ Production: %{customdata}<extra></extra>',
    customdata: this.data.storage_state_kg.map((val: number) =>
    Number.isInteger(val) ? val.toFixed(0) : val.toFixed(3)
    )
    }
    ];
    }
    }

    private getLayout(): Partial<Plotly.Layout> {
    if (this.currentType === 'pie') {
    return {
    title: {
    text: 'Dynamic Plot',
    font: { size: 14 },
    x: 0.5,
    xanchor: 'center'
    },
    showlegend: true,
    margin: { t: 50, b: 50, l: 60, r: 70 },
    plot_bgcolor: '#F8F8F8',
    paper_bgcolor: '#F8F8F8'
    };
    } else {
    return {
    title: {
    text: 'Dynamic Plot',
    font: { size: 14 },
    x: 0.5,
    xanchor: 'center'
    },
    xaxis: {
    tickmode: 'array',
    tickvals: this.data[this.group],
    ticktext: this.data[this.group].map((val: any) =>
    this.utilsService.getDateTextForChart(val, this.group)
    ),
    tickfont: { size: 14, color: '#000000' },
    showgrid: true,
    tickangle: 0
    },
    yaxis: {
    title: {
    text: 'H₂ Storage State (MT H₂)',
    font: { size: 16, color: '#000000' },
    standoff: 30
    },
    tickfont: { size: 14, color: '#000000' },
    showgrid: false,
    rangemode: 'tozero'
    },
    dragmode: undefined,
    barmode: this.currentType === 'bar' ? 'stack' : undefined,
    margin: { t: 50, b: 50, l: 60, r: 70 },
    bargap: 0.7,
    plot_bgcolor: '#F8F8F8',
    paper_bgcolor: '#F8F8F8'
    };
    }
    }

    changePlotType(type: string, mode: string) {
    this.currentType = type; // Update the plot type
    this.currentMode = mode; // Update the plot type
    this.renderPlot(); // Re-render the plot with the new type
    }
    }


    I'm working on a project using Plotly and Angular, where I need to allow users to switch between different chart types dynamically (e.g., bar, pie, scatter, waterfall, etc.).

    Here I'm manually providing a few options that supports array type for x&y. Instead of this, is there any external library, plugin, or built-in feature in Plotly that can suggest appropriate chart types based on the structure or type of the dataset? For example, if the data is categorical vs. numerical, the tool should recommend bar or pie charts.

    Continue reading...

Compartilhe esta Página