Kendo UI gauge animation - kendo-ui

I would like to animate my kendoUI gauges in realtime, whenever the data changes. I currently can do this by setting the values of the gauge pointer directly and refresh, but when i do that it will jump straight to the new value and not animate gracefully to it. How do I add the animation, like the Gauge control does when it first starts?

You don't need to refresh it, just set the new value using value and it gets updated and animated.
Example: Defined an HTML input that I decorate with a Kendo Numeric Text Box. Each time I update the value both a radial and linear gauge get updated.
HTML code:
<div>
<input id="gauge-value" value="65">
</div>
<div id="gauge-container">
<div id="gaugeR"></div>
<div id="gaugeL"></div>
</div>
JavaScript (Gauges initialization):
var gaugeR = $("#gaugeR").kendoRadialGauge({
pointer: {
value: value.value()
},
scale : {
minorUnit : 5,
startAngle: -30,
endAngle : 210,
max : 180
}
}).data("kendoRadialGauge");
var gaugeL = $("#gaugeL").kendoLinearGauge({
pointer: {
value: value.value(),
shape: "arrow"
},
scale : {
majorUnit: 20,
minorUnit: 5,
max : 180
}
}).data("kendoLinearGauge");
and NumericTextBox with change event handler that updates the gauges:
var value = $("#gauge-value").kendoNumericTextBox({
min : 0,
max : 180,
change: function () {
var v = $("#gauge-value").val();
gaugeR.value(v);
gaugeL.value(v);
}
}).data("kendoNumericTextBox");
Example in JSFiddle

Related

AmChart move labelText to right a few pixels

I'm trying to move label test to right few pixels because the way it's displayed now it looks like it is more to the left:
Label text is aligned to center for 2d bar charts but when you have 3d bars you have this slight offset effect to left that needs to be corrected.Label position values are: "bottom", "top", "right", "left", "inside", "middle".
I wasn't able to fine tune it.
Any ideas on this?
As mentioned in my comment, the labels are centered with respect to the angle setting for 3D charts. The API doesn't allow you to shift the label left or right, so you have to manipulate the graph SVG nodes directly through the drawn event. If you set addClassNames to true, you can retrieve the label elements using document.querySelectorAll through the generated DOM class names and then modifying the translate value in the transform attribute accordingly. You can use a technique from this SO answer to easily manipulate the transform attribute as an object:
// ...
"addClassNames": true,
"listeners": [{
"event": "drawn",
"method": function(e) {
Array.prototype.forEach.call(
document.querySelectorAll(".amcharts-graph-g4 .amcharts-graph-label"),
function(graphLabel) {
var transform = parseTransform(graphLabel.getAttribute('transform'));
transform.translate[0] = parseFloat(transform.translate[0]) + 5; //adjust X offset
graphLabel.setAttribute('transform', serializeTransform(transform));
});
}
}]
// ...
// from http://stackoverflow.com/questions/17824145/parse-svg-transform-attribute-with-javascript
function parseTransform(a) {
var b = {};
for (var i in a = a.match(/(\w+\((\-?\d+\.?\d*e?\-?\d*,?)+\))+/g)) {
var c = a[i].match(/[\w\.\-]+/g);
b[c.shift()] = c;
}
return b;
}
//serialize transform object back to an attribute string
function serializeTransform(transformObj) {
var transformStrings = [];
for (var attr in transformObj) {
transformStrings.push(attr + '(' + transformObj[attr].join(',') + ')');
}
return transformStrings.join(',');
}
Updated fiddle

D3 datamaps changing border width on mouseover

I'm trying to make a combined map/chart visualization work. I want to be able to mouseover/select a country on the map, and have an effect applied not only to the country but also to the line on the chart representing the country's data (of whatever, let's say population growth over the last decade).
In the done section of the map initialization, I use a callback highlightMap and pass in the countryName. This in theory would also be called by the chart when I mouseover that.
Questions:
1) In highlightMap my attempt to get the country element and change it's border width doesn't work. What's the right way to grab a map subunit and apply an effect to it?
2) Is this the right way to do this in general?
var map;
function setupMap(mouseoverCallback, mouseoutCallback) {
var width = mapWidth;
var height = mapHeight;
map = new Datamap({
element: document.getElementById(mapContainerDiv),
projection: 'mercator',
// responsive: true,
width: width,
height: height,
fills: {
defaultFill: "#ffffff"
},
geographyConfig: {
borderColor: '#000000',
},
data: {},
done: function(datamap) {
datamap.svg.selectAll('.datamaps-subunit').on('mouseover', function(geography) {
var countryName = geography.properties.name;
highlightMap(countryName);
});
datamap.svg.selectAll('.datamaps-subunit').on('mouseout', function(geography) {
var countryName = geography.properties.name;
highlightMap(countryName);
});
}
});
}
function highlightMap(name, highlight) {
var code = country2Code[name];
if (highlight) {
var countryElement = map.svg.select("#datamaps-subunit "+code);
countryElement.attr('stroke-width', 10); // Change border of country to something nutty
// reset color
...
}
}
Sort out your selectors:
.datamaps-subunit is not the same as #datamaps-subunit
Moreover, each country geometry has an additional class (like "ESP" or "USA") with the country code
To later select the country you just use map.svg.selectAll(".datamaps-subunit.ESP") or map.svg.selectAll(".datamaps-subunit.USA")
Notice there is no space between class names, as they are applied to the same SVG element
Use select() or selectAll() depending on how many elements you expect to get (one or possibly many)
EDIT: A much easier option would be to simply add this rule to your CSS sheet:
.datamaps-subunit:hover {
stroke-width: 2px;
}

Infinite Scrolling with wookmark plugins scrolling

With ref. to above subject, I am using wookmark plugin to scroll our home page data dynamically….I have studied the tutorial provided on wookmark and I m using the exact script provided by wookmark and working fine shorts of not 100% working.
Things it stucks when it reaches at bottom of the window then we slightly press the up arrow key, that loads the products again and this is happens randomly some time it scrolls perfectly and some time it stucks and if presses up arrow key it starts working again.
Kindly help me out where I m going wrong. Kindly provide me the easy working script for the same.
I m using following code :
(function ($) {
$('#main').imagesLoaded(function () {
var handler = null;
// Prepare layout options.
var options = {
itemWidth: 200, // Optional min width of a grid item
autoResize: true, // This will auto-update the layout when the browser window is resized.
container: $('#main'), // Optional, used for some extra CSS styling
offset: 20, // Optional, the distance between grid items
outerOffset: 20, // Optional the distance from grid to parent
flexibleWidth: 300 // Optional, the maximum width of a grid item
};
function applyLayout() {
$('#main').imagesLoaded(function () {
// Destroy the old handler
if (handler.wookmarkInstance) {
handler.wookmarkInstance.clear();
}
// Create a new layout handler.
handler = $('#display li');
handler.wookmark(options);
});
handler.wookmark(options);
}
/**
* When scrolled all the way to the bottom, add more tiles.
*/
function onScroll(event) {
// Check if we're within 100 pixels of the bottom edge of the broser window.
var winHeight = window.innerHeight ? window.innerHeight : $(window).height(); // iphone fix
//var closeToBottom = ($(window).scrollTop() >= $((document)).height() - $((window)).height() - $("#footer").height() - 500); //(($(window).scrollTop() - 100)); //+ "%"
var closeToBottom = ($(window).scrollTop() + winHeight > $(document).height() - 100);
if (closeToBottom) {
// Get the first then items from the grid, clone them, and add them to the bottom of the grid.
var items = $('#display li'),
firstTen = items.slice(0, 10);
//$('#display').append(firstTen.clone());
applyLayout();
}
};
// Capture scroll event.
$(window).bind('scroll', onScroll);
// Call the layout function.
handler = $('#display li');
handler.wookmark(options);
});
$(window).load(function () {
handler.wookmark(options);
});
})(jQuery);
If you commented out
//$('#display').append(firstTen.clone());
then the new items will not be loaded on the end of list. You need to uncomment that line to get new items.
In real life instead of
var items = $('#display li'),
firstTen = items.slice(0, 10);
$('#display').append(firstTen.clone());
you would need a code that will load new items.
Also I think it might make sense to change > to >=
var closeToBottom = ($(window).scrollTop() + winHeight >= $(document).height() - 100);
to load new items if scroll position is more or equal to the height of window - 100, where 100 is just some value - you could try 200 or even more to see if it will work better for you.

Bing Maps API v7 Custom HTML pushpins in Firefox not positioned correctly

I've created an app where I use several custom HTML pushpins. Each one of these pushpins has a click event that will call setView on the map to center the map on the selected pin. This works perfectly in all browsers except for Firefox (testing version 22.0).
In Firefox, after the setView animation completes and the map is centered on the pushpin, the pushpin is then offset horizontally, vertically or both by a certain amount of pixels. The amount seems to correspond with amount of pixels the map has moved. If you then drag the map manually with the mouse, upon releasing the mouse button, the pushpin snaps back to its proper place. I've checked the top and left position values of the MapPushpinBase anchor tag in compared it with other browsers and the values differ.
Unfortunately, I cannot post a live example because the product has not yet been publicly released. But see below for the code I'm using.
this.clickHandlers.push(Microsoft.Maps.Events.addHandler(node, 'click', function (e) {
var element = $(e.target._htmlContent);
self.nodeHitboxHandler(element);
}));
Within the nodeHitboxHandler function, the only piece of Bing Map code is this:
this.map.setView({
center: new Microsoft.Maps.Location(panStart.latitude, panStart.longitude),
zoom: this.zoom,
mapTypeId: Microsoft.Maps.MapTypeId[self.mapTypeId]
});
Thanks in advance for any help.
UPDATE:
In order to make things clearer, I've created a simple example that demonstrates the problem. You can see it here: http://ginof.com/tests/bing/
In Firefox, try clicking on the different pushpins and watch the behaviour of the pushpin you've just clicked on after the map finishes panning to its new location. The map works fine in all browsers except Firefox.
Here's the complete JavaScript code for this example:
$(document).ready(function () {
var map = null,
initialCoordinates = {latitude: 40.71435, longitude: -74.00597},
initialPoint = new Microsoft.Maps.Location(initialCoordinates.latitude, initialCoordinates.longitude),
range = {
top: 3,
right: 5,
bottom: 0.01,
left: 5
},
mapOptions = {
credentials:"BING-MAPS-API-KEY",
disableKeyboardInput: true,
disableZooming: true,
enableClickableLogo: false,
enableSearchLogo: false,
showBreadcrumb: false,
showDashboard: false,
showMapTypeSelector: false,
showScalebar: false,
inertiaIntensity: 0.5,
mapTypeId: Microsoft.Maps.MapTypeId.birdseye,
labelOverlay: Microsoft.Maps.LabelOverlay.hidden,
center: initialPoint,
zoom: 14
};
function GetMap() {
// Initialize the map
map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), mapOptions);
// Create nodes
map.entities.clear();
var pushpinOptions,
pushpin,
nodeCoordinates;
for (var i = 0; i < 5; i++) {
pushpinOptions = {width: null, height: null, htmlContent: '<div id="node' + i + '" class="node">' + i + '. Custom HTML</div>'};
nodeCoordinates = {latitude: initialCoordinates.latitude + i * 0.005, longitude: initialCoordinates.longitude + i * 0.005};
pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(nodeCoordinates.latitude, nodeCoordinates.longitude), pushpinOptions);
pushpinClick = Microsoft.Maps.Events.addHandler(pushpin, 'click',
(function () {
var nodeId = i,
homeCoordinates = nodeCoordinates;
return function () {
console.log("node " + nodeId + " clicked.");
map.setView({center: new Microsoft.Maps.Location(homeCoordinates.latitude, homeCoordinates.longitude)});
}
})()
);
map.entities.push(pushpin);
}
}
GetMap();
});
Thanks again for any help.
This is a known issue which I was able to reproduce an has been escalated to the development team. Note that the Bing Maps forums are the best place to report these types of issues. You can find a similar thread on this topic here: http://social.msdn.microsoft.com/Forums/en-US/f77e6a80-2e0f-44c3-81cc-edb4c2327016/custom-html-pushpins-in-firefox-not-positioned-correctly

One vertical scroll bar for whole Dijit BorderContainer

Here is the structure of my HTML body.
<body class="claro">
<div id="BorderContainerMain" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline'" style="width: 100%; border:0; padding:0; margin:0;">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'" style="border: 0;">
<div id="topBanner" data-dojo-type="core.widget.GeneralMainHeader" ></div>
</div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'left'" style="border: 0;">
<div id="leftNav" data-dojo-type="core.widget.GeneralLeftNavigation"></div>
</div>
<div id="contentStackContainer" data-dojo-type="dijit.layout.StackContainer" data-dojo-props="region:'center', style: 'border: 0; padding: 0; margin: 0;'"></div>
</div>
Now, my desire is to make the whole screen auto grow in height depending on the content of the center region and let the viewport handle the vertical scrolling.
I am fairly new into dijit layout and I am using DOJO 1.6. I have already learned that I have to write code to achieve this. So, I am trying to get some experience guidance on this.
Thanks,
Rishi
So, I wrote up a custom resize for my purpose but it is not working. Is there any why it not working. Here is the code:
dojo.provide("core.widget.ClientBorderContainer");
dojo.require("dijit.layout.BorderContainer");
dojo.declare("core.widget.ClientBorderContainer", [dijit.layout.BorderContainer], {
totalHeight: 0,
_setupChild: function(/*dijit._Widget*/ child){
// Override BorderContainer._setupChild().
var region = child.region;
console.debug("region :: "+region);
if(region){
this.inherited(arguments);
dojo.addClass(child.domNode, this.baseClass+"Pane");
var ltr = this.isLeftToRight();
if(region == "leading"){ region = ltr ? "left" : "right"; }
if(region == "trailing"){ region = ltr ? "right" : "left"; }
// Create draggable splitter for resizing pane,
// or alternately if splitter=false but BorderContainer.gutters=true then
// insert dummy div just for spacing
if(region != "center" && (child.splitter || this.gutters) && !child._splitterWidget){
var _Splitter = dojo.getObject(child.splitter ? this._splitterClass : "dijit.layout._Gutter");
var splitter = new _Splitter({
id: child.id + "_splitter",
container: this,
child: child,
region: region,
live: this.liveSplitters
});
splitter.isSplitter = true;
child._splitterWidget = splitter;
dojo.place(splitter.domNode, child.domNode, "after");
// Splitters aren't added as Contained children, so we need to call startup explicitly
splitter.startup();
console.debug("Should not be printed as there is no splitter");
}
child.region = region; // TODO: technically wrong since it overwrites "trailing" with "left" etc.
}
},
resize: function(newSize, currentSize){
// Overrides BorderContainer.resize().
// resetting potential padding to 0px to provide support for 100% width/height + padding
// TODO: this hack doesn't respect the box model and is a temporary fix
if(!this.cs || !this.pe){
var node = this.domNode;
this.cs = dojo.getComputedStyle(node);
this.pe = dojo._getPadExtents(node, this.cs);
this.pe.r = dojo._toPixelValue(node, this.cs.paddingRight);
this.pe.b = dojo._toPixelValue(node, this.cs.paddingBottom);
dojo.style(node, "padding", "0px");
}
//Following section calculates the desired height of the BorderContainer
console.debug(this.id+" contentBox height ::: "+dojo.contentBox(this.domNode).h);
this.totalHeight = 0;
dojo.forEach(this.getChildren(), this.calculateHeight, this);
console.debug("this.totalHeight ::: "+this.totalHeight);
console.debug("newSize "+newSize);
console.debug("currentSize "+currentSize);
////////////////////////////////////////////////
// summary:
// Call this to resize a widget, or after its size has changed.
// description:
// Change size mode:
// When changeSize is specified, changes the marginBox of this widget
// and forces it to relayout its contents accordingly.
// changeSize may specify height, width, or both.
//
// If resultSize is specified it indicates the size the widget will
// become after changeSize has been applied.
//
// Notification mode:
// When changeSize is null, indicates that the caller has already changed
// the size of the widget, or perhaps it changed because the browser
// window was resized. Tells widget to relayout its contents accordingly.
//
// If resultSize is also specified it indicates the size the widget has
// become.
//
// In either mode, this method also:
// 1. Sets this._borderBox and this._contentBox to the new size of
// the widget. Queries the current domNode size if necessary.
// 2. Calls layout() to resize contents (and maybe adjust child widgets).
//
// changeSize: Object?
// Sets the widget to this margin-box size and position.
// May include any/all of the following properties:
// | {w: int, h: int, l: int, t: int}
//
// resultSize: Object?
// The margin-box size of this widget after applying changeSize (if
// changeSize is specified). If caller knows this size and
// passes it in, we don't need to query the browser to get the size.
// | {w: int, h: int}
var node = this.domNode;
// set margin box size, unless it wasn't specified, in which case use current size
if(newSize){
dojo.marginBox(node, newSize);
// set offset of the node
if(newSize.t){ node.style.top = newSize.t + "px"; }
if(newSize.l){ node.style.left = newSize.l + "px"; }
}
// If either height or width wasn't specified by the user, then query node for it.
// But note that setting the margin box and then immediately querying dimensions may return
// inaccurate results, so try not to depend on it.
var mb = currentSize || {};
dojo.mixin(mb, {h: this.totalHeight}); // calculated height overrides currentSize
if( !("h" in mb) || !("w" in mb) ){
mb = dojo.mixin(dojo.marginBox(node), mb); // just use dojo.marginBox() to fill in missing values
}
// Compute and save the size of my border box and content box
// (w/out calling dojo.contentBox() since that may fail if size was recently set)
var cs = dojo.getComputedStyle(node);
var me = dojo._getMarginExtents(node, cs);
var be = dojo._getBorderExtents(node, cs);
console.debug("mb.w "+mb.w);
console.debug("mb.h "+mb.h);
var bb = (this._borderBox = {
w: mb.w - (me.w + be.w),
h: mb.h - (me.h + be.h)
});
var pe = dojo._getPadExtents(node, cs);
console.debug("bb.w "+bb.w);
console.debug("bb.h "+bb.h);
this._contentBox = {
l: dojo._toPixelValue(node, cs.paddingLeft),
t: dojo._toPixelValue(node, cs.paddingTop),
w: bb.w - pe.w,
h: bb.h - pe.h
};
// Callback for widget to adjust size of its children
this.layout();
///////////////////////////////////////////////
console.debug(this.id+" contentBox height ::: "+dojo.contentBox(this.domNode).h);
},
calculateHeight: function(/*dijit._Widget*/ child){
var region = child.region;
console.debug("region :: "+region);
if(region && (region == "top" || region == "center" || region == "bottom")){
var childHeight = 0;
if(child instanceof dijit.layout.StackContainer){
console.debug("selectedChildWidget "+child.selectedChildWidget);
if(child.selectedChildWidget)
childHeight = dojo.contentBox(child.selectedChildWidget.domNode).h;
else
childHeight = dojo.contentBox(child.domNode).h;
}else{
childHeight = dojo.contentBox(child.domNode).h;
}
this.totalHeight = this.totalHeight+childHeight;
console.debug("childHeight = "+childHeight+" child.declaredClass"+child.declaredClass);
}
},
_layoutChildren: function(/*String?*/ changedChildId, /*Number?*/ changedChildSize){
// summary:
// This is the main routine for setting size/position of each child.
// description:
// With no arguments, measures the height of top/bottom panes, the width
// of left/right panes, and then sizes all panes accordingly.
//
// With changedRegion specified (as "left", "top", "bottom", or "right"),
// it changes that region's width/height to changedRegionSize and
// then resizes other regions that were affected.
// changedChildId:
// Id of the child which should be resized because splitter was dragged.
// changedChildSize:
// The new width/height (in pixels) to make specified child
if(!this._borderBox || !this._borderBox.h){
// We are currently hidden, or we haven't been sized by our parent yet.
// Abort. Someone will resize us later.
return;
}
console.debug("custom lay out children called");
// Generate list of wrappers of my children in the order that I want layoutChildren()
// to process them (i.e. from the outside to the inside)
var wrappers = dojo.map(this.getChildren(), function(child, idx){
return {
pane: child,
weight: [
child.region == "center" ? Infinity : 0,
child.layoutPriority,
(this.design == "sidebar" ? 1 : -1) * (/top|bottom/.test(child.region) ? 1 : -1),
idx
]
};
}, this);
wrappers.sort(function(a, b){
var aw = a.weight, bw = b.weight;
for(var i=0; i<aw.length; i++){
if(aw[i] != bw[i]){
return aw[i] - bw[i];
}
}
return 0;
});
// Make new list, combining the externally specified children with splitters and gutters
var childrenAndSplitters = [];
dojo.forEach(wrappers, function(wrapper){
var pane = wrapper.pane;
childrenAndSplitters.push(pane);
if(pane._splitterWidget){
childrenAndSplitters.push(pane._splitterWidget);
}
});
// Compute the box in which to lay out my children
console.debug("this._borderBox.h :: "+this._borderBox.h);
var dim = {
l: this.pe.l,
t: this.pe.t,
w: this._borderBox.w - this.pe.w,
h: this._borderBox.h - this.pe.h
};
// Layout the children, possibly changing size due to a splitter drag
dijit.layout.layoutChildren(this.domNode, dim, childrenAndSplitters,
changedChildId, changedChildSize);
}
});
BorderContainer was written to take a sized box and calculate the center based on what's left over, sort of the opposite of what you're trying to do. AFAIK it won't support this.

Resources