Save and Restore rectangles with connections in Draw2D.js touch via JSON - draw2d-js

How do I create rectangles with 4 ports (each side) in a correct way, so I can save and restore them via JSON?
I tried this one, but only the rectangles are been saved. The connections and labels got lost.
JSFiddle: http://jsfiddle.net/xfvf4/36/
Create two elements (Add) - move them and connect them
Write: This gives the content as JSON-Array
Read: Should make the grafic out of the JSON-Array
The last point doesn't work.
JS:
var LabelRectangle = draw2d.shape.basic.Rectangle.extend({
NAME: "draw2d.shape.basic.Rectangle",
init: function (attr) {
this._super(attr);
this.label = new draw2d.shape.basic.Label({
text: "Text",
fontColor: "#0d0d0d",
stroke: 0
});
this.add(this.label, new draw2d.layout.locator.CenterLocator(this));
this.label.installEditor(new draw2d.ui.LabelInplaceEditor());
this.createPort("hybrid", new draw2d.layout.locator.BottomLocator(this));
},
getPersistentAttributes: function () {
var memento = this._super();
memento.labels = [];
var ports = [];
ports = this.getPorts();
memento.ports = [];
console.log(ports);
this.children.each(function (i, e) {
console.log(e);
memento.labels.push({
id: e.figure.getId(),
label: e.figure.getText(),
locator: e.locator.NAME
});
ports.each(function (i, e) {
memento.ports.push({
//id: e.id,
name: e.name,
locator: e.locator.NAME
});
});
});
return memento;
},
setPersistentAttributes: function (memento) {
this._super(memento);
this.resetChildren();
$.each(memento.labels, $.proxy(function (i, e) {
var label = new draw2d.shape.basic.Label(e.label);
var locator = eval("new " + e.locator + "()");
locator.setParent(this);
this.add(label, locator);
}, this));
}
});
$(window).load(function () {
var canvas = new draw2d.Canvas("gfx_holder");
$("#add").click(function (e) { // Add a new rectangle
var rect = new LabelRectangle({
width: 200,
height: 40,
radius: 3,
bgColor: '#ffffff',
stroke: 0
});
rect.createPort("hybrid", new draw2d.layout.locator.OutputPortLocator(rect));
rect.createPort("hybrid", new draw2d.layout.locator.InputPortLocator(rect));
rect.createPort("hybrid", new draw2d.layout.locator.TopLocator(rect));
canvas.add(rect, 150, 200);
});
$("#write").click(function (e) { // Write to pre-Element (JSON)
var writer = new draw2d.io.json.Writer();
writer.marshal(canvas, function(json){
$("#json").text(JSON.stringify(json,null,2));
$('#gfx_holder').empty();
});
});
$("#read").click(function (e) { // Read from pre-Element (JSON)
var canvas = new draw2d.Canvas("gfx_holder");
var jsonDocument = $('#json').text();
var reader = new draw2d.io.json.Reader();
reader.unmarshal(canvas, jsonDocument);
});
});
HTML:
<ul class="toolbar">
<li>Add</li>
<li>Write</li>
<li>Read</li>
</ul>
<div id="container" class="boxed">
<div onselectstart="javascript:/*IE8 hack*/return false" id="gfx_holder" style="width:100%; height:100%; ">
</div>
<pre id="json" style="overflow:auto;position:absolute; top:10px; right:10px; width:350; height:500;background:white;border:1px solid gray">
</pre>
</div>

Just use the write.js and Reader.js in the "json"-Folder of Draw2D.js 5.0.4 and this code:
$(window).load(function () {
var canvas = new draw2d.Canvas("gfx_holder");
// unmarshal the JSON document into the canvas
// (load)
var reader = new draw2d.io.json.Reader();
reader.unmarshal(canvas, jsonDocument);
// display the JSON document in the preview DIV
//
displayJSON(canvas);
// add an event listener to the Canvas for change notifications.
// We just dump the current canvas document into the DIV
//
canvas.getCommandStack().addEventListener(function(e){
if(e.isPostChangeEvent()){
displayJSON(canvas);
}
});
});
function displayJSON(canvas){
var writer = new draw2d.io.json.Writer();
writer.marshal(canvas,function(json){
$("#json").text(JSON.stringify(json, null, 2));
});
}

This should work:
var LabelRectangle = draw2d.shape.basic.Rectangle.extend({
NAME: "draw2d.shape.basic.Rectangle",
init: function (attr) {
this._super(attr);
this.label = new draw2d.shape.basic.Label({
text: "Text",
fontColor: "#0d0d0d",
stroke: 0
});
this.add(this.label, new draw2d.layout.locator.CenterLocator(this));
this.label.installEditor(new draw2d.ui.LabelInplaceEditor());
},
getPersistentAttributes: function () {
var memento = this._super();
memento.labels = [];
memento.ports = [];
this.getPorts().each(function(i,port){
memento.ports.push({
name : port.getName(),
port : port.NAME,
locator: port.getLocator().NAME
});
});
this.children.each(function (i, e) {
memento.labels.push({
id: e.figure.getId(),
label: e.figure.getText(),
locator: e.locator.NAME
});
});
return memento;
},
setPersistentAttributes: function (memento) {
this._super(memento);
this.resetChildren();
if(typeof memento.ports !=="undefined"){
this.resetPorts();
$.each(memento.ports, $.proxy(function(i,e){
var port = eval("new "+e.port+"()");
var locator = eval("new "+e.locator+"()");
this.add(port, locator);
port.setName(e.name);
},this));
}
$.each(memento.labels, $.proxy(function (i, e) {
var label = new draw2d.shape.basic.Label(e.label);
var locator = eval("new " + e.locator + "()");
locator.setParent(this);
this.add(label, locator);
}, this));
}
});

Related

How does Stripe conceal data input by users into Stripe-element objects?

var stripeElements = function (publicKey, setupIntent) {
var stripe = Stripe(publicKey);
var elements = stripe.elements();
// Element styles
var style = {
base: {
fontSize: '16px',
color: '#32325d',
fontFamily:
'-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif',
fontSmoothing: 'antialiased',
'::placeholder': {
color: 'rgba(0,0,0,0.4)',
},
},
};
var card = elements.create('card', { style: style });
console.log(card); // returns a "t" object
card.mount('#card-element');
// Element focus ring
card.on('focus', function () {
var el = document.getElementById('card-element');
el.classList.add('focused');
});
card.on('blur', function () {
var el = document.getElementById('card-element');
el.classList.remove('focused');
});
// Handle payment submission when user clicks the pay button.
var button = document.getElementById('submit');
button.addEventListener('click', function (event) {
event.preventDefault();
changeLoadingState(true);
var email = document.getElementById('email').value;
stripe
.confirmCardSetup(setupIntent.client_secret, {
payment_method: {
card: card,
billing_details: { email: email },
},
})
.then(function (result) {
if (result.error) {
changeLoadingState(false);
var displayError = document.getElementById('card-errors');
displayError.textContent = result.error.message;
} else {
// The PaymentMethod was successfully set up
orderComplete(stripe, setupIntent.client_secret);
}
});
});
};
Stripe uses the above stripe.confirmCardSetup method to create a setupIntent object. This object can be used later to issue a charge.
In the above example, a Stripe "element" is used to create a "card" (the credit card) input. After I submit this info., this card-element gets attached to the object passed into the stripe.confirmCardSetup method, but when I attempt to console log the card object and find the CC data that was just input, I don't see it and I've been through every attribute.
How does Stripe conceal this info.?

How to add text via chart.renderer.text in Highcharts?

I have succeeded adding additional text to my charts, like here. This, I achieved through adding a "function(chart)" to my "var chart = new Highcharts.Chart"
$.get('xxx.csv', function(data)
{
var chart = new Highcharts.Chart({
...
plotOptions:
{
series:
{
....
}
}
}, function(chart)
{
chart.renderer.text('The dotted line represents ...', 100, 86)
.css({
fontSize: '13px',
color: '#666666'
})
.add();
}
)};
My current format is however different:
$(function () {
var options =
{
chart:
{
...
},
...
};
$.get('xxx.csv', function(data)
{
var series = {
data: []
};
var temp = []
// Split the lines
var lines = data.split('\n');
// For each line, split the record into seperate attributes
$.each(lines, function(lineNo, line) {
var items = line.split(',');
if (lineNo !== 0) {
var xValue = +items[0],
kwh = parseFloat(items[2] / 1000);
if (!isNaN(kwh)) {
series.data.push({x:xValue,y: kwh, extra:items[1]});
}
}
});
// Push the completed series
options.series.push(series);
new Highcharts.Chart(options);
});
});
Now, I wonder how I can add a chart.renderer.text to the graph. I have tried different things, but didn't succeed. Where and how am I supposed to add the code for the text now? Here is a fiddle for this. Thanks for any hints!
You can add your text inside load event callback function of your chart. You can add this function inside your options - options.chart.events object.
http://api.highcharts.com/highcharts#chart.events.load
options.chart.events = {
load: function() {
var chart = this;
chart.renderer.text('The dotted line represents ...', 100, 186)
.css({
fontSize: '13px',
color: '#666666'
})
.add();
}
}
Here you can see an example how it can work:
http://jsfiddle.net/17ed42pa/1/
Best regards.

Use Socket.io to fill google Area Chart - 'google.visualization.DataTable is not a constructor'

I use NodeJS and Socket.io to get data from a database. I now want to fill a google area chart with these data but i kind of fail at doing it.
The data is transmitted as Objects. Each Object contains two values (datetime and value). I append these values to an array and then store them in a DataTable:
google.load('visualization', '1', {
packages: ['corechart']
});
google.setOnLoadCallback(drawChart);
var socket = io();
getData();
function drawChart(dataArray) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'DateTime');
data.addColumn('number', 'Value');
for (var i = 0; i < dataArray.length; i += 2) {
console.log(dataArray[0]);
data.addRow([dataArray[i], dataArray[i + 1]]);
}
var chart = new google.visualization.AreaChart(document.getElementById('chart'));
chart.draw(data, {
title: "Data Visualization",
isStacked: true,
width: '50%',
height: '50%',
vAxis: {
title: 'Data v-Axis'
},
hAxis: {
title: 'Data h-Axis'
}
})
}
function getData() {
socket.emit('GET');
socket.on('serverSent', function (data) {
var processedData = processData(data);
drawChart(processedData);
})
}
function processData(data) {
var arr = new Array();
jQuery.each(data, function (index, object) {
arr.push(object['datetime'], parseInt(object['value']));
})
return arr;
}
If i call my website i see the chart but without any values and the error message `google.visualization.DataTable is not a constructor´. So what am i doing wrong?
The problem is drawChart is being called twice.
From both google.setOnLoadCallback and getData.
If getData is called before google.setOnLoadCallback,
then google.visualization.DataTable will not be recognized.
In addition, it is recommended to use loader.js vs. jsapi.
See Load the Libraries for more info...
As such, please try the following...
Replace...
<script src="https://www.google.com/jsapi"></script>
With...
<script src="https://www.gstatic.com/charts/loader.js"></script>
And try something like...
google.charts.load('current', {
callback: init,
packages: ['corechart']
});
function init() {
var socket = io();
socket.emit('GET');
socket.on('serverSent', function (data) {
var processedData = processData(data);
drawChart(processedData);
});
}
function drawChart(dataArray) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'DateTime');
data.addColumn('number', 'Value');
for (var i = 0; i < dataArray.length; i += 2) {
console.log(dataArray[0]);
data.addRow([dataArray[i], dataArray[i + 1]]);
}
var chart = new google.visualization.AreaChart(document.getElementById('chart'));
chart.draw(data, {
title: "Data Visualization",
isStacked: true,
width: '50%',
height: '50%',
vAxis: {
title: 'Data v-Axis'
},
hAxis: {
title: 'Data h-Axis'
}
})
}

nodejs jade_ unexpected token 'indent'

i have a problem in this code (anyway sorry for my short Eng.)
i think this is a right code but don't know why it makes errors about indentation? any solutions or advices for this code :( ??
u can ignore the Korean that i wrote in this code
- if (!isSuccess)
script
alert('cannot make a chat room.');
location.href = '/enter';
- else
h3 room title :
span#roomName= roomName
input#leave(type='button', value='나가기')
#chatWindow(style='width:400px; height:400px; overflow:auto; border:1px solid #000; float:left; margin-right:10px;')
div(style='width:100px; height:400px; overflow:auto; border:1px solid #000;')
p 참가자
ul#attendants
each attendant in attendants
li(id='attendant-'+attendant)= attendant
form
span#myName #{nickName}
input(type='text', style='width:300px;')#message
input(type='submit', value='보내기')
script(type='text/javascript')
$(document).ready(function() {
var room = io.connect('/room');
var chatWindow = $('#chatWindow');
var messageBox = $('#message');
var myName = $('#myName').text();
var attendants = $('#attendants');
var showMessage = function(msg) {
chatWindow.append($('<p>').text(msg));
chatWindow.scrollTop(chatWindow.height());
};
room.on('connect', function() {
room.emit('join', {roomName:$('#roomName').text(), nickName:myName});
});
room.on('joined', function(data) {
if(data.isSuccess) {
showMessage(data.nickName + '님이 입장하셨습니다.');
attendants.append($('<li>')
.attr('id', 'attendant-'+data.nickName)
.text(data.nickName));
}
});
room.on('message', function(data) {
showMessage(data.nickName + ' : ' + data.msg);
});
room.on('leaved', function(data) {
showMessage(data.nickName + '님이 나가셨습니다.');
$('#attendant-'+data.nickName).remove();
});
$('form').submit(function(e) {
e.preventDefault();
var msg = messageBox.val();
if ($.trim(msg) !== '') {
showMessage(myName + ' : ' + msg);
room.json.send({nickName:myName, msg:msg});
messageBox.val('');
}
});
$('#leave').click(function(e) {
room.emit('leave', {nickName:myName});
location.href='/enter';
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
If you want to add multiple lines/blocks when you're writing inline JS/CSS you need to add a .
script.
alert('cannot make a chat room.');
location.href = '/enter';
script(type='text/javascript').
$(document).ready(function() {
var room = io.connect('/room');

Secondary tile web url

I have to pin secondary tile in my windows phone 8.1 application.
I followed the msdn tutorial : http://code.msdn.microsoft.com/windowsapps/secondary-tiles-sample-edf2a178/
It does work with internal image (ms-appx://.. ) but not with web url (http://)
working sample:
var logo = new Windows.Foundation.Uri("ms-appx:///Images/square30x30Tile-sdk.png");
var currentTime = new Date();
var TileActivationArguments = data.ad_id + " WasPinnedAt=" + currentTime;
var tile = new Windows.UI.StartScreen.SecondaryTile(data.ad_id,
data.subject,
TileActivationArguments,
logo,
Windows.UI.StartScreen.TileSize.square150x150);
tile.visualElements.foregroundText = Windows.UI.StartScreen.ForegroundText.light;
tile.visualElements.square30x30Logo = logo;
tile.visualElements.showNameOnSquare150x150Logo = true;
var selectionRect = this.element.getBoundingClientRect();
// Now let's try to pin the tile.
// We'll make the same fundamental call as we did in pinByElement, but this time we'll return a promise.
return new WinJS.Promise(function (complete, error, progress) {
tile.requestCreateForSelectionAsync({ x: selectionRect.left, y: selectionRect.top, width: selectionRect.width, height: selectionRect.height }, Windows.UI.Popups.Placement.above).done(function (isCreated) {
if (isCreated) {
complete(true);
} else {
complete(false);
}
});
});
And if I use
var logo = new Windows.Foundation.Uri(data.images[0]);
I got an invalid parameter exception.
You can take a look at the documentation for the SecondaryTile.Logo property. In it you'll see this:
The location of the image. This can be expressed as one of these schemes:
ms-appx:///
ms-appdata:///local/
You can download the image first and then set it using the ms-appdata:///local/ scheme. I'm not sure that changing the logo with something from the Internet is a good idea, though. This should be the app's logo, so it should be in the package.
I found the solution
fileExists: function (fileName) {
var applicationData = Windows.Storage.ApplicationData.current;
var folder = applicationData.localFolder;
return folder.getFileAsync(fileName).then(function (file) {
return file;
}, function (err) {
return null;
});
},
download: function (imgUrl, imgName) {
return WinJS.xhr({ url: imgUrl, responseType: "blob" }).then(function (result) {
var blob = result.response;
var applicationData = Windows.Storage.ApplicationData.current;
var folder = applicationData.localFolder;
return folder.createFileAsync(imgName, Windows.Storage.
CreationCollisionOption.replaceExisting).then(function (file) {
// Open the returned file in order to copy the data
return file.openAsync(Windows.Storage.FileAccessMode.readWrite).
then(function (stream) {
return Windows.Storage.Streams.RandomAccessStream.copyAsync
(blob.msDetachStream(), stream).then(function () {
// Copy the stream from the blob to the File stream
return stream.flushAsync().then(function () {
stream.close();
});
});
});
});
}, function (e) {
//var msg = new Windows.UI.Popups.MessageDialog(e.message);
//msg.showAsync();
});
},
var self = this;
this.download(data.images[0], data.ad_id).then(function () {
self.fileExists(data.ad_id).then(function (file) {
var logo = new Windows.Foundation.Uri("ms-appdata:///Local/" + data.ad_id);
....
I need to download the image, store it and then I can use ms-appdata:///Local

Resources