NumberFormatter not working on danielgindi Charts - swift

I just updated https://github.com/danielgindi/Charts to Charts 4.1 from 3.1
Before I formatted my values with this code
let pFormatter = NumberFormatter()
pFormatter.numberStyle = .percent
pFormatter.maximumFractionDigits = 0
pFormatter.multiplier = 1
pFormatter.percentSymbol = "%"
chartData.setValueFormatter(DefaultValueFormatter(formatter: pFormatter))
But it has no effect at all. Values are rare, unformatted and no percentSymbol at all.
I tried to google, but all solutions seem to be the same code as mine.
For some reason, the formatter has no effect at all, before it worked.
I checked the changelog but I can't find anything which had changed in terms of value formatting.

Related

Formatting percent number to zh (simplified Chinese) using the right percent sign (ie. %)

I'd like to use NumberFormatter to generate zh-localised percents as follows, in order to supersede my own code as follow:
let locale = Locale(identifier: lang)
let formatter = NumberFormatter()
formatter.locale = locale
formatter.numberStyle = .percent
formatter.maximumFractionDigits = d
let number = NSNumber(value: Double(n))
if let r = formatter.string(from: number) {
if lang == "zh" { return r.replace(["%"], withString: "%")
return r
}
// My fallback code
Unfortunately, unlike my code, in simplified Chinese NumberFormatter generates latin % sign rather than the chinese version % (hence the replacement patch I do).
I am wondering if one could tweak NumberFormatter further so that it take care of it? (and in other non-latin languages).
You seem to imply that what NumberFormatter outputs is incorrect. However, as a native Chinese, I can confidently say that "50%" is the natural way of writing a percentage in the zh locale. This is also evident from this Baidu Baike (Chinese counterpart of Wikipedia) article. I have never seen any app write percentages with the full-width percentage sign. I can't even type it with the Chinese IME on my Mac.
To my eyes, "50%" looks weird, probably because it's mixing full-width and half-width characters. I've occasionally seen "50%" in Japanese sites, but it's still rather rare.
if you really want, you can set the percentSymbol property in NumberFormatter:
let formatter = NumberFormatter()
formatter.percentSymbol = "%"
formatter.numberStyle = .percent
print(formatter.string(from: 0.5) ?? "failed")
To be honest, I would trust the output of NumberFormatter, which is designed by a bunch of professional localisation engineers.

OS X App converting textfield with comma causing issues with double value

I am creating an OS X app and when I do this:
var tempVal = 10495.33
tempTextField.doubleValue = self.tempVal
It shows like this: 10,495.33. Notice the comma.
Now when I modify that value to 30,400.34 in the NSTextField and try to assign it back to the doubleValue things get messed up.
tempVal = tempTextField.doubleValue //Now this makes tempVal = 30 instead of 30,400.34
This is all because of the comma. Without the comma things are fine.
I know there is a bad fix where I just remove all commas from the number string but I feel like there is a better/correct way to do this.
The issue is most likely cause by by your system settings. Apparently (do not kwon why) you should enter the numbers in a US like format (using a "." as decimal separator), but the output to the textfield is depending on your system setting. So if you are in Europe most likely you use "," as a decimal separator
you can fix it as follows (you configure the format of the NSTextField, so no need to format the data you enter)
//This codes works in swift 4
//This should be your textfield. It is either programmed or you link it through storyboard
var myTextField = NSTextField()
//This is a formatter. You can set it up how to format the textfield
var myFormat = NumberFormatter()
myFormat.decimalSeparator = "."
myFormat.numberStyle = .decimal
//Now you connect the two
myTextField.formatter = myFormat

Swift Charts Format Not Working

I am using the Charts framwork for Swift found here. I have a chart that I am trying to fix two issues shown in the chart below:
The first is trying to format my X values from doubles to Ints. I want the value to show 67 and not 67.0. I have tried the following to adjust it but
numbers still stay the same:
let format = NumberFormatter()
format.minimumIntegerDigits = 0
format.minimumFractionDigits = 0
let formatter = DefaultValueFormatter(formatter: format)
chartview.rightAxis.valueFormatter = (formatter as? IAxisValueFormatter)
I also have a problem where the buttom bars dont line up with the buttom of the graph. If you look at the graph above, it looks like 0 starts above the X axis and not at the orgin. Theres a little space below the bars. I would like the bottom of each bar to touch the X-Axis.
Please try like this :
let format = NumberFormatter()
format.minimumIntegerDigits = 0
format.minimumFractionDigits = 0
let formatter = DefaultValueFormatter(formatter: format)
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Label") // replace with your set
chartDataSet.valueFormatter = formatter
For lining Button bars. please try this:
barChartView.rightAxis.axisMinimum = 0.0
barChartView.leftAxis.axisMinimum = 0.0

Why is that an invalid number?

There are very different ways of displaying numbers, for example:
16666,67
16666.67
16.666,67
16.666.67
Those are all valid numbers for different regions and / or countries.
In our usecase we have to use following representation:
16.666.67
Because
Its easier to see how big the number is using the thousands seperator
We needed to prevent wrong user inputs so we are replacing all commas with a period
Though, for a numberformatter with a period as decimal sperator 16.666.67 is not a valid number:
self.numberFormatter = NumberFormatter()
self.numberFormatter.numberStyle = .decimal;
self.numberFormatter.minimumFractionDigits = 0;
self.numberFormatter.maximumFractionDigits = 2;
self.numberFormatter.decimalSeparator = ".";
print(self.numberFormatter.number(from: "16.666.67");
which is resulting in nil. Why is that an invalid number? And how can I solve that problem?'
EDIT
Following test:
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal;
numberFormatter.minimumFractionDigits = 0;
numberFormatter.maximumFractionDigits = 2;
numberFormatter.groupingSeparator = ".";
numberFormatter.decimalSeparator = ".";
print(numberFormatter.number(from: "16666"));
print(numberFormatter.number(from: "16666,67"));
print(numberFormatter.number(from: "16666.67"));
print(numberFormatter.number(from: "16.666"));
print(numberFormatter.number(from: "16.666,67"));
print(numberFormatter.number(from: "16.666.67"));
output is:
Optional(16666)
nil
Optional(16666.67)
Optional(16666)
nil
nil
The issue is that the String 16.667.67 is no less an invalid number as This.is.a.number.00.
You need to make your String variable be something valid.
EDIT:
Based on the comments this sounds like a language behavior issue (Java versus Swift).
I'm seeing other comments on handling this, but to me, it looks like it gets down to how the Swift NumberFormatter automatically handles a String input with multiple decimal points. Unlike (some) other languages, you may need to do some pre-formatting of the string before calling NumberFormatter.

Keeping Trailing Zeros from .doubleValue() in Swift

I am working on an application that needs to do some displaying and calculating of Double types in Swift. The struct that I created takes a Double as a parameter, and since it also displays it, I would like to keep the trailing zero at the end of the value. However, I cannot seem to keep the trailing zero from being truncated.
Here is what I have been trying in a Playground:
let numberString = "-3.60"
// "3.60"
let positiveString = numberString.stringByReplacingOccurrencesOfString("-", withString: "", options: nil, range: nil)
// 3.6
let positiveDouble = (positiveString as NSString).doubleValue
// "3.60"
let positiveDoubleString = NSString(format: "%0.02f", positiveDouble)
// 3.6
let positiveDoubleWithZeros = positiveDoubleString.doubleValue
I keep getting 3.6 as the result, no matter what I try. What is the obvious part of the conversion that I am missing?
You have to use NSNumberFormatter:
let formatter = NSNumberFormatter()
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 3
println(formatter.stringFromNumber(1.0000))
println(formatter.stringFromNumber(1.2345))
This example will print 1.00 for the first case and 1.234 for the second, the number of minimum and maximum decimal places can be adjust as you need.
I Hope that helps you!