Can I add rich text to google sheets note? - google-sheets

Can I do this by using a Google API? Assume note is the variable of richtext
'repeatCell': {
'range': {
'sheetId': 0,
'startRowIndex': start_row,
'endRowIndex': end_row + 1,
'startColumnIndex': start_col,
'endColumnIndex': end_col + 1,
},
'cell': {
'note': note,
'userEnteredFormat': {
'backgroundColor': backgroundColor,
'numberFormat': numberFormat,
},
},
'fields': 'note,userEnteredFormat',
},
}

As #Tanaike said, Notes (and Comments) only accept plain-text. However, you can fill a Feature Request in Issue Tracker.

Related

GoogleSheets API does not work. It does not let to strikethrough with API

One can reproduce the problem.
Create new Spreadsheet.
Take SpreadsheetId (https://docs.google.com/spreadsheets/d/1rp11nqj0t0x1111111111111111111111111137Wj4XU/edit#gid=0, here it is 1rp11nqj0t0x1111111111111111111111111137Wj4XU)
Fill range A1:F15 with any content, let's use 'lorem ipsum' string, for instance.
Visit https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/batchUpdate
4.1 Look at right side where one can find "Try this method"
4.2 Fill field "spreadsheetId" with one you've taken on step 2.
4.3 Fill "Request body" with
{
"requests": [
{
"repeatCell": {
"cell": {
"userEnteredFormat": {
"textFormat": {
"strikethrough": true
}
}
},
"fields": "*",
"range": {
"startRowIndex": 2,
"endRowIndex": 2,
"startColumnIndex": 1,
"endColumnIndex": 3
}
}
}
]
}
4.4 Press "Execute" button at the bottom of right side.
5. Check you spreadshet.
6. No error, nothing happened.
What am I doing wrong ?
Modification points:
In your following request body, the values of startRowIndex and endRowIndex are the same. By this, this request body cannot be correctly worked. I thought that this might be the reason for your current issue of No error, nothing happened..
{
"requests":[
{
"repeatCell":{
"cell":{
"userEnteredFormat":{
"textFormat":{
"strikethrough":true
}
}
},
"fields":"*",
"range":{
"startRowIndex":2,
"endRowIndex":2,
"startColumnIndex":1,
"endColumnIndex":3
}
}
}
]
}
And also, in your request body, even when the above modification is reflected, the cell values are cleared by "fields":"*". Please be careful about this.
When these points are reflected in your request body, how about the following modification?
Modified request body:
{
"requests": [
{
"repeatCell": {
"cell": {
"userEnteredFormat": {
"textFormat": {
"strikethrough": true
}
}
},
"fields": "userEnteredFormat.textFormat.strikethrough",
"range": {
"startRowIndex": 0,
"endRowIndex": 15,
"startColumnIndex": 0,
"endColumnIndex": 6,
}
}
}
]
}
In this modified request body, from Fill range A1:F15 with any content, let's use 'lorem ipsum' string, for instance., the cells "A1:F15" are used. So, strikethrough is used for these cells.
In your request body, sheetId is not used. So, in this case, the 1st tab in Google Spreadsheet is used. Please be careful about this. If you want to use it for the specific sheet, please add the property of "sheetId": ### to range. ### is the sheet ID.
References:
RepeatCellRequest
GridRange

MS Graph API GetActivitiesByInterval gives blank itemActivitySet

Busy writing some implementation on the beta branch of MS Graph API.
Using GetActivitiesByInterval, it brings back the activity stats (how many activities / how many actors) but no activity sets (itemActivitySet)
{
"StartDateTime": "2023-01-12T00:00:00+00:00",
"EndDateTime": "2023-01-12T23:59:59+00:00",
"Access": {
"ActionCount": 4,
"ActorCount": 1,
"AdditionalData": {
"timeSpentInSeconds": 0
},
"ODataType": "microsoft.graph.itemActionStat"
},
"Create": null,
"Delete": null,
"Edit": null,
"Move": null,
"IsTrending": null,
"IncompleteData": {
"MissingDataBeforeDateTime": null,
"WasThrottled": false,
"AdditionalData": {
"resultsPending": false,
"notSupported": false
},
"ODataType": "microsoft.graph.incompleteData"
},
"Activities": null,
"Id": null,
"ODataType": "#microsoft.graph.itemActivityStat",
"AdditionalData": {
"aggregationInterval": "None"
}
}
There were definitely activities on those, a comment, a rename and a move. I can check those activities are on SharePoint.
I've also tried adding query option expand=activities on returning the drive item but that gives back an empty set (not null, just no data filled with "[],")
There also doesn't seem to be a hidden list called "userActivityFeedHiddenList" in SharePoint that I could use to reference activities for a particular file.
I've googled quite a bit to try and get as much information and went through quite a number of SO posts (hence all the things I tried) but none has worked.
Any suggestions?

GAS - create google slide scribble line with script

I would like to create a line with some point array with google-slide-api script. but I do not found any document about how to do it.
Then I create a line with scribble tool manually then read it by google-slide-api. I got below output:
- Slide #1 contains 1 elements.
elem #0 - {
"line": {
"lineProperties": {
"dashStyle": "SOLID",
"endArrow": "NONE",
"lineFill": {
"solidFill": {
"alpha": 1,
"color": {
"themeColor": "DARK2"
}
}
},
"startArrow": "NONE",
"weight": {
"magnitude": 9525,
"unit": "EMU"
}
}
},
"objectId": "gf0b4bb3376_0_2",
"size": {
"height": {
"magnitude": 786825,
"unit": "EMU"
},
"width": {
"magnitude": 763325,
"unit": "EMU"
}
},
"transform": {
"scaleX": 1,
"scaleY": 1,
"translateX": 1196175,
"translateY": 777044.3325,
"unit": "EMU"
}
}
That means google slide actual create it as a line type but nothing special to define the data points! then it's not possible to create the same from the output json data.
Answer:
Unfortunately, this isn't currently possible.
More Information:
As explained by Iamblichus in this answer, the Slides API does not support this kind of line, and as you have pointed out smoothing between separate lines does not work.
Feature Request:
You can however let Google know that this is a feature that is important for access to their APIs, and that you would like to request they implement it.
Google's Issue Tracker is a place for developers to report issues and make feature requests for their development services, I'd urge you to make a feature request there. The best component to file this under would be the Google Slides component, with the Feature Request template.

Is it possible to move a Shape from a slide to another?

I use the Google Slides API on a NodeJS server to edit a presentation and I can't find anything in the documentation on moving an object to another slide, a Shape for example.
Answer:
You have to do this by getting the shape from the response of presentations.pages.get, removing it, and inserting it with presentations.batchUpdate.
More Information:
In order to 'move' an object from one slide to another using the API, you in fact have to make two requests: one to remove the current object, and one to insert it into the new slide.
Firstly, you will need to make a request to presentations.pages.get in order to get all PageElement objects in the page. As per the documentation, a Shape is an instance of a PageElement object which represents a shape on a slide.
The response of presentations.pages.get will be a Page resource:
{
"objectId": string,
"pageType": enum (PageType),
"pageElements": [
{
object (PageElement)
}
],
"revisionId": string,
"pageProperties": {
object (PageProperties)
},
// Union field properties can be only one of the following:
"slideProperties": {
object (SlideProperties)
},
"layoutProperties": {
object (LayoutProperties)
},
"notesProperties": {
object (NotesProperties)
},
"masterProperties": {
object (MasterProperties)
}
}
The Shape will be contained within the response['pageElements'] resource from this request and will be of the form:
{
"objectId": string,
"size": {
object (Size)
},
"transform": {
object (AffineTransform)
},
"title": string,
"description": string,
// Union field element_kind can be only one of the following:
"elementGroup": {
object (Group)
},
"shape": {
"shapeType": enum (Type),
"text": {
object (TextContent)
},
"shapeProperties": {
object (ShapeProperties)
},
"placeholder": {
object (Placeholder)
}
},
}
Once you have obtained the Shape object out of the response you get from presentations.pages.get, you will need to then create a CreateShapeRequest out of the retrieved properties:
{
"objectId": string,
"elementProperties": {
object (PageElementProperties)
},
"shapeType": enum (Type)
}
And a DeleteObjectRequest which can be used to remove the Shape on the previous slide:
{
"objectId": string
}
The DeleteObjectRequest and CreateShapeRequest can be both contained inside the same batchUpdate request. The request body should be of the form:
{
"requests": [
{
object (Request)
}
],
"writeControl": {
object (WriteControl)
}
}
The full documentation for the batchUpdate method can be seen here.
References:
Shapes | Slides API | Google Developers
REST Resource: presentations.pages | Slides API | Google Developers
Requests | Slides API | Google Developers
Method: presentations.batchUpdate | Slides API | Google Developers

Manage multiple highchart charts in a single webpage

I am having multiple highchart charts of various types(Bar,Pie, Scatter type) in a single web page. Currently I am creating config object for each graph like,
{
chart : {},
blah blah,
}
And feeding them to a custom function which will just call HighCharts.chart(). But this results in duplication of code. I want to manage all this chart rendering logic centrally.
Any Idea on how to do this?
You can use jQuery.extend() and Highcharts.setOptions.
So first you'll make the first object which will be extended by all your charts, this object will contain your Highchart default functions.
You can do it using namespacing.
The following way is good when you have very different charts.
Default graphic:
var defaultChart = {
chartContent: null,
highchart: null,
defaults: {
chart: {
alignTicks: false,
borderColor: '#656565',
borderWidth: 1,
zoomType: 'x',
height: 400,
width: 800
},
series: []
},
// here you'll merge the defauls with the object options
init: function(options) {
this.highchart= jQuery.extend({}, this.defaults, options);
this.highchart.chart.renderTo = this.chartContent;
},
create: function() {
new Highcharts.Chart(this.highchart);
}
};
Now, if you want to make a column chart, you'll extend defaultChart
var columnChart = {
chartContent: '#yourChartContent',
options: {
// your chart options
}
};
columnChart = jQuery.extend(true, {}, defaultChart, columnChart);
// now columnChart has all defaultChart functions
// now you'll init the object with your chart options
columnChart.init(columnChart.options);
// when you want to create the chart you just call
columnChart.create();
If you have similar charts use Highcharts.setOptions which will apply the options for all created charts after this.
// `options` will be used by all charts
Highcharts.setOptions(options);
// only data options
var chart1 = Highcharts.Chart({
chart: {
renderTo: 'container1'
},
series: []
});
var chart2 = Highcharts.Chart({
chart: {
renderTo: 'container2'
},
series: []
});
Reference
http://api.highcharts.com/highcharts#Highcharts.setOptions%28%29
COMPLETE DEMO
I know this has already been answered, but I feel that it can be taken yet further. I'm still newish to JavaScript and jQuery, so if anyone finds anything wrong, or thinks that this approach breaks guidelines or rules-of-thumb of some kind, I'd be grateful for feedback.
Building on the principles described by Ricardo Lohmann, I've created a jQuery plugin, which (in my opinion) allows Highcharts to work more seamlessly with jQuery (i.e. the way that jQuery works with other HTML objects).
I've never liked the fact that you have to supply an object ID to Highcharts before it draws the chart. So with the plug-in, I can assign the chart to the standard jQuery selector object, without having to give the containing <div> an id value.
(function($){
var chartType = {
myArea : {
chart: { type: 'area' },
title: { text: 'Example Line Chart' },
xAxis: { /* xAxis settings... */ },
yAxis: { /* yAxis settings... */ },
/* etc. */
series: []
},
myColumn : {
chart: { type: 'column' },
title: { text: 'Example Column Chart' },
xAxis: { /* xAxis settings... */ },
yAxis: { /* yAxis settings... */ },
/* etc. */
series: []
}
};
var methods = {
init:
function (chartName, options) {
return this.each(function(i) {
optsThis = options[i];
chartType[chartName].chart.renderTo = this;
optsHighchart = $.extend (true, {}, chartType[chartName], optsThis);
new Highcharts.Chart (optsHighchart);
});
}
};
$.fn.cbhChart = function (action,objSettings) {
if ( chartType[action] ) {
return methods.init.apply( this, arguments );
} else if ( methods[action] ) {
return methods[method].apply(this,Array.prototype.slice.call(arguments,1));
} else if ( typeof action === 'object' || !action ) {
$.error( 'Invalid arguments to plugin: jQuery.cbhChart' );
} else {
$.error( 'Action "' + action + '" does not exist on jQuery.cbhChart' );
}
};
})(jQuery);
With this plug-in, I can now assign a chart as follows:
$('.columnChart').cbhChart('myColumn', optionsArray);
This is a simplistic example of course; for a real example, you'd have to create more complex chart-properties. But it's the principles that concern us here, and I find that this approach addresses the original question. It re-uses code, while still allowing for individual chart alterations to be applied progressively on top of each other.
In principle, it also allows you to group together multiple Ajax calls into one, pushing each graph's options and data into a single JavaScript array.
The obligatory jFiddle example is here: http://jsfiddle.net/3GYHg/1/
Criticism welcome!!
To add to #Ricardo's great answer, I have also done something very similar. In fact, I won't be wrong if i said I went a step further than this. Hence would like to share the approach.
I have created a wrapper over the highchart library. This gives multiple benefits, following being the main advantages that encouraged going in this path
Decoupling: Decouples your code from highcharts
Easy Upgrades: This wrapper will be the only code that will require modification in case of any breaking changes in highchart api after upgrades, or even if one decides to move to a differnt charting library altogether (even from highchart to highstock can be exhaustive if your application uses charts extensively)
Easy of use: The wrapper api is kept very simple, only things that may vary are exposed as options (That too whose values won't be as a deep js object like HC already has, mostly 1 level deep), each having a default value. So most of the time our chart creation is very short, with the constructor taking 1 options object with merely 4-5 properties whose defaults don't suit the chart under creation
Consistent UX: Consistent look & feel across the application. eg: tool tip format & position, colors, font family, colors, toolbar (exporting) buttons, etc
Avoid duplication: Of course as a valid answer of the asked question it has to avoid duplication, and it does to a huge extent
Here is what the options look like with their default values
defaults : {
chartType : "line",
startTime : 0,
interval : 1000,
chartData : [],
title : "Product Name",
navigator : true,
legends : true,
presetTimeRanges : [],
primaryToolbarButtons : true,
secondaryToolbarButtons : true,
zoomX : true,
zoomY : false,
height : null,
width : null,
panning : false,
reflow : false,
yDecimals : 2,
container : "container",
allowFullScreen : true,
credits : false,
showAll : false,
fontSize : "normal", // other option available is "small"
showBtnsInNewTab : false,
xAxisTitle : null,
yAxisTitle : null,
onLoad : null,
pointMarkers : false,
categories : []
}
As you can see, most of the times, its just chartData that changes. Even if you need to set some property, its mainly just true/false types, nothing like the horror that highchart constructor expects (not critizing them, the amount of options they provide is just amazing from customization Point of View, but for every developer in the team to understand & master it can take some time)
So creation of chart is as simple as
var chart=new myLib.Chart({
chartData : [[1000000,1],[2000000,2],[3000000,1],[4000000,5]]
});

Resources