How do I get a multiple-line subtitle in google sheet charts? - google-apps-script

I am creating a bar chart in google sheet, recording it with a macro, and running the code for different data cases.
When the subtitle is too long, there is missing text on the chart, shown with ellipses (...)
Increasing the chart's width reveals more of the text but not all.
Increasing the chart's height does nothing! (It reveals a long title, but not a long subtitle!)
Adding a line break doesn't work. When using one, all I can see is the first line of the subtitle, while the others stay completely hidden...
How can I have a subtitle that shows all of the text I want to display?
Given that titles are responsive in both the horizontal and vertical axes, it's really odd for subtitles not to be.
Thank you
---- Edit ----
The script helps automate things, but I don't think that it adds new functionalities. That being said, the code I use is the following:
function Macro3() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getActiveSheet();
var chart = sheet.newChart()
.asBarChart()
.addRange(spreadsheet.getActiveRange())
.setMergeStrategy(Charts.ChartMergeStrategy.MERGE_COLUMNS)
.setTransposeRowsAndColumns(false)
.setNumHeaders(4)
.setHiddenDimensionStrategy(Charts.ChartHiddenDimensionStrategy.IGNORE_BOTH)
.setOption('bubble.stroke', '#000000')
.setOption('useFirstColumnAsDomain', true)
.setOption('isStacked', 'false')
.setOption('su', SpreadsheetApp.getActiveSheebtitlet().getRange("B2:B2").getValue())
.setOption('title', SpreadsheetApp.getActiveSheet().getRange("B1:B1").getValue())
.setOption('annotations.domain.textStyle.color', '#808080')
.setOption('textStyle.color', '#000000')
.setOption('legend.textStyle.color', '#1a1a1a')
.setOption('subtitleTextStyle.color', '#999999')
.setOption('titleTextStyle.color', '#757575')
.setOption('annotations.total.textStyle.color', '#808080')
.setXAxisTitle(SpreadsheetApp.getActiveSheet().getRange("B4:B4").getValue())
.setOption('hAxis.textStyle.color', '#000000')
.setYAxisTitle(SpreadsheetApp.getActiveSheet().getRange("A4:A4").getValue())
.setOption('vAxes.0.textStyle.color', '#000000')
.setPosition(2, 1, 30, 0)
.build();
sheet.insertChart(chart);
};
I wanted to include a screenshot of the Google sheet this macro is used upon, but this is my 1st post on stackoverflow and apparently I need at least 10 reputation to post images.
If you think it would help to share this screenshot and there is a neat way of doing it, please let me know.
Thanks again

In the current state it is not possible to add multiple lines to the subtitles of Google Sheets charts. Therefore I recommend you to go to Help > Help Sheets to Improve and add this request. Alternatively, you can use this template to request this functionality for Apps Script, for example, allowing EmbeddedCharts to have titles written with HTMLService.
Possible workarounds:
Change the font size according to the string length.
As I told you in the comments, you can measure the amount of words your subtitle has and according to that, apply different font sizes. For example:
function calcFontSize(subtitle){
const lenS = subtitle.split(" ").length
if(lenS > 12) return 8
if(len <= 12) return 12
}
// Inside your macro
.setOption(
'subtitleTextStyle.fontSize',
calcFontSize(sheet.getRange('B2:B2').getValue())
)
PROS : You have a "responsive" subtitle.
CONS: As you say In long texts ... The text becomes too small to read
Use Charts Service to create your chart
As this service allows you to add jump lines to your title, you can achieve what you want:
function createGoogleChart() {
// extracted from here https://developers.google.com/apps-script/reference/charts/charts
const data = Charts.newDataTable()
.addColumn(Charts.ColumnType.STRING, 'Month')
.addColumn(Charts.ColumnType.NUMBER, 'In Store')
.addColumn(Charts.ColumnType.NUMBER, 'Online')
.addRow(['January', 10, 1])
.addRow(['February', 12, 1])
.addRow(['March', 20, 2])
.addRow(['April', 25, 3])
.addRow(['May', 30, 4])
.build();
const chart = Charts.newAreaChart()
.setDataTable(data)
.setStacked()
.setRange(0, 40)
.setTitle("My title\nMy long long long long long \n long long long long \n subtitle")
.build();
SpreadsheetApp.getActiveSheet().insertImage(
chart.getAs('image/png'), 10, 10
)
}
PROS : You can achieve what you need.
CONS:
You insert a still image (not editable)
There is no default subtitle option
You have to build it from Apps Script, and adapt it to your macro

Related

Plotly Dash Hovertemplate for charts

I would like to modify the format of my Hoverinfo in Plotly Dash:
Im working with plotly and not plotly express for some reasons.
My Code:
fig.add_trace(go.Bar(x = summe2[monat_week], y = summe2['Umsatz'], name='Umsatz', offsetgroup = 1, marker_color = 'blue'), secondary_y = False)
fig.update_traces(hovertemplate = "Umsatz:%{y:20,.2f}'+ 'X%{monat_week}: %{x}", secondary_y=False)
At the beginning when i hovered on on my chart it displayed 100K instead of 100,000
With hovertemplate = "Umsatz<:%{y:.2f} I fixed it and now im getting 100000.00 as intended but I have no clue how to set an group delimiter 3 that im getting the 100000.00 displayed
like 100,000.00. I found an older post from here but its not working from me
Link: Plotly: How to format numeric yaxis and hover text?
I Wrote the code for the formatting as in the previous link but nothing changed and maybe you could tell me if i can change the formatting to EU like 100.000,00 instead of 100,000.00
via Dash fig.update_traces(hovertemplate = 'Umsatz: %{y: 20,.2f}') should work to display it like 100,000.00 but there is no difference to
%{y: .2f} Display: 100000.00
Thank you in advance
Greetings LittleStudent

Changing a Chart Border Color in Google Apps Script

I'm working in Google Apps Script, and I'm inserting a chart into my sheet through a script. I noticed when recording the creation of the chart with a macro, not all of the attributes of the chart get recorded.
For example, I record a macro and I set the background of the chart to be transparent (or any color really), then when I run that macro, the background comes back a standard white.
I am able to fix the background color by setting it in under .setOptions (see code below), but I can't seem to figure out how to change the color of a border (really I want to just get rid of it).
chart = sheet.getSheetByName("Sheet1").newChart()
.asLineChart()
.addRange(sheet.getSheetByName("ForGraphs").getRange(1, 1, 22, team_names.length + 1))
.setMergeStrategy(Charts.ChartMergeStrategy.MERGE_COLUMNS)
.setTransposeRowsAndColumns(false)
.setNumHeaders(-1)
.setHiddenDimensionStrategy(Charts.ChartHiddenDimensionStrategy.IGNORE_BOTH)
.setOption('backgroundColor.fill', "#0000ffff")
.setOption('bubble.stroke', '#000000')
.setOption('useFirstColumnAsDomain', true)
.setOption('focusTarget', 'category')
.setOption('curveType', 'none')
.setOption('legend.position', 'top')
.setOption('annotations.domain.textStyle.color', '#808080')
.setOption('textStyle.color', '#000000')
.setOption('legend.textStyle.color', '#1a1a1a')
.setOption('subtitleTextStyle.color', '#999999')
.setOption('titleTextStyle.color', '#757575')
.setOption('annotations.total.textStyle.color', '#808080')
.setOption('hAxis.slantedText', true)
.setOption('hAxis.slantedTextAngle', 0)
.setOption('hAxis.textStyle.color', '#000000')
.setOption('hAxis.titleTextStyle.color', '#000000')
.setOption('vAxes.0.minorGridlines.count', 5)
.setOption('vAxes.0.minorGridlines.color', '#f3f3f3')
.setOption('vAxes.0.textStyle.color', '#000000')
.setOption('vAxes.0.titleTextStyle.color', '#000000')
.setOption('height', 322)
.setOption('width', 659)
.setPosition(26, 5, 2, 16)
.build();
I've manually added the .setOption('backgroundColor', "#0000ffff") into this chunk.
I see in Google's official documentation that they say the backgroundColor.fill option can take an object as an input, but they neglect to say what they object will look like. I would assume it would be something with a .stroke and .strokeWeight, but that hasn't seemed to work.
Thanks so much!
It means you can set by either setOption('backgroundcolor', 'white') or setOption('backgroundcolor', {fill:'white'})
According to the document, not further option for background is supported
Line colors are set by setOptions('colors', ['blue', 'red'])
Chart area background color is set by chartArea.backgroundColor
It is stated in the document.

Is it possible to convert a Chart to and EmbeddedChart?

I'm attempting to Create a few charts out of a Sheet of data, but the charts are grabbing sort of specific data so I have found it advantageous to use the DataTableBuilder class. I am able to specify labels for the data more easily than I can from the original sheet. However, I cannot embed a Chart Class into a Sheet. Is it possible to either convert a Chart to an EmbeddedChart or use a DataTable to create an EmbeddedChart?I'm attempting to Create a few charts out of a Sheet of data, but the charts are grabbing sort of specific data so I have found it advantageous to use the DataTableBuilder class. I am able to specify labels for the data more easily than I can from the original sheet. However, I cannot embed a Chart Class into a Sheet. Is it possible to either convert a Chart to an EmbeddedChart or use a DataTable to create an EmbeddedChart?
This is the data below, and I need only the last column (5/11) and I don't need the total row. So its not a concise range, else I would just use the Embedded chart builder.
May 5/1 5/2 5/3 5/11
Critical 0 0 0 0
High 0 0 0 0
Call Immediate 4 11 4 3
Daytime Call 3 3 6 1
Totals 7 14 10 4
Below is the how I've built the Chart in which dailyTotals is a range of [0, 0, 3, 1]. This works fine, but I can't label anything.
var dailyChart = LOB.newChart()
.setChartType(Charts.ChartType.BAR)
.setOption('title', LOB.getName())
.addRange(dailyTotals)
.build();
LOB.insertChart(dailyChart);
Below is building the DataTable, this time daily totals is just an array. But this gives me labels.
dailyTable = Charts.newDataTable()
.addColumn(Charts.ColumnType.STRING, "Priority")
.addColumn(Charts.ColumnType.NUMBER, "Incidents")
.addRow('P1', dailyTotals[0])
.addRow('P2', dailyTotals[1])
.addRow('P3', dailyTotals[2])
.addRow('P4', dailyTotals[3])
.build();
How can I either use a DataTable to create an EmbeddedChart? or how can I turn a Chart into and Embedded chart?
I actually figured out a solution that worked for me before I got a response from anyone. It involves using a legend to determine which bar is which, rather than labels along the x-axis, but it totally covers my requirements and might help out some one else out.
var dailySeries = {
0:{color: 'blue', labelInLegend: 'P1'},
1:{color: 'red', labelInLegend: 'P2'},
2:{color: 'yellow', labelInLegend: 'P3'},
3:{color: 'green', labelInLegend: 'P4'}
}
var dailyChart = LOB.newChart()
.setPosition(8, 27, 0, 0)
.setChartType(Charts.ChartType.BAR)
.asColumnChart()
.setOption('title', LOB.getName())
.addRange(dailyTotals.getCell(1, 1))
.addRange(dailyTotals.getCell(2, 1))
.addRange(dailyTotals.getCell(3, 1))
.addRange(dailyTotals.getCell(4, 1))
.setOption('series', dailySeries)
.build();
LOB.insertChart(dailyChart);
You would need to re-create the below range somewhere else in the sheet and add that as range instead.
A B
P1 0
P2 0
P3 3
P4 1
The range [P1, P2, P3, P4] can also be somewhere else. Then you can add both ranges:
.addRange([P1 to P4 range])
.addRange(dailyTotals)
.setOption('useFirstColumnAsDomain','true')

Customising Google Bar Chart Using Google App Script

I am currently having some issues configuring a simple graph using Google App Scripts. I seem to be unable to find the correct documentation in order to progress any further!
I have everything hooked up pulling data from a couple of spreadsheets, so that aspect is fine!
I see that there are various ways in order to customise the looks of a chart and there are tools available for example:
http://imagecharteditor.appspot.com/
http://code.google.com/apis/ajax/playground/?type=visualization
I wish to add colours to my bar charts like in this example
http://code.google.com/apis/ajax/playground/?type=visualization#image_multicolor_bar_chart
Additionally in the first link there are options to create sections using the range marker tool. I was hoping that with these tools I could copy the code across to use in my App Script Chart.
The only way I can see this working is using .setOption(string, object)
I've tried this...
var data = Charts.newDataTable()
.addColumn(Charts.ColumnType.STRING, 'Month')
.addColumn(Charts.ColumnType.NUMBER, 'Mark Achieved')
for(var x=0; x < ChartData.length;x++){
data.addRow(ChartData[x]);
}
data.build();
var chart = Charts.newColumnChart()
.setDataTable(data)
.setDimensions(1000, 600)
.setRange(0, 100)
.setTitle('Test Scores')
.setLegendPosition(Charts.Position.BOTTOM)
.setOption('options',{cht: 'bvs', chco: 'A2C180,3D7930', max: 100})
.build();
app.add(chart);
any help would be much appreciated!
EDIT
The options you are trying to use are applicable to the static image charts (which are now deprecated), and won't work with ColumnCharts. ColumnCharts color the bars by series, not by data point, so if you want multi-colored bars, you have to separate them out into different data series. I wrote a hack that does this (see on jsfiddle for the standard javascript version). My reading of the AppsScript implementation of the Visualization API seems to preclude using calculated columns in the DataViews, but it is possible that the documentation is incomplete here. Try creating a view like this:
// add one calculated column for each month
var dataViewDefinition = Charts.newDataViewDefinition().setColumns([0, {
type: Charts.ColumnType.NUMBER,
label: 'Mark Achieved',
calc: function (dt, row) {
if (dt.getValue(row, 0) == 'January') ? dt.getValue(row, 1) : null;
}
}, {
type: Charts.ColumnType.NUMBER,
label: 'Mark Achieved',
calc: function (dt, row) {
if (dt.getValue(row, 0) == 'February') ? dt.getValue(row, 1) : null;
}
}/*...*/]);
It is probable that this needs to be tweaked, and possible that it won't work at all, in which case you would have to either change the query of the spreadsheet or rearrange the structure of the spreadsheet.
As far as adding the ranges to the chart, can you elaborate more on what you would like those to look like?

Flash Builder: PieChart issue

I am trying to show data in my pieChart. Everything works great if I have multiple fields in my dataprovide (ex: EmployeeA, EmployeeB..etc). The pie will be divided into pieces and have texts shown on each pieces.
However, if my dataprovider only has one field (ex: EmployeeA). The pieChart will show the whole pie with no texts on the pieChart. I was wondering if there are any ways to show the data text inside the pieChart. Thanks a lot.
Code:
<mx:PieChart id="piechart1" x="254" y="321" width="367" height="367"
dataProvider="{getHours.lastResult}">
<mx:series>
<mx:PieSeries id="pieSeries" labelFunction="pieFunction"
explodeRadius="0.05" field="EmployeeOverTime" labelPosition="inside"/>
</mx:series>
</mx:PieChart>
//EmployeeOverTime data will show on each pie pieces if I have multiple
//employees in the department but won't show if the department has only one employee.
It looks like it was a bug in the PieSeries code. I had to monkey patch the charting code in order to get this to work. Here's an fxp file that works.
http://dl.dropbox.com/u/20054635/forever/piechart.fxp
The bug is that on line 3323 there's this code:
var rscale:Number = 1;
// find out how much we would have to scale to get to the next neighbor up
/* var RXScale:Number = Math.abs(ld.labelX - nextNeighbor.labelX)/(ld.labelWidth/2 + nextNeighbor.labelWidth/2);
Then on line 3338 it removes the label based on rscale (which is now zero because there was no nextNeighbor when there is only 1 item in the piechart)
if (rscale * Number(labelFormat.size) < insideLabelSizeLimit)
{
ld.prev.next = ld.next;
ld.next.prev = ld.prev;
removedLabels.push(ld);