editor-chart/Chart.tsx (149 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { FC, useState } from 'react';
import { Button, Dropdown } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
import { useRenderChart } from './hooks';
export interface ChartProps {
editor;
previewElement: HTMLElement;
}
const Chart: FC<ChartProps> = ({ editor, previewElement }) => {
useRenderChart(previewElement);
const { t } = useTranslation('plugin', {
keyPrefix: 'chart_editor.frontend',
});
const [isLocked, setLockState] = useState(false);
const handleMouseEnter = () => {
if (isLocked) {
return;
}
setLockState(true);
};
const handleMouseLeave = () => {
setLockState(false);
};
const headerList = [
{
label: t('flow_chart'),
tpl: `graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]`,
},
{
label: t('sequence_diagram'),
tpl: `sequenceDiagram
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
John-->>-Alice: I feel great!
`,
},
{
label: t('state_diagram'),
tpl: `stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
`,
},
{
label: t('class_diagram'),
tpl: `classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
`,
},
{
label: t('pie_chart'),
tpl: `pie title Pets adopted by volunteers
"Dogs" : 386
"Cats" : 85
"Rats" : 15
`,
},
{
label: t('gantt_chart'),
tpl: `gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
another task : 24d
`,
},
{
label: t('entity_relationship_diagram'),
tpl: `erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ INVOICE : "liable for"
DELIVERY-ADDRESS ||--o{ ORDER : receives
INVOICE ||--|{ ORDER : covers
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
`,
},
];
const handleChange = (tpl: string) => {
const { ch } = editor.getCursor();
editor.replaceSelection(`${ch ? '\n' : ''}\`\`\`mermaid\n${tpl}\n\`\`\`\n`);
};
return (
<div className="toolbar-item-wrap">
<Dropdown>
<Dropdown.Toggle
type="button"
as={Button}
variant="link"
title={t('title')}
className="p-0 b-0 btn-no-border toolbar text-body">
<i className="bi bi-diagram-3-fill"></i>
</Dropdown.Toggle>
<Dropdown.Menu
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}>
{headerList.map((header) => {
return (
<Dropdown.Item
key={header.label}
onClick={(e) => {
e.preventDefault();
handleChange(header.tpl);
}}>
{header.label}
</Dropdown.Item>
);
})}
</Dropdown.Menu>
</Dropdown>
</div>
);
};
export default Chart;