Maybe this is a newbie question, how to set grid layout to full screen ?
My current code is :
var container = new qx.ui.container.Composite().set({
decorator: "main",
backgroundColor: "yellow",
allowGrowX: false,
allowGrowY: false
});
var layout = new qx.ui.layout.Grid(2,2);
layout.setSpacing(5);
container.setLayout(layout);
var w1 = new qx.ui.core.Widget();
var w2 = new qx.ui.core.Widget();
var w3 = new qx.ui.core.Widget();
var w4 = new qx.ui.core.Widget();
container.add(w1, {row: 0, column: 0});
container.add(w2, {row: 0, column: 1});
container.add(w3, {row: 1, column: 0});
container.add(w4, {row: 1, column: 1});
container.set({backgroundColor : "white"});
this.getRoot().add(container, {edge: 0});
What did I miss ? It occupies only small part of the browser .
p.s. I am working on qx.Desktop.
To make the Grid layout occupy full screen, I have to add :
layout.setRowFlex(1, 1);
layout.setColumnFlex(1, 1);
after var layout = new qx.ui.layout.Grid(2,2); .
The code is to set the width & height of the grid at (1,1) of the Grid Layour flexible. For function setRowFlex() or setColumnFlex() , the 1st parameter is the index of the grid, while second parameter sets whether the grid has flexible width / height ( 1 = Flexible , 0 = Fixed )
What about
...
allowGrowX: true,
allowGrowY: true
...
?! (Just think of the names).
Related
I have a map with multiple points I want to draw arrows that point to these locations from the border of the map. The arrow should dynamically update its position on the screen when to users pan or zoom the map.
How can one draw an arrow on a map that point to location?
You can draw regular lines to the points and apply arrow style to them as shown in this example.
You just need to place the arrow at the end coordinate instead of applying it on each segment.
var styleFunction = function (feature) {
var geometry = feature.getGeometry();
var styles = [
// Linestring
new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#ffcc33',
width: 2
})
})
];
var coordinates = geometry.getCoordinates();
var length = coordinates.length;
// Last two coordinates for calculating rotation
var end = coordinates[length - 1];
var start = coordinates[length - 2];
var dx = end[0] - start[0];
var dy = end[1] - start[1];
var rotation = Math.atan2(dy, dx);
// Arrow
styles.push(new ol.style.Style({
geometry: new ol.geom.Point(end),
image: new ol.style.Icon({
src: 'https://openlayers.org/en/v4.6.5/examples/data/arrow.png',
anchor: [0.75, 0.5],
rotateWithView: true,
rotation: -rotation
})
}));
return styles;
};
I am having a button on page on the click of the button i need to add rows inside extjs grid.
The row will contain the controls like textbox, combobox, datefields etc.
I have added dynamic rows to the store like this -
var r = Ext.create('Model', {
name: 'XYZ',
email: 'abc#abc.com',
start: new Date(),
salary: 50000,
active: true
});
var i = 0;
page.store.insert(i, r);
But this way i can add records only. and i want to add controls to the grid. Please suggest.
Thanks,
I have used the grid row editing plugin for the issue.
Here i am adding the row to the store and opening it in edit mode via edit plugin.
Sample code is here.
tbar: [
{
text: 'Add Row',
iconCls: 'employee-add',
handler: function () {
//var Date = new Date();
//var Time = new Date().getTime() / 1000;
rowEditing.cancelEdit();
// Create a model instance
var r = Ext.create('TagAdjustment', {
startDate: Ext.Date.clearTime(new Date()),
startTime: 10,
stopDate: Ext.Date.clearTime(new Date()),
stopTime: 10,
rampStart: 10,
rampStop: 10,
gen: 10
});
var selectedRecord = grid.getSelectionModel().getSelection()[0];
var row = grid.store.indexOf(selectedRecord);
store.insert(row + 1, r);
rowEditing.startEdit(row + 1, 0);
}
},
I have ExtJs 4 Area chart with Time serie. I'd like user to be able to horizontally select part of chart and then obtain higher density data from server adequately. Problem is I can't get boundary dates from selection. I've got:
var chart = Ext.create('Ext.chart.Chart', {
store: store,
enableMask: true,
mask: 'horizontal',
listeners: {
select: {
fn: function(me, selection) {
console.log(arguments); // selection = Object { height: 218, width: 117, x: 665, y: 123 }
}
},
...
But select listener provides only pixel data. Is there some way to get boundary axis data (e.g. { from: 2013-08-01, to: 2013-08-20 } or some way to unproject pixels to values? I'm desperade I would say it's such a basic thing but can't find solution anywhere. Thanks in advance.
Well.. it probably doesn't exists a method for this. After digging into source code I've utilized lines from chart.setZoom() method to create function for manual unprojecting of mask selection to X axis data:
var unprojectXAxis = function(chart, selection) {
zoomArea = {
x : selection.x - chart.el.getX(),
width : selection.width
};
xScale = chart.chartBBox.width,
zoomer = {
x : zoomArea.x / xScale,
width : zoomArea.width / xScale
}
ends = chart.axes.items[0].calcEnds();
from = (ends.to - ends.from) * zoomer.x + ends.from;
to = (ends.to - ends.from) * zoomer.width + from;
return { from: new Date(from), to: new Date(to) };
}
I am using a the following code to draw a rectangle on the map to a random lat. & long. based on a city name when a find button is clicked. The problem is if you do not put a different city name in and click the find button the program will draw a second rectangle on the cities original lat. & long. I either need to clear the map and redraw the rectangle or something not quite sure so a second rectangle can not be drawn. Here is the code I am using.
function codeAddress() {
var address = document.getElementById("gadres").value;
if(address=='') {
alert("Address can not be empty!");
return;
}
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
document.getElementById('lat').value=results[0].geometry.location.lat().toFixed(6);
document.getElementById('lng').value=results[0].geometry.location.lng().toFixed(6);
var latlong = "(" + results[0].geometry.location.lat().toFixed(6) + " , " +
+ results[0].geometry.location.lng().toFixed(6) + ")";
map.setZoom(15);
var mapcenter = map.getCenter();
var maplat = mapcenter.lat();
var maplng = mapcenter.lng();
var bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(maplat - 0.002, maplng - 0.002),
new google.maps.LatLng(maplat + 0.002, maplng + 0.002)
);
var rectangle = new google.maps.Rectangle({
bounds: bounds,
draggable:true,
editable: true,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 4,
fillColor: '#FF0000',
fillOpacity: 0.30,
});
rectangle.setMap(map);
google.maps.event.addListener(rectangle, 'bounds_changed', function() {
document.getElementById('coords').value = rectangle.getBounds();
});
} else {
alert("Lat and long cannot be found.");
}
});
}
all help greatly appreciated.
I haven't tried this yet but perhaps you can store your bounds to an array then use a loop statement for that array to check if there is an equal bounds using the equals() method
https://developers.google.com/maps/documentation/javascript/reference#LatLngBounds
In the extjs 4.1.1a code below is a working example of a line chart. Now I need to highlight a part of that chart on a given min and max timestamp.
{'xtype' : 'chart',
'store' : 'ChartData',
'height' : '100%',
'width' : '100%',
'legend' : {'position' : top},
'axes': [{
'title': 'Power',
'type': 'Numeric',
'position': 'left',
'fields': ['power']
},{
'title': 'Timestamp',
'type': 'Numeric',
'position': 'bottom',
'fields': ['timestamp'],
'minorTickSteps': 3
}],
'series': [{
'type': 'line',
'fill': true,
'axis' : 'left',
'xField': 'timestamp',
'yField': 'power'
}]}
I've searched the sencha forum and found nothing in particular that meets my requirements.
For now I managed to change the color of the points on the line chart with a custom renderer.
'renderer': function(sprite, record, attr, index, store) {
var item = store.getAt(index);
if(item != undefined && (item.get('timestamp') < startdate || item.get('timestamp') > enddate)){
return Ext.apply(attr, {'fill': '#00cc00', 'stroke-width': 3, 'radius': 4});
}else{
return Ext.apply(attr, {'fill': '#ff0000', 'stroke-width': 3, 'radius': 4});
}}
But I have not found a way to change the color below the line.
Any suggestions on that?
UPDATE - Working fine now
I implement a solution based on the answer given by Colombo.
doCustomDrawing: function () {: function (p){
var me = this, chart = me.chart;
if(chart.rendered){
var series = chart.series.items[0];
if (me.groupChain != null) {
me.groupChain.destroy();
me.groupChain = null;
}
me.groupChain = Ext.create('Ext.draw.CompositeSprite', {
surface: chart.surface
});
if(series != null && series.items != null){
var surface = chart.surface;
var pathV = 'M';
var first = true;
// need first and last x cooridnate
var mX = 0,hX = 0;
Ext.each(series.items, function(item){
var storeItem = item.storeItem,
pointX = item.point[0],
pointY = item.point[1];
// based on given startdate and enddate start collection path coordinates
if(!(storeItem.get('timestamp') < startdate || storeItem.get('timestamp') > enddate)){
if(hX<pointX){
hX = pointX;
}
if(first){
first = false;
mX = pointX;
pathV+= + pointX + ' ' + pointY;
}else{
pathV+= ' L' + pointX + ' ' + pointY;
}
}
});
var sprite = Ext.create('Ext.draw.Sprite', {
type: 'path',
fill: '#f00',
surface: surface,
// to draw a sprite with the area below the line we need the y coordinate of the x axe which is in my case items[1]
path : pathV + ' L'+ hX + ' ' + chart.axes.items[1].y + ' L'+ mX + ' ' + chart.axes.items[1].y + 'z'
});
me.groupChain.add(sprite);
me.groupChain.show(true);
}
}}
This looks really good and has the effect I was hoping for and in case you resize the container the new sprite is cleared from the chart. Thx to Colombo again.
This is possible to implement. Here is how I would do it.
1. Add a listener for afterrender event for series.
listeners: {
afterrender: function (p) {
this.doCustomDrawing();
},
scope: me
}
2. Create a CompositeSprite
doCustomDrawing: function () {
var me = this, chart = me.chart;
if (chart.rendered) {
var series = chart.series.items[0];
if (me.groupChain != null) {
me.groupChain.destroy();
me.groupChain = null;
}
me.groupChain = Ext.create('Ext.draw.CompositeSprite', {
surface: chart.surface
});
// Draw hilight here
Ext.each(series.items, function (item) {
var storeItem = item.storeItem,
pointX = item.point[0],
pointY = item.point[1];
//TODO: Create your new line sprite using pointX and pointY
// and add it to CompositeSprite me.groupChain
});
me.groupChain.show(true);
}
},
There is no "built-in" way to go about this. You are probably running into some difficulties looking for it because "highlighting" a line chart currently means something totally different in the ExtJS API. It normally refers to making the line and markers bold when you hover the mouse over a data series.
However your idea sounds interesting, I might need use this in a project I have coming up.
I don't have the time to work out the exact code right now but this could be done by creating a rectangular sprite and adding it to the chart's surface property.
You can do that even after the chart has been all rendered using the Ext.draw.Surface.add method as described here in the docs.
You will have to come up with logic for determining width and positioning, if I remember the chart API properly, you should be able to extract x coordinates (horizontal location) of individual records by fishing around in the items property of the Ext.chart.series.Line object inside the chart.
The height of the highlight should be easy though - just read the height of the chart.