The default titanium slider only allows you to have one pin on it.
How could you modify it, so that it accepts a range of values. Such as age range?
Cheers.
UPDATE (after installing module):
// Double Slider example
var tidoubleslider = require('com.semanticpress.tidoubleslider');
var dSlider = tidoubleslider.createSlider({
top: 40,
height: 50,
width: 280,
leftTrackImage:'left2.png',
highlightedLeftTrackImage:'highlightedLeft2.png',
disabledLeftTrackImage:'disabledLeft2.png',
centerTrackImage:'center2.png',
highlightedCenterTrackImage:'highlightedCenter2.png',
disabledCenterTrackImage:'disabledCenter2.png',
rightTrackImage:'right2.png',
highlightedRightTrackImage:'highlightedRight2.png',
disabledRightTrackImage:'disabledRight2.png',
leftThumbImage:'thumb.png',
highlightedLeftThumbImage:'highlightedThumb.png',
disabledLeftThumbImage:'disabledThumb.png',
rightThumbImage:'thumb.png',
highlightedRightThumbImage:'highlightedThumb.png',
disabledRightThumbImage:'disabledThumb.png',
min:0,
max:50,
leftValue:25,
rightValue:50,
enabled: true
});
$.ageSliderView.add(dSlider);
var leftLabel = Ti.UI.createLabel({
top:30,
left:20,
width:100,
height: 20,
color:'black',
text:dSlider.leftValue
});
$.ageSliderView.add(leftLabel);
var rightLabel = Ti.UI.createLabel({
top:30,
right:20,
width:100,
height: 20,
color:'black',
text:dSlider.rightValue,
textAlign:'right'
});
$.ageSliderView.add(rightLabel);
dSlider.addEventListener('touchstart', function(e) {
if (typeof e.value !== 'undefined') {
if (e.thumbIndex === 0) {
leftLabel.text = e.value.toFixed(1);
leftLabel.color = 'red';
}
else {
rightLabel.text = e.value.toFixed(1);
rightLabel.color = 'red';
}
}
else {
leftLabel.color = 'gray';
rightLabel.color = 'gray';
}
});
dSlider.addEventListener('change', function(e) {
if (e.thumbIndex === 0) {
leftLabel.text = e.value.toFixed(1);
}
else {
rightLabel.text = e.value.toFixed(1);
}
});
dSlider.addEventListener('touchend', function(e) {
if (typeof e.value !== 'undefined') {
if (e.thumbIndex === 0) {
leftLabel.text = e.value.toFixed(1);
leftLabel.color = 'black';
}
else {
rightLabel.text = e.value.toFixed(1);
rightLabel.color = 'black';
}
}
else {
leftLabel.color = 'black';
rightLabel.color = 'black';
}
});
The slider does not appear on the screen. I guess it is because the slider images are missing?
Here you go.The slider With raning option in titanium
https://github.com/tzmartin/Ti-Double-Slider/tree/master/dist
Thanks
Related
I'm using vuejs-pdf to print some pages of my pdf and the print is not show the characters :
that's the code i'm using :
<button #click="$refs.myPdfComponent.print(100,pages)">Print </button>
<pdf v-for="i in pages" :key="i" ref="newpdf" :src="'pdf/'+src" :page="i" class="rounded border
border-info mb-4" :rotate="rotate" #progress="loadedRatio = $event" #error="error" #num-pages="numPages = $event" #link-clicked="page = $event" > </pdf>
and the pdf i'm printing is myPdfComponent the newpdf is the only the pages i need :
<pdf v-if="show" ref="myPdfComponent" class="rounded border border-info mb-4" :src="'pdf/'+src"
:page="page" :rotate="rotate" #progress="loadedRatio = $event" #error="error" #num-pages="numPages =
$event" #link-clicked="page = $event"></pdf>
Open the vue-pdf plugin directory node_modules/vue-pdf/src/pdfjsWrapper.js
and replace
import { PDFLinkService } from 'pdfjs-dist/es5/web/pdf_viewer';
var pendingOperation = Promise.resolve();
export default function(PDFJS) {
function isPDFDocumentLoadingTask(obj) {
return typeof(obj) === 'object' && obj !== null && obj.__PDFDocumentLoadingTask === true;
// or: return obj.constructor.name === 'PDFDocumentLoadingTask';
}
function createLoadingTask(src, options) {
var source;
if ( typeof(src) === 'string' )
source = { url: src };
else if ( src instanceof Uint8Array )
source = { data: src };
else if ( typeof(src) === 'object' && src !== null )
source = Object.assign({}, src);
else
throw new TypeError('invalid src type');
// source.verbosity = PDFJS.VerbosityLevel.INFOS;
// source.pdfBug = true;
// source.stopAtErrors = true;
if ( options && options.withCredentials )
source.withCredentials = options.withCredentials;
var loadingTask = PDFJS.getDocument(source);
loadingTask.__PDFDocumentLoadingTask = true; // since PDFDocumentLoadingTask is not public
if ( options && options.onPassword )
loadingTask.onPassword = options.onPassword;
if ( options && options.onProgress )
loadingTask.onProgress = options.onProgress;
return loadingTask;
}
function PDFJSWrapper(canvasElt, annotationLayerElt, emitEvent) {
var pdfDoc = null;
var pdfPage = null;
var pdfRender = null;
var canceling = false;
canvasElt.getContext('2d').save();
function clearCanvas() {
canvasElt.getContext('2d').clearRect(0, 0, canvasElt.width, canvasElt.height);
}
function clearAnnotations() {
while ( annotationLayerElt.firstChild )
annotationLayerElt.removeChild(annotationLayerElt.firstChild);
}
this.destroy = function() {
if ( pdfDoc === null )
return;
// Aborts all network requests and destroys worker.
pendingOperation = pdfDoc.destroy();
pdfDoc = null;
}
this.getResolutionScale = function() {
return canvasElt.offsetWidth / canvasElt.width;
}
this.printPage = function(dpi, pageNumberOnly) {
if ( pdfPage === null )
return;
// 1in == 72pt
// 1in == 96px
var PRINT_RESOLUTION = dpi === undefined ? 150 : dpi;
var PRINT_UNITS = PRINT_RESOLUTION / 72.0;
var CSS_UNITS = 96.0 / 72.0;
/*var iframeElt = document.createElement('iframe');
function removeIframe() {
iframeElt.parentNode.removeChild(iframeElt);
}*/
var printContainerElement = document.createElement('div');
printContainerElement.setAttribute('id', 'print-container')
function removePrintContainer() {
printContainerElement.parentNode.removeChild(printContainerElement);
}
new Promise(function(resolve, reject) {
/*
iframeElt.frameBorder = '0';
iframeElt.scrolling = 'no';
iframeElt.width = '0px;'
iframeElt.height = '0px;'
iframeElt.style.cssText = 'position: absolute; top: 0; left: 0';
iframeElt.onload = function() {
resolve(this.contentWindow);
}
window.document.body.appendChild(iframeElt);*/
printContainerElement.frameBorder = '0';
printContainerElement.scrolling = 'no';
printContainerElement.width = '0px;'
printContainerElement.height = '0px;'
printContainerElement.style.cssText = 'position: absolute; top: 0; left: 0';
window.document.body.appendChild(printContainerElement);
resolve(window)
})
.then(function(win) {
win.document.title = '';
return pdfDoc.getPage(1)
.then(function(page) {
var viewport = page.getViewport({ scale: 1 });
//win.document.head.appendChild(win.document.createElement('style')).textContent =
printContainerElement.appendChild(win.document.createElement('style')).textContent =
'#supports ((size:A4) and (size:1pt 1pt)) {' +
'#page { margin: 1pt; size: ' + ((viewport.width * PRINT_UNITS) / CSS_UNITS) + 'pt ' + ((viewport.height * PRINT_UNITS) / CSS_UNITS) + 'pt; }' +
'}' +
'#print-canvas { display: none }' +
'#media print {' +
'body { margin: 0 }' +
'canvas { page-break-before: avoid; page-break-after: always; page-break-inside: avoid }' +
'#print-canvas { page-break-before: avoid; page-break-after: always; page-break-inside: avoid; display: block }' +
'body > *:not(#print-container) { display: none; }' +
'}'+
'#media screen {' +
'body { margin: 0 }' +
'}'+
''
return win;
})
})
.then(function(win) {
var allPages = [];
for ( var pageNumber = 1; pageNumber <= pdfDoc.numPages; ++pageNumber ) {
if ( pageNumberOnly !== undefined && pageNumberOnly.indexOf(pageNumber) === -1 )
continue;
allPages.push(
pdfDoc.getPage(pageNumber)
.then(function(page) {
var viewport = page.getViewport({ scale: 1 });
//var printCanvasElt = win.document.body.appendChild(win.document.createElement('canvas'));
var printCanvasElt = printContainerElement.appendChild(win.document.createElement('canvas'));
printCanvasElt.setAttribute('id', 'print-canvas')
printCanvasElt.width = (viewport.width * PRINT_UNITS);
printCanvasElt.height = (viewport.height * PRINT_UNITS);
return page.render({
canvasContext: printCanvasElt.getContext('2d'),
transform: [ // Additional transform, applied just before viewport transform.
PRINT_UNITS, 0, 0,
PRINT_UNITS, 0, 0
],
viewport: viewport,
intent: 'print'
}).promise;
})
);
}
Promise.all(allPages)
.then(function() {
win.focus(); // Required for IE
if (win.document.queryCommandSupported('print')) {
win.document.execCommand('print', false, null);
} else {
win.print();
}
removePrintContainer();
})
.catch(function(err) {
removePrintContainer();
emitEvent('error', err);
})
})
}
this.renderPage = function(rotate) {
if ( pdfRender !== null ) {
if ( canceling )
return;
canceling = true;
pdfRender.cancel();
return;
}
if ( pdfPage === null )
return;
var pageRotate = (pdfPage.rotate === undefined ? 0 : pdfPage.rotate) + (rotate === undefined ? 0 : rotate);
var scale = canvasElt.offsetWidth / pdfPage.getViewport({ scale: 1 }).width * (window.devicePixelRatio || 1);
var viewport = pdfPage.getViewport({ scale: scale, rotation:pageRotate });
emitEvent('page-size', viewport.width, viewport.height, scale);
canvasElt.width = viewport.width;
canvasElt.height = viewport.height;
pdfRender = pdfPage.render({
canvasContext: canvasElt.getContext('2d'),
viewport: viewport
});
annotationLayerElt.style.visibility = 'hidden';
clearAnnotations();
var viewer = {
scrollPageIntoView: function(params) {
emitEvent('link-clicked', params.pageNumber)
},
};
var linkService = new PDFLinkService();
linkService.setDocument(pdfDoc);
linkService.setViewer(viewer);
pendingOperation = pendingOperation.then(function() {
var getAnnotationsOperation =
pdfPage.getAnnotations({ intent: 'display' })
.then(function(annotations) {
PDFJS.AnnotationLayer.render({
viewport: viewport.clone({ dontFlip: true }),
div: annotationLayerElt,
annotations: annotations,
page: pdfPage,
linkService: linkService,
renderInteractiveForms: false
});
});
var pdfRenderOperation =
pdfRender.promise
.then(function() {
annotationLayerElt.style.visibility = '';
canceling = false;
pdfRender = null;
})
.catch(function(err) {
pdfRender = null;
if ( err instanceof PDFJS.RenderingCancelledException ) {
canceling = false;
this.renderPage(rotate);
return;
}
emitEvent('error', err);
}.bind(this))
return Promise.all([getAnnotationsOperation, pdfRenderOperation]);
}.bind(this));
}
this.forEachPage = function(pageCallback) {
var numPages = pdfDoc.numPages;
(function next(pageNum) {
pdfDoc.getPage(pageNum)
.then(pageCallback)
.then(function() {
if ( ++pageNum <= numPages )
next(pageNum);
})
})(1);
}
this.loadPage = function(pageNumber, rotate) {
pdfPage = null;
if ( pdfDoc === null )
return;
pendingOperation = pendingOperation.then(function() {
return pdfDoc.getPage(pageNumber);
})
.then(function(page) {
pdfPage = page;
this.renderPage(rotate);
emitEvent('page-loaded', page.pageNumber);
}.bind(this))
.catch(function(err) {
clearCanvas();
clearAnnotations();
emitEvent('error', err);
});
}
this.loadDocument = function(src) {
pdfDoc = null;
pdfPage = null;
emitEvent('num-pages', undefined);
if ( !src ) {
canvasElt.removeAttribute('width');
canvasElt.removeAttribute('height');
clearAnnotations();
return;
}
// wait for pending operation ends
pendingOperation = pendingOperation.then(function() {
var loadingTask;
if ( isPDFDocumentLoadingTask(src) ) {
if ( src.destroyed ) {
emitEvent('error', new Error('loadingTask has been destroyed'));
return
}
loadingTask = src;
} else {
loadingTask = createLoadingTask(src, {
onPassword: function(updatePassword, reason) {
var reasonStr;
switch (reason) {
case PDFJS.PasswordResponses.NEED_PASSWORD:
reasonStr = 'NEED_PASSWORD';
break;
case PDFJS.PasswordResponses.INCORRECT_PASSWORD:
reasonStr = 'INCORRECT_PASSWORD';
break;
}
emitEvent('password', updatePassword, reasonStr);
},
onProgress: function(status) {
var ratio = status.loaded / status.total;
emitEvent('progress', Math.min(ratio, 1));
}
});
}
return loadingTask.promise;
})
.then(function(pdf) {
pdfDoc = pdf;
emitEvent('num-pages', pdf.numPages);
emitEvent('loaded');
})
.catch(function(err) {
clearCanvas();
clearAnnotations();
emitEvent('error', err);
})
}
annotationLayerElt.style.transformOrigin = '0 0';
}
return {
createLoadingTask: createLoadingTask,
PDFJSWrapper: PDFJSWrapper,
}
}
I am making a editor using fabric js 2.4.1 and have completed all functionality except for the dynamic image cropping. The functionality involves creating a rectangle with the mouse over an image and clicking a crop button.
I have successfully done a proof of concept with a rectangle that was created statically but can't get it to render in my dynamic code. I don't think that the problem has to do with the dynamically created rect but I can't seem to isolate the problem. It has to be something simple that I'm overlooking and I think the problem might be in my crop button code.
document.getElementById("crop").addEventListener("click", function() {
if (target !== null && mask !== null) {
mask.setCoords();
target.clipPath = mask; // THIS LINE IS NOT WORKING!!!
//target.selectable = true;
target.setCoords();
console.log(target);
canvas.renderAll();
//canvas.remove(mask);
}
});
Here is a fiddle to the dynamic code that has the problem:
https://jsfiddle.net/Larry_Robertson/mqrv5fnt/
Here is a fiddle to the static code that I gained proof of concept from:
https://jsfiddle.net/Larry_Robertson/f34q67op/
Source code of Dynamic Version:
HTML
<canvas id="c" width="500" height="500" style="border:1px solid #ccc"></canvas>
<button id="crop">Crop</button>
JS
var canvas = new fabric.Canvas('c', {
selection: true
});
var rect, isDown, origX, origY, done, object, mask, target;
var src = "http://fabricjs.com/lib/pug.jpg";
fabric.Image.fromURL(src, function(img) {
img.selectable = false;
img.id = 'image';
object = img;
canvas.add(img);
});
canvas.on('object:added', function(e) {
target = null;
mask = null;
canvas.forEachObject(function(obj) {
//alert(obj.get('id'));
var id = obj.get('id');
if (id === 'image') {
target = obj;
}
if (id === 'mask') {
//alert('mask');
mask = obj;
}
});
});
document.getElementById("crop").addEventListener("click", function() {
if (target !== null && mask !== null) {
mask.setCoords();
target.clipPath = mask; // THIS LINE IS NOT WORKING!!!
//target.selectable = true;
target.setCoords();
console.log(target);
canvas.renderAll();
//canvas.remove(mask);
}
});
canvas.on('mouse:down', function(o) {
if (done) {
canvas.renderAll();
return;
}
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
rect = new fabric.Rect({
left: origX,
top: origY,
//originX: 'left',
//originY: 'top',
width: pointer.x - origX,
height: pointer.y - origY,
//angle: 0,
fill: 'rgba(255,0,0,0.3)',
transparentCorners: false,
//selectable: true,
id: 'mask'
});
canvas.add(rect);
canvas.renderAll();
});
canvas.on('mouse:move', function(o) {
if (done) {
canvas.renderAll();
return;
}
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
if (origX > pointer.x) {
rect.set({
left: Math.abs(pointer.x)
});
}
if (origY > pointer.y) {
rect.set({
top: Math.abs(pointer.y)
});
}
rect.set({
width: Math.abs(origX - pointer.x)
});
rect.set({
height: Math.abs(origY - pointer.y)
});
canvas.renderAll();
});
canvas.on('mouse:up', function(o) {
if (done) {
canvas.renderAll();
return;
}
isDown = false;
//rect.selectable = true;
rect.set({
selectable: true
});
rect.setCoords();
canvas.setActiveObject(rect);
canvas.bringToFront(rect);
canvas.renderAll();
//alert(rect);
rect.setCoords();
object.clipPath = rect;
object.selectable = true;
object.setCoords();
canvas.renderAll();
//canvas.remove(rect);
done = true;
});
You need to set the dirty parameter on image on true, so object's cache will be rerendered next render call.
Here is the fiddle:
https://jsfiddle.net/mqrv5fnt/115/
var canvas = new fabric.Canvas('c', {
selection: true
});
var rect, isDown, origX, origY, done, object, mask, target;
var src = "http://fabricjs.com/lib/pug.jpg";
fabric.Image.fromURL(src, function(img) {
img.selectable = false;
img.id = 'image';
object = img;
canvas.add(img);
});
canvas.on('object:added', function(e) {
target = null;
mask = null;
canvas.forEachObject(function(obj) {
//alert(obj.get('id'));
var id = obj.get('id');
if (id === 'image') {
target = obj;
}
if (id === 'mask') {
//alert('mask');
mask = obj;
}
});
});
document.getElementById("crop").addEventListener("click", function() {
if (target !== null && mask !== null) {
mask.setCoords();
target.clipPath = mask; // THIS LINE IS NOT WORKING!!!
target.dirty=true;
//target.selectable = true;
target.setCoords();
canvas.remove(mask);
canvas.renderAll();
//canvas.remove(mask);
}
});
canvas.on('mouse:down', function(o) {
if (done) {
canvas.renderAll();
return;
}
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
rect = new fabric.Rect({
left: origX,
top: origY,
//originX: 'left',
//originY: 'top',
width: pointer.x - origX,
height: pointer.y - origY,
//angle: 0,
fill: 'rgba(255,0,0,0.3)',
transparentCorners: false,
//selectable: true,
id: 'mask'
});
canvas.add(rect);
canvas.renderAll();
});
canvas.on('mouse:move', function(o) {
if (done) {
canvas.renderAll();
return;
}
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
if (origX > pointer.x) {
rect.set({
left: Math.abs(pointer.x)
});
}
if (origY > pointer.y) {
rect.set({
top: Math.abs(pointer.y)
});
}
rect.set({
width: Math.abs(origX - pointer.x)
});
rect.set({
height: Math.abs(origY - pointer.y)
});
canvas.renderAll();
});
canvas.on('mouse:up', function(o) {
if (done) {
canvas.renderAll();
return;
}
isDown = false;
//rect.selectable = true;
rect.set({
selectable: true
});
rect.setCoords();
canvas.setActiveObject(rect);
canvas.bringToFront(rect);
canvas.renderAll();
//alert(rect);
rect.setCoords();
object.clipPath = rect;
object.selectable = true;
object.setCoords();
canvas.renderAll();
//canvas.remove(rect);
done = true;
});
PDF export for custom widget doesn't work from icCube reporting. Server engine version is 5.0.3 and reporting 5.0.3 (6:2163).
We didn't see any error message within the logs, the process remains stuck into the Monitoring -> Active Requests tab.
The report included is based on icCube demo Sales schema.
Widget code:
FishboneChart.js:
test = {
module : {}
}
test.module.FishboneChart = (function (_super) {
__extends(FishboneChart, _super);
function FishboneChart(container, options) {
_super.call(this, container, options);
this.options = options;
this.container = container;
var chartContainer = $("<div class='ic3w-fishbone-chart'></div>");
var contentContainer = $("<div class='ic3w-fishbone-chart-content'></div>");
var ct = $(this.container);
ct.append(chartContainer);
chartContainer.append(contentContainer);
};
$.extend(FishboneChart.prototype, {
buildInHtml : function (gviTable) {
var chartData = buildChartDataJson(gviTable);
renderFishboneChart(chartData);
}
});
return FishboneChart;
})(viz.GviChartBase);
test.module.FishboneChartAdapterFactory = (function (_super) {
__extends(FishboneChartAdapterFactory, _super);
function FishboneChartAdapterFactory() {
_super.call(this, "test.module.FishboneChartAdapter");
}
FishboneChartAdapterFactory.prototype.getId = function () {
return 'testFishboneChart';
};
FishboneChartAdapterFactory.prototype.getMenuGroupName = function () {
return "testMenu"
};
FishboneChartAdapterFactory.prototype.getTag = function () {
return "testFishboneChart"
};
return FishboneChartAdapterFactory;
})(ic3.WidgetAdapterFactory);
test.module.FishboneChartAdapter = (function (_super) {
__extends(FishboneChartAdapter, _super);
function FishboneChartAdapter(context) {
_super.call(this, context);
this.classID = "test.module.FishboneChartAdapter";
}
FishboneChartAdapter.prototype.reportTypeName = function () {
return 'Test fishbone-chart';
};
FishboneChartAdapter.prototype.getWidgetGroupName = function() {
return 'chart';
};
FishboneChartAdapter.prototype.getNameForCssClass = function() {
return 'test-chart';
};
FishboneChartAdapter.prototype.gutsMeta = function () {
return [
{
name: 'title',
type: 'text'
}
]
};
FishboneChartAdapter.prototype.createWidget = function (options, container) {
return new test.module.FishboneChart(container, options);
};
return FishboneChartAdapter;
})(ic3.ChartAdapter);
var initializeFishbone = function(d3){
"use strict";
d3.fishbone = function(){
var _margin = 50,
_marginRoot = 20,
_marginTail = 100,
_marginTop = 30,
_nodes,
_links,
_node,
_link,
_root,
_arrowId = function(d){ return "arrow"; },
_children = function(d){ return d.children; },
_label = function(d){ return d.name; },
_perNodeTick = function(d){},
_linkScale = d3.scale.log()
.domain([1, 5])
.range([20, 10]),
_chartSize = getChartSize(),
_force = d3.layout.force()
.gravity(0)
.size([
_chartSize.width,
_chartSize.height
])
.linkDistance(_linkDistance)
.chargeDistance([10])
.on("tick", _tick);
var fb1 = function($){
_links = [];
_nodes = [];
_build_nodes($.datum());
_force
.nodes(_nodes)
.links(_links);
_link = $.selectAll(".link")
.data(_links);
_link.enter().append("line");
_link
.attr({
"class": function(d){ return "link link-" + d.depth; },
"marker-end": function(d){
return d.arrow ? "url(#" + _arrowId(d) + ")" : null;
}
});
_link.exit().remove();
_node = $.selectAll(".node").data(_nodes);
_node.enter().append("g")
.attr({
"class": function(d){ return "node" + (d.root ? " root" : ""); }
})
.append("text");
_node.select("text")
.attr({
"class": function(d){ return "label-" + d.depth; },
"text-anchor": function(d){
return !d.depth ? "start" : d.horizontal ? "end" : "middle";
},
dy: function(d){
return d.horizontal ? ".35em" : d.region === 1 ? "1em" : "-.2em";
}
})
.text(_label);
_node.exit().remove();
_node
.call(_force.drag)
.on("mousedown", function(){ d3.event.stopPropagation(); });
_root = $.select(".root").node();
};
function _arrow($){
var defs = $.selectAll("defs").data([1]);
defs.enter().append("defs");
defs.selectAll("marker#" + _arrowId())
.data([1])
.enter().append("marker")
.attr({
id: _arrowId(),
viewBox: "0 -5 10 10",
refX: 10,
refY: 0,
markerWidth: 10,
markerHeight: 10,
orient: "auto"
})
.append("path")
.attr({d: "M0,-5L10,0L0,5"});
}
function _build_nodes(node){
_nodes.push(node);
var cx = 0;
var between = [node, node.connector],
nodeLinks = [{
source: node,
target: node.connector,
arrow: true,
depth: node.depth || 0
}],
prev,
childLinkCount;
if(!node.parent){
_nodes.push(prev = {tail: true});
between = [prev, node];
nodeLinks[0].source = prev;
nodeLinks[0].target = node;
node.horizontal = true;
node.vertical = false;
node.depth = 0;
node.root = true;
node.totalLinks = []
}else{
node.connector.maxChildIdx = 0;
node.connector.totalLinks = [];
}
node.linkCount = 1;
(_children(node) || []).forEach(function(child, idx){
child.parent = node;
child.depth = (node.depth || 0) + 1;
child.childIdx = idx;
child.region = node.region ? node.region : (idx & 1 ? 1 : -1);
child.horizontal = !node.horizontal;
child.vertical = !node.vertical;
if(node.root && prev && !prev.tail){
_nodes.push(child.connector = {
between: between,
childIdx: prev.childIdx
})
prev = null;
}else{
_nodes.push(prev = child.connector = {between: between, childIdx: cx++});
}
nodeLinks.push({
source: child,
target: child.connector,
depth: child.depth
});
childLinkCount = _build_nodes(child);
node.linkCount += childLinkCount;
between[1].totalLinks.push(childLinkCount);
});
between[1].maxChildIdx = cx;
Array.prototype.unshift.apply(_links, nodeLinks);
return node.linkCount;
}
function _linePosition($){
$.attr({
x1: function(d){ return d.source.x; },
y1: function(d){ return d.source.y; },
x2: function(d){ return d.target.x; },
y2: function(d){ return d.target.y; }
})
}
function _nodePosition($){
$.attr("transform", function(d){
return "translate(" + d.x + "," + d.y + ")";
})
}
function _linkDistance(d){
return (d.target.maxChildIdx + 1) * _linkScale(d.depth === 0 ? 1 : d.depth);
}
function _tick(e){
var k = 6 * e.alpha,
size = _force.size(),
width = size[0],
height = size[1],
a,
b;
_nodes.forEach(function(d){
if(d.root){ d.x = width - (_marginRoot + _root.getBBox().width); }
if(d.tail){ d.x = _marginTail; d.y = height / 2; }
if(d.depth === 1){
d.y = d.region === -1 ? _marginTop : (height - _marginTop);
d.x -= 10 * k;
}
if(d.vertical){ d.y += k * d.region; }
if(d.depth){ d.x -= k; }
if(d.between){
a = d.between[0];
b = d.between[1];
d.x = b.x - (1 + d.childIdx) * (b.x - a.x) / (b.maxChildIdx + 1);
d.y = b.y - (1 + d.childIdx) * (b.y - a.y) / (b.maxChildIdx + 1);
}
_perNodeTick(d);
});
_node.call(_nodePosition);
_link.call(_linePosition);
}
fb1.links = function(){ return _links; };
fb1.nodes = function(){ return _nodes; };
fb1.force = function(){ return _force; };
fb1.defaultArrow = _arrow;
fb1.margin = function(_){
if(!arguments.length){ return _margin; }
_margin = _;
return my;
};
fb1.children = function(_){
if(!arguments.length){ return _children; }
_children = _;
return my;
};
fb1.label = function(_){
if(!arguments.length){ return _label; }
_label = _;
return my;
};
fb1.perNodeTick = function(_){
if(!arguments.length){ return _perNodeTick; }
_perNodeTick = _;
return my;
};
return fb1;
};
};
var getChartSize = function() {
var chart = $('.ic3w-fishbone-chart');
return {
width : chart.width() || 0,
height : chart.height() || 0
};
};
var renderFishboneChart = function(chartData) {
if (!d3.fishbone) {
initializeFishbone(d3);
}
d3.selectAll('.ic3w-fishbone-chart-content svg').remove();
var fishbone = d3.fishbone();
d3.select('.ic3w-fishbone-chart-content')
.append("svg")
.attr(getChartSize())
.datum(chartData)
.call(fishbone.defaultArrow)
.call(fishbone);
fishbone.force().start();
};
var buildChartDataJson = function(gviTable) {
var rowCount = gviTable.getRowCount();
var colCount = gviTable.getColumnCount();
var currentLevel, levelDepthStr;
var currentBranch = [];
for (var i = 0; i < colCount; i++) {
levelDepthStr = gviTable.getPropertyForColumnHeader(i, 0, "a_ld");
currentLevel = parseInt(levelDepthStr);
if (!isNaN(currentLevel)) {
var currentEl = {
name: gviTable.getColumnLabel(i),
children: []
};
if (currentLevel <= currentBranch.length - 1) {
removeElements(currentBranch, currentLevel);
}
currentBranch[currentLevel] = currentEl;
if (currentLevel != 0) {
var parent = currentBranch[currentLevel - 1];
parent.children.push(currentEl);
}
}
}
return currentBranch.length > 0 ? currentBranch[0] : {};
};
var removeElements = function(array, targetLength) {
if (array) {
while (array.length > targetLength) {
array.pop();
}
}
};
FishBonePlugin.js:
ic3globals.plugins.push(
{
name: "Fishbone Chart",
loadCSS: function (options) {
var root = options.rootLocal + "plugins/";
ic3css(root + 'Fishbone.css');
},
loadJS: function (options) {
var root = options.rootLocal + "plugins/";
var deps = ['FishboneChart'];
$script(root + 'FishboneChart.js', deps[0]);
$script.ready(deps, function () { /* asynchronous callback */
options.callback && options.callback();
});
},
registerWidgetFactories: function (manager) {
manager.addWidgetFactory(new test.module.FishboneChartAdapterFactory());
},
registerBabylonTags: function (babylon) {
}
});
Fishbone.css:
.ic3w-fishbone-chart {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.ic3w-fishbone-chart-content *{
font-family: "Gill Sans", "Gill Sans MT";
}
.ic3w-fishbone-chart-content .label-0 {
font-size: 2em;
}
.ic3w-fishbone-chart-content .label-1 {
font-size: 1.5em;
fill: #111;
}
.ic3w-fishbone-chart-content .label-2 {
font-size: 1em;
fill: #444;
}
.ic3w-fishbone-chart-content .label-3 {
font-size: .9em;
fill: #888;
}
.ic3w-fishbone-chart-content .label-4 {
font-size: .8em;
fill: #aaa;
}
.ic3w-fishbone-chart-content .link-0 {
stroke: #000;
stroke-width: 2px;
}
.ic3w-fishbone-chart-content .link-1 {
stroke: #333;
stroke-width: 1px;
}
.ic3w-fishbone-chart-content .link-2, .ic3w-fishbone-chart-content .link-3, .ic3w-fishbone-chart-content .link-4 {
stroke: #666;
stroke-width: .5px;
}
Report code:
{"classID":"ic3.ReportGuts","guts_":{"ic3Version":13,"schemaName":"Sales","cubeName":"Sales","layout":{"classID":"ic3.FixedLayout","guts_":{"ic3Version":13,"grid":10,"boxes":[{"classID":"ic3.FixedLayoutBox","guts_":{"ic3Version":13,"header":"widget-0 ( widgetGroup.testMenu/testFishboneChart )","behaviour":"Fixed Box","noPrint":false,"position":{"top":0,"left":170,"width":1380,"height":820},"widgetAdapterUid":"w1","zIndex":2001,"ic3_uid":"ic3-164"}}]}},"widgetMgr":{"classID":"ic3.WidgetAdapterContainerMgr","guts_":{"ic3Version":13,"items":[{"classID":"test.module.FishboneChartAdapter","guts_":{"ic3Version":13,"navigationGuts":{"classID":"ic3.NavigationStrategy","guts_":{"ic3Version":13,"menuVisibility":{"back":true,"axisXChange":"All","axisYChange":"All","filter":"All","reset":true,"widget":true,"others":"All"},"maxAxisMemberCount":25}},"ic3_name":"widget-0","ic3_uid":"w1","ic3_eventMapper":{"classID":"ic3.EventWidgetMapper","guts_":{"__ic3_widgetEventsDescription":{}}},"ic3_mdxBuilderUid":"m1","__ic3_widgetTypeName":"widgetGroup.testMenu/testFishboneChart"}}]}},"constantMgr":{"classID":"ic3.ConstantsMgr","guts_":{"ic3Version":13}},"cssMgr":{"classID":"ic3.CssMgr","guts_":{}},"javascriptMgr":{"classID":"ic3.ReportJavascriptMgr","guts_":{"ic3Version":13,"js":"/** \n * A function called each time an event is generated. \n * \n * #param context the same object is passed between consumeEvent calls. \n * Can be used to store information. \n * { \n * $report : jQuery context of the report container \n * fireEvent : a function( name, value ) triggering an event \n * } \n * \n * #param event the event information \n * \n { \n * name : as specified in the 'Events' tab \n * value : (optional) actual event value \n * type : (optional) e.g., ic3selection \n * } \n * \n * Check the 'Report Event Names' menu for the list of available events. \n */ \n \nfunction consumeEvent( context, event ) { \n if (event.name == 'ic3-report-init') { \n \n ic3globals.plugins.push(\n {\n name: \"Fishbone Chart\",\n\n loadCSS: function (options) {\n },\n\n loadJS: function (options) {\n },\n\n registerWidgetFactories: function (manager) {\n console.log('korte1');\n manager.addWidgetFactory(new test.module.FishboneChartAdapterFactory());\n },\n\n registerBabylonTags: function (babylon) {\n }\n });\n } \n}"}},"calcMeasureMgr":{"classID":"ic3.CalcMeasureMgr","guts_":{"measures":[]}},"mdxQueriesMgr":{"classID":"ic3.MdxQueriesContainerMgr","guts_":{"mdxQueries":{"classID":"ic3.BaseContainerMgr","guts_":{"ic3Version":13,"items":[{"classID":"ic3.QueryBuilderWidget","guts_":{"mdxWizard":{"classID":"ic3.QueryBuilderWizardForm","guts_":{"rows":[],"cols":[{"classID":"ic3.QueryBuilderHierarchyForm","guts_":{"hierarchy":{"name":"Geography","uniqueName":"[Customers].[Geography]"},"type":"membersOf","membersOf":"all members"}}],"filters":[],"nonEmptyOnRows":false,"nonEmptyOnColumns":false}},"mdxFlat":{"classID":"ic3.QueryBuilderFlatMdxForm","guts_":{"useMdxStatement":false}},"ic3_name":"mdx Query-0","ic3_uid":"m1"}}]}},"mdxFilter":{"classID":"ic3.BaseContainerMgr","guts_":{"ic3Version":13,"items":[]}},"actionBuilders":{"classID":"ic3.BaseContainerMgr","guts_":{"ic3Version":13,"items":[]}}}}}}
Thanks,
Balint Ruzsa
Widget adapter code needs two extra functions(workaround for internal bug):
FishboneChartAdapter.prototype.hasNavigation = function()
{
return false;
};
FishboneChartAdapter.prototype.getNavigationMenuItems = function()
{
return [];
};
isRendered method should be modified, because layout for chart computed dynamicaly. I suggest to use simple setTimeout to with heuristic timeout, but you may implement custom check.
FishboneChart:
test.module.FishboneChart = (function (_super) {
__extends(FishboneChart, _super);
function FishboneChart(container, options) {
_super.call(this, container, options);
this.options = options;
this.container = container;
this.rendered = false;
var chartContainer = $("<div class='ic3w-fishbone-chart'></div>");
var contentContainer = $("<div class='ic3w-fishbone-chart-content'></div>");
var ct = $(this.container);
ct.append(chartContainer);
chartContainer.append(contentContainer);
};
$.extend(FishboneChart.prototype, {
buildInHtml: function (gviTable) {
var chartData = buildChartDataJson(gviTable);
renderFishboneChart(chartData);
var self = this;
// wait until layout is stabilized
setTimeout(function(){self.rendered = true;}, 10000);
},
isRendered: function () {
return this.rendered;
}
});
return FishboneChart;
})(viz.GviChartBase);
As I am new to KineticJs so, I have tried implementing the functionality using Kinectic js for drawing the multiple image on different- different x and y. Now I wanted to resize the stage layer or canvas. I have done that by using the code given below
window.onresize = function (event) {
stage.setWidth(($('#tab' + tabId).innerWidth() / 100) * 80);
var _images = layer.getChildren();
for (var i = 0; i < _images.length; i++) {
if (typeof _images[i].getId() != 'undefined') {
//alert(stage.getScale().x);
_images[i].setX(_images[i].getX() * stage.getScale().x);
layer.draw();
}
}
}
but now the problem is the are being defined and now if browser resize than stage is resized but the images on the prev x and y are fixed . I would like to keep them fixed on the position on resizing of stage layer or canvas.Here are the link of the image before resize and after resizing.beforeresize and afterResize .
Here is my entire code given below:-
$("#tabs li").each(function () {
$(this).live("click", function () {
clearInterval(_timer);
var tabname = $(this).find("a").attr('name');
tabname = $.trim(tabname.replace("#tab", ""));
var tabId = $(this).find("a").attr('href');
tabId = $.trim(tabId.replace("#", ""));
$.ajax({
url: "/Home/GetTabsDetail",
dataType: 'json',
type: 'GET',
data: { tabId: tabId },
cache: false,
success: function (data) {
var bayStatus = [];
var i = 0;
var image_array = [];
var BayExist = false;
var BayCondition;
var imgSrc;
var CanvasBacgroundImage;
var _X;
var _bayNumber;
var _Y;
var _ZoneName;
$(data).each(function (i, val) {
i = i + 1;
if (!BayExist) {
bayStatus = val.BayStatus;
CanvasBacgroundImage = val.TabImageLocation;
BayExist = true;
}
$.each(val, function (k, v) {
if (k == "BayNumber") {
BayCondition = bayStatus[v];
_bayNumber = v;
if (BayCondition == "O")
imgSrc = "../../images/Parking/OccupiedCar.gif"
else if (BayCondition == "N")
imgSrc = "../../images/Parking/OpenCar.gif";
}
if (k == "BayX")
_X = v;
if (k == "BayY")
_Y = v;
if (k == "ZoneName")
_ZoneName = v;
});
image_array.push({ img: imgSrc, xAxis: _X, yAxis: _Y, toolTip: _bayNumber, ZoneName: _ZoneName });
});
var imageUrl = CanvasBacgroundImage;
if ($('#tab' + tabId).length) {
// $('#tab' + tabId).css('background-image', 'url("../../images/Parking/' + imageUrl + '")');
var stage = new Kinetic.Stage({
container: 'tab' + tabId,
width: ($('#tab' + tabId).innerWidth() / 100) * 80, // 80% width of the window.
height: 308
});
window.onresize = function (event) {
stage.setWidth(($('#tab' + tabId).innerWidth() / 100) * 80);
}
$('#tab' + tabId).find('.kineticjs-content').css({ 'background-image': 'url("../../images/Parking/' + imageUrl + '")', 'background-repeat': ' no-repeat', 'background-size': '100% 100%' });
var layer = new Kinetic.Layer();
var planetOverlay;
function writeMessage(message, _x, _y) {
text.setX(_x + 20);
text.setY(_y + 1);
text.setText(message);
layer.draw();
}
var text = new Kinetic.Text({
fontFamily: 'Arial',
fontSize: 14,
text: '',
fill: '#000',
width: 200,
height: 60,
align: 'center'
});
var opentooltip = new Opentip(
"div#tab" + tabId, //target element
"dummy", // will be replaced
"", // title
{
showOn: null // I'll manually manage the showOn effect
});
Opentip.styles.win = {
borderColor: "black",
shadow: false,
background: "#EAEAEA"
};
Opentip.defaultStyle = "win";
// _timer = setInterval(function () {
for (i = 0; i < image_array.length; i++) {
img = new Image();
img.src = image_array[i].img;
planetOverlay = new Kinetic.Image({
x: image_array[i].xAxis,
y: image_array[i].yAxis,
image: img,
height: 18,
width: 18,
id: image_array[i].toolTip,
name: image_array[i].ZoneName
});
planetOverlay.on('mouseover', function () {
opentooltip.setContent("<span style='color:#87898C;'><b>Bay:</b></span> <span style='color:#25A0D3;'>" + this.getId() + "</span><br> <span style='color:#87898C;'><b>Zone:</b></span><span style='color:#25A0D3;'>" + this.getName() + "</span>");
//writeMessage("Bay: " + this.getId() + " , Zone: " + this.getName(), this.getX(), this.getY());//other way of showing tooltip
opentooltip.show();
$("#opentip-1").offset({ left: this.getX(), top: this.getY() });
});
planetOverlay.on('mouseout', function () {
opentooltip.hide();
// writeMessage('');
});
planetOverlay.createImageHitRegion(function () {
layer.draw();
});
layer.add(planetOverlay);
layer.add(text);
stage.add(layer);
}
// clearInterval(_timer);
//$("#tab3 .kineticjs-content").find("canvas").css('background-image', 'url("' + imageUrl + '")');
// },
// 500)
}
}
,
error: function (result) {
alert('error');
}
});
});
});
I want to keep the icons on the position where they were before resizing. I have tried but could not get the right solution to get this done.
How can How can I update x,y position for the images . Any suggestions would be appreciated.
Thanks is advance.
In window.resize, you're changing the stage width by a scaling factor.
Save that scaling factor.
Then multiply the 'x' coordinate of your images by that scaling factor.
You can reset the 'x' position of your image like this:
yourImage.setX( yourImage.getX() * scalingFactor );
layer.draw();
In the above mentioned code for window.onresize. The code has been modified which as follow:-
window.onresize = function (event) {
_orignalWidth = stage.getWidth();
var _orignalHeight = stage.getHeight();
// alert(_orignalWidth);
// alert($('#tab' + tabId).outerHeight());
stage.setWidth(($('#tab' + tabId).innerWidth() / 100) * 80);
//stage.setHeight(($('#tab' + tabId).outerHeight() / 100) * 80);
_resizedWidth = stage.getWidth();
_resizedHeight = stage.getHeight();
// alert(_resizedWidth);
_scaleFactorX = _resizedWidth / _orignalWidth;
var _scaleFactorY = _resizedHeight / _orignalHeight;
//alert(_scaleFactor);
var _images = layer.getChildren();
for (var i = 0; i < _images.length; i++) {
if (typeof _images[i].getId() != 'undefined') {
//alert(stage.getScale().x);
_images[i].setX(_images[i].getX() * _scaleFactorX);
//_images[i].setY(_images[i].getY() * _scaleFactorY);
layer.draw();
}
}
}
I am trying to get globalPoint in Titanium iPhone application when touchmove event occur, I use following code to get globalPoint
var x = parseInt(e.globalPoint.x, 10);
It work fine until I updated Titanium 3.0.2 GA to 3.1.0 GA, after updating I run the application I got following error
'undefined' is not an object (evaluating 'e.globalPoint.x')
I am using this code for swiping window
var animateLeft = Ti.UI.createAnimation({
left : 250,
curve : Ti.UI.ANIMATION_CURVE_EASE_OUT,
duration : 150
});
var animateRight = Ti.UI.createAnimation({
left : 0,
curve : Ti.UI.ANIMATION_CURVE_EASE_OUT,
duration : 150
});
var touchStartX = 0;
var touchStarted = false;
$.innerwin.addEventListener('touchstart', function(e) {
touchStartX = parseInt(e.x, 10);
});
$.innerwin.addEventListener('touchend', function(e) {
touchStarted = false;
if ($.win.left >= 150) {
$.win.animate(animateLeft);
hasSlided = true;
} else {
$.win.animate(animateRight);
hasSlided = false;
}
});
$.innerwin.addEventListener('touchmove', function(e) {
var x = parseInt(e.globalPoint.x, 10);
var newLeft = x - touchStartX;
if (touchStarted) {
if (newLeft <= 250 && newLeft >= 0) {
$.win.left = newLeft;
}
}
if (newLeft > 30) {
touchStarted = true;
}
});
$.button.addEventListener('singletap', function(e) {
$.toggleSlider();
});
var hasSlided = false;
exports.toggleSlider = function() {
if (!hasSlided) {
$.win.animate(animateLeft);
hasSlided = true;
} else {
$.win.animate(animateRight);
hasSlided = false;
}
}
This has been deprecated:
Instead you need to do this (in this very contrived example), and use the convertPointToView method:
var baseview = Ti.UI.createView({width : Ti.UI.FILL, height : Ti.UI.FILL});
var view = Ti.UI.createView({ width : 20, height : 20 });
view.addEventListener('touchmove', function(e) {
var globalPoint = convertPointToView({x : e.x, y : e.y}, baseview);
});
Finally, I used following widget
http://www.danielsefton.com/2013/05/slider-menu-widget-v2-for-titanium-alloy/