How to remove negative symbol on values Google Charts? - charts

i have a column chart and work fine, but i want to allways show positive number, but i force negative number to "divide" bars on top and bottom.
He a example:
Here my code
google.load('visualization','1.1',{packages:['corechart']});
google.setOnLoadCallback(function(){
var GoogleChart=new google.visualization.ColumnChart(document.getElementById( 'chart' ));
var data = google.visualization.arrayToDataTable([
["Age","Male","Female"],
["<15",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["15-20",{"v":8.3333333333333,"f":"8,3333333333333%"},{"v":0,"f":"0%"}],
["20-25",{"v":75,"f":"75%"},{"v":-8.3333333333333,"f":"8,3333333333333%"}],
["25-30",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["30-35",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["35-40",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["40-45",{"v":8.3333333333333,"f":"8,3333333333333%"},{"v":0,"f":"0%"}],
["45-50",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["50-55",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["55-60",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
[">60",{"v":0,"f":"0%"},{"v":0,"f":"0%"}]
]);
new google.visualization.NumberFormat({"pattern":"#,##%"}).format(data, 1);
new google.visualization.NumberFormat({"pattern":"#,##%"}).format(data, 2);
var options ={
"isStacked":true,
"hAxis":{
"title":"age"
},
"vAxis":{
"title":"Percentage",
"format":"#,##%",
"viewWindowMode":"explicit",
"viewWindow":{
"min":-100,
"max":100
}
}
};
GoogleChart.draw(data, options);
i dont know how to remove negative symbol("-").
Thanks
P.S: Google Charts 1.1

The google visualization pattern format is a subset of the ICU pattern set. By that you can specify subpatterns for both positive and negative numbers to avoid the minus sign (because if the negative subpattern is not specified, you will get the minus prefix by default) :
format: "#,##%;#,##%"
Unfortunetaly this does not work in visualization - it complains about "Too many percent/permills" - but since % is nothing but "Multiply by 100 and show as percentage" - then you can simply add ,00% as a string suffix instead :
vAxis:{
format:"#,##',00%';#,##',00%'",
...
}
new google.visualization.NumberFormat({"pattern":"#,##',00%';#,##',00%'"}).format(data, 1);
new google.visualization.NumberFormat({"pattern":"#,##',00%';#,##',00%'"}).format(data, 2);
Minus sign now removed from both the vAxis and tooltips.
demo -> http://jsfiddle.net/pcvtf7q9/

Related

How to draw box plot of columns of a table using dc.js

I have a table as follows:
The number of experiments are arbitrary but the column name's prefix is "client_" following by the client number.
I want to draw a box plot of values against the "client_#" using dc.js. The table is a csv file which is loaded using d3.csv().
There are examples using ordinary groups, however I need each column to be displayed as its own boxplot and none of the examples do this. How can I create a boxplot from each column?
This is very similar to this question:
dc.js - how to create a row chart from multiple columns
Many of the same caveats apply - it will not be possible to filter (brush) using this chart, since every row contributes to every box plot.
The difference is that we will need all the individual values, not just the sum total.
I didn't have an example to test with, but hopefully this code will work:
function column_values(dim, cols) {
var _groupAll = dim.groupAll().reduce(
function(p, v) { // add
cols.forEach(function(c) {
p[c].splice(d3.bisectLeft(p[c], v[c]), 0, v[c]);
});
return p;
},
function(p, v) { // remove
cols.forEach(function(c) {
p[c].splice(d3.bisectLeft(p[c], v[c]), 1);
});
return p;
},
function() { // init
var p = {};
cols.forEach(function(c) {
p[c] = [];
});
return p;
});
return {
all: function() {
// or _.pairs, anything to turn the object into an array
return d3.map(_groupAll.value()).entries();
}
};
}
As with the row chart question, we'll need to group all the data in one bin using groupAll - ordinary crossfilter bins won't work since every row contributes to every bin.
The init function creates an object which will be keyed by column name. Each entry is an array of the values in that column.
The add function goes through all the columns and inserts each column's value into each array in sorted order.
The remove function finds the value using binary search and removes it.
When .all() is called, the {key,value} pairs will be built from the object.
The column_values function takes either a dimension or a crossfilter object for the first parameter, and an array of column names for the second parameter. It returns a fake group with a bin for each client, where the key is the client name and the value is all of the values for that client in sorted order.
You can use column_values like this:
var boxplotColumnsGroup = column_values(cf, ['client_1', 'client_2', 'client_3', 'client_4']);
boxPlot
.dimension({}) // no valid dimension as explained in earlier question
.group(boxplotColumnsGroup);
If this does not work, please attach an example so we can debug this together.

Customized Android GraphView x-axis date labels not displaying as per setNumHorizontalValues()

I attempt to show a tersely formatted date/time on the x-axis in a graphview chart. As per the API Code examples, I set HumanRounding to false when using using a date formatter on that axis. I'm also setting the NumHorizontalLabels to 3 in order to display reasonably OK in both orientations.
This results in e.g. the following, where the date labels show as a black shape, and the LineChart background is different. I'm speculating that the black shape is the result of all my date data points overwriting each other:
With HumanRounding set to true (commented out), I get labels showing, but instead of the expected 3 evenly distributed labels, they are unpredictably spread out and/or not equal to 3, sometimes the labels over-write each other, sometimes they are bunched on the left...
The number of date data-points on the x-axis can vary depending on how much history the user has selected. Note that this can vary from 60 to thousands of minutes.
Here's the code that receives data and charts it. Note that the unixdate retrieved from wxList elements has already been converted to a Java date (by multiplying by 1000) by the time they get used here (the time portion of the x-axis are in fact correct when they do show up in a reasonably distributed manner):
protected void onPostExecute(List<WxData> wxList) {
// We will display MM/dd HH:mm on the x-axes on all graphs...
SimpleDateFormat shortDateTime = new SimpleDateFormat("MM/dd HH:mm");
shortDateTime.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
DateAsXAxisLabelFormatter xAxisFormat = new DateAsXAxisLabelFormatter(parentContext, shortDateTime);
if (wxList == null || wxList.isEmpty()) {
makeText(parentContext,
"Could not retrieve data from server",
Toast.LENGTH_LONG).show();
} else {
// Temperature Celcius
GraphView tempGraph = findViewById(R.id.temp_graph);
tempGraph.removeAllSeries();
tempGraph.setTitle(parentContext.getString(R.string.temp_graph_label));
DataPoint[] tempCArray = new DataPoint[wxList.size()];
for (int i = 0; i < wxList.size(); i++) {
tempCArray[i] = new DataPoint(wxList.get(i).getUnixtime(), wxList.get(i).getTempC().doubleValue());
}
LineGraphSeries<DataPoint> tempCSeries = new LineGraphSeries<>(tempCArray);
tempGraph.addSeries(tempCSeries);
tempGraph.getGridLabelRenderer().invalidate(false, false);
tempGraph.getGridLabelRenderer().setLabelFormatter(xAxisFormat);
tempGraph.getGridLabelRenderer().setNumHorizontalLabels(3);
tempGraph.getViewport().setMinX(wxList.get(0).getUnixtime());
tempGraph.getViewport().setMaxX(wxList.get(wxList.size() - 1).getUnixtime());
tempGraph.getViewport().setXAxisBoundsManual(true);
// Code below seems buggy - with humanRounding, X-axis turns black
// tempGraph.getGridLabelRenderer().setHumanRounding(false);
...
I have tried many variations,but I cannot get the graph to consistently display 3 datetimes evenly spread out, for both orientations, for varyings sample sizes. Any help is appreciated.

How to use sheets.spreadsheets.batchUpdate() to apply formatting?

I am attempting to automatically apply new formatting to my spreadsheet, however while it does not appear to cause any errors, it is not working.
My goal is to apply duration formatting to columns G and H (index 6 and 7) of my spreadsheet. I am automatically updating the spreadsheet with string data in the format without brackets:
[D]:[H]:[M]
Where D, H, and M may be single or double digit. I would like it to display in the following format without brackets on the spreadsheet:
[hh]:[mm]:[ss]
Where there is always at least two digits in each column. However, the spreadsheet seems to automatically choose formatting regardless of what formatting I request, and it chooses a decimal number format. How can I use the batchUpdate() function to apply a working duration formatting to just these two columns?
My Code attempt is below. I am using the Node.js Google API Client Library.
sheets.spreadsheets.batchUpdate({
spreadsheetId: '1AakOf_W90JdAtL0R8XeMmacWrnBx8wLKrMCdHdnNmhM',
resource: {
requests: [{
updateCells:{
range: {
startColumnIndex: 6,
endColumnIndex: 8
},
'fields': 'userEnteredFormat/numberFormat(pattern,type),effectiveFormat/numberFormat(pattern,type)',
rows:[{
values:[{
userEnteredFormat:{
numberFormat:{
pattern: '[hh]:[mm]:[ss]',
type: 'TIME'
}
},
effectiveFormat:{
numberFormat:{
pattern: '[hh]:[mm]:[ss]',
type: 'TIME'
}
}
}]
}]
}
}
]
}
}, function(err, response, responseBody){
if(err){
console.log(err);
console.log(err.code);
}
});
It would seem that the issue lies within the indexing of columns on the spreadsheet. When writing this code, I assumed that the columns were indexed starting at zero. However, it would appear that the indexing starts at -1, as columns G and H are actually represented by indices 5 and 6.

Custom axis labels with missing table rows

There is a Spreadsheet with two columns: Date, Integer. And some rows are missing.
When I insert chart manually, I see long horizontal line instead of missing rows.
But when I do this:
var sheet = SpreadsheetApp.openById(id).getSheets()[0];
var table = Charts.newDataTable().
addColumn(Charts.ColumnType.STRING, "Date").
addColumn(Charts.ColumnType.NUMBER, "asd");
sheet.getSheetValues(sheet.getLastRow() - 9, 1, 10, 2).forEach( function(line) {
var date = new Date(line[0]);
table.addRow( [
date.getDate() + " " + ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][date.getMonth()],
line[1]
] );
} );
var chart = Charts.newLineChart().
setDataTable(table).
setXAxisTitle("Date").
setYAxisTitle("asd").
setTitle("asd").
build();
var temp = "<img src=\'cid:asd\'/>";
MailApp.sendEmail("asd#gmail.com", "asd", temp, {
htmlBody: temp,
inlineImages: { asd: chart }
} );
the X axis is collapsed, because its values aren't actually Dates, because I reformatted them.
(red lines were made in mspaint to focus your attention)
What is a proper way to make it with horizontal line, like in Spreadsheet, and with customly formatted Dates, like in the image from email?
Whenever you do this it will take the regular behavior in this case make the connection between available values.
If you change the type of chart, it would illustrate missing values more appropriately; bars or other type of charts would illustrate in a better way missing values.

Function equivalent to SUM() for multiplication in SQL Reporting

I'm looking for a function or solution to the following:
For the chart in SQL Reporting i need to multiply values from a Column A. For summation i would use =SUM(COLUMN_A) for the chart. But what can i use for multiplication - i was not able to find a solution so far?
Currently i am calculating the value of the stacked column as following:
=ROUND(SUM(Fields!Value_Is.Value)/SUM(Fields!StartValue.Value),3)
Instead of SUM i need something to multiply the values.
Something like that:
=ROUND(MULTIPLY(Fields!Value_Is.Value)/MULTIPLY(Fields!StartValue.Value),3)
EDIT #1
Okay tried to get this thing running.
The expression for the chart looks like this:
=Exp(Sum(Log(IIf(Fields!Menge_Ist.Value = 0, 10^-306, Fields!Menge_Ist.Value)))) / Exp(Sum(Log(IIf(Fields!Startmenge.Value = 0, 10^-306, Fields!Startmenge.Value))))
If i calculate my 'needs' manually i have to get the following result:
In my SQL Report i get the following result:
To make it easier, these are the raw values:
and you have the possibility to group the chart by CW, CQ or CY
(The values from the first pictures are aggregated Sum values from the raw values by FertStufe)
EDIT #2
Tried your expression, which results in this:
Just to make it clear:
The values in the column
=Value_IS / Start_Value
in the first picture are multiplied against each other
0,9947 x 1,0000 x 0,59401 = 0,58573
Diffusion Calenderweek 44 Sums
Startvalue: 1900,00 Value Is: 1890,00 == yield:0,99474
Waffer unbestrahlt Calenderweek 44 Sums
Startvalue: 620,00 Value Is: 620,00 == yield 1,0000
Pellet Calenderweek 44 Sums
Startvalue: 271,00 Value Is: 160,00 == yield 0,59041
yield Diffusion x yield Wafer x yield Pellet = needed Value in chart = 0,58730
EDIT #3
The raw values look like this:
The chart ist grouped - like in the image - on these fields
CY (Calendar year), CM (Calendar month), CW (Calendar week)
You can download the data as xls here:
https://www.dropbox.com/s/g0yrzo3330adgem/2013-01-17_data.xls
The expression i use (copy / past from the edit window)
=Exp(Sum(Log(Fields!Menge_Ist.Value / Fields!Startmenge.Value)))
I've exported the whole report result to excel, you can get it here:
https://www.dropbox.com/s/uogdh9ac2onuqh6/2013-01-17_report.xls
it's actually a workaround. But I am pretty sure is the only solution for this infamous problem :D
This is how I did:
Exp(∑(Log(X))), so what you should do is:
Exp(Sum(Log(Fields!YourField.Value)))
Who said math was worth nothing? =D
EDIT:
Corrected the formula.
By the way, it's tested.
Addressing Ian's concern:
Exp(Sum(Log(IIf(Fields!YourField.Value = 0, 10^-306, Fields!YourField.Value))))
The idea is change 0 with a very small number. Just an idea.
EDIT:
Based on your updated question this is what you should do:
Exp(Sum(Log(Fields!Value_IS.Value / Fields!Start_Value.Value)))
I just tested the above code and got the result you hoped for.