#javascript #gojs
#javascript #gojs
Вопрос:
Я настраивал проект планировщика этажей из GoJS и хочу создать свой собственный настраиваемый элемент (сгруппированные элементы) в области палитры. Я смог сгенерировать элемент, но элементы внутри группы не реагируют на карту шаблона узла, которую я настроил, как показано на скриншоте ниже:
Чего я ожидал, так это иметь сгруппированный элемент, подобный этому:
Вот как я настраиваю свои карты шаблонов:
Для синих линий
function makeBlueLine() {
var $ = go.GraphObject.make;
return $(go.Node, "Auto",
{
contextMenu: makeContextMenu(),
selectionObjectName: "SHAPE",
selectionAdorned: false,
resizeAdornmentTemplate: makeWallPartResizeAdornment(),
locationSpot: go.Spot.Left,
toolTip: makeNodeToolTip(),
resizable: true,
resizeObjectName: "SHAPE",
rotatable: true,
doubleClick: function (e) { if (e.diagram.floorplanUI) e.diagram.floorplanUI.hideShow("selectionInfoWindow"); },
},
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
new go.Binding("visible", "showOnPlan"),
new go.Binding("angle", "angle"),
$(go.Shape,
{ name: "SHAPE", fill: "blue", stroke: "#000", strokeWidth: 1, height: 1, figure: "Rectangle" },
new go.Binding("width", "length").makeTwoWay(),
new go.Binding("stroke", "isSelected", function (s, obj) {
return s ? "green" : "blue";
}).ofObject(),
),
);
}
Для группы
function makeLineContainer() {
var $ = go.GraphObject.make;
return $(go.Group, "Vertical",
{
//isSubGraphExpanded: false,
contextMenu: makeContextMenu(),
doubleClick: function (e) {
if (e.diagram.floorplanUI) e.diagram.floorplanUI.hideShow("selectionInfoWindow");
},
toolTip: makeGroupToolTip()
},
new go.Binding("location", "loc"),
$(go.Panel, "Auto",
$(go.Shape, "RoundedRectangle", { fill: "rgba(0,0,0,0)", stroke: null, name: 'SHAPE', strokeCap: 'square' },
new go.Binding("fill", "isSelected", function (s, obj) {
return s ? "rgba(128, 128, 128, 0.10)" : "rgba(0,0,0,0)";
}).ofObject()
),
$(go.Placeholder, { padding: 5 })
)
)
}
Это моя настройка массива модели:
BLUE_LINE_DATA_ARRAY = [
{
category: "LineParent",
key: "Type1",
isGroup: true,
},
{
category: "BlueLine",
group: "Type1",
loc: '0 0',
angle: 90,
length: 50,
key: "G1",
},
{
category: "BlueLine",
group: "Type1",
loc: '10 10',
angle: 0,
length: 50,
key: "G2",
},
];
Для инициализации палитры я не внес никаких изменений, кроме добавления карты шаблона группы. Вот сопоставление шаблона, которое я сделал:
this.nodeTemplateMap.add("BlueLine", makeBlueLine());
this.groupTemplateMap.add("LineParent", makeLineContainer());
Я не смог найти то, чего мне не хватает. Я также проверил на macros.html пример, и все выглядит аналогично.
Ответ №1:
Я только что попытался реализовать такой образец, но не смог столкнуться с какими-либо проблемами с группами в палитре. Вот мой код:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
<script src="go.js"></script>
<script>
function init() {
var $ = go.GraphObject.make;
// initialize main Diagram
myDiagram =
$(go.Diagram, "myDiagramDiv",
{ "undoManager.isEnabled": true });
myDiagram.nodeTemplate =
$(go.Node, "Auto",
new go.Binding("location", "location", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Shape,
{ fill: "white", stroke: "gray", strokeWidth: 2 },
new go.Binding("stroke", "color")),
$(go.TextBlock,
{ margin: 4 },
new go.Binding("text").makeTwoWay())
);
// initialize Palette
myPalette =
$(go.Palette, "myPaletteDiv",
{ nodeTemplateMap: myDiagram.nodeTemplateMap });
myPalette.model.nodeDataArray = [
{ key: 1, group: 3, text: "blue node", color: "blue", location: "30 0" },
{ key: 2, group: 3, text: "orange node", color: "orange", location: "0 40" },
{ key: 3, isGroup: true, text: "GROUP" }
];
// initialize Overview
myOverview =
$(go.Overview, "myOverviewDiv",
{ observed: myDiagram, contentAlignment: go.Spot.Center });
load();
}
// save a model to and load a model from Json text, displayed below the Diagram
function save() {
var str = myDiagram.model.toJson();
document.getElementById("mySavedModel").value = str;
}
function load() {
var str = document.getElementById("mySavedModel").value;
myDiagram.model = go.Model.fromJson(str);
}
</script>
</head>
<body onload="init()">
<div style="width: 100%; display: flex; justify-content: space-between">
<div style="display: flex; flex-direction: column; margin: 0 2px 0 0">
<div id="myPaletteDiv" style="flex-grow: 1; width: 120px; background-color: whitesmoke; border: solid 1px black"></div>
<div id="myOverviewDiv" style="margin: 2px 0 0 0; width: 120px; height: 100px; background-color: lightgray; border: solid 1px black"></div>
</div>
<div id="myDiagramDiv" style="flex-grow: 1; height: 400px; border: solid 1px black"></div>
</div>
<div id="buttons">
<button id="loadModel" onclick="load()">Load</button>
<button id="saveModel" onclick="save()">Save</button>
</div>
<textarea id="mySavedModel" style="width:100%;height:200px">
{ "class": "go.GraphLinksModel",
"nodeDataArray": [
{"key":1, "text":"hello", "color":"green", "location":"0 0"},
{"key":2, "text":"world", "color":"red", "location":"70 0"}
],
"linkDataArray": [
{"from":1, "to":2}
]}
</textarea>
</body>
</html>
Обратите внимание, как группа отображается в палитре, и когда копия удаляется на главной диаграмме. Каждый из двух узлов-членов расположен в соответствии с привязкой, и они остаются в этом относительном местоположении, пока пользователь не переместит узел-член на главной диаграмме.
Комментарии:
1. Спасибо за ваш ответ, Уолтер. Да, я также пытался изменить Macros.html образец, который поставляется с загружаемым GoJS, и он отлично работает, как и предполагалось. Просто в примере планировщика этажей он действует по-другому. Я пытался отключить прослушиватели и вызовы пользовательских методов, но все еще безуспешно. Могло ли это быть связано с тем, как палитра объявлена в планировщике этажа? Это единственное, что я могу найти, которое было реализовано по-разному в примере, который вы предоставили, и с Macros.html пример.
Ответ №2:
Попытался изучить это еще немного, но, к сожалению, я все еще не нашел окончательной причины проблемы. Тем не менее, я нашел обходной путь, но это будет стоить мне возможности иметь несколько палитр для планировщика этажей. Итак, в основном, я изменил конструктор палитры пакета floor planner, чтобы следовать шаблону образцов для палитры, найденных на веб-сайте GoJS.
Как это было объявлено первым:
function FloorplanPalette(div, floorplan, nodeDataArray) {
go.Palette.call(this, div);
var $ = go.GraphObject.make;
this.model = $(go.GraphLinksModel, { nodeDataArray: nodeDataArray });
this.contentAlignment = go.Spot.Center;
this.nodeTemplateMap = floorplan.nodeTemplateMap;
this.groupTemplateMap = floorplan.groupTemplateMap;
this.toolManager.contextMenuTool.isEnabled = false;
// add this new FloorplanPalette to the "palettes" field of its associated Floorplan
floorplan.palettes.push(this);
} go.Diagram.inherit(FloorplanPalette, go.Palette);
Мое изменение:
function FloorplanPalette(div, floorplan, nodeDataArray) {
var $ = go.GraphObject.make;
myPalette =
$(go.Palette, div, // must name or refer to the DIV HTML element
{
nodeTemplateMap: floorplan.nodeTemplateMap,
groupTemplateMap: floorplan.groupTemplateMap,
contentAlignment: go.Spot.Center,
});
myPalette.model = new go.GraphLinksModel(nodeDataArray);
}