@ant-design/icons#AreaChartOutlined TypeScript Examples

The following examples show how to use @ant-design/icons#AreaChartOutlined. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: general-chart.editor.tsx    From next-basics with GNU General Public License v3.0 6 votes vote down vote up
export function GeneralChartEditor({
  nodeUid,
}: EditorComponentProps): React.ReactElement {
  const node = useBuilderNode<GeneralChartProperties>({ nodeUid });

  return (
    <EditorContainer nodeUid={nodeUid}>
      <div className={styles.chartContainer}>
        <div className={styles.layout}>
          <BarChartOutlined className={styles.chartIcon} />
        </div>
        <div className={styles.layout}>
          <LineChartOutlined className={styles.chartIcon} />
        </div>
        <div className={styles.layout}>
          <PieChartFilled className={styles.chartIcon} />
        </div>
        <div className={styles.layout}>
          <AreaChartOutlined className={styles.chartIcon} />
        </div>
      </div>
    </EditorContainer>
  );
}
Example #2
Source File: Layout.tsx    From jitsu with MIT License 6 votes vote down vote up
menuItems = [
  makeItem(<HomeFilled />, "Home", "/connections", "#77c593"),
  makeItem(<ThunderboltFilled />, "Live Events", "/events-stream", "#fccd04"),
  makeItem(<AreaChartOutlined />, "Statistics", "/dashboard", "#88bdbc"),
  makeItem(<Icon component={KeyIcon} />, "API Keys", "/api-keys", "#d79922"),
  makeItem(<ApiFilled />, "Sources", "/sources", "#d83f87"),
  makeItem(<NotificationFilled />, "Destinations", "/destinations", "#4056a1"),
  makeItem(<Icon component={DbtCloudIcon} />, "dbt Cloud Integration", "/dbtcloud", "#e76e52"),
  makeItem(<SettingOutlined />, "Project settings", "/project-settings", "#0d6050"),
  makeItem(<Icon component={GlobeIcon} />, "Geo data resolver", "/geo-data-resolver", "#41b3a3"),
  makeItem(<CloudFilled />, "Custom Domains", "/domains", "#5ab9ea", f => f.enableCustomDomains),
  makeItem(<Icon component={DownloadIcon} />, "Download Config", "/cfg-download", "#14a76c"),
]
Example #3
Source File: ChartTypeSelector.tsx    From datart with Apache License 2.0 5 votes vote down vote up
ChartTypeSelector: FC<{
  type;
  translate: (title: string) => string;
  onChange: (value) => void;
  onCreateDownloadDataTask?: () => void;
}> = memo(({ type, onChange, onCreateDownloadDataTask }) => {
  const t = useI18NPrefix(`viz.action.common`);
  const typeChange = useCallback(
    type => () => {
      onChange(type);
    },
    [onChange],
  );

  return (
    <StyledChartTypeSelector>
      <TypeSelector
        fontSize={FONT_SIZE_HEADING}
        className={classnames({ active: type === ChartPresentType.GRAPH })}
        onClick={typeChange(ChartPresentType.GRAPH)}
      >
        <AreaChartOutlined />
      </TypeSelector>
      <TypeSelector
        fontSize={FONT_SIZE_HEADING}
        className={classnames({ active: type === ChartPresentType.RAW })}
        onClick={typeChange(ChartPresentType.RAW)}
      >
        <TableOutlined />
      </TypeSelector>
      <TypeSelector
        fontSize={FONT_SIZE_HEADING}
        className={classnames({ active: type === ChartPresentType.SQL })}
        onClick={typeChange(ChartPresentType.SQL)}
      >
        <ConsoleSqlOutlined />
      </TypeSelector>
      <TypeSelector
        fontSize={FONT_SIZE_HEADING}
        className={classnames({ active: type === ChartPresentType.DOWNLOAD })}
      >
        <Popconfirm
          placement="left"
          title={t('downloadForExcel')}
          onConfirm={onCreateDownloadDataTask}
        >
          <CloudDownloadOutlined />
        </Popconfirm>
      </TypeSelector>
    </StyledChartTypeSelector>
  );
})
Example #4
Source File: ChartFilter.tsx    From posthog-foss with MIT License 4 votes vote down vote up
export function ChartFilter({ filters, onChange, disabled }: ChartFilterProps): JSX.Element {
    const { insightProps } = useValues(insightLogic)
    const { chartFilter } = useValues(chartFilterLogic(insightProps))
    const { setChartFilter } = useActions(chartFilterLogic(insightProps))
    const { preflight } = useValues(preflightLogic)

    const cumulativeDisabled = filters.insight === InsightType.STICKINESS || filters.insight === InsightType.RETENTION
    const tableDisabled = false
    const pieDisabled = filters.insight === InsightType.RETENTION || filters.insight === InsightType.STICKINESS
    const barDisabled = filters.insight === InsightType.RETENTION
    const barValueDisabled =
        barDisabled || filters.insight === InsightType.STICKINESS || filters.insight === InsightType.RETENTION
    const defaultDisplay: ChartDisplayType =
        filters.insight === InsightType.RETENTION
            ? ChartDisplayType.ActionsTable
            : filters.insight === InsightType.FUNNELS
            ? ChartDisplayType.FunnelViz
            : ChartDisplayType.ActionsLineGraphLinear

    function Label({ icon, children = null }: { icon: React.ReactNode; children: React.ReactNode }): JSX.Element {
        return (
            <>
                {icon} {children}
            </>
        )
    }

    function WarningTag({ children = null }: { children: React.ReactNode }): JSX.Element {
        return (
            <Tag color="orange" style={{ marginLeft: 8, fontSize: 10 }}>
                {children}
            </Tag>
        )
    }

    const options =
        filters.insight === InsightType.FUNNELS
            ? preflight?.is_clickhouse_enabled
                ? [
                      {
                          value: FunnelVizType.Steps,
                          label: <Label icon={<OrderedListOutlined />}>Steps</Label>,
                      },
                      {
                          value: FunnelVizType.Trends,
                          label: (
                              <Label icon={<LineChartOutlined />}>
                                  Trends
                                  <WarningTag>BETA</WarningTag>
                              </Label>
                          ),
                      },
                  ]
                : [
                      {
                          value: FunnelVizType.Steps,
                          label: <Label icon={<OrderedListOutlined />}>Steps</Label>,
                      },
                  ]
            : [
                  {
                      label: 'Line Chart',
                      options: [
                          {
                              value: ChartDisplayType.ActionsLineGraphLinear,
                              label: <Label icon={<LineChartOutlined />}>Linear</Label>,
                          },
                          {
                              value: ChartDisplayType.ActionsLineGraphCumulative,
                              label: <Label icon={<AreaChartOutlined />}>Cumulative</Label>,
                              disabled: cumulativeDisabled,
                          },
                      ],
                  },
                  {
                      label: 'Bar Chart',
                      options: [
                          {
                              value: ChartDisplayType.ActionsBarChart,
                              label: <Label icon={<BarChartOutlined />}>Time</Label>,
                              disabled: barDisabled,
                          },
                          {
                              value: ChartDisplayType.ActionsBarChartValue,
                              label: <Label icon={<BarChartOutlined />}>Value</Label>,
                              disabled: barValueDisabled,
                          },
                      ],
                  },
                  {
                      value: ChartDisplayType.ActionsTable,
                      label: <Label icon={<TableOutlined />}>Table</Label>,
                      disabled: tableDisabled,
                  },
                  {
                      value: ChartDisplayType.ActionsPieChart,
                      label: <Label icon={<PieChartOutlined />}>Pie</Label>,
                      disabled: pieDisabled,
                  },
              ]
    return (
        <Select
            key="2"
            defaultValue={filters.display || defaultDisplay}
            value={chartFilter || defaultDisplay}
            onChange={(value: ChartDisplayType | FunnelVizType) => {
                setChartFilter(value)
                onChange?.(value)
            }}
            bordered
            dropdownAlign={ANTD_TOOLTIP_PLACEMENTS.bottomRight}
            dropdownMatchSelectWidth={false}
            data-attr="chart-filter"
            disabled={disabled}
            options={options}
        />
    )
}
Example #5
Source File: Icon.tsx    From html2sketch with MIT License 4 votes vote down vote up
IconSymbol: FC = () => {
  return (
    <Row>
      {/*<CaretUpOutlined*/}
      {/*  className="icon"*/}
      {/*  symbolName={'1.General/2.Icons/1.CaretUpOutlined'}*/}
      {/*/>*/}
      {/*  className="icon"*/}
      {/*  symbolName={'1.General/2.Icons/2.MailOutlined'}*/}
      {/*/>*/}
      {/*<StepBackwardOutlined*/}
      {/*  className="icon"*/}
      {/*  symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
      {/*/>*/}
      {/*<StepForwardOutlined*/}
      {/*  className="icon"*/}
      {/*  symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
      {/*/>*/}
      <StepForwardOutlined />
      <ShrinkOutlined />
      <ArrowsAltOutlined />
      <DownOutlined />
      <UpOutlined />
      <LeftOutlined />
      <RightOutlined />
      <CaretUpOutlined />
      <CaretDownOutlined />
      <CaretLeftOutlined />
      <CaretRightOutlined />
      <VerticalAlignTopOutlined />
      <RollbackOutlined />
      <FastBackwardOutlined />
      <FastForwardOutlined />
      <DoubleRightOutlined />
      <DoubleLeftOutlined />
      <VerticalLeftOutlined />
      <VerticalRightOutlined />
      <VerticalAlignMiddleOutlined />
      <VerticalAlignBottomOutlined />
      <ForwardOutlined />
      <BackwardOutlined />
      <EnterOutlined />
      <RetweetOutlined />
      <SwapOutlined />
      <SwapLeftOutlined />
      <SwapRightOutlined />
      <ArrowUpOutlined />
      <ArrowDownOutlined />
      <ArrowLeftOutlined />
      <ArrowRightOutlined />
      <LoginOutlined />
      <LogoutOutlined />
      <MenuFoldOutlined />
      <MenuUnfoldOutlined />
      <BorderBottomOutlined />
      <BorderHorizontalOutlined />
      <BorderInnerOutlined />
      <BorderOuterOutlined />
      <BorderLeftOutlined />
      <BorderRightOutlined />
      <BorderTopOutlined />
      <BorderVerticleOutlined />
      <PicCenterOutlined />
      <PicLeftOutlined />
      <PicRightOutlined />
      <RadiusBottomleftOutlined />
      <RadiusBottomrightOutlined />
      <RadiusUpleftOutlined />
      <RadiusUprightOutlined />
      <FullscreenOutlined />
      <FullscreenExitOutlined />
      <QuestionOutlined />
      <PauseOutlined />
      <MinusOutlined />
      <PauseCircleOutlined />
      <InfoOutlined />
      <CloseOutlined />
      <ExclamationOutlined />
      <CheckOutlined />
      <WarningOutlined />
      <IssuesCloseOutlined />
      <StopOutlined />
      <EditOutlined />
      <CopyOutlined />
      <ScissorOutlined />
      <DeleteOutlined />
      <SnippetsOutlined />
      <DiffOutlined />
      <HighlightOutlined />
      <AlignCenterOutlined />
      <AlignLeftOutlined />
      <AlignRightOutlined />
      <BgColorsOutlined />
      <BoldOutlined />
      <ItalicOutlined />
      <UnderlineOutlined />
      <StrikethroughOutlined />
      <RedoOutlined />
      <UndoOutlined />
      <ZoomInOutlined />
      <ZoomOutOutlined />
      <FontColorsOutlined />
      <FontSizeOutlined />
      <LineHeightOutlined />
      <SortAscendingOutlined />
      <SortDescendingOutlined />
      <DragOutlined />
      <OrderedListOutlined />
      <UnorderedListOutlined />
      <RadiusSettingOutlined />
      <ColumnWidthOutlined />
      <ColumnHeightOutlined />
      <AreaChartOutlined />
      <PieChartOutlined />
      <BarChartOutlined />
      <DotChartOutlined />
      <LineChartOutlined />
      <RadarChartOutlined />
      <HeatMapOutlined />
      <FallOutlined />
      <RiseOutlined />
      <StockOutlined />
      <BoxPlotOutlined />
      <FundOutlined />
      <SlidersOutlined />
      <AndroidOutlined />
      <AppleOutlined />
      <WindowsOutlined />
      <IeOutlined />
      <ChromeOutlined />
      <GithubOutlined />
      <AliwangwangOutlined />
      <DingdingOutlined />
      <WeiboSquareOutlined />
      <WeiboCircleOutlined />
      <TaobaoCircleOutlined />
      <Html5Outlined />
      <WeiboOutlined />
      <TwitterOutlined />
      <WechatOutlined />
      <AlipayCircleOutlined />
      <TaobaoOutlined />
      <SkypeOutlined />
      <FacebookOutlined />
      <CodepenOutlined />
      <CodeSandboxOutlined />
      <AmazonOutlined />
      <GoogleOutlined />
      <AlipayOutlined />
      <AntDesignOutlined />
      <AntCloudOutlined />
      <ZhihuOutlined />
      <SlackOutlined />
      <SlackSquareOutlined />
      <BehanceSquareOutlined />
      <DribbbleOutlined />
      <DribbbleSquareOutlined />
      <InstagramOutlined />
      <YuqueOutlined />
      <AlibabaOutlined />
      <YahooOutlined />
      <RedditOutlined />
      <SketchOutlined />
      <AccountBookOutlined />
      <AlertOutlined />
      <ApartmentOutlined />
      <ApiOutlined />
      <QqOutlined />
      <MediumWorkmarkOutlined />
      <GitlabOutlined />
      <MediumOutlined />
      <GooglePlusOutlined />
      <AppstoreAddOutlined />
      <AppstoreOutlined />
      <AudioOutlined />
      <AudioMutedOutlined />
      <AuditOutlined />
      <BankOutlined />
      <BarcodeOutlined />
      <BarsOutlined />
      <BellOutlined />
      <BlockOutlined />
      <BookOutlined />
      <BorderOutlined />
      <BranchesOutlined />
      <BuildOutlined />
      <BulbOutlined />
      <CalculatorOutlined />
      <CalendarOutlined />
      <CameraOutlined />
      <CarOutlined />
      <CarryOutOutlined />
      <CiCircleOutlined />
      <CiOutlined />
      <CloudOutlined />
      <ClearOutlined />
      <ClusterOutlined />
      <CodeOutlined />
      <CoffeeOutlined />
      <CompassOutlined />
      <CompressOutlined />
      <ContactsOutlined />
      <ContainerOutlined />
      <ControlOutlined />
      <CopyrightCircleOutlined />
      <CopyrightOutlined />
      <CreditCardOutlined />
      <CrownOutlined />
      <CustomerServiceOutlined />
      <DashboardOutlined />
      <DatabaseOutlined />
      <DeleteColumnOutlined />
      <DeleteRowOutlined />
      <DisconnectOutlined />
      <DislikeOutlined />
      <DollarCircleOutlined />
      <DollarOutlined />
      <DownloadOutlined />
      <EllipsisOutlined />
      <EnvironmentOutlined />
      <EuroCircleOutlined />
      <EuroOutlined />
      <ExceptionOutlined />
      <ExpandAltOutlined />
      <ExpandOutlined />
      <ExperimentOutlined />
      <ExportOutlined />
      <EyeOutlined />
      <FieldBinaryOutlined />
      <FieldNumberOutlined />
      <FieldStringOutlined />
      <DesktopOutlined />
      <DingtalkOutlined />
      <FileAddOutlined />
      <FileDoneOutlined />
      <FileExcelOutlined />
      <FileExclamationOutlined />
      <FileOutlined />
      <FileImageOutlined />
      <FileJpgOutlined />
      <FileMarkdownOutlined />
      <FilePdfOutlined />
      <FilePptOutlined />
      <FileProtectOutlined />
      <FileSearchOutlined />
      <FileSyncOutlined />
      <FileTextOutlined />
      <FileUnknownOutlined />
      <FileWordOutlined />
      <FilterOutlined />
      <FireOutlined />
      <FlagOutlined />
      <FolderAddOutlined />
      <FolderOutlined />
      <FolderOpenOutlined />
      <ForkOutlined />
      <FormatPainterOutlined />
      <FrownOutlined />
      <FunctionOutlined />
      <FunnelPlotOutlined />
      <GatewayOutlined />
      <GifOutlined />
      <GiftOutlined />
      <GlobalOutlined />
      <GoldOutlined />
      <GroupOutlined />
      <HddOutlined />
      <HeartOutlined />
      <HistoryOutlined />
      <HomeOutlined />
      <HourglassOutlined />
      <IdcardOutlined />
      <ImportOutlined />
      <InboxOutlined />
      <InsertRowAboveOutlined />
      <InsertRowBelowOutlined />
      <InsertRowLeftOutlined />
      <InsertRowRightOutlined />
      <InsuranceOutlined />
      <InteractionOutlined />
      <KeyOutlined />
      <LaptopOutlined />
      <LayoutOutlined />
      <LikeOutlined />
      <LineOutlined />
      <LinkOutlined />
      <Loading3QuartersOutlined />
      <LoadingOutlined />
      <LockOutlined />
      <MailOutlined />
      <ManOutlined />
      <MedicineBoxOutlined />
      <MehOutlined />
      <MenuOutlined />
      <MergeCellsOutlined />
      <MessageOutlined />
      <MobileOutlined />
      <MoneyCollectOutlined />
      <MonitorOutlined />
      <MoreOutlined />
      <NodeCollapseOutlined />
      <NodeExpandOutlined />
      <NodeIndexOutlined />
      <NotificationOutlined />
      <NumberOutlined />
      <PaperClipOutlined />
      <PartitionOutlined />
      <PayCircleOutlined />
      <PercentageOutlined />
      <PhoneOutlined />
      <PictureOutlined />
      <PoundCircleOutlined />
      <PoundOutlined />
      <PoweroffOutlined />
      <PrinterOutlined />
      <ProfileOutlined />
      <ProjectOutlined />
      <PropertySafetyOutlined />
      <PullRequestOutlined />
      <PushpinOutlined />
      <QrcodeOutlined />
      <ReadOutlined />
      <ReconciliationOutlined />
      <RedEnvelopeOutlined />
      <ReloadOutlined />
      <RestOutlined />
      <RobotOutlined />
      <RocketOutlined />
      <SafetyCertificateOutlined />
      <SafetyOutlined />
      <ScanOutlined />
      <ScheduleOutlined />
      <SearchOutlined />
      <SecurityScanOutlined />
      <SelectOutlined />
      <SendOutlined />
      <SettingOutlined />
      <ShakeOutlined />
      <ShareAltOutlined />
      <ShopOutlined />
      <ShoppingCartOutlined />
      <ShoppingOutlined />
      <SisternodeOutlined />
      <SkinOutlined />
      <SmileOutlined />
      <SolutionOutlined />
      <SoundOutlined />
      <SplitCellsOutlined />
      <StarOutlined />
      <SubnodeOutlined />
      <SyncOutlined />
      <TableOutlined />
      <TabletOutlined />
      <TagOutlined />
      <TagsOutlined />
      <TeamOutlined />
      <ThunderboltOutlined />
      <ToTopOutlined />
      <ToolOutlined />
      <TrademarkCircleOutlined />
      <TrademarkOutlined />
      <TransactionOutlined />
      <TrophyOutlined />
      <UngroupOutlined />
      <UnlockOutlined />
      <UploadOutlined />
      <UsbOutlined />
      <UserAddOutlined />
      <UserDeleteOutlined />
      <UserOutlined />
      <UserSwitchOutlined />
      <UsergroupAddOutlined />
      <UsergroupDeleteOutlined />
      <VideoCameraOutlined />
      <WalletOutlined />
      <WifiOutlined />
      <BorderlessTableOutlined />
      <WomanOutlined />
      <BehanceOutlined />
      <DropboxOutlined />
      <DeploymentUnitOutlined />
      <UpCircleOutlined />
      <DownCircleOutlined />
      <LeftCircleOutlined />
      <RightCircleOutlined />
      <UpSquareOutlined />
      <DownSquareOutlined />
      <LeftSquareOutlined />
      <RightSquareOutlined />
      <PlayCircleOutlined />
      <QuestionCircleOutlined />
      <PlusCircleOutlined />
      <PlusSquareOutlined />
      <MinusSquareOutlined />
      <MinusCircleOutlined />
      <InfoCircleOutlined />
      <ExclamationCircleOutlined />
      <CloseCircleOutlined />
      <CloseSquareOutlined />
      <CheckCircleOutlined />
      <CheckSquareOutlined />
      <ClockCircleOutlined />
      <FormOutlined />
      <DashOutlined />
      <SmallDashOutlined />
      <YoutubeOutlined />
      <CodepenCircleOutlined />
      <AliyunOutlined />
      <PlusOutlined />
      <LinkedinOutlined />
      <AimOutlined />
      <BugOutlined />
      <CloudDownloadOutlined />
      <CloudServerOutlined />
      <CloudSyncOutlined />
      <CloudUploadOutlined />
      <CommentOutlined />
      <ConsoleSqlOutlined />
      <EyeInvisibleOutlined />
      <FileGifOutlined />
      <DeliveredProcedureOutlined />
      <FieldTimeOutlined />
      <FileZipOutlined />
      <FolderViewOutlined />
      <FundProjectionScreenOutlined />
      <FundViewOutlined />
      <MacCommandOutlined />
      <PlaySquareOutlined />
      <OneToOneOutlined />
      <RotateLeftOutlined />
      <RotateRightOutlined />
      <SaveOutlined />
      <SwitcherOutlined />
      <TranslationOutlined />
      <VerifiedOutlined />
      <VideoCameraAddOutlined />
      <WhatsAppOutlined />

      {/*</Col>*/}
    </Row>
  );
}
Example #6
Source File: getProducts.tsx    From XFlow with MIT License 4 votes vote down vote up
getProducts = ({
  t,
  language,
}: {
  t: (key: string) => string;
  language: string;
  rootDomain?: string;
  isChinaMirrorHost?: boolean;
}): ProductItem[] => {
  const hosts: { [name: string]: string } = {};
  ['g2', 'g2plot', 'g6', 'l7', 'f2', 'graphin', 'g', 'x6', 'ava'].forEach((name: string) => {
    hosts[name] = `${name}.${ANTV_DOMAIN}`;
  });
  const products = [
    {
      title: 'G2',
      icon: 'https://gw.alipayobjects.com/zos/antfincdn/trEfLRh5pc/G2%252520keshihuatuxingyufa.svg',
      slogan: t('可视化引擎'),
      description: t('数据驱动,高度易用,可扩展的可视化图形语法。'),
      category: Categories[0],
      links: [
        {
          icon: <HomeOutlined />,
          title: t('产品首页'),
          url: `https://${hosts.g2}/${language}`,
        },
        {
          icon: <PieChartOutlined />,
          title: t('图表示例'),
          url: `https://${hosts.g2}/${language}/examples`,
        },
        {
          icon: <ReadOutlined />,
          title: t('使用文档'),
          url: `https://${hosts.g2}/${language}/docs/manual`,
        },
        {
          icon: <ReadOutlined />,
          title: t('API 文档'),
          url: `https://${hosts.g2}/${language}/docs/api`,
        },
        {
          icon: <HistoryOutlined />,
          title: t('更新日志'),
          url: `https://github.com/antvis/g2/blob/master/CHANGELOG.md`,
          openExternal: true,
        },
        {
          icon: <GithubOutlined />,
          title: t('GitHub 仓库'),
          url: `https://github.com/antvis/g2`,
          openExternal: true,
        },
        {
          icon: '??',
          title: t('国内镜像'),
          url: `https://antv-g2.gitee.io`,
          openExternal: true,
        },
      ],
    },
    {
      title: 'G6',
      icon: 'https://gw.alipayobjects.com/zos/antfincdn/zS1wZZJVcJ/G6%252520tukeshihuayinqing.svg',
      slogan: t('图可视化引擎'),
      description: t('便捷的关系数据可视化引擎与图分析工具。'),
      category: Categories[0],
      links: [
        {
          icon: <HomeOutlined />,
          title: t('产品首页'),
          url: `https://${hosts.g6}/${language}`,
        },
        {
          icon: <PieChartOutlined />,
          title: t('图表示例'),
          url: `https://${hosts.g6}/${language}/examples`,
        },
        {
          icon: <ReadOutlined />,
          title: t('使用文档'),
          url: `https://${hosts.g6}/${language}/docs/manual`,
        },
        {
          icon: <ReadOutlined />,
          title: t('API 文档'),
          url: `https://${hosts.g6}/${language}/docs/api`,
        },
        {
          icon: <HistoryOutlined />,
          title: t('更新日志'),
          url: `https://github.com/antvis/g6/blob/master/CHANGELOG.md`,
          openExternal: true,
        },
        {
          icon: <GithubOutlined />,
          title: t('GitHub 仓库'),
          url: `https://github.com/antvis/g6`,
          openExternal: true,
        },
        {
          icon: '??',
          title: t('国内镜像'),
          url: `https://antv-g6.gitee.io`,
          openExternal: true,
        },
      ],
    },
    {
      title: 'F2',
      icon: 'https://gw.alipayobjects.com/zos/antfincdn/D%26fDbWqVkv/F2%252520yidongduankeshihuafangan.svg',
      slogan: t('移动可视化方案'),
      description: t('专注于移动端的可视化解决方案,兼容 H5/小程序/Weex 等多端环境'),
      category: Categories[0],
      links: [
        {
          icon: <HomeOutlined />,
          title: t('产品首页'),
          url: `https://${hosts.f2}/${language}`,
        },
        {
          icon: <PieChartOutlined />,
          title: t('图表示例'),
          url: `https://${hosts.f2}/${language}/examples`,
        },
        {
          icon: <ReadOutlined />,
          title: t('使用文档'),
          url: `https://${hosts.f2}/${language}/docs/tutorial/getting-started`,
        },
        {
          icon: <ReadOutlined />,
          title: t('API 文档'),
          url: `https://${hosts.f2}/${language}/docs/api`,
        },
        {
          icon: <HistoryOutlined />,
          title: t('更新日志'),
          url: `https://github.com/antvis/f2/blob/master/CHANGELOG.md`,
          openExternal: true,
        },
        {
          icon: <GithubOutlined />,
          title: t('GitHub 仓库'),
          url: `https://github.com/antvis/f2`,
          openExternal: true,
        },
        {
          icon: '??',
          title: t('国内镜像'),
          url: `https://antv-f2.gitee.io`,
          openExternal: true,
        },
      ],
    },
    {
      title: 'L7',
      icon: 'https://gw.alipayobjects.com/zos/antfincdn/OI%26h7HXH33/L7%252520dilikongjianshujukeshihua.svg',
      slogan: t('地理空间数据可视化'),
      description: t('高性能/高渲染质量的地理空间数据可视化框架。'),
      category: Categories[0],
      links: [
        {
          icon: <HomeOutlined />,
          title: t('产品首页'),
          url: `https://${hosts.l7}/${language}`,
        },
        {
          icon: <PieChartOutlined />,
          title: t('图表示例'),
          url: `https://${hosts.l7}/${language}/examples`,
        },
        {
          icon: <ReadOutlined />,
          title: t('使用文档'),
          url: `https://${hosts.l7}/${language}/docs/tutorial`,
        },
        {
          icon: <ReadOutlined />,
          title: t('API 文档'),
          url: `https://${hosts.l7}/${language}/docs/api/l7`,
        },
        {
          icon: <HistoryOutlined />,
          title: t('更新日志'),
          url: `https://github.com/antvis/L7/blob/master/CHANGELOG.md`,
          openExternal: true,
        },
        {
          icon: <GithubOutlined />,
          title: t('GitHub 仓库'),
          url: `https://github.com/antvis/L7`,
          openExternal: true,
        },
        {
          icon: '??',
          title: t('国内镜像'),
          url: `https://antv-l7.gitee.io`,
          openExternal: true,
        },
      ],
    },
    {
      title: 'G2Plot',
      icon: 'https://gw.alipayobjects.com/zos/antfincdn/SlbIagEvT7/G2plot.svg',
      slogan: t('开箱即用的图表库'),
      description: t('开箱即用、易于配置、极致体验的通用图表库。'),
      category: Categories[1],
      links: [
        {
          icon: <HomeOutlined />,
          title: t('产品首页'),
          url: `https://${hosts.g2plot}/${language}`,
        },
        {
          icon: <PieChartOutlined />,
          title: t('图表示例'),
          url: `https://${hosts.g2plot}/${language}/examples`,
        },
        {
          icon: <ReadOutlined />,
          title: t('使用文档'),
          url: `https://${hosts.g2plot}/${language}/docs/manual`,
        },
        {
          icon: <HistoryOutlined />,
          title: t('更新日志'),
          url: `https://github.com/antvis/g2plot/blob/master/CHANGELOG.md`,
          openExternal: true,
        },
        {
          icon: <GithubOutlined />,
          title: t('GitHub 仓库'),
          url: `https://github.com/antvis/g2plot`,
          openExternal: true,
        },
        {
          icon: '??',
          title: t('国内镜像'),
          url: `https://antv-g2plot.gitee.io`,
          openExternal: true,
        },
      ],
    },
    {
      title: 'Graphin',
      icon: 'https://gw.alipayobjects.com/zos/antfincdn/0b4HzOcEJY/Graphin.svg',
      slogan: t(''),
      description: t('基于 G6 封装的图分析应用组件。'),
      category: Categories[1],
      links: [
        {
          icon: <HomeOutlined />,
          title: t('产品首页'),
          url: `https://${hosts.graphin}/${language}`,
        },
        {
          icon: <ReadOutlined />,
          title: t('使用文档'),
          url: `https://${hosts.graphin}/${language}/docs/manual/introduction`,
        },
        {
          icon: <ReadOutlined />,
          title: t('API 文档'),
          url: `https://${hosts.graphin}/${language}/docs/api/graphin`,
        },
        {
          icon: <HistoryOutlined />,
          title: t('更新日志'),
          url: `https://github.com/antvis/graphin/blob/master/CHANGELOG.md`,
          openExternal: true,
        },
        {
          icon: <GithubOutlined />,
          title: t('GitHub 仓库'),
          url: `https://github.com/antvis/graphin`,
          openExternal: true,
        },
        {
          icon: '??',
          title: t('国内镜像'),
          url: `https://antv-graphin.gitee.io`,
          openExternal: true,
        },
      ],
    },
    {
      title: 'ChartCube',
      icon: 'https://gw.alipayobjects.com/zos/antfincdn/Zr74jx8YNX/chartcube.svg',
      slogan: t('图表魔方'),
      description: t('AntV 在线图表制作利器。'),
      category: Categories[1],
      links: [
        {
          icon: <HomeOutlined />,
          title: t('产品首页'),
          url: `https://chartcube.alipay.com`,
          openExternal: true,
        },
        {
          icon: <AreaChartOutlined />,
          title: t('生成图表'),
          url: `https://chartcube.alipay.com/guide`,
          openExternal: true,
        },
        {
          icon: <YuqueOutlined />,
          title: t('语雀社区'),
          url: `https://www.yuque.com/chartcube`,
          openExternal: true,
        },
        {
          icon: <DingdingOutlined />,
          title: t('钉钉服务群'),
          url: `dingtalk://dingtalkclient/action/joingroup?cid=8305538734`,
          openExternal: true,
        },
      ],
    },
    {
      title: t('墨者学院'),
      icon: 'https://gw.alipayobjects.com/zos/antfincdn/12j36RPVldO/mozhexueyuan.svg',
      description: t('数据可视化社团'),
      category: Categories[2],
      links: [
        {
          title: t('学院首页'),
          url: `https://www.yuque.com/mo-college`,
          openExternal: true,
        },
      ],
    },
    {
      title: 'BizCharts',
      icon: 'https://gw.alipayobjects.com/zos/antfincdn/Q1pbg%26O2TM/BizCharts.svg',
      description: t('基于商业场景下的数据可视化解决方案'),
      category: Categories[2],
      links: [
        {
          title: t('产品首页'),
          url: 'https://bizcharts.net',
          openExternal: true,
        },
      ],
    },
    {
      title: 'Viser',
      icon: 'https://gw.alipayobjects.com/zos/antfincdn/QAyW5h99HVa/Viser.svg',
      description: t('基于 G2 实现的可视化解决方案'),
      category: Categories[2],
      links: [
        {
          title: t('产品首页'),
          url: `https://viserjs.github.io/`,
          openExternal: true,
        },
      ],
    },
  ];

  return products;
}
Example #7
Source File: DestinationEditor.tsx    From jitsu with MIT License 4 votes vote down vote up
DestinationEditor = ({
  editorMode,
  paramsByProps,
  disableForceUpdateOnSave,
  onAfterSaveSucceded,
  onCancel,
  isOnboarding,
}: Props) => {
  const history = useHistory()

  const forceUpdate = useForceUpdate()

  const services = ApplicationServices.get()

  const urlParams = useParams<DestinationURLParams>()
  const params = paramsByProps || urlParams

  const [activeTabKey, setActiveTabKey] = useState<DestinationTabKey>("config")
  const [savePopover, switchSavePopover] = useState<boolean>(false)
  const [testConnecting, setTestConnecting] = useState<boolean>(false)
  const [destinationSaving, setDestinationSaving] = useState<boolean>(false)
  const [testConnectingPopover, switchTestConnectingPopover] = useState<boolean>(false)

  const sources = sourcesStore.list
  const destinationData = useRef<DestinationData>(getDestinationData(params))

  const destinationReference = useMemo<Destination | null | undefined>(() => {
    if (params.type) {
      return destinationsReferenceMap[params.type]
    }
    return destinationsReferenceMap[getDestinationData(params)._type]
  }, [params.type, params.id])

  if (!destinationReference) {
    return <DestinationNotFound destinationId={params.id} />
  }

  const submittedOnce = useRef<boolean>(false)

  const handleUseLibrary = async (newMappings: DestinationMapping, newTableName?: string) => {
    destinationData.current = {
      ...destinationData.current,
      _formData: {
        ...destinationData.current._formData,
        tableName: newTableName ? newTableName : destinationData.current._formData?.tableName,
      },
      _mappings: newMappings,
    }

    const { form: mappingsForm } = destinationsTabs[2]
    const { form: configForm } = destinationsTabs[0]

    await mappingsForm.setFieldsValue({
      "_mappings._mappings": newMappings._mappings,
      "_mappings._keepUnmappedFields": newMappings._keepUnmappedFields,
    })

    destinationsTabs[2].touched = true

    if (newTableName) {
      await configForm.setFieldsValue({
        "_formData.tableName": newTableName,
      })

      destinationsTabs[0].touched = true
    }

    await forceUpdate()

    actionNotification.success("Mappings library has been successfully set")
  }

  const validateTabForm = useCallback(
    async (tab: Tab) => {
      const tabForm = tab.form

      try {
        if (tab.key === "sources") {
          const _sources = tabForm.getFieldsValue()?._sources

          if (!_sources) {
            tab.errorsCount = 1
          }
        }

        tab.errorsCount = 0

        return await tabForm.validateFields()
      } catch (errors) {
        // ToDo: check errors count for fields with few validation rules
        tab.errorsCount = errors.errorFields?.length
        return null
      } finally {
        forceUpdate()
      }
    },
    [forceUpdate]
  )
  const configForm = Form.useForm()[0]
  const hideMapping =
    params.standalone == "true" ||
    isOnboarding ||
    editorMode === "add" ||
    (destinationsReferenceMap[destinationReference.id].defaultTransform.length > 0 &&
      !destinationData.current._mappings?._mappings) ||
    !destinationData.current._mappings?._mappings
  let mappingForm = undefined
  if (!hideMapping) {
    mappingForm = Form.useForm()[0]
  }

  const tabsInitialData: Tab<DestinationTabKey>[] = [
    {
      key: "config",
      name: "Connection Properties",
      getComponent: (form: FormInstance) => (
        <DestinationEditorConfig
          form={form}
          destinationReference={destinationReference}
          destinationData={destinationData.current}
          handleTouchAnyField={validateAndTouchField(0)}
        />
      ),
      form: configForm,
      touched: false,
    },
    {
      key: "transform",
      name: "Transform",
      getComponent: (form: FormInstance) => (
        <DestinationEditorTransform
          form={form}
          configForm={configForm}
          mappingForm={mappingForm}
          destinationReference={destinationReference}
          destinationData={destinationData.current}
          handleTouchAnyField={validateAndTouchField(1)}
        />
      ),
      form: Form.useForm()[0],
      touched: false,
      isHidden: params.standalone == "true",
    },
    {
      key: "mappings",
      name: "Mappings (Deprecated)",
      isDisabled: destinationData.current["_transform_enabled"],
      getComponent: (form: FormInstance) => (
        <DestinationEditorMappings
          form={form}
          initialValues={destinationData.current._mappings}
          handleTouchAnyField={validateAndTouchField(2)}
          handleDataUpdate={handleUseLibrary}
        />
      ),
      form: mappingForm,
      touched: false,
      isHidden: hideMapping,
    },
    {
      key: "sources",
      name: "Linked Connectors & API Keys",
      getComponent: (form: FormInstance) => (
        <DestinationEditorConnectors
          form={form}
          initialValues={destinationData.current}
          destination={destinationReference}
          handleTouchAnyField={validateAndTouchField(3)}
        />
      ),
      form: Form.useForm()[0],
      errorsLevel: "warning",
      touched: false,
      isHidden: params.standalone == "true",
    },
  ]

  const [destinationsTabs, setDestinationsTabs] = useState<Tab<DestinationTabKey>[]>(tabsInitialData)

  const validateAndTouchField = useCallback(
    (index: number) => (value: boolean) => {
      destinationsTabs[index].touched = value === undefined ? true : value

      setDestinationsTabs(oldTabs => {
        let tab = oldTabs[index]
        let oldErrorsCount = tab.errorsCount
        let newErrorsCount = tab.form.getFieldsError().filter(a => a.errors?.length > 0).length
        if (newErrorsCount != oldErrorsCount) {
          tab.errorsCount = newErrorsCount
        }
        if (
          oldTabs[1].form.getFieldValue("_transform_enabled") !== oldTabs[2].isDisabled ||
          newErrorsCount != oldErrorsCount
        ) {
          const newTabs = [
            ...oldTabs.slice(0, 2),
            { ...oldTabs[2], isDisabled: oldTabs[1].form.getFieldValue("_transform_enabled") },
            ...oldTabs.slice(3),
          ]
          if (newErrorsCount != oldErrorsCount) {
            newTabs[index].errorsCount = newErrorsCount
          }
          return newTabs
        } else {
          return oldTabs
        }
      })
    },
    [validateTabForm, destinationsTabs, setDestinationsTabs]
  )

  const handleCancel = useCallback(() => {
    onCancel ? onCancel() : history.push(projectRoute(destinationPageRoutes.root))
  }, [history, onCancel])

  const handleViewStatistics = () =>
    history.push(
      projectRoute(destinationPageRoutes.statisticsExact, {
        id: destinationData.current._id,
      })
    )

  const testConnectingPopoverClose = useCallback(() => switchTestConnectingPopover(false), [])

  const savePopoverClose = useCallback(() => switchSavePopover(false), [])

  const handleTestConnection = useCallback(async () => {
    setTestConnecting(true)

    const tab = destinationsTabs[0]

    try {
      const config = await validateTabForm(tab)
      const values = makeObjectFromFieldsValues<DestinationData>(config)
      destinationData.current._formData = values._formData
      destinationData.current._package = values._package
      destinationData.current._super_type = values._super_type
      await destinationEditorUtils.testConnection(destinationData.current)
    } catch (error) {
      switchTestConnectingPopover(true)
    } finally {
      setTestConnecting(false)
      forceUpdate()
    }
  }, [validateTabForm, forceUpdate])

  const handleSaveDestination = useCallback(() => {
    submittedOnce.current = true

    setDestinationSaving(true)

    Promise.all(destinationsTabs.filter((tab: Tab) => !!tab.form).map((tab: Tab) => validateTabForm(tab)))
      .then(async allValues => {
        destinationData.current = {
          ...destinationData.current,
          ...allValues.reduce((result: any, current: any) => {
            return {
              ...result,
              ...makeObjectFromFieldsValues(current),
            }
          }, {}),
        }

        try {
          await destinationEditorUtils.testConnection(destinationData.current, true)

          let savedDestinationData: DestinationData = destinationData.current
          if (editorMode === "add") {
            savedDestinationData = await flowResult(destinationsStore.add(destinationData.current))
          }
          if (editorMode === "edit") {
            await flowResult(destinationsStore.replace(destinationData.current))
          }
          await connectionsHelper.updateSourcesConnectionsToDestination(
            savedDestinationData._uid,
            savedDestinationData._sources || []
          )

          destinationsTabs.forEach((tab: Tab) => (tab.touched = false))

          if (savedDestinationData._connectionTestOk) {
            if (editorMode === "add") actionNotification.success(`New ${savedDestinationData._type} has been added!`)
            if (editorMode === "edit") actionNotification.success(`${savedDestinationData._type} has been saved!`)
          } else {
            actionNotification.warn(
              `${savedDestinationData._type} has been saved, but test has failed with '${firstToLower(
                savedDestinationData._connectionErrorMessage
              )}'. Data will not be piped to this destination`
            )
          }

          onAfterSaveSucceded ? onAfterSaveSucceded() : history.push(projectRoute(destinationPageRoutes.root))
        } catch (errors) {}
      })
      .catch(() => {
        switchSavePopover(true)
      })
      .finally(() => {
        setDestinationSaving(false)
        !disableForceUpdateOnSave && forceUpdate()
      })
  }, [
    destinationsTabs,
    destinationData,
    sources,
    history,
    validateTabForm,
    forceUpdate,
    editorMode,
    services.activeProject.id,
    services.storageService,
  ])

  const connectedSourcesNum = sources.filter(src =>
    (src.destinations || []).includes(destinationData.current._uid)
  ).length

  const isAbleToConnectItems = (): boolean =>
    editorMode === "edit" &&
    connectedSourcesNum === 0 &&
    !destinationData.current?._onlyKeys?.length &&
    !destinationsReferenceMap[params.type]?.hidden

  useEffect(() => {
    let breadcrumbs = []
    if (!params.standalone) {
      breadcrumbs.push({
        title: "Destinations",
        link: projectRoute(destinationPageRoutes.root),
      })
    }
    breadcrumbs.push({
      title: (
        <PageHeader
          title={destinationReference?.displayName ?? "Not Found"}
          icon={destinationReference?.ui.icon}
          mode={params.standalone ? "edit" : editorMode}
        />
      ),
    })
    currentPageHeaderStore.setBreadcrumbs(...breadcrumbs)
  }, [destinationReference])

  return (
    <>
      <div className={cn("flex flex-col items-stretch flex-auto", styles.wrapper)}>
        <div className={styles.mainArea} id="dst-editor-tabs">
          {isAbleToConnectItems() && (
            <Card className={styles.linkedWarning}>
              <WarningOutlined className={styles.warningIcon} />
              <article>
                This destination is not linked to any API keys or Connector. You{" "}
                <span className={styles.pseudoLink} onClick={() => setActiveTabKey("sources")}>
                  can link the destination here
                </span>
                .
              </article>
            </Card>
          )}
          <TabsConfigurator
            type="card"
            className={styles.tabCard}
            tabsList={destinationsTabs}
            activeTabKey={activeTabKey}
            onTabChange={setActiveTabKey}
            tabBarExtraContent={
              !params.standalone &&
              !isOnboarding &&
              editorMode == "edit" && (
                <Button
                  size="large"
                  className="mr-3"
                  type="link"
                  onClick={handleViewStatistics}
                  icon={<AreaChartOutlined />}
                >
                  Statistics
                </Button>
              )
            }
          />
        </div>

        <div className="flex-shrink border-t py-2">
          <EditorButtons
            save={{
              isRequestPending: destinationSaving,
              isPopoverVisible: savePopover && destinationsTabs.some((tab: Tab) => tab.errorsCount > 0),
              handlePress: handleSaveDestination,
              handlePopoverClose: savePopoverClose,
              titleText: "Destination editor errors",
              tabsList: destinationsTabs,
            }}
            test={{
              isRequestPending: testConnecting,
              isPopoverVisible: testConnectingPopover && destinationsTabs[0].errorsCount > 0,
              handlePress: handleTestConnection,
              handlePopoverClose: testConnectingPopoverClose,
              titleText: "Connection Properties errors",
              tabsList: [destinationsTabs[0]],
            }}
            handleCancel={params.standalone ? undefined : handleCancel}
          />
        </div>
      </div>

      <Prompt message={destinationEditorUtils.getPromptMessage(destinationsTabs)} />
    </>
  )
}
Example #8
Source File: index.tsx    From fe-v5 with Apache License 2.0 4 votes vote down vote up
export default function Chart() {
  const { t } = useTranslation();
  const { ids } =
    useParams<{
      ids: string;
    }>();
  const [chartData, setChartData] = useState<
    Array<{
      ref: any;
      dataProps: any;
      highLevelConfig: HighLevelConfigType;
    }>
  >([]);
  const [range, setRange] = useState<Range>({
    num: 1,
    unit: 'hour',
    description: t('小时'),
  });
  const [step, setStep] = useState<number | null>(null);
  const [chartType, setChartType] = useState<ChartType>(ChartType.Line);
  const { clusters } = useSelector<RootState, CommonStoreState>((state) => state.common);
  const [curCluster, setCurCluster] = useState<string>('');

  useEffect(() => {
    initChart();
  }, []);

  const initChart = () => {
    GetTmpChartData(ids).then((res) => {
      let data = res.dat
        .filter((item) => !!item)
        .map((item) => {
          return { ...JSON.parse(item.configs), ref: React.createRef() };
        });
      const curCluster = data[0].curCluster;
      setChartType(data[0].dataProps.chartType || ChartType.Line);
      setStep(data[0].dataProps.step);
      setRange(data[0].dataProps.range);
      // TODO: 处理当前选中集群不在集群列表的情况
      setCurCluster(curCluster);
      localStorage.setItem('curCluster', curCluster);
      setChartData(data);
    });
  };

  const clusterMenu = (
    <Menu selectedKeys={[curCluster]}>
      {clusters.map((cluster) => (
        <Menu.Item
          key={cluster}
          onClick={(_) => {
            setCurCluster(cluster);
            localStorage.setItem('curCluster', cluster);
            chartData.forEach((item) => item.ref.current.refresh());
          }}
        >
          {cluster}
        </Menu.Item>
      ))}
    </Menu>
  );

  const handleDateChange = (e) => {
    if (isAbsoluteRange(e) ? !_.isEqual(e, range) : e.num !== (range as RelativeRange).num || e.unit !== (range as RelativeRange).unit) {
      setRange(e);
    }
  };

  const handleRefresh = () => {
    initChart();
  };

  return (
    <div className='chart-container'>
      {chartData && chartData.length > 0 && curCluster ? (
        <>
          <div className='chart-container-header'>
            <div className='left'></div>
            <div className='right'>
              <Space>
                <div>
                  <span>集群:</span>
                  <Dropdown overlay={clusterMenu}>
                    <Button>
                      {curCluster} <DownOutlined />
                    </Button>
                  </Dropdown>
                </div>
                <DateRangePicker onChange={handleDateChange} value={chartData[0].dataProps.range} />
                <Resolution onChange={(v) => setStep(v)} initialValue={step} />
                {!semver.valid(chartData[0].dataProps?.version) && (
                  <Radio.Group
                    options={[
                      { label: <LineChartOutlined />, value: ChartType.Line },
                      { label: <AreaChartOutlined />, value: ChartType.StackArea },
                    ]}
                    onChange={(e) => {
                      e.preventDefault();
                      setChartType(e.target.value);
                    }}
                    value={chartType}
                    optionType='button'
                    buttonStyle='solid'
                  />
                )}
              </Space>
              {/* <ResfeshIcon onClick={handleRefresh} className='reload-icon' /> */}
            </div>
          </div>
          {chartData.map((item: any, index) => {
            if (semver.valid(item.dataProps?.version)) {
              return (
                <div style={{ height: 400, border: '1px solid #efefef' }}>
                  <Renderer dashboardId={item.id} key={index} time={range} step={step} type={item.dataProps?.type} values={item.dataProps as any} isPreview />
                </div>
              );
            }
            const newItem = {
              ...item.dataProps,
              range,
              step,
              chartType,
              title: (
                <Tooltip
                  placement='bottomLeft'
                  title={() => (
                    <div>
                      {item.dataProps.promqls?.map((promql) => {
                        return <div>{promql.current ? promql.current : promql}</div>;
                      })}
                    </div>
                  )}
                >
                  <Button size='small' type='link'>
                    promql 语句
                  </Button>
                </Tooltip>
              ),
            };
            return <Graph ref={item.ref} key={index} data={{ ...newItem }} graphConfigInnerVisible={false} isShowShare={false} highLevelConfig={item.highLevelConfig || {}} />;
          })}
        </>
      ) : (
        <h2 className='holder'>
          <FieldNumberOutlined
            style={{
              fontSize: '30px',
            }}
          />
          <span>{t('该分享链接无图表数据')}</span>
        </h2>
      )}
    </div>
  );
}
Example #9
Source File: panel.tsx    From fe-v5 with Apache License 2.0 4 votes vote down vote up
Panel: React.FC<PanelProps> = ({ metrics, defaultPromQL, removePanel }) => {
  const { t } = useTranslation();
  const { clusters } = useSelector<CommonRootState, CommonStoreState>((state) => state.common);
  const curPanelTab = useRef<PanelType>(PanelType.Table);
  const graphRef = useRef(null);
  const inputValue = useRef(defaultPromQL);
  const lastEndTime = useRef<number | null>(null);
  const abortInFlightFetch = useRef<(() => void) | null>(null);

  // 公共状态
  const [queryStats, setQueryStats] = useState<QueryStats | null>(null);
  const [chartType, setChartType] = useState<ChartType>(ChartType.Line);
  const [optionsRecord, setOptionsRecord] = useState<PanelOptions>({
    type: PanelType.Table,
    range: { num: 1, unit: 'hour', description: t('小时') },
    endTime: null,
    resolution: null,
    stacked: false,
    showExemplars: false,
  });
  const [errorContent, setErrorContent] = useState<string>('');
  // Table 相关状态
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [vectorData, setVectorData] = useState<VectorDataType | null>(null);

  // 更新输入框表达式内容
  function handleExpressionChange(value: string) {
    inputValue.current = value;
  }

  function handleTabChange(type: PanelType) {
    if (optionsRecord.type !== type) {
      // 同步 Table 页时间戳和 Graph 时间选择组件的时间
      if (type === PanelType.Graph && lastEndTime.current !== optionsRecord.endTime) {
        if (optionsRecord.endTime === null) {
          setOptions({ range: { num: 1, unit: 'hour', description: 'hour' } });
        } else {
          setOptions({
            range: {
              start: optionsRecord.endTime - 60 * 60,
              end: optionsRecord.endTime,
            },
          });
        }
      } else {
        lastEndTime.current = optionsRecord.endTime;
      }

      curPanelTab.current = type;
      setOptions({ type });
      setQueryStats(null);
    }
  }

  // 获取请求的结束时间戳
  function getEndTime(endTime = optionsRecord.endTime): number {
    return endTime === null ? moment().unix() : endTime;
  }

  // 更新时间戳
  function handleTimestampChange(endTime: Moment | null): void {
    setOptions({ endTime: endTime ? endTime?.unix() : null });
  }

  function setOptions(opts: Partial<PanelOptions>): void {
    setOptionsRecord((optionsRecord) => ({ ...optionsRecord, ...opts }));
  }

  // 图表选中时间改变,触发更新
  function handleGraphDateChange(range: Range) {
    const prevRange = optionsRecord.range;
    if (isAbsoluteRange(range) ? !_.isEqual(prevRange, range) : range.num !== (prevRange as RelativeRange).num || range.unit !== (prevRange as RelativeRange).unit) {
      const endTime = range.hasOwnProperty('unit') ? null : (range as AbsoluteRange).end;
      setOptions({
        endTime,
        range,
      });
    }
  }

  // 图表请求完成,回填请求信息
  function onGraphRequestCompleted(newQueryStats: QueryStats) {
    if (curPanelTab.current === PanelType.Graph) {
      setQueryStats(newQueryStats);
    }
  }

  // 触发语句查询
  function executeQuery(isExecute: boolean = true) {
    const expr = inputValue.current;
    if (!isExecute || expr === '' || clusters.length === 0) return;

    // 模式下直接调用图表组件的刷新方法
    if (curPanelTab.current === PanelType.Graph) {
      setQueryStats(null);
      graphRef.current && (graphRef.current as any).refresh();
      return;
    }
    // 存储查询历史
    // this.props.onExecuteQuery(expr);
    // 设置外部 options 参数
    // if (this.props.optionsRecord.expr !== expr) {
    //   this.setOptions({ expr });
    // }

    // 如果正在进行上一个请求,那么终止
    if (abortInFlightFetch.current) {
      abortInFlightFetch.current();
      abortInFlightFetch.current = null;
    }

    // 设置一个新的请求控制器
    const abortController = new AbortController();
    abortInFlightFetch.current = () => abortController.abort();
    setIsLoading(true);
    setQueryStats(null);
    const queryStart = Date.now();

    // 初始化参数
    const endTime = getEndTime();
    const params: URLSearchParams = new URLSearchParams({
      query: expr,
    });

    // 设置请求需要的参数
    let path = 'query';
    params.append('time', endTime.toString());

    prometheusAPI(path, params, {
      cache: 'no-store',
      credentials: 'same-origin',
      signal: abortController.signal,
    })
      .then((res: any) => {
        abortInFlightFetch.current = null;
        setIsLoading(false);
        if (curPanelTab.current === PanelType.Graph) {
          return;
        }
        if (res.hasOwnProperty('status') && res.status === 'success') {
          var tooLong = false;
          var LENGTH = 10000;
          var maxLength = 0;
          let { resultType, result } = res.data;
          if (result) {
            if (result.length > LENGTH) {
              tooLong = true;
              maxLength = result.length;
              result = result.slice(LENGTH);
            }
            result.forEach((item) => {
              if (item.values && item.values.length > LENGTH) {
                tooLong = true;
                if (item.values.length > maxLength) {
                  maxLength = item.values.length;
                }
                item.values = item.values.slice(LENGTH);
              }
            });
          }
          if (tooLong) {
            setErrorContent(`Warning:Fetched ${maxLength} metrics, only displaying first ${LENGTH}`);
          } else {
            setErrorContent('');
          }
          if (resultType === 'scalar' || resultType === 'string') {
            setVectorData({ resultType, result: [result] });
          } else {
            setVectorData({ resultType, result });
          }
          setQueryStats({
            loadTime: Date.now() - queryStart,
            resultSeries: res.data.result.length,
          });
        } else {
          setVectorData(null);
          setErrorContent(res?.error || '');
        }
      })
      .catch((error) => {
        setIsLoading(false);
      });
  }

  // 请求发生错误时,展示错误信息
  function onErrorOccured(errorArr: ErrorInfoType[]) {
    if (errorArr.length) {
      const errInfo = errorArr[0].error;
      setErrorContent(errInfo);
    } else {
      setErrorContent('');
    }
  }

  // 当时间戳变更时,重新获取数据
  useEffect(() => {
    optionsRecord.type === PanelType.Table && executeQuery();
  }, [optionsRecord.endTime, clusters]);

  // 切换标签到 Table 时获取数据
  useEffect(() => {
    optionsRecord.type === PanelType.Table && executeQuery();
  }, [optionsRecord.type, clusters]);

  return (
    <div className='panel'>
      {/* 输入框 */}
      <ExpressionInput
        queryHistory={['abs(go_gc_duration_seconds)']}
        value={inputValue.current}
        onExpressionChange={handleExpressionChange}
        metricNames={metrics}
        isLoading={isLoading}
        executeQuery={executeQuery}
      />
      {errorContent && <Alert className='error-alert' message={errorContent} type='error' />}
      {!isLoading && !errorContent && queryStats && <QueryStatsView {...queryStats} />}
      <Tabs className='panel-tab-box' type='card' activeKey={optionsRecord.type} onChange={handleTabChange}>
        <TabPane tab='Table' key='table'>
          <div className='table-timestamp'>
            Timestamp:{' '}
            <DatePicker
              placeholder='Evaluation time'
              showTime
              showNow={false}
              disabledDate={(current) => current > moment()}
              value={optionsRecord.endTime ? moment(optionsRecord.endTime * 1000) : null}
              onChange={handleTimestampChange}
            />
          </div>
          <List
            className='table-list'
            size='small'
            bordered
            loading={isLoading}
            dataSource={vectorData ? vectorData.result : []}
            renderItem={(item) => {
              const { metric, value, values } = item;
              return (
                <List.Item>
                  <div className='list-item-content'>
                    <div className='left'>{getListItemContent(vectorData?.resultType, metric)}</div>
                    {vectorData?.resultType === 'scalar' || vectorData?.resultType === 'string' ? (
                      item[1]
                    ) : (
                      <div>
                        {value && value.length > 1 && <div className='right'>{value[1] || '-'}</div>}
                        {values && values.length > 0 && (
                          <div className='right'>
                            {values.map((value) => {
                              return (
                                <>
                                  {value && value.length > 1 && (
                                    <span style={{ display: 'inline-block' }}>
                                      {value[1]} @{value[0]}
                                    </span>
                                  )}
                                  <br />
                                </>
                              );
                            })}
                          </div>
                        )}
                      </div>
                    )}
                  </div>
                </List.Item>
              );
            }}
          />
        </TabPane>
        <TabPane tab='Graph' key='graph'>
          {/* 操作栏 */}
          <div className='graph-operate-box'>
            <div className='left'>
              <Space>
                <DateRangePicker placement='bottomRight' value={optionsRecord.range} onChange={handleGraphDateChange} />
                <Resolution onChange={(v: number) => setOptions({ resolution: v })} initialValue={optionsRecord.resolution} />
                <Radio.Group
                  options={[
                    { label: <LineChartOutlined />, value: ChartType.Line },
                    { label: <AreaChartOutlined />, value: ChartType.StackArea },
                  ]}
                  onChange={(e) => {
                    e.preventDefault();
                    setChartType(e.target.value);
                  }}
                  value={chartType}
                  optionType='button'
                  buttonStyle='solid'
                />
              </Space>
            </div>
          </div>
          {/* 图 */}
          <div>
            {optionsRecord.type === PanelType.Graph && (
              <Graph
                ref={graphRef}
                showHeader={true}
                isShowRefresh={false}
                data={{
                  step: optionsRecord.resolution,
                  range: optionsRecord.range,
                  promqls: [inputValue],
                  chartType: chartType,
                }}
                onErrorOccured={onErrorOccured}
                onRequestCompleted={onGraphRequestCompleted}
              />
            )}
          </div>
        </TabPane>
      </Tabs>
      <span className='remove-panel-btn' onClick={removePanel}>
        <CloseCircleOutlined />
      </span>
    </div>
  );
}