I'm trying to put together a chart with nested elements that connect to each others' endpoints. As you can see in this jsFiddle, it's not going very well. The JS is reproduced below in full:
jsPlumb.ready(function () {
jsPlumb.importDefaults({ ConnectionOverlays: [["Arrow", { location: 1 }]] });
var pinCount = 0;
var pin = {
endpoint: "Dot",
isSource: true,
isTarget: true,
maxConnections: -1,
paintStyle: {
strokeStyle: "#1e8151",
fillStyle: "transparent",
radius: 7,
lineWidth: 2
},
connectorStyle: {
lineWidth: 3,
strokeStyle: "#deea18",
joinstyle: "round",
outlineColor: "#eaedef",
outlineWidth: 0,
overlays: [
["Arrow", {
location: 1
}]
]
},
connectorHoverStyle: {
lineWidth: 4,
strokeStyle: "#5C96BC",
outlineWidth: 2,
outlineColor: "white"
},
connector: ["StateMachine", {
stub: [5, 5],
gap: 10,
cornerRadius: 5,
alwaysRespectStubs: true
}]
}
jsPlumb.draggable($(".container"));
jsPlumb.draggable($(".reactor"), { containment: "parent" });
function rebalance(part, side) {
var ends = $.grep(jsPlumb.getEndpoints(part), function (elem, i) {
return elem.anchor.type == side
});
var len = ends.length + 1;
$.each(ends, function (i, elem) {
elem.anchor.y = (1 / len) * (i + 1);
});
jsPlumb.repaintEverything();
}
function addPin(part, side) {
jsPlumb.addEndpoint(part, pin, { anchor: side, uuid: "pin" + pinCount });
pinCount++;
rebalance(part, side);
}
var $c = $("#container");
var $r1 = $("#child1"), $r2 = $("#child2");
addPin($c, "Left");
addPin($c, "Right");
addPin($r1, "Left");
addPin($r1, "Right");
addPin($r2, "Left");
addPin($r2, "Right");
jsPlumb.connect({uuids: ["pin0", "pin2"]});
jsPlumb.connect({uuids: ["pin3", "pin4"]});
jsPlumb.connect({uuids: ["pin5", "pin1"]});
});
Peer node connections, as in ["pin3", "pin4"], look sane until you move any part of the chart. Then they explode. Connections between parent/child endpoints never really do what they're supposed to. Removing position: absolute; and draggable from all elements involved does something half-way passable, but a) still has some placement issues and b) removing those properties defeats the purpose.
General jsPlumb tips welcome, but specifically: Am I doing something wrong that prevents this from lining up properly? Am I misusing some property of connectors/endpoints? Is there a workaround for the placement issue I'm running into here?
Related
Could someone help me out with what I am missing?
The scenario is: there are several nodes. Among them, one node can connect with 3 other nodes and those connections should be labeled.
The codes are connecting multiple nodes with labels, but on save it doesn't save the labels. On page load, it shows the connections but not the labels.
Here are my codes.
let connector = [
"EditableBezier",
{
cornerRadius: 0,
curviness: 30,
},
];
let paintStyle = {
strokeWidth: 2,
stroke: "rgb(217,217,217)",
outlineWidth: 3,
outlineStroke: "transparent",
};
let paintStyle = {
strokeWidth: 2,
stroke: "rgb(217,217,217)",
outlineWidth: 3,
outlineStroke: "transparent",
};
let hoverStyle = {
strokeWidth: 2,
stroke: "rgb(67,67,67)",
};
let abLabelCounter = 1;
function abSplitConnections(params) {
var source = params.connection.source;
var target = params.connection.target;
if (source.id === target.id) return false;
var conn = jsPlumb.getInstance();
let c = conn.connect({
source: source,
target: target,
editable: true,
anchor: "AutoDefault",
endpoint: "Blank",
connector: connector,
paintStyle: paintStyle,
hoverPaintStyle: hoverStyle,
overlays: [
[
"Arrow",
{
location: 1,
width: 10,
length: 10,
},
],
[
"Label",
{
location: 0.5,
label: () => {
if (abLabelCounter === 1) {
abLabelCounter++;
return "A";
}
if (abLabelCounter === 2) {
abLabelCounter++;
return "B";
}
if (abLabelCounter === 3) {
abLabelCounter = 1;
return "C";
}
},
id: "partition",
},
],
],
});
}
My version is gojs-1.7.22 and I am trying to load the sample productionProcess but its retrieving the following error:
"GraphObject.make requires a class function or GoJS class name or name of an object builder, not: ToolTip".
I am doing something wrong?
// Load libs
var $ = go.GraphObject.make; // for conciseness in defining templates
myDiagram = $(go.Diagram, "myDiagramDiv", // create a Diagram for the DIV HTML element
{
maxSelectionCount: 1, // users can select only one part at a time
"toolManager.hoverDelay": 10, // how quickly tooltips are shown
initialAutoScale: go.Diagram.Uniform, // scale to show all of the contents
"ChangedSelection": onSelectionChanged, // view additional information
});
function infoString(obj) {
var part = obj.part;
if (part instanceof go.Adornment) part = part.adornedPart;
var msg = "";
if (part instanceof go.Link) {
msg = "";
} else if (part instanceof go.Node) {
msg = part.data.text + ":\n\n" + part.data.description;
}
return msg;
}
var colors = {
"red": "#be4b15",
"green": "#52ce60",
"blue": "#6ea5f8",
"lightred": "#fd8852",
"lightblue": "#afd4fe",
"lightgreen": "#b9e986",
"pink": "#faadc1",
"purple": "#d689ff",
"orange": "#fdb400",
};
// A data binding conversion function. Given an name, return the Geometry.
// If there is only a string, replace it with a Geometry object, which can be shared by multiple Shapes.
function geoFunc(geoname) {
var geo = icons[geoname];
if (typeof geo === "string") {
geo = icons[geoname] = go.Geometry.parse(geo, true);
}
return geo;
}
myDiagram.nodeTemplate =
$(go.Node, "Spot",
{
locationObjectName: 'main',
locationSpot: go.Spot.Center,
toolTip:
$("ToolTip",
$(go.TextBlock, { margin: 4, width: 140 },
new go.Binding("text", "", infoString).ofObject())
)
},
new go.Binding("location", "pos", go.Point.parse).makeTwoWay(go.Point.stringify),
// The main element of the Spot panel is a vertical panel housing an optional icon,
// plus a rectangle that acts as the port
$(go.Panel, "Vertical",
$(go.Shape, {
name: 'icon',
width: 1, height: 1,
stroke: null, strokeWidth: 0,
fill: colors.blue
},
new go.Binding("fill", "color", function (c) { return colors[c]; }),
new go.Binding("width", "iconWidth"),
new go.Binding("height", "iconHeight"),
new go.Binding("geometry", "icon", geoFunc)),
$(go.Shape, {
name: 'main',
width: 40, height: 40,
margin: new go.Margin(-1, 0, 0, 0),
portId: "",
stroke: null, strokeWidth: 0,
fill: colors.blue
},
new go.Binding("fill", "color", function (c) { return colors[c]; }),
new go.Binding("width", "portWidth"),
new go.Binding("height", "portHeight"))
),
$(go.TextBlock, {
font: "Bold 14px Lato, sans-serif",
textAlign: "center",
margin: 3,
maxSize: new go.Size(100, NaN),
alignment: go.Spot.TopCenter,
alignmentFocus: go.Spot.BottomCenter
},
new go.Binding("text"))
);
// Some links need a custom to or from spot
function spotConverter(dir) {
if (dir === "left") return go.Spot.LeftSide;
if (dir === "right") return go.Spot.RightSide;
if (dir === "top") return go.Spot.TopSide;
if (dir === "bottom") return go.Spot.BottomSide;
if (dir === "rightsingle") return go.Spot.Right;
}
myDiagram.linkTemplate =
$(go.Link, {
toShortLength: -2,
fromShortLength: -2,
layerName: "Background",
routing: go.Link.Orthogonal,
corner: 15,
fromSpot: go.Spot.RightSide,
toSpot: go.Spot.LeftSide
},
// make sure links come in from the proper direction and go out appropriately
new go.Binding("fromSpot", "fromSpot", function (d) { return spotConverter(d); }),
new go.Binding("toSpot", "toSpot", function (d) { return spotConverter(d); }),
new go.Binding("points").makeTwoWay(),
// mark each Shape to get the link geometry with isPanelMain: true
$(go.Shape, { isPanelMain: true, stroke: colors.lightblue, strokeWidth: 10 },
new go.Binding("stroke", "color", function (c) { return colors[c]; })),
$(go.Shape, { isPanelMain: true, stroke: "white", strokeWidth: 3, name: "PIPE", strokeDashArray: [20, 40] })
);
myDiagram.model = go.Model.fromJson(document.getElementById("mySavedModel").value);
loop(); // animate some flow through the pipes
I am following the sample described in the following link
https://github.com/NorthwoodsSoftware/GoJS/blob/master/samples/productionProcess.html
The "ToolTip" builder was added in version 2.0. Try using the sample from the 1.7 version.
I'm trying to create one real-time flot and my problem is that I can't get to see the flot grid through the filling of my data's lines..
If you have any idea to get my filling a bit transparent like the picture below, I'd like to apply it as well on my Fiddle!
What I'm trying to achieve is something like that:
Picture of what I try to get
Here is the Fiddle on what I'm working:
My flot on Fiddle
Code:
$(function () {
getRandomData = function(){
var rV = [];
for (var i = 0; i < 10; i++){
rV.push([i,Math.random() * 10]);
}
return rV;
}
getRandomDataa = function(){
var rV = [];
for (var i = 0; i < 10; i++){
rV.push([i,Math.random() * 10 + 5]);
}
return rV;
}
getSeriesObj = function() {
return [
{
data: getRandomDataa(),
lines: {
show: true,
fill: true,
lineWidth: 5,
fillColor: { colors: [ "#b38618", "#b38618" ] },
tickColor: "#FFFFFF",
tickLength: 5
}
}, {
data: getRandomData(),
lines: {
show: true,
lineWidth: 0,
fill: true,
fillColor: { colors: [ "#1A508B", "#1A508B" ] },
tickColor: "#FFFFFF",
tickLength: 5
}
}];
}
update = function(){
plot.setData(getSeriesObj());
plot.draw();
setTimeout(update, 1000);
}
var flotOptions = {
series: {
shadowSize: 0, // Drawing is faster without shadows
tickColor: "#FFFFFF"
},
yaxis: {
min: 0,
autoscaleMargin: 0,
position: "right",
transform: function (v) { return -v; }, /* Invert data on Y axis */
inverseTransform: function (v) { return -v; },
font: { color: "#FFFFFF" },
tickColor: "#FFFFFF"
},
grid: {
backgroundColor: { colors: [ "#EDC240", "#EDC240" ], opacity: 0.5 }, // "Ground" color (May be a color gradient)
show: true,
borderWidth: 1,
borderColor: "#FFFFFF",
verticalLines: true,
horizontalLines: true,
tickColor: "#FFFFFF"
}
};
var plot = $.plot("#placeholder", getSeriesObj(), flotOptions);
setTimeout(update, 1000);
});
Thanks a lot!
You can use the rgba() color specification with flot to specify the fill color and alpha level (transparency):
fillColor: { colors: [ "rgba(179, 134, 24, .2)", "rgba(179, 134, 24, .2)" ] },
An alpha value of 0 is fully transparent, while an alpha value of 1 is fully opaque.
Hopefully someone can help me as I'm stuck at the moment after searching for a solution already for the last 2 days.
I decided to look into HighCharts yesterday for a new project and it does do what I'm after. However I'm trying to make the implementation option into my WordPress plugin as clean as possible and that's where I'm stuck at the moment.
This JSFiddle is working and shows what I like to get as output: http://jsfiddle.net/golabs/tpKU3/
But I would like to be able to create a new chart by just calling a function and supply the target div ID and the 2 dataArray's. My attempt can be found here: http://jsfiddle.net/golabs/rstpA/
or see the jscode here:
/**
* However this second section of code does NOT work as nothing is displayed in the container21 div...
* What am I doing wrong here?
* I like to be able to create a new chart by only supplying the target div ID and the dataArray's, this
* to have be able to manage the general settings centrally.
*
* This JSFIDDLE is related to: http://jsfiddle.net/golabs/tpKU3/
**/
$(function () {
var __catergories__ = ['AAA','BBB','CCC','DDD','EEE','FFF','GGG'];
var getChartConfig = function( renderId, dataArray1, dataArray2 ) {
var config = {};
config.chart = {
renderTo: renderId, polar: true, type: 'line', height: 254, width: 360, className: 'SpiderPolarChart', backgroundColor: 'rgba(101,101,101,.1)'
};
config.title = {
text: ''
};
config.legend = {
layout: 'horizontal', align: 'center', verticalAlign: 'bottom', y: -3,
};
config.credits = {
enabled: true, text: 'highcharts.com', href: 'http://highcharts.com/', position: {
verticalAlign: 'bottom',
x: -11,
}
};
config.pane = {
startAngle: -90, endAngle: 90, center: ['50%', '93%'], size: 300, background: null
};
config.xAxis = {
categories: __catergories__,
tickmarkPlacement: 'on', tickPixelInterval: 1, lineWidth: 0, labels: {
rotation: 'auto',
distance: 12
}, showLastLabel: true
};
config.yAxis = {
gridLineInterpolation: 'circle', gridLineDashStyle: 'LongDash', tickInterval: 1, lineWidth: 0, min: 0, max: 5, ceiling: 5, labels: {
x: 4, y: 15
}, showLastLabel: true
};
config.exporting = {
enabled: false
};
config.tooltip = {
shared: true, pointFormat: '<span style="color:{series.color}">{series.name}: <b>{point.y:,.0f}</b><br/>'
};
config.series = [{
name: 'Overall Rating', data: dataArray1, color: '#D4A539', type: 'area', pointPlacement: 'on', connectEnds: false, index: 1, legendIndex: 2
},{
name: 'Personal Rating', data: dataArray2, color: '#333', type: 'line', pointPlacement: 'on', connectEnds: false, index: 2, legendIndex: 1
}];
return config;
};
// ===========================================================================
charts.push(new Highcharts.Chart(
getChartConfig( "container21", [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
));
});
I've run the code through JSHint.com so all typos should be tackled as it doesn't show any errors at the moment.
I hope someone can guide me into the right direction to get this to work.
Cheers!
** Updated the links to the JSFiddles **
** ISSUE RESOLVED, see below **
In this jsFiddle (http://jsfiddle.net/golabs/rstpA/) you are not telling it what chart is. You are trying to set the options for a chart that you have not created to update the options you are passing. It is sort of backwards.
Here is a quick "fix":
var newChart = new Highcharts.Chart(
getChartConfig( "container21", [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
);
Now, I would think it would be better to setup a global option set and then merge in your new set (specific to chart you want to build) as in my linked SO answer. This may or may not give you more flexibility.
charts was not defined.
Is this the solution you are looking for?
var charts = [];
charts.push(new Highcharts.Chart(
getChartConfig( "container21", [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
));
http://jsfiddle.net/37Gsv/1/
you may try this:
var charts = [];
var i=0;
for (i =1; i< 10; i++){
var o =i.toString();
charts.push(new Highcharts.Chart(
getChartConfig( "container2"+o, [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
));
}
test link: http://jsfiddle.net/newpiseth/8u0tkkkL/5/
I'm plotting a graph with jQuery Plot. The graph contents 2 lines with points. I set the the option 'clickable' in grid on true. It makes all points clickable.
The question is how can I set only separate points clickable?
Here is my code:
d1 = [[889.0, y_max], [905.0, y_max], [915.0, y_max], [935, y_max]];
d2 = [[885.0, 0.4], [905.0, 0.6], [915.0, 0.34], [935, 0.39]];
options = {
yaxis: { min: y_min, max: y_max },
grid: { hoverable: true,
clickable: true,
borderWidth: 0 },
legend: {
show: true,
noColumns: 4,
container: $("#labeler"),
labelFormatter: function (label, series) {
var cb = label;
return cb;
}
}
};
ed_data = [
{ data: d1,
points: { show: true, symbol: "diamond" },
lines: { show: false },
color: "#FF0000"
},
{ label: "Serie 1",
data: d2,
points: { show: true,
symbol: "triangle" },
lines: { show: true,
lineWidth: 1 }
}];
pl = $.plot($("#placeholder_top"), ed_data, options);
OK, this is a bit of a hack, but it works. The idea is to expand the array that defines a data point from two elements (x and y) to three (x, y, and clickable). So you'd define your data something like this:
d2 = [[885.0, 0.4], [905.0, 0.6, true], [915.0, 0.34, false], [935, 0.39, true]];
The first point won't be clickable (its third element is undefined), the second and fourth will be (the third element for both is set to true), the third point won't be clickable (its third element is false).
Now, when you bind a plotclick event, you can easily filter out the items you won't respond to:
$("#chart").bind("plotclick", function (event, pos, item) {
if (item) {
var dataPoint = item.series.data[item.dataIndex];
if (dataPoint[2]) {
// respond to the click
}
}
});