Stock chart in ExtJS 4 - extjs

How can I draw an stock chart or a line chart with hundreds points?
I disabled animation in regular line chart, but not successful and still too heavy and slow.

I've recently written a blog post on creating stock charts in Ext JS 4 - http://www.scottlogic.co.uk/2011/12/ext-js-4-stock-charts/. It uses a couple of hundred points and performs fine in modern browsers and isn't too bad in IE7-8.
This said however, even after messing with the Ext JS build system, the minimum Ext build required to run the charts is still something like .5MB which is too heavy weight for some applications. The CSS however can be chopped down to just a few rules - if you're willing to spend the time trying to figure out which ones you need out of the huge ext-all.css!

My app is completely Ext-JS based. However, when performance is a problem, I use flot. The API is much better designed (and I'm an Ext-JS fan boy) and it performs much better. This is at the expense of working with raw pixel data (canvas, which is pixel based) if you need to interact with the chart. Since in Ext-JS, everything is an SVG object, you can simply attach event handlers to the lines, or anything else you draw yourself.
For example. For a wave monitor, we use flot. For another chart where we let the user drag and drop some lines on the screen, we use Ext-JS charts.
Here's a simplistic wrapper to use flot as an Ext.Component
Ext.define('cci.view.wavemon.Flot', {
extend: 'Ext.Component',
alias: 'widget.cci-flot',
/**
* #cfg {number[][]} data The data to be drawn when it gets rendered
*/
data: null,
/**
* #cfg {object} flotOptions
* The options to be passed in to $.plot
*/
flotOptions: null,
/**
* #property
* The Flot object used to render the chart and to manipulate it in the future. It will only
* be available after the first resize event
* You may not set this property but you are free to call methods on it
*/
flot: null,
initComponent: function() {
this.callParent(arguments);
// The only time that we're guaranteed to have dimensions is after the first resize event
this.on('resize', function(comp) {
if (!this.flot) {
this.flot = $.plot(this.getTargetEl().dom, this.data, this.flotOptions);
} else {
// Flot knows to look at the containers size and resize itself
this.flot.resize();
}
}, this);
}
});

If you generate extjs code dynamically (php, python, asp.net...) and data source is static - you can easily generate chart to png and load it at ext.panel.

I've found flot (http://code.google.com/p/flot/) to have much better performance with many points / series, whereas the performance of the ExtJS 4 charts was unacceptable. Flot also has a clearer API and reads data in a simple format.

There's a complete example on how to create stock line charts for Sencha Charts here:
http://dev.sencha.com/deploy/touch-charts-1.0.0/examples/Stock/
As you can see, the example handles > 100 data points easily.
The example is for touch charts, but the API is nearly identical to what's in Sencha's ExtJS 4. Copy and pasting the chart instanciation code should do the work.

Related

Mapbox Icon-Image Dynamic Symbol (icon) Loading with Sprite

I am trying to do something I feel is very simple, yet seems that I am clearly misunderstanding a crucial piece of the mapbox addlayer feature.
The Goal
Create dynamically identified icons, based on a features data value (e.g. geojson feature data vale title: "walmart"). Essentially just adding dynamic store icons from the sprite image when those locations are queried via tilequery. picture representation here
The problem
I keep getting an error when trying to use the sprite values from the style. Error: util.js:349 Image "airport-11" could not be loaded. Please make sure you have added the image with map.addImage() or a "sprite" property in your style. You can provide missing images by listening for the "styleimagemissing" map event.
I see tons of resources talking about sprites, but none discuss how to exactly implement them in this fashion. I have even tried querying the sprite and then adding the values using dot notation to access sprite values. This gives an error of "undefined" and invalid value.
Example code:
map.addLayer({
id: "tilequery-points",
type: "symbol",
source: "tilequery", // Set the layer source
layout: {
"icon-image": [
"match",
["get", "title"],
["HEB"],
"H-E-B_logo",
["Pilot Flying j"],
sprite.Pilot_Travel_Centers_logo,
// "Pilot_Travel_Centers_logo",
["Dollar General"],
"Dollar_General_logo",
["Cumberland Farms Corp"],
"Cumberland_Farms_logo (1)",
["CEFCO"],
"CEFCO-convenience-stores-Logo_510px",
["BJs Wholesale Inc"],
The Question
How do I access the sprite values and not get an error?!!!
Thanks for the help! I Wouldn't ask if I didn't need it!
UPDATE
I have figured out that to use sprite images inside of any layer, the images will automatically be available if you have them in your Mapbox studio sprite image collection. The confusion was that previously, I was not able to use them from link. However, it should work automatically.
Hope it helps!
It's true the documentation about sprites is not super clear. I'll try to summarise (simplifying a bit).
A Mapbox GL style has one sprite. That's a PNG containing all the icons, plus a JSON file specifying what each icon is called (its icon ID), and where it located within the PNG. The sprite is specified by giving a URL as the sprite property: https://docs.mapbox.com/mapbox-gl-js/style-spec/sprite/
You can also add images to the sprite dynamically after the map loads, with map.loadImage and map.addImage, specifying the icon ID.
To display an icon, you use that same ID in a symbol layer: "icon-image": "myicon".
You can run into trouble when you try to combine your own icons with those in a Mapbox basemap (which are Maki icons with names like `airport-11').
To combine them, you can do one of these three things:
upload your icons to a style in Mapbox Studio
load your icons dynamically
generate a new sprite sheet offline, using something like mbsprite
I don't know what you meant about "dot notation", but no, that's not the right path.

Update extjs chart config on its store update

I am going to use Extjs gauge chart in my application, I want to update some config option on its store update,
for eg. you can see code on bellow link.
Ext JS Chart Kitchen Sink
In this code I am used Temp chart, There I want to update maximum (which is maximum: 250 in code, Look 3rd chart) On its store. I am able to update its store but not maximum config vaiable. is any solution from you.
I found the solution for my problem getting lots of efforts
these bellows line get solved my problem.
by using this we can change axis or series Config.
Ext.getCmp('chartid').axes.get("gauge").maximum = 100;
Ext.getCmp('chartid').redraw();

how to display lightmaps in the appcreator

running on macbook iOs X(yosemite) and chrome browser,
i try to view an archilogic model:
Model Used
in https://appcreator.3d.io/
but the result doesn't seem to display the same lightmaps mapping on interiors:
https://app.3d.io/lLOkYR
This might be due to the fact that the lighting system in spaces editor is a different one than the lighting system in aframe. I recommend you to adjust the lighting in your aframe scene using the following parameters (search for these values inside your html code in the app creator):
lightMapIntensity: 1.887; lightMapExposure: 0.55
also you can adjust overall lighting intensity by modifying:
<a-scene io3d-lighting="intensity:0.9">

Rendering problems when saving multiple Dygraphs as a PNG on mobile devices

I have a web application that uses Dygraphs to create charts.
The application allows a user to create multiple Dygraph charts (each with their own Y-Axis) that will be stacked on top of each other.
Here's an example of what the multiple Dygraphs look like on a PC browser: Notice that the example displays three different Dygraphs each having their own Y-axis, but the X-axis is hidden for the top 2 charts and visible on the bottom chart.
I will allow the user to save the chart to disk as a PNG. - The way I currently save the multiple Dygraphs as one PNG is:
Create a target canvas that will be used to contain all the visible Dygraphs
Extract each canvas out of each Dygraph, then add each canvas to the target canvas **
Create a PNG via the .toDataURL() function on the target canvas
Here's an example of what the above screenshot looks like when saved as one PNG: (This is exactly what I want from the PNG)
The procedure works fine on browsers on a PC. But when I attempt to save the multiple Dygraphs into one PNG on a phone/tablet browser, the resultant PNG doesn't match the graph that is visible on the screen.
Example:
Here's what the multiple Dygraphs look like on an iPad (screenshot)
And here's what the resultant PNG looks like (Notice how the width and height of each chart does not match the actual iPad display).
I don't understand why the PNG is rendered correctly when I use a PC browser, but is not rendered correctly when I use a browser on a mobile device.
I'm not sure if this problem is due to limitations of the Canvas.toDataURL() function or if this is a Dygraphs problem or something else. I'm fishing for advice that may point me in the right direction and/or shed light on this particular problem.
**I should mention that I use Juan Manuel Caicedo Carvajal's Dygraph-Export extension
I'm guessing the Problem occurs, because the generated canvas isn't rendered fully to the responsive screen of an iPad.
You can try to export the original canvas (instead of generating a new one with the said library) yourself with toDataUrl https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
Dygraphs generates 2 canvas, one for the legend and one for the actual graph and lays them ontop of each other. So make sure you choose the right one (not the _hidden_canvas). If the examples works you can draw the legend onto the graph canvas with canvas.drawImage(otherCanvas)
How to Copy Contents of One Canvas to Another Canvas Locally
Hope this helps. Keep me updated!
My workaround/hack for the problem stated in my OP was to make a change to the Dygraph source in the Dygraph.getContextPixelRatio function.
Notice in the code below that I set devicePixelRatio = 1
dygraph-combined.js
Dygraph.getContextPixelRatio = function (context) {
try {
//var devicePixelRatio = window.devicePixelRatio;
var devicePixelRatio = 1; // Hack!!!
var backingStoreRatio = context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
if (devicePixelRatio !== undefined) {
return devicePixelRatio / backingStoreRatio;
} else {
// At least devicePixelRatio must be defined for this ratio to make sense.
// We default backingStoreRatio to 1: this does not exist on some browsers
// (i.e. desktop Chrome).
return 1;
}
} catch (e) {
return 1;
}
};
In my case, this hack fixed my problem (stated in the OP) and didn't negatively affect any other parts of my application that uses Dygraphs. That said, if you find a better/correct way to fix the problem stated in the OP, please share.

Extjs 4: Time Stacked Bar Chart, possible?

Hi I'm trying to accomplish a time stacked bar chart where the input data looks like this:
{"name":"Folienwechsel",
"starttime":"02/29/2012 09:50:07",
"endtime":"02/29/2012 09:50:46",
"duration":38546.0},
{"name":"Pause",
"starttime":"02/29/2012 09:50:46",
"endtime":"02/29/2012 09:51:36",
"duration":49943.0},
{"name":"Wartezeiten",
"starttime":"02/29/2012 09:51:36",
"endtime":"02/29/2012 10:04:43",
"duration":787086.0}
As you see the start time and end time are continued, when a state finish the other one starts, I've been trying with the timeaxis, based on this tutorial http://aboutfrontend.com/extjs/extjs...-and-timeaxis/, and also with the stackbar example in sencha http://docs.sencha.com/ext-js/4-0/#!...tackedBar.html. An image example of what I'm trying to do:
I already done this with HighChart, but my company has bought ExtJs then I need to do this with Extjs, then it would be great if someone can tell me if its possible, and if it is, then if could guide me with an example or how should I start...
Thanks.
I spent some time working with time based charts in ExtJs4 and I have to warn you - that TimeAxis is buggy. I even had to replace my time axes with simple numeric ones. The idea is simple - convert your dates into the timestamps and pass them to your numeric axis.
Stackbar chart is a good choice for you. See this example (modified a bit), from official sencha examples:
http://jsfiddle.net/UDwz7/

Resources