Here is my charts, dynamically update. Now im trying to add a button which, to start the dynamic charts.
Ideally, i wish the data to be initialized when i press the button, however it seems that the data could not be initialized simultaneously with the method.Or let's be simply, is it possible to add a button that i could control, when to start the chart and, when to stop or pause?
var time = null;
var bol = false;
var chart;
var data = [];
// function play(){
// var time = (new Date()).getTime(), i;
// for(i = -1999; i <= 0; i += 1){
// data.push([
// time + i *1000,
// Math.round(Math.random() * 100)
// ]);
// }
// }
data = (function () {
var data = [], time = (new Date()).getTime(), i;
for (i = -1999; i <= 0; i += 1) {
data.push([time + i * 1000, Math.round(Math.random() * 100)]);
}
return data;
}());
Related
The final goal is to retrieve stock data in table form from provided broker website and save it to some text file. Here is the code, that I managed to compile so far by reading few tutorials:
var casper = require("casper").create();
var url = 'https://iqoption.com/en/historical-financial-quotes?active_id=1&tz_offset=60&date=2016-12-19-21-59';
var terminate = function() {
this.echo("Exiting ...").exit();
};
var processPage = function() {
var rows = document.querySelectorAll('#mCSB_3_container > table'); //get table from broker site (copy/paste via copy selector in chrome tools)
//var nodes = document.getElementsByClassName('mCSB_container');
this.echo(rows);
this.echo(rows.length);
for (var i = 0; i < rows.length; i++)
{
var cell = rows[i].querySelector('.quotes-table-result__date');
this.echo(cell); //print each cell
}
};
casper.start(url);
casper.waitForSelector('#mCSB_3_container', processPage, terminate);
casper.run();
This code should retrieve the stock price table and print out each cell. However, all what I get is 'undefined', which likely means that I got no objects returned by queryselector call. And please assume that I don't know any web programming (HTML,CSS).
First of all, on problem is that the waitFor wasn't set so good, you have to wait for the rows/cells.
The Nodes you get out on this page are a bit wired,if anybody got a more abstract solution where ChildNodes are better handled that in my solution i would be really interested:
var casper = require('casper').create();
var url = 'https://eu.iqoption.com/en/historical-financial-quotes?active_id=1&tz_offset=60&date=2016-12-19-21-59';
var length;
casper.start(url);
casper.then(function() {
this.waitForSelector('#mCSB_3_container table tbody tr');
});
function getCellContent(row, cell) {
cellText = casper.evaluate(function(row, cell) {
return document.querySelectorAll('table tbody tr')[row].childNodes[cell].innerText.trim();
}, row, cell);
return cellText;
}
casper.then(function() {
var rows = casper.evaluate(function() {
return document.querySelectorAll('table tbody tr');
});
length = rows.length;
this.echo("table length: " + length);
});
// This part can be done nicer, but it's the way it should work ...
casper.then(function() {
for (var i = 0; i < length; i++) {
this.echo("Date: " + getCellContent(i, 0));
this.echo("Bid: " + getCellContent(i, 1));
this.echo("Ask: " + getCellContent(i, 2));
this.echo("Quotes: " + getCellContent(i, 3));
}
});
casper.run();
How do I time out a XMLHttpRequest in QML? I have the following code, but it won't time out. It seems the timeout functionality is not implemented!? Is there any other way to achieve timeouts?
var http = new XMLHttpRequest();
http.open("POST", "http://localhost/test.xml", true);
http.setRequestHeader('Content-type', 'application/json; charset=utf-8')
http.timeout = 4000;
http.ontimeout = function () {
console.log("timed out")
}
http.onreadystatechange = function() {
if (http.readyState === XMLHttpRequest.DONE) {
// Do something
}
}
http.send(JSON.stringify(data));
Edit:
The code is not in a qml, but in a js file. And it won't go into a qml file as it is part of the model (MVC).
It looks that QML XMLHttpRequest does not support timeout function.
This is a list of supported subset of functions/properties:
http://qt-project.org/doc/qt-5/qtqml-javascript-qmlglobalobject.html#xmlhttprequest
But you can use QML Timer item for this purposes, for example:
import QtQuick 2.3
Item {
id: root
width: 600
height: 400
Text {
anchors.fill: parent
id: response
text: "Click me"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
MouseArea {
anchors.fill: parent
onClicked: {
response.text = "Loading...";
var req = new XMLHttpRequest();
var timer = Qt.createQmlObject("import QtQuick 2.3; Timer {interval: 4000; repeat: false; running: true;}",root,"MyTimer");
timer.triggered.connect(function(){
req.abort();
response.text = "timed out";
});
req.open("GET","http://google.com--",true); // correct me
req.onreadystatechange = function() {
if (req.readyState === XMLHttpRequest.DONE && req.status == 200) {
response.text = req.getAllResponseHeaders();
timer.running = false;
}
}
req.send();
}
}
}
}
A global setTimeout() and setInterval() utility that models the functionality found in browsers.
It can be used to indirectly timeout an XMLHttpRequest. Or used sparingly elsewhere within the application.
timeoutId = util.timer.setTimeout(function() {}, 4500);
util.timer.clearInterval(timeoutId);
Main QML Snippet
With the following code, any child is able to access the methods under the app.util.timer namespace (or util.timer namespace if JS code is loaded in the main codebehind file).
import "CodeBehind.js" as CodeBehind
id: appWindow
QtObject {
id: app
property var util: CodeBehind.util
}
Component.onCompleted: {
CodeBehind.util.timer.init(appWindow);
}
CodeBehind JS Snippet
var util = util || {};
Qt.include("qrc:/Util/Timer.js");
Utility JS File
var util = util || {};
/**
Mimics the window.setTimeout() and window.setInterval() functionality
found in browsers.
#namespace timer
#memberof util
*/
util.timer = new function() {
var _timer;
var _timerList = [];
var _currentTime = 0;
var _api = {};
var _private = {};
var _enums = {};
/*************** Private ENUMS ***************/
_enums.type = {
timeout: 0,
interval: 1
};
/*************** Public API Methods ***************/
/**
Mimics the window.setTimeout() functionality found in browsers.
#param {function} callback
#param {int} interval Milliseconds
#public
#memberof util.timer
*/
_api.setTimeout = function(callback, interval) {
var timer, id;
id = parseInt(Math.random() * Date.now());
timer = new Timer(id, callback, interval, _enums.type.timeout);
_timerList.push({ id: id, timer: timer });
return id;
};
/**
Mimics the window.setInterval() functionality found in browsers.
#param {function} callback
#param {int} interval Milliseconds
#public
#memberof util.timer
*/
_api.setInterval = function(callback, interval) {
var timer, id;
id = parseInt(Math.random() * Date.now());
timer = new Timer(id, callback, interval, _enums.type.interval);
_timerList.push({ id: id, timer: timer });
return id;
};
/**
Clears an interval or timout by the interval id that is returned
when setTimeout() or setInterval() is called.
#param {int} intervalId
#public
#memberof util.timer
*/
_api.clearInterval = function(intervalId) {
var idx, len, idxOfTimer;
if (_timerList) {
// Find the index of the timer
len = _timerList.length;
for (idx = 0; idx < len; idx++) {
if (_timerList[idx].id === intervalId) {
idxOfTimer = idx;
break;
}
}
// Remove the timer from the array
_timerList.splice(idxOfTimer, 1);
}
// If: There are no more timers in the timer list
// Then: Stop the QML timer element
if (!_timerList || _timerList.length === 0) {
_private.stop();
}
};
/*************** Private Helper Methods ***************/
_private.start = function() {
_timer.start();
};
_private.stop = function() {
_timer.stop();
_currentTime = 0;
};
_private.runInterval = function() {
var idx, len, tempList;
// Increment the current timer
_currentTime++;
if (_timerList) {
// Create a temp list of timers
tempList = [];
len = _timerList.length;
for (idx = 0; idx < len; idx++) {
tempList.push(_timerList[idx].timer);
}
// Trigger each method
len = tempList.length;
for (idx = 0; idx < len; idx++) {
tempList[idx].trigger();
}
}
};
/*************** Objects ***************/
/**
A timer object contains a trigger to check and see if it needs
to run the callback.
#param {int} id
#param {function} callback
#param {int} interval Milliseconds
#param {enum} type type.interval | type.timeout
#public
#memberof util.timer
*/
var Timer = function(id, callback, interval, type) {
var _obj = {};
_obj.api = {};
_obj.hasRun = false;
_obj.endTime = _currentTime + interval;
_obj.api.trigger = function() {
if (_currentTime >= _obj.endTime && !_api.hasRun) {
_obj.hasRun = true;
callback();
if (type === _enums.type.interval) {
_obj.endTime += interval;
_api.hasRun = false;
}
else {
_api.clearInterval(id);
}
}
};
_private.start();
return _obj.api;
};
/*************** Initialize ***************/
_api.init = function(appWindow) {
_timer = Qt.createQmlObject("import QtQuick 2.3; Timer { interval: 1; repeat: true; running: false;}", appWindow, "timer");
_timer.triggered.connect(_private.runInterval);
};
return _api;
};
I have a route that is a combination of multiple sub routes. (By sub routes i mean multiple DirectionsRenderer objects)
I also have a loop where i go throught all of the DirectionsRenderer objects and attach "directions_changed" event to all of them.
Unfortunatelly only that last DirectionsRenderer object fires the event when i try to test what happens when i drag the polyline.
Here is a part of my code:
for(var k=0; k<directionsRenderers.length; k++)
{
var directionsRenderer = directionsRenderers[k];
var a = registerDirectionsChangedEvent(k,directionsRenderer);
}
function registerDirectionsChangedEvent(index, directionsRenderer)
{
this.index = index;
this.directionsRenderer = directionsRenderer;
var that = this;
var a = google.maps.event.addListener(this.directionsRenderer, "directions_changed", function()
{
var newStopPoint;
var directionsResult = that.directionsRenderer.getDirections();
var route = directionsResult.routes[0];
var legs = route.legs;
var legsIndex = 0;
for(var i=0; i<legs.length; i++)
{
var cLeg = legs[i];
var viaWaypoints = cLeg.via_waypoints;
if(viaWaypoints.length > 0)
{
newStopPoint = viaWaypoints[0];
if(that.index === 1) legsIndex += 9;
else if(that.index === 2) legsIndex += 18;
break;
}
legsIndex++;
}
addNewStopPoint(newStopPoint,legsIndex);
});
return a;
}
As i have mentioned above not only the last DirectionsRenderer object get fired but the ones before the last event do not implement the default behaviour.
Maybe you have noticed that i use:
this.index = index;
this.directionsRenderer = directionsRenderer;
var that = this;
event without it it still does not work.
I also tried to use a function created inside the loop like this:
(function someFunction(a,b){//do something here})(a,b);
but still no luck!
any advice how to make it works?
Use function closure, this is probably a duplicate (not tested):
for(var k=0; k<directionsRenderers.length; k++)
{
var directionsRenderer = directionsRenderers[k];
var a = registerDirectionsChangedEvent(k,directionsRenderer);
}
function registerDirectionsChangedEvent(index, directionsRenderer)
{
var a = google.maps.event.addListener(directionsRenderer, "directions_changed", function()
{
var newStopPoint;
var directionsResult = directionsRenderer.getDirections();
var route = directionsResult.routes[0];
var legs = route.legs;
var legsIndex = 0;
for(var i=0; i<legs.length; i++)
{
var cLeg = legs[i];
var viaWaypoints = cLeg.via_waypoints;
if(viaWaypoints.length > 0)
{
newStopPoint = viaWaypoints[0];
if(index === 1) legsIndex += 9;
else if(index === 2) legsIndex += 18;
break;
}
legsIndex++;
}
addNewStopPoint(newStopPoint,legsIndex);
});
return a;
}
I have flex 4 and writing my own autocomplete component (based on the popupanchor) to search for different books. In the dropdown box, how can I highlight the text that matches? For instance, a user types in "ema" and the search returns "Pet Sematary"....I want to highlight the letters "ema" within "Pet Sematary"
Wrote auto-complete a week ago :) You need to use Spark text components and pass custom TextFlow to them:
private function init():void
{
var textFlow:TextFlow = new TextFlow();
var paragraph:ParagraphElement = new ParagraphElement();
textFlow.addChild(paragraph);
var elements:Vector.<FlowElement> = highlight("Pet Sematary", "Se");
var n:int = elements.length;
for (var i:int = 0; i < n; i++)
{
paragraph.addChild(elements[i]);
}
label.textFlow = textFlow;
}
private function highlight(text:String, query:String):Vector.<FlowElement>
{
var result:Vector.<FlowElement> = new Vector.<FlowElement>();
// since we need to compare ignore-case we can not use split()
// and have to collect indexes of "query" matches in "text"
var indexes:Vector.<int> = new Vector.<int>();
var index:int = 0;
var textLowerCase:String = text.toLocaleLowerCase();
var queryLowerCase:String = query.toLocaleLowerCase();
var queryLength:int = query.length;
while (true)
{
index = textLowerCase.indexOf(queryLowerCase, index);
if (index == -1)
break;
indexes.push(index);
index += queryLength;
}
// now add SpanElement for each part of text. E.g. if we have
// text="aBc" and query is "b" then we add "a" and "c" as simple
// span and "B" as highlighted span.
var backgroundColor:uint = 0xFFCC00;
var n:int = indexes.length;
if (n == 0) // no matches
{
addSpan(result, text);
}
else
{
var startIndex:int = 0;
for (var i:int = 0; i < n; i++)
{
if (startIndex != indexes[i])
addSpan(result, text.substring(startIndex, indexes[i]));
addSpan(result, text.substr(indexes[i], queryLength),
backgroundColor);
startIndex = indexes[i] + queryLength;
}
if (startIndex != text.length)
addSpan(result, text.substr(startIndex));
}
return result;
}
private function addSpan(vector:Vector.<FlowElement>, text:String,
backgroundColor:* = "transparent"):void
{
var span:SpanElement = new SpanElement();
span.text = text;
span.backgroundColor = backgroundColor;
vector.push(span);
}
MXML code:
<s:RichEditableText editable="false" multiline="false"
selectable="false" id="label"
horizontalCenter="0" verticalCenter="0"/>
P.S: If you will have troubles with popup taking focus - add it manually to the toolTipChildren:
systemManager.toolTipChildren.addChildAt(child, 0);
i'm loading several sound files, and want to error check each load. however, instead programming each one with their own complete/error functions, i would like them to all use the same complete/error handler functions.
a successfully loaded sound should create a new sound channel variable, while an unsuccessfully loaded sound will produce a simple trace with the name of the sound that failed to load. however, in order to do this, i need to dynamically create variables, which i haven't yet figured out how to do.
here's my code for my complete and error functions:
function soundLoadedOK(e:Event):void
{
//EX: Sound named "explosion" will create Sound Channel named "explosionChannel"
var String(e.currentTarget.name + "Channel"):SoundChannel = new SoundChannel();
}
function soundLoadFailed(e:IOErrorEvent):void
{
trace("Failed To Load Sound:" + e.currentTarget.name);
}
-=-=-=-=-=-=-=-=-
UPDATED (RE: viatropos)
-=-=-=-=-=-=-=-=-
can not find the error.
TypeError: Error #1009: Cannot access a property or method of a null object reference. at lesson12_start_fla::MainTimeline/loadSounds() at lesson12_start_fla::MainTimeline/frame1():
//Sounds
var soundByName:Object = {};
var channelByName:Object = {};
var soundName:String;
var channelName:String;
loadSounds();
function loadSounds():void
{
var files:Array = ["robotArm.mp3", "click.mp3"];
var i:int = 0;
var n:int = files.length;
for (i; i < n; i++)
{
soundName = files[i];
soundByName[soundName] = new Sound();
soundByName[soundName].addEventListener(Event.COMPLETE, sound_completeHandler);
soundByName[soundName].addEventListener(IOErrorEvent.IO_ERROR, sound_ioErrorHandler);
soundByName[soundName].load(new URLRequest(soundName));
}
}
function sound_completeHandler(event:Event):void
{
channelName = event.currentTarget.id3.songName;
channelByName[channelName] = new SoundChannel();
}
function sound_ioErrorHandler(event:IOErrorEvent):void
{
trace("Failed To Load Sound:" + event.currentTarget.name);
}
You can do this a few ways:
Storing your SoundChannels in an Array. Good if you care about order or you don't care about getting them by name.
Storing SoundChannels by any name in an Object. Good if you want to easily be able to get the by name. Note, the Object class can only store keys ({key:value} or object[key] = value) that are Strings. If you need Objects as keys, use flash.utils.Dictionary, it's a glorified hash.
Here's an example demonstrating using an Array vs. an Object.
var channels:Array = [];
// instead of creating a ton of properties like
// propA propB propC
// just create one property and have it keep those values
var channelsByName:Object = {};
function loadSounds():void
{
var files:Array = ["soundA.mp3", "soundB.mp3", "soundC.mp3"];
var sound:Sound;
var soundChannel:SoundChannel;
var i:int = 0;
var n:int = files.length;
for (i; i < n; i++)
{
sound = new Sound();
sound.addEventListener(Event.COMPLETE, sound_completeHandler);
sound.addEventListener(IOErrorEvent.IO_ERROR, sound_ioErrorHandler);
sound.load(files[i]);
}
}
function sound_completeHandler(event:Event):void
{
// option A
var channelName:String = event.currentTarget.id3.songName;
// if you want to be able to get them by name
channelsByName[channelName] = new SoundChannel();
// optionB
// if you just need to keep track of all of them,
// and don't care about the name specifically
channels.push(new SoundChannel())
}
function sound_ioErrorHandler(event:IOErrorEvent):void
{
trace("Failed To Load Sound:" + event.currentTarget.name);
}
Let me know if that works out.
//Load Sounds
var soundDictionary:Dictionary = new Dictionary();
var soundByName:Object = new Object();
var channelByName:Object = new Object();
loadSounds();
function loadSounds():void
{
var files:Array = ["robotArm.mp3", "click.mp3"]; //etc.
for (var i:int = 0; i < files.length; i++)
{
var soundName:String = files[i];
var sound:Sound=new Sound();
soundDictionary[sound] = soundName;
soundByName[soundName] = sound;
sound.addEventListener(Event.COMPLETE, sound_completeHandler);
sound.addEventListener(IOErrorEvent.IO_ERROR, sound_ioErrorHandler);
sound.load(new URLRequest(soundName));
}
}
function sound_completeHandler(e:Event):void
{
var soundName:String=soundDictionary[e.currentTarget];
channelByName[soundName] = new SoundChannel();
}
function sound_ioErrorHandler(e:IOErrorEvent):void
{
trace("Failed To Load Sound:" + soundDictionary[e.currentTarget]);
}
//Play Sound
channelByName["robotArm.mp3"] = soundByName["robotArm.mp3"].play();
//Stop Sound
channelByName["robotArm.mp3"].stop();