Extjs Chart Legend items with scroll bar when legend items overflows - extjs

I have an Ext JS pie chart with too many items. Because of this legend overflows and few items are not visible. I took a look at Smart legends (https://market.sencha.com/extensions/ext-ux-chart-smartlegend). But that seems ugly when the legend items are too many, and that makes the Chart looks tiny. So I'm looking for a solution where it would add a vertical scrollbar (when legend is in left or right hand side of the graph).
I was trying to see if I could add the scrollable container to the graph on which I could add the legends and when it overflows, scrollable container would add the scrollbar. So I was trying to override the "Ext.chart.Legend", and override the 'createBox' function. But I'm not sure how to add the component to the Chart since createBox() adds the Sprite to the chart's surface. Not sure how to add the 'scrollable container' to the chart on which I could add the legend.
Basically I'm looking for the graph which looks like in the attached image. Please help me on this.!! I need it ASAP. Thanks in advance!
https://www.dropbox.com/s/4q9o6v5ei4ba96r/Chart%20Legend%20items%20with%20scroll%20bar.png
Thanks!
Omega

JavaScript:
Ext.override(Ext.chart.Legend, {
createItems: function() {
if (this.customLegend != null) {
this.customLegend.remove();
}
this.customLegend = $('<div class="custom-legend"></div>');
$(this.chart.el.dom).append(this.customLegend);
this.callParent();
},
createLegendItem: function(series, yFieldIndex) {
var colorItem = series.getLegendColor(yFieldIndex).match(/.+?\-(.+?)\-.+?/i)[1];
var legendItem = $('<div class="custom-legendItem"><div class="custom-legendItemMarker" style="background-color: #'+colorItem+'"></div>'+series.yField[yFieldIndex]+'</div>');
$(this.customLegend).append(legendItem);
legendItem.on('mouseover', function() {
series._index = yFieldIndex;
series.highlightItem();
});
legendItem.on('mouseout', function() {
series._index = yFieldIndex;
series.unHighlightItem();
});
legendItem.on('mousedown', function() {
var me = this,
index = yFieldIndex;
if (!me.hiddenSeries) {
series.hideAll(index);
legendItem.addClass('hide');
} else {
series.showAll(index);
legendItem.removeClass('hide');
}
me.hiddenSeries = !me.hiddenSeries;
me.legend.chart.redraw();
});
},
updateItemDimensions: function() {
return {
totalWidth: 0,
totalHeight: 0,
maxWidth: 0,
maxHeight: 0
};
},
updatePosition: function() {
},
removeItems: function() {
}
});
CSS:
.custom-legend {
position: absolute;
right: 20px;
top: 0;
height: 100%;
overflow-y: auto;
border: 1px solid #CCC;
padding: 20px;
min-width: 200px;
}
.custom-legendItem {
margin: 4px 0;
}
.custom-legendItem.hide {
opacity: 0.5;
}
.custom-legendItem:hover {
cursor: pointer;
font-weight: bold;
}
.custom-legendItemMarker { display: inline-block; width: 12px; height: 12px; margin-right: 12px; }

Related

Not able to solve the media query issue (responsive design)

I tried the following code for making my page responsive, but still the elements are moving out. Can anyone lease have a look at it and help me out?
#media only screen and (max-width: 500px) {
.top-bar-section ul {
margin-top: 15px;
}
}
#media only screen and (min-width: 300px) and (max-width: 500px) {
.widget-area {
display: none;
}
.stat {
margin-bottom: 30px;
}
.clients-style-2 .slides li .client-logo {
margin-bottom: 5px;
}
#clients .slides li .client-logo {
margin-bottom: 5px;
}
#icategories li {
margin-bottom: 10px;
}
}
Ref url: http://7drives.in/dsq/index.html
You have a YouTube video in an iframe, and that iframe has a hard coded width of 500px, so this will be a problem on narrower viewports.
CSS Tricks has one solution to this, jQuery below. There are other solutions for responsive iframes, I like that this is a simple drop fix which doesn't require any changes to your HTML, and also that it resizes both the width and the height of your video.
Hope this helps!
// By Chris Coyier & tweaked by Mathias Bynens
$(function() {
// Find all YouTube videos
var $allVideos = $("iframe[src^='http://www.youtube.com']"),
// The element that is fluid width
$fluidEl = $("body");
// Figure out and save aspect ratio for each video
$allVideos.each(function() {
$(this)
.data('aspectRatio', this.height / this.width)
// and remove the hard coded width/height
.removeAttr('height')
.removeAttr('width');
});
// When the window is resized
// (You'll probably want to debounce this)
$(window).resize(function() {
var newWidth = $fluidEl.width();
// Resize all videos according to their own aspect ratio
$allVideos.each(function() {
var $el = $(this);
$el
.width(newWidth)
.height(newWidth * $el.data('aspectRatio'));
});
// Kick off one resize to fix all videos on page load
}).resize();
});

How can I sequence animations

I've been trying to get a sequence of two animations running but I'm getting really annoyed as I just can't make it work! I need to fade a div in and then slide it to the right. Fade in is easy using:
.fadein.ng-hide-remove {
animation: 0.8s appear;
display: block!important;
}
.fadein.ng-hide-remove.ng-hide-remove-active {
opacity:1;
}
#keyframes appear {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
and
<div id="settings" ng-show="settingsPanel" class="fadein"></div>
and
$scope.showSettings = function(){
$scope.settingsPanel = true;
}
Settings looks like this:
#settings {
background:#353734;
position:fixed;
top:0;
bottom:0;
left:-280px;
width:500px;
z-index:100;
}
I've completed sliding too in a similar way but to get them to trigger one after the other is proving impossible for me. Could someone show me how to do this please?
How about using keyframes as follows:
#settings {
background:#353734;
position:fixed;
top:25px;
bottom:0;
left:0px;
width:200px;
z-index:100;
}
.fadein.ng-hide-remove {
animation: 2.8s appear;
display: block!important;
}
#keyframes appear {
0% {
left: -100px;
opacity: 0;
}
50% {
left: -100px;
opacity: 1;
}
100% {
left: 0;
opacity: 1;
}
}
See working fiddle here:
http://jsfiddle.net/HB7LU/20650/
Why not set keyframes up for animations and simply set different stages for each animation. Bit like this
#keyframes slide-right {
0% {
left: -450px;
}
100% {
left: 0;
}
}

Apply a loadmask to Viewport that also covers floating Components

How can I add a loadmask within the launch method of the Ext.applcation to the viewport that will also covers floating components like windows when get showed?
Currently the mask work but does not cover any opened window.
I found the answer here, the trick is to increase the z-order of the mask:
Ext.getBody().mask().dom.style.zIndex = '99999';
I made a test, it works for me.
You can create custom loader that will hide itself when everything is loaded...
1.Create html holder in body:
<div id="loading-mask"></div>
<div id="loading">
<span id="loading-message">Loading. Please wait...</span>
</div>
2. Add css to properly position mask:
#loading-mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #ffffff;
z-index: 1;
}
#loading {
position: absolute;
top: 40%;
left: 45%;
z-index: 2;
font-family: tahoma,arial,verdana,sans-serif;
font-size: 12px;
}
#loading span {
padding: 5px 30px;
display: block;
}
3. Create js function outside Ext.onReady call:
function hidePreloader() {
var loadingMask = Ext.get('loading-mask');
var loading = Ext.get('loading');
// Hide loading message
loading.fadeOut({ duration: 0.2, remove: true });
// Hide loading mask
loadingMask.setOpacity(0.9);
loadingMask.shift({
xy: loading.getXY(),
width: loading.getWidth(),
height: loading.getHeight(),
remove: true,
duration: 1,
opacity: 0.1,
easing: 'bounceOut'
});
}
4. Call hidePreloader method when all components and tasks are completed and ready, in your case after app.js launch method is fininshed loading, for example:
listeners: {
afterrender: function(form) {
hidePreloader();
}
}
here is a example in fiddle.
I preferred my solution with CSS:
body.x-masked .x-mask {
z-index: 20000;
}
since window z-index is 19001, so 20000 is not bad.

Responsive video player

I need a video player for responsive layout website which is developed by using bootstrap. That means when i do re-size the screen or viewing the page in different size screens the player should be automatically fit to the screen.
I had tried with jwplayer and flowplayer but it didn't work.
http://www.longtailvideo.com/support/forums/jw-player/setup-issues-and-embedding/24635/responsive-video-internet-explorer-100-widthheight
note: The player should be able to play the youtube videos....
Is there anyway to make jwplayer/flowplayer responsive?
Better version of Luka's answer:
$(window).resize(function() {
var $width = $("#holder").width();
var $height = $width/1.5;
jwplayer().resize($width,$height);
});
User the resize function from the JW Player API:
http://www.longtailvideo.com/support/jw-player/29411/resizing-the-player
Another solution:
Check their Responsive Design Support documentation: http://www.longtailvideo.com/support/jw-player/32427/responsive-design-support
<div id="myElement"></div>
<script>
jwplayer("myElement").setup({
file: "/uploads/myVideo.mp4",
image: "/uploads/myPoster.jpg",
width: "100%",
aspectratio: "12:5" // Set your image ratio here
});
</script>
you can change by simple css style
/* Video small screen */
.video {
position: relative;
padding-bottom: 56.25%;
height: 0;
overflow: hidden;
}
.video iframe,
.video object,
.video embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
I am using jQuery for resizing. #holder is your div where movie is positioned (#videocontainer).
Structure:
<div id="holder">
<div id="videocontainer"></div>
</div>
It takes #holder size and give it to #videocontainer. It works in ie9, ie8, ...
$(window).resize(function() {
var $width = $("#holder").width();
var $height = $width/1.5;
jwplayer("videocontainer").setup({
flashplayer: "jwplayer/player.swf",
file: "###.mp4",
width: $width,
height: $height,
image: "###.jpg"
});
});
Hope it helps!
Try FitVids: http://fitvidsjs.com/
If you want to make jwPlayer responsive, try adding this to your CSS file:
#video-jwplayer_wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 format */
padding-top: 30px;
height: 0;
overflow: hidden;
}
#video-jwplayer_wrapper iframe, #video-jwplayer_wrapper object, #video-jwplayer_wrapper embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
source: http://webdesignerwall.com/tutorials/css-elastic-videos
When calling jwplayer, you might also need to set width to 100%:
jwplayer("myElement").setup({
width: 100%
});
The easiest way is to use javascript
function sizing() {
$('#player').css('width', $('#container').outerWidth());
$('#player').css('height',$('#player').outerWidth() / 1.33);
}
$(document).ready(sizing);
$(window).resize(sizing);
Don't forget to include jquery library and to change the aspect ration (1.33 is for 4:3, 1,77 is for 16:9).
This work well for me
JW Player goes here
<script type="text/javascript">
if($( window ).width() <= 400){
pl_width = 300;
pl_heith = 150;
}else if($( window ).width() <= 600){
pl_width = 500;
pl_heith = 250;
}else{
pl_width = 700;
pl_heith = 350;
}
//alert(pl_width);
jwplayer("video_top").setup({
flashplayer: "<?php echo $player_path; ?>",
file: "<?php echo $your_file; ?>",
controlbar: "bottom",
height:pl_heith,
width:pl_width
});
You can just use YouTube videos in your site and use the FitVid.Js plugin to make it responsive.

ExtJS: setDisabled(true) makes fields too dim / transparent to read

When I set a form field into the disabled state using setDisabled or the disabled: true config, for example:
form.getComponent(1).setDisabled(true);
it makes the field unreadable due to the transparency. Is there a good way to improve the look and feel of my disabled fields?
This Worked for me:)
.x-item-disabled {
filter : '' !important;
}
A quick solution is to change the opacity setting in the ext-all.css (or ext-all-debug.css) file. The default setting seems to be:
.x-item-disabled .x-form-trigger {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
opacity: 0.3; }
If you change the opacity values to 0.6 you get a readable form.
Obviously not ideal as you are changing the core framework files but I certainly didn't find a quicker way to correct this.
I did something similar to y'all..
in ExtJS
{
xtype: 'combobox',
name: 'comboTest',
store: "ComboTest",
fieldLabel: "testCombo",
queryMode: "local",
displayField: "display",
valueField: "value",
disabledCls: "disabledComboTestCls" // you are now totally overriding the disabled class as set by .x-item-disabled
}
In you CSS file
.disabledComboTestCls {
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
filter: alpha(opacity=50);
-moz-opacity:0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
}
.disabledComboTestCls input {
font-weight: bold;
color: #888888;
}
And this works well.
We use an override on Ext.form.Field, which hides the triggers etc, and then we add a css class. We then style the component, because the disabled function of ExtJS is indeed not readable enough.
Here is example code:
var originalRender = Ext.form.Field.prototype.onRender;
Ext.override(Ext.form.Field, {
UxReadOnly: false,
UxDisplayOnly: function (displayOnly, cls) {
// If no parameter, assume true
var displayOnly = (displayOnly === false) ? false : true;
if (displayOnly) {
// If a class name is passed in, use that, otherwise use the default one.
// The classes are defined in displayOnly.html for this example
var cls = (cls) ? cls : 'x-form-display-only-field';
// Add or remove the class
this.addClass(cls);
// Set the underlying DOM element's readOnly attribute
this.setReadOnly(displayOnly);
this.editable = false;
// Get this field's xtype (ie what kind of field is it?)
var xType = this.getXType();
if (xType == 'combo' | xType == 'combobox' | xType == 'Ext.ux.Combo' | xType == 'Ext.ux.ComboSearch') {
this.addClass('x-form-display-only-combo');
this.hideTrigger = true;
this.on('expand', function (field) {
if (field.hideTrigger)
field.collapse();
});
}
else if (xType == 'datefield') {
this.addClass('x-form-display-only-datefield');
this.hideTrigger = true;
this.on('expand', function () {
if (this.hideTrigger)
this.collapse();
});
this.editable = false;
} //elseif for each component u want readonly enabled
else {
this.addClass('x-form-display-only-other');
}
// For fields that have triggers (eg date,time,dateTime),
// show/hide the trigger
if (this.trigger) {
this.trigger.setDisplayed(!displayOnly);
}
} else {
this.UxFullField(cls);
}
},
afterRender: function () {
var me = this;
me.UxDisplayOnly(me.UxReadOnly, 'x-form-display-only-field');
this.callParent(arguments);
},
UxFullField: function (cls) {
// If a class name is passed in, use that, otherwise use the default one.
// The classes are defined in displayOnly.html for this example
var cls = (cls) ? cls : 'x-form-display-only-field';
this.removeCls(cls);
// Set the underlying DOM element's readOnly attribute
this.setReadOnly(false);
this.editable = true;
// Get this field's xtype (ie what kind of field is it?)
var xType = this.getXType();
if (xType == 'combo' | xType == 'combobox' | xType == 'Ext.ux.Combo' | xType == 'Ext.ux.ComboSearch') {
this.removeCls('x-form-display-only-combo');
this.setHideTrigger(false);
}
else if (xType == 'datefield') {
this.removeCls('x-form-display-only-datefield');
this.setHideTrigger(false);
this.editable = true;
}//elseif for each component u want readonly enabled
else {
this.removeCls('x-form-display-only-other');
}
// For fields that have triggers (eg date,time,dateTime),
// show/hide the trigger
if (this.trigger) {
this.setHideTrigger(false);
}
}
});
With css you hide stuff like borders etc...
.x-form-display-only-field{}
.x-form-display-only-other input, .x-form-display-only-other select { background: transparent !important; border: 1px solid transparent !important; cursor: pointer; cursor: default; font-weight: bold; background-image: none !important; background-color: transparent !important; }
.x-form-display-only-combo input, .x-form-display-only-combo select { background: transparent !important; border: 1px solid transparent !important; cursor: pointer; cursor: default; font-weight: bold; background-image: none !important; background-color: transparent !important; }
.x-form-display-only-datefield input, .x-form-display-only-datefield select { background: transparent !important; border: 1px solid transparent !important; cursor: pointer; cursor: default; font-weight: bold; background-image: none !important; background-color: transparent !important; }
.x-form-display-only-file input, .x-form-display-only-file select { background: transparent !important; border: 1px solid transparent !important; cursor: pointer; cursor: default; font-weight: bold; background-image: none !important; background-color: transparent !important; }
.x-form-display-only-checkbox { }
.x-form-display-only-radiogroup { }
Now you can add your field the following way:
Ext.create('Ext.form.field.Text', {
name: 'example',
UxReadOnly: true
});
For you Googlers, these answers are outdated if you're on Ext 5 and up. There's now a readOnly bool. The field looks exactly the same, but the value isn't editable.
documentation

Resources