Put flags on OHLC chart in highstocks - highcharts

I'm trying to put some flags on OHLC charts, same as done on line chart in this example.
I've made a series object:
series : [
{
name : ticker,
type: 'candlestick',
data : chartData,
tooltip: {
valueDecimals: 2
}
},
{
type : 'flags',
data : markersData,
onSeries : 'dataseries',
shape : 'circlepin',
width : 16
}
]
Here is what I get - chart is not being drawn at all. Fiddle
How do I put flags on OHLC chart?

You add flags to OHLC the same way you add them to any other type of chart.
The problem with your chart is that none of the dates provided in your parsed JSON are treated as dates, since they are just strings in the format "2014-08-04T15:00:00.000Z". You need to provide Highstock with dates in the form of timestamps in milliseconds.
You can either change the JSON you receieve to provide this, or do it in post-processing like this:
for(i in chartData.data) {
chartData.data[i][0] = new Date(chartData.data[i][0]).getTime();
}
for(i in markersData.data) {
markersData.data[i].x = new Date(markersData.data[i].x).getTime();
}
As in this updated JSFiddle code. The Date object parses the string and the getTime function return the timestamp in milliseconds.
I may also add that the flags are not on the series as you are not providing a ID for the series in your chartData JSON.

Related

How can I group messages by date?

Let's say that I am fetching messages (objects) from a database. They do not arrive at the same time, a message always arrives alone (one fetch -> one message; a function gets called for every message) and at any time.
Every message contains a time stamp that represents the date when the message was created. So I can call message.date and I will get the date when the message was created.
The messages do not arrive in any order; it can be that the created last message is at the third/fourth/... position.
I'd like to group these messages by day in order to present them in a UITableView.
Each section represents a day. Eeach section header includes the day and every cell includes the time (kind of like in WhatsApp Messenger).
I know how to create custom header views, insert sections, rows etc.
The problem is that I don't know how or as what data type to sort the messages in order to create the TableView easily and resource-saving and efficient (in terms of storage requirement and clarity).
It would be easy if I had a two-dimensional array, but I am not clever enough to think up an efficient approach to sort (or rather group) the messages.
Thanks a lot for help!
The time stamp is a date, so sort by date (array) and group by day (dictionary).
Sorting an array that includes date information by date is a one-liner in Swift.
Grouping a sorted array that includes date information into a dictionary keyed by day is also a one-liner in Swift.
So that's two lines of code, and you didn't have to change anything.
However, a dictionary has no order, so I would then suggest taking a third step where you transform the dictionary into an array of some custom struct reflecting the section-row structure of your table. The correct data source for any sectioned table view is going to have a structure like this:
struct Row {
// row properties
}
struct Section {
var rowData : [Row]
// section properties
}
var model : [Section]!
So after you've made your dictionary as a way of grouping, you just map it onto an array of Section and maintain that going forward.
Of course if you have no data to start with and the data arrives one item at a time, then you can omit the two bulleted steps above. Just start with the structured model and keep slotting each item into the right spot as it arrives.
EDIT: You expressed interest (in a comment) on how to insert an element into the right place in an already sorted array, so here's an example (see https://stackoverflow.com/a/26679191/341994):
extension Array {
func insertionIndex(of elem: Element, by f: (Element, Element) -> Bool) -> Int {
var lo = 0
var hi = self.count - 1
while lo <= hi {
let mid = (lo + hi)/2
if f(self[mid], elem) {
lo = mid + 1
} else if f(elem, self[mid]) {
hi = mid - 1
} else {
return mid // found at position mid
}
}
return lo // not found, would be inserted at position lo
}
mutating func insertSorted(_ elem:Element, by f: (Element, Element) -> Bool) {
self.insert(elem, at:self.insertionIndex(of:elem, by:f))
}
}
Here's a test; of course your ordering function won't be as simple as < but that's really the only difference:
var arr = [Int]()
arr.insertSorted(1, by:<)
arr.insertSorted(10, by:<)
arr.insertSorted(9, by:<)
arr.insertSorted(3, by:<)
arr.insertSorted(5, by:<)
arr.insertSorted(7, by:<)
arr.insertSorted(6, by:<)
// [1, 3, 5, 6, 7, 9, 10]
It is very easy you can grouped it.
for example messages contain these following:
struct message {
let senderName:String
let mess:String
let reciever:String
let time:Date
}
and you have some messages:
var messages = [message]()
messages.append(message(senderName: "snow", mess: "Hello", reciever: "Dani", time: Date(timeIntervalSince1970: 1533078663)))
messages.append(message(senderName: "john", mess: "Hello", reciever: "Dani", time: Date(timeIntervalSince1970: 1533078606)))
messages.append(message(senderName: "alix", mess: "Hello", reciever: "Dani", time: Date(timeIntervalSince1970: 1533078633)))
you can grouped it easily by using this:
let groupedMessage = Dictionary(grouping: messages) { (mess) -> Date in
return mess.time
}

How to map ordered NSDictionary using JSONModel

I've got a JSON as below.
odds: {
0501: {
x: 2.75,
description: "a"
},
0502: {
x: 3.25,
description: "b"
},
0513: {
x: 3.5,
description: "c"
},
0503: {
x: 3.5,
description: "d"
},
0505: {
x: 7.5,
description: "e"
},
0504: {
x: 7.5,
description: "f"
},
0512: {
x: 10,
description: "g"
}
}
This hash comes from HTTP response as I want to show but the thing that I use JSONModel to map it and there is only way to map that NSDictionary. When map this JSON to NSDictionary (as you can guess) this an unordered and sequence of data comes up mixed.
So, how to map this JSON, without broke up its sequence using JSONModel and NSDictionary ?
NSDictionary is inherently unordered:
Are keys and values in an NSDictionary ordered?
If you want to preserve the order of key-value entries, you need to use a data structure other than NSDictionary. Any library that passes your data through an NSDictionary cannot preserve the order.
Something I've done in this situation is to sort the dictionary keys in a separate array, in addition to the dictionary. Use the ordered key array to determine how to display your dictionary values.
Dictionaries can not be sorted, but as your JSON seems to be an array of objects, iterate thru your resulting NSDictionary with for...in and add the elements to a mutable array.
Afterwards sort the resulting array using .sortInPlace by comparing the x-value.

In Firebase, how can I query the most recent 10 child nodes?

I'm using childByAutoId() to generate my children. Each child looks like:
{
user_id: 1
}
I'd like to get the last 10 most recently added, sorted by time DESC. What's the easiest way to do this?
The answer is that you need to use a bit of reverse logic, and also store a timestamp key:value pair within each node as a negative value. I omitted the user_id: 1 to keep the answer cleaner.
Here's the Firebase structure
"test" : {
"-KFUR91fso4dEKnm3RIF" : {
"timestamp" : -1.46081635550362E12
},
"-KFUR9YH5QSCTRWEzZLr" : {
"timestamp" : -1.460816357590991E12
},
"-KFURA4H60DbQ1MbrFC1" : {
"timestamp" : -1.460816359767055E12
},
"-KFURAh15i-sWD47RFka" : {
"timestamp" : -1.460816362311195E12
},
"-KFURBHuE7Z5ZvkY9mlS" : {
"timestamp" : -1.460816364735218E12
}
}
and here's how that's written out to Firebase; I just used a IBAction for a button to write out a few nodes:
let testRef = self.myRootRef.childByAppendingPath("test")
let keyRef = testRef.childByAutoId()
let nodeRef = keyRef.childByAppendingPath("timestamp")
let t1 = Timestamp
nodeRef.setValue( 0 - t1) //note the negative value
and the code to read it in
let ref = self.myRootRef.childByAppendingPath("test")
ref.queryOrderedByChild("timestamp").queryLimitedToFirst(3).observeEventType(.ChildAdded, withBlock: { snapshot in
print("The key: \(snapshot.key)") //the key
})
and I declared a little function to return the current Timestamp
var Timestamp: NSTimeInterval {
return NSDate().timeIntervalSince1970 * 1000
}
and the output
The key: -KFURBHuE7Z5ZvkY9mlS
The key: -KFURAh15i-sWD47RFka
The key: -KFURA4H60DbQ1MbrFC1
As you can see, they are in reverse order.
Things to note:
Writing out your timestamp as negative values
When reading in use .queryLimitedToFirst instead of last.
On that note, you can also just read the data as usual and add it to an Array then then sort the array descending. That puts more effort on the client and if you have 10,000 nodes may not be a good solution.
I'm assuming your data actually looks like this:
someDataSet: {
longUID-1: {
timeCreated: 9999999999, // (seconds since the javascript epoch)
user_id: 1
},
longUID-2: {
timeCreated: 1111111111,
user_id: 2
},
longUID-3: {
timeCreated: 3141592653,
user_id: 3
}
}
You could automate that by calling Firebase.push({user_id: ###, timeCreated: ###}) multiple times in a for loop or any other method. Maybe you're adding news stories to a webpage, but you only want your user to see the most current stories--- IDK. But the answer to your question is to use Firebase's ref.orderByChild() and ref.limitToLast().
var ref = new Firebase("<YOUR-FIREBASE-URL>.firebaseio.com/someDataSet");
//the "/someDataSet" comes from the arbitrary name that I used up above
var sortedRef = ref.orderByChild('timeCreated');
//sort them by timeCreated, ascending
sortedRef.limitToLast(2).on("child_added", function(snapshot){
var data = snapshot.val();
console.log(data);
/* do something else with the data */
});
//The console would look like this
// Object {timeCreated: 9999999999, user_id: 1}
// Object {timeCreated: 3141592653, user_id: 3}
This happened because the program took the child with the greatest timeCreated value first and then the second greatest (value) second...
Also note, the longUID means nothing when you sort them by child and neither do the other values (user_id in this case)
Here is the documentation for:
Firebase .push() method (Sorry, I'm not allowed to post this link- I dont have enough reputation)
Firebase .orderByChild method
And also, Firebase .limitToLast method
The code: ref.queryOrderedByKey().queryLimitedToLast(10) can be used for getting the most recent 10 data. However, this is an ascending order by default.
Alternatively, you can order your data via
ref.orderByChild("id").on("child_added", function(snapshot) {
console.log(snapshot.key());
});
This also presents an ascending order by default. To change it into descending order is little bit tricky. What I would suggest it to multiply ids by -1 as shown below and then sort them.
var ref= new Firebase("your data");
ref.once("value", function(allDataSnapshot) {
allDataSnapshot.forEach(function(dataSnapshot) {
var updatedkey = -1 * dataSnapshot.key();
ref.update({ element: { id: updatedkey}});
});
});
This two SO page might be useful for you also, please check:
How to delete all but most recent X children in a Firebase node?
firebaseArray descending order?

Transform data when parsing a JSON string using Dart

I'm using the parse() function provided in dart:json. Is there a way to transform the parsed data using parse()? I'm thinking of something similar to the reviver argument when parsing JSON using JavaScript:
JSON.parse(text[, reviver])
The parse() function in dart:json takes a callback as an arg that you can use to transform the parsed data. For example, you may prefer to express a date field as a DateTime object, and not as a list of numbers representing the year, month and day. Specify a ‘reviver’ function as a second argument to parse.
This function is called once for each object or list property parsed, and the return value of the reviver function is used instead of the parsed value:
import 'dart:json' as json;
void main() {
var jsonPerson = '{"name" : "joe", "date" : [2013, 10, 3]}';
var person = json.parse(jsonPerson, (key, value) {
if (key == "date") {
return new DateTime(value[0], value[1], value[2]);
}
return value;
});
person['name']; // 'joe'
person['date'] is DateTime; // true
}

Convert IQueryable generic to JSON

I'm producing a projection via:
var query = from book in books
select new
{
label = book.Title,
value = book.ID
};
In my razor page I need to use:
var booksArray = [{
#(json)
}];
such that the resulting array looks like:
label: 'c++',
value: 'c++'
}, {
label: 'java',
value: 'java'
}, {
label: 'php',
value: 'php'
}, {
label: 'coldfusion',
value: 'coldfusion'
}
I've come very very close from a couple different approaches - I can get a string that looks correct on the server side but when rendered to the page itself, all the ' marks become ' .
But focusing on achieving this via JSON.net...
The most likely approach seems like it should be:
var json = JsonConvert.ToString(query);
but that tosses:
Unsupported type: System.Linq.Enumerable+WhereSelectListIterator`2[Project.Entity.Book,<>f__AnonymousType3`2[System.String,System.Int32]]. Use the JsonSerializer class to get the object's JSON representation.
What's the correct JSON.net syntax?
thx
You need a combination of .ToArray() and Html.Raw()
ToArray() to evaluate the query and make JsonConvert happy
var query = from book in books
select new
{
label = book.Title,
value = book.ID
};
var json = JsonConvert.SerializeObject(query.ToArray());
Note: you need to use JsonConvert.SerializeObject if you want to serialize complex types. JsonConvert.ToString is used to convert simple types like bool, guid, int, uri etc.
And in your view Html.Raw to not html encode the JSON:
var booksArray = #(Html.Raw(json))

Resources