Custom linetype creation, complex linetypes, LIN file loading, and linetype manager APIs.
WebCAD supports three types of linetype elements:
| Element Type | Class | Description |
|---|
| Simple element | SimpleLinetypeElement | Solid segments, gaps, points |
| Text element | TextLinetypeElement | Embedded text |
| Shape element | ShapeLinetypeElement | Embedded SHX shape symbols |
| Value | Meaning |
|---|
| Positive number | Solid segment length (same unit as drawing unit) |
| Negative number | Gap length (absolute value is the gap size) |
| 0 | Dot (draw a point at that position) |
const { LinetypeDefinition, SimpleLinetypeElement, Engine } = vjcad;
const ltManager = Engine.linetypeManager;
// Create dashed line: 12-unit solid, 6-unit gap, repeat...
const dashed = new LinetypeDefinition("MY_DASHED", "Simple dashed line ---- ----");
dashed.addElement(new SimpleLinetypeElement(12)); // 12-unit solid
dashed.addElement(new SimpleLinetypeElement(-6)); // 6-unit gap
ltManager.registerLinetype(dashed, "custom");
// Dash-dot line: solid - gap - dot - gap, repeat...
const dashdot = new LinetypeDefinition("MY_DASHDOT", "Dash-dot ____ . ____");
dashdot.addElement(new SimpleLinetypeElement(12)); // Solid
dashdot.addElement(new SimpleLinetypeElement(-3)); // Gap
dashdot.addElement(new SimpleLinetypeElement(0)); // Dot
dashdot.addElement(new SimpleLinetypeElement(-3)); // Gap
ltManager.registerLinetype(dashdot, "custom");
// Dash-dot-dot: solid - gap - dot - gap - dot - gap
const dashdotdot = new LinetypeDefinition("MY_DASHDOTDOT", "Dash-dot-dot ____ . . ____");
dashdotdot.addElement(new SimpleLinetypeElement(12));
dashdotdot.addElement(new SimpleLinetypeElement(-3));
dashdotdot.addElement(new SimpleLinetypeElement(0)); // First dot
dashdotdot.addElement(new SimpleLinetypeElement(-3));
dashdotdot.addElement(new SimpleLinetypeElement(0)); // Second dot
dashdotdot.addElement(new SimpleLinetypeElement(-3));
ltManager.registerLinetype(dashdotdot, "custom");
// Border line: solid - gap - solid - gap - dot - gap
const border = new LinetypeDefinition("MY_BORDER", "Border __ __ . __ __ .");
border.addElement(new SimpleLinetypeElement(10));
border.addElement(new SimpleLinetypeElement(-4));
border.addElement(new SimpleLinetypeElement(10));
border.addElement(new SimpleLinetypeElement(-4));
border.addElement(new SimpleLinetypeElement(0)); // Dot
border.addElement(new SimpleLinetypeElement(-4));
ltManager.registerLinetype(border, "custom");
const { TextLinetypeElement, TextRotationMode } = vjcad;
new TextLinetypeElement(text, style, options);
| Parameter | Description |
|---|
text | Text content to display |
style | Text style name (such as "STANDARD") |
options.scale | Scale ratio (default 1.0) |
options.rotation | Rotation angle (degrees) |
options.rotationMode | Rotation mode (see table below) |
options.xOffset | Offset in X direction (positive values follow line direction) |
options.yOffset | Offset in Y direction (negative values go downward; around -scale*0.3 can vertically center text) |
| Mode | Description |
|---|
TextRotationMode.UPRIGHT ("U") | Upright, text always remains readable |
TextRotationMode.RELATIVE ("R") | Relative, rotates with the line angle |
TextRotationMode.ABSOLUTE ("A") | Absolute, rotates relative to the origin |
const {
LinetypeDefinition, SimpleLinetypeElement,
TextLinetypeElement, TextRotationMode, Engine
} = vjcad;
const ltManager = Engine.linetypeManager;
// Hot water pipeline: ----HW----HW----
const hotWater = new LinetypeDefinition("HOT_WATER", "Hot water pipe ----HW----");
hotWater.addElement(new SimpleLinetypeElement(15)); // 15-unit solid
hotWater.addElement(new SimpleLinetypeElement(-2)); // Gap before text
hotWater.addElement(new TextLinetypeElement("HW", "STANDARD", {
scale: 2.0,
rotationMode: TextRotationMode.UPRIGHT, // Text always upright
yOffset: -0.6
}));
hotWater.addElement(new SimpleLinetypeElement(-8)); // Gap after text (must accommodate text width)
ltManager.registerLinetype(hotWater, "complex");
// Gas pipeline: ----GAS----GAS----
const gasLine = new LinetypeDefinition("GAS_LINE", "Gas pipe ----GAS----");
gasLine.addElement(new SimpleLinetypeElement(12));
gasLine.addElement(new SimpleLinetypeElement(-2));
gasLine.addElement(new TextLinetypeElement("GAS", "STANDARD", {
scale: 1.5,
rotationMode: TextRotationMode.UPRIGHT,
yOffset: -0.45
}));
gasLine.addElement(new SimpleLinetypeElement(-8));
ltManager.registerLinetype(gasLine, "complex");
const { ShapeLinetypeElement } = vjcad;
new ShapeLinetypeElement(shapeName, shapeFile, options);
| Parameter | Description |
|---|
shapeName | SHX shape name |
shapeFile | SHX shape file name |
options | Same as TextLinetypeElement |
const { ShapeLinetypeElement, TextRotationMode } = vjcad;
// Flow direction line: with arrow
const flowArrow = new LinetypeDefinition("FLOW_ARROW", "Flow line -->-->-->");
flowArrow.addElement(new SimpleLinetypeElement(12));
flowArrow.addElement(new SimpleLinetypeElement(-1));
flowArrow.addElement(new ShapeLinetypeElement("ARROW", "ltypeshp.shx", {
scale: 0.8,
rotation: 0,
rotationMode: TextRotationMode.RELATIVE // Rotates with line direction
}));
flowArrow.addElement(new SimpleLinetypeElement(-1));
ltManager.registerLinetype(flowArrow, "complex");
// Track line: with square
const track = new LinetypeDefinition("TRACK", "Track --□--□--");
track.addElement(new SimpleLinetypeElement(10));
track.addElement(new SimpleLinetypeElement(-2));
track.addElement(new ShapeLinetypeElement("BOX", "ltypeshp.shx", {
scale: 1.2,
rotationMode: TextRotationMode.UPRIGHT // Square remains upright
}));
track.addElement(new SimpleLinetypeElement(-2));
ltManager.registerLinetype(track, "complex");
;; Comments start with semicolon
*linetype_name,description
A,pattern_element1,pattern_element2,...
*ACAD_ISO02W100,ISO dashed line ____ ____
A,12,-3
*ACAD_ISO07W100,ISO dash-dot line ____ . ____
A,24,-3,0,-3
const { LinetypeParser, Engine } = vjcad;
const ltManager = Engine.linetypeManager;
// .lin format definition string
const linDefinitions = `
*MY_DASHED,My dashed line ____ ____
A,12,-3
*MY_DOTTED,My dotted line . . . .
A,0,-6
*MY_DIVIDE,My divide line ____ . ____
A,12.7,-6.35,0,-6.35
`;
// Parse .lin format
const parser = new LinetypeParser();
const definitions = parser.parse(linDefinitions);
console.log(`Parsed ${definitions.length} linetype definitions`);
// Register parsed linetypes
for (const def of definitions) {
if (parser.validateDefinition(def)) {
ltManager.registerLinetype(def, "imported");
console.log(`Registered: ${def.name}`);
}
}
// Or use the convenience method to load all at once
const loadedCount = ltManager.loadFromLinDefinitions(linDefinitions, "imported");
console.log(`Loaded ${loadedCount} linetypes`);
const ltManager = Engine.linetypeManager;
// Register linetype
ltManager.registerLinetype(definition, "category");
// Get linetype definition
const def = ltManager.getLinetype("HIDDEN");
console.log(def.name); // Linetype name
console.log(def.description); // Description
console.log(def.elements); // Element array
console.log(def.patternLength); // Pattern length
console.log(def.isComplex); // Whether complex linetype
// Check whether it exists
const exists = ltManager.hasLinetype("MY_LINETYPE");
// Remove linetype (built-in linetypes cannot be removed)
ltManager.removeLinetype("MY_LINETYPE");
// Get all linetype names
const allNames = ltManager.getAllLinetypeNames();
const categoryNames = ltManager.getAllLinetypeNames("custom");
// Get all linetype definitions
const allDefs = ltManager.getAllLinetypes();
// Export as .lin format
const linString = ltManager.exportToLinFormat(["MY_LINE1", "MY_LINE2"]);
const categoryLin = ltManager.exportToLinFormat(null, "custom");
// Get all categories
const categories = ltManager.getCategories();
// Returns: ["builtin", "custom", "complex", "imported", ...]
// Check whether it is a built-in linetype
const isBuiltin = ltManager.isBuiltinLinetype("CONTINUOUS"); // true
// Clear all custom linetypes
ltManager.clearCustomLinetypes();
// Reset to default state
ltManager.reset();
// Get statistics
const stats = ltManager.getStatistics();
console.log(stats.total); // Total linetype count
console.log(stats.categories); // Count per category
// Export to JSON
const jsonDef = definition.toJSON();
// Restore from JSON
const restoredDef = LinetypeDefinition.fromJSON(jsonDef);
const line = new LineEnt([0, 0], [100, 0]);
line.setDefaults();
line.lineType = "HOT_WATER"; // Linetype name
line.lineTypeScale = 1.0; // Linetype scale
Engine.addEntities(line);
| lineTypeScale | Effect |
|---|
| 0.5 | Denser (smaller elements) |
| 1.0 | Default |
| 2.0 | Sparser (larger elements) |
Tip: ISO linetypes often need scale adjustment (such as 0.5) to display correctly.
WebCAD includes the following commonly used linetypes:
| Name | Description |
|---|
CONTINUOUS | Continuous (default) |
HIDDEN | Dashed |
CENTER | Center line |
PHANTOM | Phantom line |
DASHED | Short dashed line |
DASHDOT | Dash-dot line |
BORDER | Border line |
DIVIDE | Divide line |
const {
MainView, initCadContainer, LineEnt, Engine,
LinetypeDefinition, SimpleLinetypeElement,
TextLinetypeElement, TextRotationMode
} = vjcad;
// Initialize
const cadView = new MainView({...});
initCadContainer("map", cadView);
await cadView.onLoad();
const ltManager = Engine.linetypeManager;
// 1. Create simple linetype
const myDash = new LinetypeDefinition("MY_DASH", "Custom dashed line");
myDash.addElement(new SimpleLinetypeElement(10));
myDash.addElement(new SimpleLinetypeElement(-5));
ltManager.registerLinetype(myDash, "custom");
// 2. Create complex linetype (with text)
const pipeLine = new LinetypeDefinition("PIPE", "Pipeline");
pipeLine.addElement(new SimpleLinetypeElement(12));
pipeLine.addElement(new SimpleLinetypeElement(-2));
pipeLine.addElement(new TextLinetypeElement("P", "STANDARD", {
scale: 2.0,
rotationMode: TextRotationMode.UPRIGHT,
yOffset: -0.6
}));
pipeLine.addElement(new SimpleLinetypeElement(-4));
ltManager.registerLinetype(pipeLine, "complex");
// 3. Apply linetypes
const line1 = new LineEnt([0, 0], [200, 0]);
line1.setDefaults();
line1.lineType = "MY_DASH";
line1.lineTypeScale = 1.0;
Engine.addEntities(line1);
const line2 = new LineEnt([0, 30], [200, 30]);
line2.setDefaults();
line2.lineType = "PIPE";
line2.lineTypeScale = 1.0;
Engine.addEntities(line2);
Engine.zoomExtents();