<commit_before>import {
    Autowired,
    Component,
    IComponent,
    MenuItemDef,
    PostConstruct,
    RefSelector,
    Dialog,
    PopupService,
    GridOptionsWrapper,
    ChartType
} from "ag-grid-community";
import { MenuItemMapper } from "../menu/menuItemMapper";
import { MenuList } from "../menu/menuList";
import { MenuItemComponent } from "../menu/menuItemComponent";
import {IGridChartComp} from "./gridChartComp";

export class ChartMenu extends Component {

    private static TEMPLATE =
        `<div class="ag-chart-menu">
            <span ref="eChartMenu" class="ag-icon-menu"></span>
        </div>`;

    @RefSelector('eChartMenu') private eChartMenu: HTMLElement;

    private chart: Component;

    constructor(chart: Component) {
        super(ChartMenu.TEMPLATE);
        this.chart = chart;
    }

    @Autowired('popupService') private popupService: PopupService;

    @PostConstruct
    private postConstruct(): void {
        this.addDestroyableEventListener(this.eChartMenu, 'click', () => this.showMenu());
    }

    private showMenu(): void {
        const menu = new Menu(this.chart);

        this.getContext().wireBean(menu);

        const hidePopup = this.popupService.addAsModalPopup(
            menu.getGui(),
            true,
            () => menu.destroy.bind(this)
        );

        this.popupService.positionPopupUnderComponent(
            {
                type: 'chartMenu',
                eventSource: this.eChartMenu,
                ePopup: menu.getGui(), keepWithinBounds: true
            });

        menu.addDestroyFunc(() => hidePopup());
    }
}

class Menu extends Component implements IComponent<any> {

    @Autowired('gridOptionsWrapper') private gridOptionsWrapper: GridOptionsWrapper;
    @Autowired('menuItemMapper') private menuItemMapper: MenuItemMapper;

    private chart: Component;

    constructor(chartMenu: Component) {
        super('<div class="ag-menu"></div>');
        this.chart = chartMenu;
    }

    @PostConstruct
    private addMenuItems(): void {
        const menuList = new MenuList();
        this.getContext().wireBean(menuList);

        menuList.addMenuItems(this.getMenuItems());

        this.appendChild(menuList);
        menuList.addEventListener(MenuItemComponent.EVENT_ITEM_SELECTED, this.destroy.bind(this));
    }

    private getMenuItems(): (MenuItemDef )[] {
        const localeTextFunc = this.gridOptionsWrapper.getLocaleTextFunc();

        return [
            {
                name: 'Chart Range',
                subMenu: [
                    {
                        name: localeTextFunc('groupedBarRangeChart', 'Bar (Grouped)'),
                        action: () => {
                            const chartComp: any = this.chart;
                            (chartComp as IGridChartComp).setChartType(ChartType.GroupedBar);
                        }
                    },
                    {
                        name: localeTextFunc('stackedBarRangeChart', 'Bar (Stacked)'),
                        action: () => {
                            const chartComp: any = this.chart;
                            (chartComp as IGridChartComp).setChartType(ChartType.StackedBar);
                        }
                    },
                    {
                        name: localeTextFunc('lineRangeChart', 'Line'),
                        action: () => {
                            const chartComp: any = this.chart;
                            (chartComp as IGridChartComp).setChartType(ChartType.Line);
                        }
                    },
                    {
                        name: localeTextFunc('pieRangeChart', 'Pie'),
                        action: () => {
                            const chartComp: any = this.chart;
                            (chartComp as IGridChartComp).setChartType(ChartType.Pie);
                        }
                    }
                ]
            },
            {
                name: localeTextFunc('downloadChart', 'Download'),
                action: () => {
                    const chartComp: any = this.chart;
                    const chart = (chartComp as IGridChartComp).getChart();
                    chart.scene.download("chart");
                }
            },
            {
                name: localeTextFunc('closeDialog', 'Close'),
                action: () => {
                    const chartContainer = this.chart.getContainer();
                    (chartContainer as Dialog).close();
                }
            }
        ];
    }
}<commit_msg>AG-2796 - added separator to chart menu<commit_after>import {
    Autowired,
    Component,
    IComponent,
    MenuItemDef,
    PostConstruct,
    RefSelector,
    Dialog,
    PopupService,
    GridOptionsWrapper,
    ChartType
} from "ag-grid-community";
import { MenuItemMapper } from "../menu/menuItemMapper";
import { MenuList } from "../menu/menuList";
import { MenuItemComponent } from "../menu/menuItemComponent";
import {IGridChartComp} from "./gridChartComp";

export class ChartMenu extends Component {

    private static TEMPLATE =
        `<div class="ag-chart-menu">
            <span ref="eChartMenu" class="ag-icon-menu"></span>
        </div>`;

    @RefSelector('eChartMenu') private eChartMenu: HTMLElement;

    private chart: Component;

    constructor(chart: Component) {
        super(ChartMenu.TEMPLATE);
        this.chart = chart;
    }

    @Autowired('popupService') private popupService: PopupService;

    @PostConstruct
    private postConstruct(): void {
        this.addDestroyableEventListener(this.eChartMenu, 'click', () => this.showMenu());
    }

    private showMenu(): void {
        const menu = new Menu(this.chart);

        this.getContext().wireBean(menu);

        const hidePopup = this.popupService.addAsModalPopup(
            menu.getGui(),
            true,
            () => menu.destroy.bind(this)
        );

        this.popupService.positionPopupUnderComponent(
            {
                type: 'chartMenu',
                eventSource: this.eChartMenu,
                ePopup: menu.getGui(), keepWithinBounds: true
            });

        menu.addDestroyFunc(() => hidePopup());
    }
}

class Menu extends Component implements IComponent<any> {

    @Autowired('gridOptionsWrapper') private gridOptionsWrapper: GridOptionsWrapper;
    @Autowired('menuItemMapper') private menuItemMapper: MenuItemMapper;

    private chart: Component;

    constructor(chartMenu: Component) {
        super('<div class="ag-menu"></div>');
        this.chart = chartMenu;
    }

    @PostConstruct
    private addMenuItems(): void {
        const menuList = new MenuList();
        this.getContext().wireBean(menuList);

        menuList.addMenuItems(this.getMenuItems());

        this.appendChild(menuList);
        menuList.addEventListener(MenuItemComponent.EVENT_ITEM_SELECTED, this.destroy.bind(this));
    }

    private getMenuItems(): (MenuItemDef | string)[] {
        const localeTextFunc = this.gridOptionsWrapper.getLocaleTextFunc();

        return [
            {
                name: 'Chart Range',
                subMenu: [
                    {
                        name: localeTextFunc('groupedBarRangeChart', 'Bar (Grouped)'),
                        action: () => {
                            const chartComp: any = this.chart;
                            (chartComp as IGridChartComp).setChartType(ChartType.GroupedBar);
                        }
                    },
                    {
                        name: localeTextFunc('stackedBarRangeChart', 'Bar (Stacked)'),
                        action: () => {
                            const chartComp: any = this.chart;
                            (chartComp as IGridChartComp).setChartType(ChartType.StackedBar);
                        }
                    },
                    {
                        name: localeTextFunc('lineRangeChart', 'Line'),
                        action: () => {
                            const chartComp: any = this.chart;
                            (chartComp as IGridChartComp).setChartType(ChartType.Line);
                        }
                    },
                    {
                        name: localeTextFunc('pieRangeChart', 'Pie'),
                        action: () => {
                            const chartComp: any = this.chart;
                            (chartComp as IGridChartComp).setChartType(ChartType.Pie);
                        }
                    }
                ]
            },
            {
                name: localeTextFunc('downloadChart', 'Download'),
                action: () => {
                    const chartComp: any = this.chart;
                    const chart = (chartComp as IGridChartComp).getChart();
                    chart.scene.download("chart");
                }
            },
            'separator',
            {
                name: localeTextFunc('closeDialog', 'Close'),
                action: () => {
                    const chartContainer = this.chart.getContainer();
                    (chartContainer as Dialog).close();
                }
            }
        ];
    }
}
{'fraction_non_alphanumeric': 0.10839578581514066, 'fraction_numerical': 0.0004344520473552732, 'mean_word_length': 1.5556480710519012, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4936988', 'n_tokens_mistral': 2315, 'n_tokens_neox': 2217, 'n_words': 423}