Carnelian Diagram is a typescript library that allows you to create interactive diagrams for your web applications.
The library aims to achieve several goals. First and foremost, it is not just a collection of pre-built tools and features, but also an engine that enables you to create your own.
Secondly, Carnelian Diagram is designed to have similarities with the popular React library. If you are already familiar with React, your skills will be transferrable to this library as well. You can develop custom interactive elements using similar concepts, such as functional components (using custom and standard hooks like useState and useEffect), JSX syntax, and higher-order components. This familiarity makes it easy to learn and integrate Carnelian Diagram into your projects.
However, it is important to note that Carnelian Diagram is not based on React and does not require its installation in your project. You can use the library with vanila TypeScript/JavaScript or alongside other tools. The library utilizes its own engine, similar to React but simpler and designed to meet specific needs.
Carnelian Diagram is available as a set of several npm packages.
This package is a core of Carnelian Diagram library and contains base functionality to create and render diagrams.
npm install @carnelian-diagram/core
This package contains tools to make a diagram and its elements respond to a user's input.
npm install @carnelian-diagram/interactivity
This package containt some ready to use basic diagram elements and shapes: rectangle, ellipse, polygons, lines, text elements, etc.
npm install @carnelian-diagram/shapes
import { Diagram, DiagramDOM, DiagramRoot } from "@carnelian-diagram/core";
import { InteractionController, withInteractivity } from "@carnelian-diagram/interactivity";
import {
InteractiveRoundedRect as RoundedRect,
InteractiveCircle as Circle
} from "@carnelian-diagram/shapes/basic";
const root = document.getElementById("root");
if (root && root instanceof SVGGraphicsElement) {
const diagram = new Diagram();
diagram.add(RoundedRect, { x: 100, y: 100, width: 200, height: 150, radius: "25%", style: { fill: "yellow" } });
diagram.add(Circle, { x: 280, y: 220, radius: 80, style: { fill: "blue" }});
const controller = new InteractionController(diagram);
const diagramDOM = DiagramDOM.createRoot(diagram, root, withInteractivity(DiagramRoot, controller));
controller.attach(root);
diagramDOM.attach();
}
Firstly, you need to configure JSX for typescript. Add the following lines to your tsconfig.json:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@carnelian-diagram/core"
}
}
Instead of adding jsxImportSource
to the tsconfig.json, you can define the typescript pragma at the beginning of your .tsx files. This can be useful when your project has already had some other JSX configuration (e.g. React projects) and you need to overwrite it for your custom diagram elements.
/** @jsxImportSource @carnelian-diagram/core */
// The rest of the .tsx file
...
Here is the example for a simple interactive rectangle:
/** @jsxImportSource @carnelian-diagram/core */
import { DiagramElement } from "@carnelian-diagram/core";
import { withInteractiveRect } from "@carnelian-diagram/interactivity";
export interface RectProps {
x: number;
y: number;
width: number;
height: number;
style?: any;
}
export const Rect: DiagramElement<RectProps> = function(props) {
const { x, y, width, height, style } = props;
return (
<rect x={x} y={y} width={width} height={height} style={style} />
);
};
export const InteractiveRect = withInteractiveRect(Rect);
See Examples folder for more examples of using the library and @carnelian-diagram/shapes package source for creating custom elements.
Demo application is available here.
This project is licensed under the terms of the MIT license.