Dynamically change column widths in ExtJS 6 dashboards - javascript

Is there a way to change the column widths in an Ext.dashboard.Dashboard after it has been rendered? It is created with a config value of:
columnWidths: [
0.35,
0.40,
0.25
]
I want to dynamically change it to:
columnWidths: [
0.5,
0.25,
0.25
]
Changing the columnWidths property directly or with setConfig does not update the dashboard. It doesn't appear to have a method for "refresh" or anything else that obviously serves the same purpose. The individual dashboard-columns have a setWidth function but that doesn't seem to do anything either.

I couldn't find anything in the API that managed this automatically but you can manually update the columnWidth values of each child component in the dashboard and then call updateLayout:
function setColumnWidths(dashboard, columnWidths){
var i = 0;
dashboard.items.each(function(item){
if(item instanceof Ext.resizer.Splitter)
return; // ignore
item.columnWidth = columnWidths[i++] || 1;
});
dashboard.updateLayout();
}
ยป Fiddle

Related

visjs timeline - set initial vertical position of items

I'm using vis-timeline to render a hundred rows of data. When the component loads, I want to see the rows starting from the beginning: 1, 2, 3, and so on. Instead, by default, vis-timeline starts by displaying the end of the list (...97, 98, 99, 100), so that you have to scroll up to get to the top?
There are methods like setWindow() for setting the horizontal time frame, but what about the vertical position? I've tried the HTML scroll() method, but that doesn't seem to do anything.
Normally I would use orientation: { item: 'top' } } in the options, but there is a bug that prevents scrolling in that case; it must be set to 'bottom'.
I've thought about initializing the component with the orientation to 'top', then once it displays, setting it to 'bottom' to allow scrolling, but that seems pretty hacky.
Is there a cleaner solution?
You can implement a custom ordering function for items (groups as well) using the order configuration option:
Provide a custom sort function to order the items. The order of the
items is determining the way they are stacked. The function order is
called with two arguments containing the data of two items to be
compared.
WARNING: Use with caution. Custom ordering is not suitable for large
amounts of items. On load, the Timeline will render all items once to
determine their width and height. Keep the number of items in this
configuration limited to a maximum of a few hundred items.
See below for an example:
var items = new vis.DataSet();
for (let i=0; i<100; i++) {
items.add({
id: i,
content: 'item ' + i,
start: new Date(2022, 4, 1),
end: new Date(2022, 4, 14)
});
}
var container = document.getElementById('visualization1');
var options = {
order: function (a, b) {
return b.id - a.id;
}
}
var timeline = new vis.Timeline(container);
timeline.setOptions(options);
timeline.setItems(items);
<link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis-timeline-graph2d.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.js" rel="script"></script>
<div id="visualization1"></div>

Why is my Handsontable custom cell renderer only working for the first row when hiddenColumns and colWidths is set?

I have the following handsontable configured:
var container = document.getElementById('example1'),
hot;
var data = [];
for (var i = 0; i < 100; i++) {
data.push({"id": 1, "rgba": "204,255,204,1"});
}
function callback (row, column, prop) {
const cellProperties = {};
cellProperties.renderer = renderer;
return cellProperties;
}
function renderer (instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
var rdata = instance.getSourceDataAtRow(row);
var colour = rdata.rgba;
td.style.backgroundColor = 'rgba(' + colour + ')';
}
hot = new Handsontable(container, {
data: data
, cells: callback
// adding either of these in isolation allows the rendering to continue working. However adding both together causes only the top row to render correctly.
, hiddenColumns: true
, colWidths: 150
});
With a running example provided in the following link:
https://jsfiddle.net/JoshAdams/sgLm5ev2/
The problem I am encountering is my custom renderer is designed to set the background colours of each handsontable row based on the value in the rgba column. Which works fine initially.
However, when both the hiddenColumns: true and colWidths: 150 (or any number) properties are introduced, it causes an issue whereby only the top row of the handsontable will render correctly.
But adding either of these properties in isolation lets the rendering work correctly.
So does anyone know why this is occurring and how to fix it?
Note
While just calling hot.render() fixes the issue, its not really a solution as this causes additional unnecessary renders of handsontables which becomes a massive performance overhead in larger tables.

Leaflet - get data from static file and API call to build a choropleth map

I got 2 data sources with JSON data.
One is a static file and contains country borders like this:
Static file
var worldboundaries = {"type":"FeatureCollection","features":
[{"type":"Feature","id":"ALB","properties":{"name":"Albania"},"geometry":{"type":"Polygon","coordinates":[[[20.590247,41.855404],[20.463175,41.515089],[20.605182,41.086226],[21.02004,40.842727],[20.99999,40.580004],[20.674997,40.435],[20.615,40.110007],[20.150016,39.624998],[19.98,39.694993],[19.960002,39.915006],[19.406082,40.250773],[19.319059,40.72723],[19.40355,41.409566],[19.540027,41.719986],[19.371769,41.877548],[19.304486,42.195745],[19.738051,42.688247],[19.801613,42.500093],[20.0707,42.58863],[20.283755,42.32026],[20.52295,42.21787],[20.590247,41.855404]]]}},
{"type":"Feature","id":"ARE","properties":{"name":"United Arab Emirates"},"geometry":{"type":"Polygon","coordinates":[[[51.579519,24.245497],[51.757441,24.294073],[51.794389,24.019826],[52.577081,24.177439],[53.404007,24.151317],[54.008001,24.121758],[54.693024,24.797892],[55.439025,25.439145],[56.070821,26.055464],[56.261042,25.714606],[56.396847,24.924732],[55.886233,24.920831],[55.804119,24.269604],[55.981214,24.130543],[55.528632,23.933604],[55.525841,23.524869],[55.234489,23.110993],[55.208341,22.70833],[55.006803,22.496948],[52.000733,23.001154],[51.617708,24.014219],[51.579519,24.245497]]]}},
....
and one contains the density information for fillColor which should be used for this country, where "count" is the value I need. This a kimonolabs api and called with an $AJAX request:
API answer
{"name":"myapi","count":51,"frequency":"Daily","version":109,"newdata":true,"lastrunstatus":"success","thisversionstatus":"success","nextrun":"Fri Sep 25 2015 11:29:40 GMT+0000 (UTC)","thisversionrun":"Thu Sep 24 2015 11:29:40 GMT+0000 (UTC)",
"results":
{"myapi":[{"name":{"href":"http://www.somelink.com","text":"Albania"},"count":"1","index":1,"url":"http://www.somelink.com"},
{"name":{"http://www.somelink.com","text":"United Arab Emirates"},"count":"30","index":2,"url":"http://www.somelink.com"},
...
For the map I'm following this guide: tutorial
JS file including API call
//Building the map
var map = L.map('map').setView([37.8, -96], 4);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=' + mapboxAccessToken, {
id: 'mapbox.light',
attribution: ...
}).addTo(map);
//Color function
function getColor(d) {
return d > 1000 ? '#800026' :
d > 500 ? '#BD0026' :
d > 200 ? '#E31A1C' :
d > 100 ? '#FC4E2A' :
d > 50 ? '#FD8D3C' :
d > 20 ? '#FEB24C' :
d > 10 ? '#FED976' :
'#FFEDA0';
}
//Style function
function style(feature) {
return {
fillColor: getColor(feature.properties.density),
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7
};
}
//Load static file
L.geoJson(worldBoundaries, {style: style}).addTo(map);
//AJAX call to API
$.ajax({
"url":"https://www.kimonolabs.com/api/myapi,
"crossDomain": true,
"dataType": "jsonp",
//Make a call to the Kimono API following the "url"
'success': function(response){
//Do some stuff, place some markers
var collection = response.results.myapi;
//collection.count is what I need from here
......
EDIT
Added a plunker for this: http://plnkr.co/edit/98OiwqYBr7pP478tJAtl?p=preview
getColor(feature.properties.density) is essentially my problem. Leaflet draws the country border layer correctly but the "density" information comes from an ajax api call and is not included in the wordlboundaries array. How can I tell it to look at the api results and using the "count" value for the correct country to color the map appropriately? How can I access the variables from the ajax call later in another function/do I have to put every function from this into the ajax call?
Country Border file contains all countries of the world where the api request does not contain all countries.
Thanks for ideas!
There are a few issues that need to be worked out before you can use the data successfully. These will be clearer if you log your data to the console to see what you're working with. Try placing the following in your AJAX success function somewhere after you've defined your boundaries layer:
console.log(response);
console.log(loadboundaries);
First of all, you will see that the API is returning data in German. There is no field called response.results.beerorigin (as your script is looking for), but instead one called response.results.bierherkunft. The count data are in a field called response.results.bierherkunft[i].count (where i is an object index from 0-52), and the country names are in response.results.bierherkunft[i].name.text.
Which brings us to the second problem: the country names returned by the API are also in German, while your GeoJSON file contains country names in English. So if you want to match up the countries in the two files, you will need to either get a GeoJSON file with country names already in German or manually translate the names in the GeoJSON file (or, perhaps better, add a new property like name_de to hold the translated names, in case you still have use for those English names). Of course, if there is an option to request data from the API in English, that would be the easiest solution to that problem.
Once you have all the data in the same language, you will need to join the beer data with your loadboundaries layer by name. This can be done by using onEachFeature when you create the layer to call a function that searches for a match between feature.properties.name_de and response.results.bierherkunft[i].name.text, then adds a new property for the count data. So assuming you have assigned response.results.bierherkunft to collection, it would go something like:
function onEachFeature(feature, layer) {
feature.properties.density = 0;
for (var i in collection) {
if(collection[i].name.text === feature.properties.name_de) {
feature.properties.density = parseInt(collection[i].count);
}
}
}
The parseInt is necessary because the count field is stored as text, and getColor is expecting a number. Applying the style can be done using the setStyle method, like so:
var loadboundaries = L.geoJson(worldboundaries, {onEachFeature: onEachFeature});
map.on('load', loadboundaries.addTo(map).setStyle(function (feature) {
return {
fillColor: getColor(feature.properties.density),
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7
};
}));
There is a working plunk here:
http://embed.plnkr.co/Qh1PKJS0Jxflc0JZ2qt4/preview

Kendo chart remove attribute using javascript

I have a kendo column chart, the datasource gets refreshed when different criterias are set via date pickers.
I want to stop the chart from displaying the value axis as a decimal and the only way I have found so far is to either set the format, which results in duplicating numbers, or the major unit, which if my data changes, then this results in overlapping value axis labels. Neither are suitable.
The only way I can now think to do it is to dynamically set the major unit based on whether my maximum value is less than 10, if it is then the major unit is set to 1, if not no major unit isn't set.
This should work fine but, if the major unit gets set to 1, and the data changes I now need to find a way to clear the major unit if my new maximum value is greater than 10.
In javascript I have:
if (highest <= 10) {
chart.data("kendoChart").options.valueAxis.majorUnit = 1;
} else {
chart.data("kendoChart").options.valueAxis.majorUnit.remove(); // This does not work
}
I can't just set majorUnit to null or 0, it doesn't like that and there is no documentation on the correct syntax for removing this kind of attribute.
This is what worked for me:
chart.data("kendoChart").options.valueAxis.majorUnit = undefined;
Don't forget to call
chart.data("kendoChart").refresh();
Do you have an example to show?
Does it help you if you just hide the value axis lines?
http://docs.kendoui.com/api/dataviz/chart#configuration-categoryAxis.line.visible
chart.data('kendoChart').options.valueAxis.line.visible = false;
If you are using datasource, you can put this code into requestEnd function, so no chart refresh is required:
$("#chart").kendoChart({
dataSource: {
transport: {
read: {
url: url,
dataType: "json",
type: 'POST'
}
},
// This is to set a step that looks appropriate for the size of the graph
requestEnd: function(e){
var max = 1;
// Iterate over your own data as you need, here my data returns "Category" and "Count" in each row.
e.response.forEach(function(row){
if(row.Count > max)
max = row.Count;
});
if(max <= 10)
$("#chart").data('kendoChart').options.valueAxis.majorUnit = 2;
else
$("#chart").data('kendoChart').options.valueAxis.majorUnit = undefined;
},
},

CamanJS - replace instance

If I have an image that I apply a filter to, e.g. Lomo filter, is there way to make that the current Caman instance?
Meaning, if I then want to then play about with the brightness on the image that I applied the filter to, and use this.revert(); to reset the brightness, I want it to revert to the canvas with the filter on it that I just applied.
Is this possible?
I'm having a nightmare with trying to apply many effects, only one at once (except for preset filters), and carry the state through...
If i understand, you want to apply filter ("Lomo") as shown on their example page and then fiddle with some properties (like brightness) and then revert changes back to "Lomo" filter?
Why not just click on filter ("Lomo") again?
EDIT:
You should probably take a look at guide and implement your own method with default values like in filters.
u.Filter.register("lomo", function (D) {
if (D == null) {
D = true
}
this.brightness(15);
this.exposure(15);
this.curves("rgb", [0, 0], [200, 0], [155, 255], [255, 255]);
this.saturation(-20);
this.gamma(1.8);
if (D) {
this.vignette("50%", 60)
}
return this.brightness(5)
});
I dont think your requirement comes "out of the box".
If i understand you correctly , You want to apply a filter and play with other effects like brightness and contrast etc.,
I made some code which will work according to your need
Caman('#canvas-camanImage',"./../media/caman.png", function () {
this.revert(false);
for(var i = 0 ;i<selectedPresets.length;i++){
this[selectedPresets[i]]();
}
for(var key in effect){
this[key](effect[key].value);
}
this.render(function () {
});
in the above code i am storing all effects like brightness contrast in effect variable like effect = {
brightness : {
min : -100,
max: 100,
value : 0
},
contrast : {
min : -100,
max: 100,
value : 0
},
saturation : {
min : -100,
max: 100,
value : 0
}
};
and presets in an array
presets = [
{filter:'vintage',name : 'Vintage'},
{filter:'lomo',name:'Lomo'},
{filter: 'clarity', name:'Clarity'},
{filter:'sinCity', name:'Sin City'}
];
So every time you add any preset or change any effect value i am changing the values in variable and rendering canvas again
It is working very fine for me Let me know if your concern is something else

Categories

Resources