I am actually working on a tool to visualize data flow. I have different types
of elements which should be used and would like to have for everyone of those elements (objects) a own html template. Does anyone have a idea if this is possible and how to implement this?
Thanks a lot for your help I really appreciate that!
Dear regards,
Raphael
Here my code (sorry for the mess):
(function() {
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({ el: $('#paper'), width: 650, height: 400, gridSize: 1, model: graph });
// Create a system element.
// -----------------------------------------------------------------------------
joint.shapes.html = {};
joint.shapes.html.Element = joint.shapes.basic.Generic.extend(_.extend({}, joint.shapes.basic.PortsModelInterface, {
markup: '<g class="rotatable"><g class="scalable"><rect/></g><g class="inPorts"/><g class="outPorts"/></g>',
portMarkup: '<g class="port<%= id %>"><circle/></g>',
defaults: joint.util.deepSupplement({
type: 'html.Element',
size: { width: 100, height: 80 },
inPorts: [],
outPorts: [],
attrs: {
'.': { magnet: false },
rect: {
stroke: 'none', 'fill-opacity': 0, width: 170, height: 250,
},
circle: {
r: 6, //circle radius
magnet: true,
stroke: 'black'
},
'.inPorts circle': { fill: 'green', magnet: 'passive', type: 'input'},
'.outPorts circle': { fill: 'red', type: 'output'}
}
}, joint.shapes.basic.Generic.prototype.defaults),
getPortAttrs: function (portName, index, total, selector, type) {
var attrs = {};
var portClass = 'port' + index;
var portSelector = selector + '>.' + portClass;
var portCircleSelector = portSelector + '>circle';
attrs[portCircleSelector] = { port: { id: portName || _.uniqueId(type), type: type } };
attrs[portSelector] = { ref: 'rect', 'ref-y': (index + 0.5) * (1 / total) };
if (selector === '.outPorts') { attrs[portSelector]['ref-dx'] = 0; }
return attrs;
}
}));
// -------------------------------------------------------------------------------------------------------------------------------------
// Create a custom view for that element that displays an HTML div above it.
// -------------------------------------------------------------------------------------------------------------------------------------
joint.shapes.html.ElementView = joint.dia.ElementView.extend({
objectname: "System",
template: [
'<div class="html-element" id=>',
'<button class="delete">x</button>',
'<button class="add">+</button>',
'<div class="head">',
'<h3>',
'System',
'</h3>',
'<input type="text" class="systemComment" placeholder = "Add a comment to this System"/>',
'</div> </br>',
'</div>'
].join(''),
//::: Start initialize function :::
initialize: function() {
_.bindAll(this, 'updateBox');
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
this.$box = $(_.template(this.template)());
// Prevent paper from handling pointerdown.
this.$box.find('input,select').on('mousedown click', function(evt) {
evt.stopPropagation();
});
// This is an example of reacting on the input change and storing the input data in the cell model.
this.$box.find('input').on('change', _.bind(function(evt) {
this.model.set('input', $(evt.target).val());
}, this));
this.$box.find('select').on('change', _.bind(function(evt) {
this.model.set('select', $(evt.target).val());
}, this));
this.$box.find('select').val(this.model.get('select'));
this.$box.find('.delete').on('click', _.bind(this.model.remove, this.model));
$('.add').on('click', function(){
//we select the box clone it and insert it after the box
$(".html-element").clone().appendTo("#paper");
});
// Update the box position whenever the underlying model changes.
this.model.on('change', this.updateBox, this);
// Remove the box when the model gets removed from the graph.
this.model.on('remove', this.removeBox, this);
this.updateBox();
},
//::: End initialize function :::
//::: Start render function :::
render: function() {
joint.dia.ElementView.prototype.render.apply(this, arguments);
this.paper.$el.prepend(this.$box);
// this.paper.$el.mousemove(this.onMouseMove.bind(this)), this.paper.$el.mouseup(this.onMouseUp.bind(this));
this.updateBox();
return this;
},
//::: End render function :::
//::: Start renderPortst function :::
renderPorts: function () {
var $inPorts = this.$('.inPorts').empty();
var $outPorts = this.$('.outPorts').empty();
var portTemplate = _.template(this.model.portMarkup);
_.each(_.filter(this.model.ports, function (p) { return p.type === 'in' }), function (port, index) {
$inPorts.append(V(portTemplate({ id: index, port: port })).node);
});
_.each(_.filter(this.model.ports, function (p) { return p.type === 'out' }), function (port, index) {
$outPorts.append(V(portTemplate({ id: index, port: port })).node);
});
},
//::: End renderPortst function :::
//::: Start update function
update: function () {
// First render ports so that `attrs` can be applied to those newly created DOM elements
// in `ElementView.prototype.update()`.
this.renderPorts();
joint.dia.ElementView.prototype.update.apply(this, arguments);
},
//::: End update function :::
//::: Start updateBox function
updateBox: function() {
// Set the position and dimension of the box so that it covers the JointJS element.
var bbox = this.model.getBBox();
// Example of updating the HTML with a data stored in the cell model.
// paper.on('blank:pointerdown', function(evt, x, y) { this.$box.find('textarea').toBack(); });
this.model.on('cell:pointerclick', function(evt, x, y) { this.$box.find('textarea').toFront(); });
this.$box.css({ width: bbox.width, height: bbox.height, left: bbox.x + 15, top: bbox.y, transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)' });
},
//::: End updateBox function :::
//::: Start removeBox function :::
removeBox: function(evt) {
this.$box.remove();
}
//::: End removeBox function :::
});
// -------------------------------------------------------------------------------------------------------------------------------------
// Create JointJS elements and add them to the graph as usual.
// -------------------------------------------------------------------------------------------------------------------------------------
var system = new joint.shapes.html.Element({
position: { x: 80, y: 80 },
size: { width: 240, height: 180 },
outPorts:['systemOut'],
inPorts: ['systemIn'],
});
var dbo = new joint.shapes.html.Element({
position: { x: 120, y: 210 },
size: { width: 240, height: 180 },
outPorts:['dboOut'],
inPorts: ['dboIn'],
})
// -------------------------------------------------------------------------------------------------------------------------------------
//Adding all to the graph
graph.addCells([system, dbo]);
}())
you can put the template definition on the model, then you can instantiate elements with custom templates, like this:
new joint.shapes.html.Element({
template: [
'<div class="my-html-element">',
'<div><input data-attribute="myinput" type="checkbox"/></div>',
'<div><input data-attribute="myinput" type="checkbox"/></div>',
'<div><input data-attribute="myinput" type="checkbox"/></div>',
'</div>'
].join(''),
});
Here is an complete example: https://jsfiddle.net/vtalas/pruz7h9w/
Please note there is a new API for easier manipulation with ports since Joint v1.0 (it's applied in demo above as well).
Related
I am trying to apply smart routing of links with the use of ports using JointJS. This documentation shows the one I am trying to achieve. The example on the docs though shows only the programmatic way of adding Link from point A to point B. How do you do this with the use of ports?
Here's my code: JSFiddle.
HTML:
<html>
<body>
<button id="btnAdd">Add Table</button>
<div id="dbLookupCanvas"></div>
</body>
</html>
JS
$(document).ready(function() {
$('#btnAdd').on('click', function() {
AddTable();
});
InitializeCanvas();
// Adding of two sample tables on first load
AddTable(50, 50);
AddTable(250, 50);
});
var graph;
var paper
var selectedElement;
var namespace;
function InitializeCanvas() {
let canvasContainer = $('#dbLookupCanvas').parent();
namespace = joint.shapes;
graph = new joint.dia.Graph({}, {
cellNamespace: namespace
});
paper = new joint.dia.Paper({
el: document.getElementById('dbLookupCanvas'),
model: graph,
width: canvasContainer.width(),
height: 500,
gridSize: 10,
drawGrid: true,
cellViewNamespace: namespace,
validateConnection: function(cellViewS, magnetS, cellViewT, magnetT, end, linkView) {
return (magnetS !== magnetT);
},
snapLinks: {
radius: 20
}
});
//Dragging navigation on canvas
var dragStartPosition;
paper.on('blank:pointerdown',
function(event, x, y) {
dragStartPosition = {
x: x,
y: y
};
}
);
paper.on('cell:pointerup blank:pointerup', function(cellView, x, y) {
dragStartPosition = null;
});
$("#dbLookupCanvas")
.mousemove(function(event) {
if (dragStartPosition)
paper.translate(
event.offsetX - dragStartPosition.x,
event.offsetY - dragStartPosition.y);
});
// Remove links not connected to anything
paper.model.on('batch:stop', function() {
var links = paper.model.getLinks();
_.each(links, function(link) {
var source = link.get('source');
var target = link.get('target');
if (source.id === undefined || target.id === undefined) {
link.remove();
}
});
});
paper.on('cell:pointerdown', function(elementView) {
resetAll(this);
let isElement = elementView.model.isElement();
if (isElement) {
var currentElement = elementView.model;
currentElement.attr('body/stroke', 'orange');
selectedElement = elementView.model;
} else
selectedElement = null;
});
paper.on('blank:pointerdown', function(elementView) {
resetAll(this);
});
$('#dbLookupCanvas')
.attr('tabindex', 0)
.on('mouseover', function() {
this.focus();
})
.on('keydown', function(e) {
if (e.keyCode == 46)
if (selectedElement) selectedElement.remove();
});
}
function AddTable(xCoord = undefined, yCoord = undefined) {
// This is a sample database data here
let data = [
{columnName: "radomData1"},
{columnName: "radomData2"}
];
if (xCoord == undefined && yCoord == undefined)
{
xCoord = 50;
yCoord = 50;
}
const rect = new joint.shapes.standard.Rectangle({
position: {
x: xCoord,
y: yCoord
},
size: {
width: 150,
height: 200
},
ports: {
groups: {
'a': {},
'b': {}
}
}
});
$.each(data, (i, v) => {
const port = {
group: 'a',
args: {}, // Extra arguments for the port layout function, see `layout.Port` section
label: {
position: {
name: 'right',
args: {
y: 6
} // Extra arguments for the label layout function, see `layout.PortLabel` section
},
markup: [{
tagName: 'text',
selector: 'label'
}]
},
attrs: {
body: {
magnet: true,
width: 16,
height: 16,
x: -8,
y: -4,
stroke: 'red',
fill: 'gray'
},
label: {
text: v.columnName,
fill: 'black'
}
},
markup: [{
tagName: 'rect',
selector: 'body'
}]
};
rect.addPort(port);
});
rect.resize(150, data.length * 40);
graph.addCell(rect);
}
function resetAll(paper) {
paper.drawBackground({
color: 'white'
});
var elements = paper.model.getElements();
for (var i = 0, ii = elements.length; i < ii; i++) {
var currentElement = elements[i];
currentElement.attr('body/stroke', 'black');
}
var links = paper.model.getLinks();
for (var j = 0, jj = links.length; j < jj; j++) {
var currentLink = links[j];
currentLink.attr('line/stroke', 'black');
currentLink.label(0, {
attrs: {
body: {
stroke: 'black'
}
}
});
}
}
Any help would be appreciated. Thanks!
The default link created when you draw a link from a port is joint.dia.Link.
To change this you can use the defaultLink paper option, and configure the router you would like.
defaultLink documentation reference
const paper = new joint.dia.Paper({
el: document.getElementById('dbLookupCanvas'),
model: graph,
width: canvasContainer.width(),
height: 500,
gridSize: 10,
drawGrid: true,
cellViewNamespace: namespace,
validateConnection: function(cellViewS, magnetS, cellViewT, magnetT, end, linkView) {
return (magnetS !== magnetT);
},
snapLinks: {
radius: 20
},
defaultLink: () => new joint.shapes.standard.Link({
router: { name: 'manhattan' },
connector: { name: 'rounded' },
})
});
You could also provide several default options in the paper.
defaultLink: () => new joint.shapes.standard.Link(),
defaultRouter: { name: 'manhattan' },
defaultConnector: { name: 'rounded' }
Ok so I build sync charts with test data. Everything works perfectly. The only problem I have is that I want to export all of them in one PDF but I only have the option to do it seperatly. So I build in a button that gets the charts in an array and exports it to PDF but it does not want to work.
This is the JS i have that builds the charts
function clickModal(test) {
document.getElementById("myModal").style.display = "block";
// Call the AJAX function that start the chart procedures
getAjaxData(test);
}
// HIGHCHART FUNCTIONALITY STARTS HERE
['mousemove', 'touchmove', 'touchstart'].forEach(function (eventType) {
document.getElementById('container').addEventListener(
eventType,
function (e) {
var chart,
point,
i,
event;
for (i = 0; i < Highcharts.charts.length; i = i + 1) {
chart = Highcharts.charts[i];
// Find coordinates within the chart
event = chart.pointer.normalize(e);
// Get the hovered point
point = chart.series[0].searchPoint(event, true);
if (point) {
point.highlight(e);
}
}
}
);
});
/**
* Override the reset function, we don't need to hide the tooltips and
* crosshairs.
*/
Highcharts.Pointer.prototype.reset = function () {
return undefined;
};
/**
* Highlight a point by showing tooltip, setting hover state and draw crosshair
*/
Highcharts.Point.prototype.highlight = function (event) {
event = this.series.chart.pointer.normalize(event);
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
/**
* Synchronize zooming through the setExtremes event handler.
*/
function syncExtremes(e) {
var thisChart = this.chart;
if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
Highcharts.each(Highcharts.charts, function (chart) {
if (chart !== thisChart) {
if (chart.xAxis[0].setExtremes) { // It is null while updating
chart.xAxis[0].setExtremes(
e.min,
e.max,
undefined,
false,
{ trigger: 'syncExtremes' }
);
}
}
});
}
}
function getAjaxData(test){
$.getJSON('datasync.php', function(chartData, tstSuccess) {
// Display the results of the getJSON call to data.php
document.getElementById("json1").innerHTML = JSON.stringify(tstSuccess, undefined, 2);
document.getElementById("json").innerHTML = JSON.stringify(chartData, undefined, 2);
var charts1 = {}; // global variable
var index = 0;
// Loop through each dataset in the returned JSON
chartData.datasets.forEach(function (dataset, i) {
// Add X values
dataset.data = Highcharts.map(dataset.data, function (val, j) {
return [chartData.xData[j], val];
});
// Create a child div for each dataset that is returned
var chartDiv = document.createElement('div');
chartDiv.className = 'chart';
document.getElementById('container').appendChild(chartDiv);
charts1[index] = Highcharts.chart(chartDiv, {
chart: {
marginLeft: 40, // Keep all charts left aligned
spacingTop: 20,
spacingBottom: 20
},
exporting: {
buttons: {
contextButton: {
menuItems: [
'downloadPDF',
'viewData'
]
}
}
},
title: {
text: dataset.name,
align: 'left',
margin: 0,
x: 30
},
credits: {
enabled: false
},
legend: {
enabled: false
},
xAxis: {
crosshair: true,
events: {
setExtremes: syncExtremes
},
labels: {
//format: '{value} km'
format: ' '
}
},
yAxis: {
title: {
text: null
}
},
tooltip: {
positioner: function () {
return {
// right aligned
x: this.chart.chartWidth - this.label.width - 40,
y: 10 // align to title
};
},
borderWidth: 0,
backgroundColor: 'none',
pointFormat: '{point.y}',
headerFormat: '',
shadow: false,
style: {
fontSize: '18px'
},
valueDecimals: dataset.valueDecimals
},
series: [{
data: dataset.data,
name: dataset.name,
type: dataset.type,
color: Highcharts.getOptions().colors[i],
fillOpacity: 0.3,
tooltip: {
valueSuffix: ' ' + dataset.unit
}
}]
});
});
index++;
});
}
$('#export-pdf').click(function() {
Highcharts.exportCharts([charts1[0], charts1[1]], {
type: 'application/pdf'
});
});
And this is my HTML
<div id="myModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<div id="container">
<button id="export-png">Export to PNG</button>
</div>
</div>
</div>
So im using PHP to build up JSON from an array ( will use SQL to build from database later just want to get the functionality working )
Then I use the highcharts library along with JS to display the charts
Ok so I figured out the problem. I brought in this piece of code
Highcharts.getSVG = function(charts) {
var svgArr = [],
top = 0,
width = 0;
$.each(charts, function(i, chart) {
var svg = chart.getSVG();
svg = svg.replace('<svg', '<g transform="translate(0,' + top + ')" ');
svg = svg.replace('</svg>', '</g>');
svg = svg.replace('-9000000000', '-999'); // Bug in v4.2.6
top += chart.chartHeight;
width = Math.max(width, chart.chartWidth);
svgArr.push(svg);
});
return '<svg height="'+ top +'" width="' + width + '" version="1.1" xmlns="http://www.w3.org/2000/svg">' + svgArr.join('') + '</svg>';
};
/**
* Create a global exportCharts method that takes an array of charts as an argument,
* and exporting options as the second argument
*/
Highcharts.exportCharts = function(charts, options) {
// Merge the options
options = Highcharts.merge(Highcharts.getOptions().exporting, options);
// Post to export server
Highcharts.post(options.url, {
filename: options.filename || 'chart',
type: options.type,
width: options.width,
svg: Highcharts.getSVG(charts)
});
};
I changed the charts so that it does not created an array of chart objects
Highcharts.chart(chartDiv, {
chart: {
marginLeft: 40, // Keep all charts left aligned
spacingTop: 20,
spacingBottom: 20
},
instead of
charts1[index] = Highcharts.chart(chartDiv, {
chart: {
marginLeft: 40, // Keep all charts left aligned
spacingTop: 20,
spacingBottom: 20
},
And in the buttons function I just used the highcharts.charts instead of the array
$('#export-pdf').click(function() {
Highcharts.exportCharts(Highcharts.charts, {
type: 'application/pdf'
});
});
Could anyone help me to figure out what I am missing on showing only last X samples in the chart, please?
Looking at this example and this thread, I am developing a simple page which receives samples from server via socket.io and plots the last 10 samples.
However, it is not working and I am struggling to figure out what I am missing.
The server.js is a simple samples generator:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function (req, res) {
res.sendfile('index.html');
});
// On connection event.
io.on('connection', function (socket) {
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconnected');
// TODO (How-to) release connection (?)
});
var max = 100; // Scale samples from 0 to 100.
// Generate random samples.
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.floor((Math.random() * max) + 1);
socket.emit('chart_data', {
x: x,
y: y
});
console.info("emitted: [" + x + "," + y + "]");
}, 2000); //update every sec.
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
The html file include such script to handle the plot:
$(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
// Instantiate the chart object which plots the samples.
var graph = new Highcharts.chart('graph_container', {
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
// set up the updating of the chart on each sample
var series = this.series[0];
socket.on('chart_data', function (sample) {
//add chart data to series
series.addPoint([sample.x, sample.y], true, false);
});
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = 0,
i;
socket.on('chart_data', function (sample) {
//add chart data to series
time = sample.x;
for (i = -19; i <= 0; i += 2) {
data.push({
x: time + i
});
}
});
return data;
}())
}]
});
});
I am brand new to node.js, but I believe that my mistake is pushing samples without y in "data.push". However, the plot is working, but without the "sliding window" of last X samples (e.g. 10).
Does anyone have a suggestion to let the "sliding window" work, please?
You should emit two events - one with the data initialisation e.g. sample of 10 points, and the second - a point fetching in time interval.
You should not initialise the data in a way you do in the line series.data = (function () ... Instead move the initialisation on load event and use series.setData.
Your series should look like this:
series: [{
name: 'Random data',
data: []
}]
and the load event like this:
events: {
load: function () {
var series = this.series[0];
var socket = io.connect('http://localhost:3000');
socket.on('chart_data_init', function (sample) {
series.setData(sample.data);
});
socket.on('chart_data', function (sample) {
//add chart data to series
series.addPoint([sample.x, sample.y], true, false);
});
}
}
Then modify your server file, you need to add chart_data_init emission with some initialised data
var initData = (function () {
var data = [], i = 0, time = new Date().getTime() - 2000 * 10;
for (; i < 10; i++) {
data.push({
x: time + i * 2000,
y: Math.floor((Math.random() * max) + 1)
});
}
return data;
})();
socket.emit('chart_data_init', {
data: initData
});
You have to have data sorted in ascending order - otherwise Highcharts will not render the data correctly.
Files
index.html
<html>
<head>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
</head>
<body>
<div id="graph_container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
<script>
// Instantiate the chart object which plots the samples.
console.log
var graph = new Highcharts.chart('graph_container', {
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
// set up the updating of the chart on each sample
var series = this.series[0];
var socket = io.connect('http://localhost:3000');
socket.on('chart_data_init', function (sample) {
series.setData(sample.data);
});
socket.on('chart_data', function (sample) {
//add chart data to series
series.addPoint([sample.x, sample.y], true, false);
});
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: []
}]
});
</script>
</body>
</html>
server.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendfile('index.html');
});
io.sockets.on('connection', function (socket) {
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconnected');
// TODO (How-to) release connection (?)
});
var max = 100; // Scale samples from 0 to 100.
var initData = (function () {
var data = [], i = 0, time = new Date().getTime() - 2000 * 10;
for (; i < 10; i++) {
data.push({
x: time + i * 2000,
y: Math.floor((Math.random() * max) + 1)
});
}
return data;
})();
socket.emit('chart_data_init', {
data: initData
});
// Generate random samples.
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.floor((Math.random() * max) + 1);
socket.emit('chart_data', {
x: x,
y: y
});
console.info("emitted: [" + x + "," + y + "]");
}, 2000); //update every sec.
});
http.listen(3000, function(){
console.log('listening on *:3000'); //jalankan server di port 3000
});
Here is my code so far. I can see the selection rectangle, but zooming isn't happening.
what have I did wrong?
function Plot(container, data) {
this.options = {
lines: {
show: true
},
points: {
show: true
},
xaxis: {
tickDecimals: 0,
tickSize: 1
},
selection: { mode: "xy" }
}
console.log("script is running")
this.data = []
this.container = container;
this.plot = $.plot(container, this.data, this.options);
this.url = '/sensor/oscillogram_debug_data/'+110;
this.container.bind("plotselected", this.zoom);
this.zoom = function(event, reanges) {
if (ranges.xaxis.to - ranges.xaxis.from < 0.00001)
ranges.xaxis.to = ranges.xaxis.from + 0.00001;
if (ranges.yaxis.to - ranges.yaxis.from < 0.00001)
ranges.yaxis.to = ranges.yaxis.from + 0.00001;
this.plot = $.plot(this.container, this.plot.getData(),
$.extend(true, {}, this.options, {
xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to },
yaxis: { min: ranges.yaxis.from, max: ranges.yaxis.to }
}));
}
}
var plot = new Plot($("#output_plot_container"));
var updateChart = function() {
$.getJSON(plot.url, function(newdata) {
for (var f_id in newdata)
if (newdata.hasOwnProperty(f_id)) {
if (f_id='demodulated') {
// plot.plot.setData([newdata[f_id]])
// plot.plot.setupGrid()
// plot.plot.draw()
}
}
})
}
A few problems here:
1.) You are binding to this.zoom before it exists, reverse those calls (and note typo in "reanges"):
this.zoom = function(event, ranges) {
....
this.container.bind("plotselected", this.zoom);
2.) Your attempt at some sort of OO scoping within this.zoom just isn't going to work. Once that function is bound, it doesn't have access to it's parent scope. If you want the this to be available in the bind, you can pass it in as eventData:
this.container.bind("plotselected", {obj: this}, this.zoom); // and replace the this in this.zoom with obj
Here's a working fiddle.
I created a rectangle on the screen and I want some buttons to appear on the rectangle when mouseover it. But I couldn't handle this work. My code is below. I couldn't understand that why
this.$('.control').removeClass('hide');
this row is not working. It does not give any error also.
$(this.rect).html(................
........css({ position: 'absolute', padding: '10px' });
I couldn't understand also that this part of my code. (Stack didn't allow the divs. I don't know why).
var KineticModel = Backbone.Model.extend({
myRect: null,
createRect : function() {
alert("rectangle created.");
var rect=new Kinetic.Rect({
x: 50,
y: 50,
width: 150,
height: 150,
fill: 'green',
stroke: 'black',
strokeWidth: 1,
offset: [0, 0],
draggable: true,
});
rect.on("mouseover",function(){
alert("Hoover : ");
$('.control').removeClass('hide');
});
rect.on("mouseout",function(){
alert("Out : ");
});
rect.on("mousedown",function(){
alert("Down : ");
});
rect.on("mouseup",function(){
alert("Up : ");
});
return rect;
}
});
var KineticView = Backbone.View.extend({
tagName: 'span',
stage: null,
layer: null,
initialize: function (options) {
model: options.model;
el: options.el;
this.layer = new Kinetic.Layer();
this.stage = new Kinetic.Stage({ container: this.el, width: 1000, height: 500 });
this.stage.add(this.layer);
},
events: {
'click': 'spanClicked'
},
render: function () {
var rect = this.model.createRect();
$(this.rect).html('<div class="shape"/>'
+ '<div class="control delete hide"/>'
+ '<div class="control change-color hide"/>'
+ '<div class="control resize hide"/>'
+ '<div class="control rotate hide"/>').css({ position: 'absolute', padding: '10px' });
this.layer.add(rect);
this.stage.add(this.layer);
alert("render");
return this;
},
spanClicked: function () {
}
});
var kModel = new KineticModel({});
var kView = new KineticView({ el: '#container', model: kModel });
$('#shapetest').click(function() {
kView.render();
});
change this.$('.control').removeClass('hide'); to :
$('.control').removeClass('hide');
And so on ...