Google Sheets API batch update updateChartSpec does not update right axis viewWindowMax - google-sheets-api

What I really want is a combo chart where right axis and left axis have the same viewWindowMax which is the one that will let all the data in the chart.
For this, I try to get the highest of the 2 and set both of them to that max.
batchUpdate of a chart in google sheets requires to update the whole chart["spec"] with updateChartSpec. I have test cases where I set viewWindowMax to a hardcoded arbitrary number. It updates properly the left axis, but the left axis goes back to a default condition with an empty viewWindowOptions even if it did have some other value before the update. IE I get this result with no error message:
{'position': 'LEFT_AXIS', 'viewWindowOptions': {'viewWindowMin': 0, 'viewWindowMax': 40, 'viewWindowMode': 'PRETTY'}}, {'position': 'RIGHT_AXIS', 'viewWindowOptions': {}}
when in the request it was like so:
{'position': 'LEFT_AXIS', 'viewWindowOptions': {'viewWindowMin': 0, 'viewWindowMax': 40, 'viewWindowMode': 'PRETTY'}}, {'position': 'RIGHT_AXIS', 'viewWindowOptions': {'viewWindowMin': 0, 'viewWindowMax': 40}}
removing the 'PRETTY' thing or adding it changes nothing.
Full request code looks like this:
requests = [
{
"updateChartSpec": {
"chartId": chart['chartId'],
"spec": spec
}
}
]
body = {
'requests': requests
}
response = build('sheets', 'v4', credentials=creds.credentials).spreadsheets().batchUpdate(
spreadsheetId=spreadsheet_id, body=body).execute()
with spec variable =
{'title': 'Tickets Opened and Closed', 'basicChart': {'chartType': 'COMBO', 'legendPosition': 'BOTTOM_LEGEND', 'axis': [{'position': 'BOTTOM_AXIS', 'viewWindowOptions': {}}, {'position': 'LEFT_AXIS', 'viewWindowOptions': {'viewWindowMin': 0, 'viewWindowMax': 40, 'viewWindowMode': 'PRETTY'}}, {'position': 'RIGHT_AXIS', 'viewWindowOptions': {'viewWindowMin': 0, 'viewWindowMax': 40}}], 'domains': [{'domain': {'sourceRange': {'sources': [{'sheetId': 1666134379, 'startRowIndex': 0, 'endRowIndex': 14, 'startColumnIndex': 0, 'endColumnIndex': 1}]}}}], 'series': [{'series': {'sourceRange': {'sources': [{'sheetId': 1666134379, 'startRowIndex': 0, 'endRowIndex': 14, 'startColumnIndex': 1, 'endColumnIndex': 2}]}}, 'targetAxis': 'LEFT_AXIS', 'type': 'COLUMN', 'color': {'red': 1}, 'colorStyle': {'rgbColor': {'red': 1}}}, {'series': {'sourceRange': {'sources': [{'sheetId': 1666134379, 'startRowIndex': 0, 'endRowIndex': 14, 'startColumnIndex': 2, 'endColumnIndex': 3}]}}, 'targetAxis': 'LEFT_AXIS', 'type': 'COLUMN', 'color': {'red': 1, 'green': 0.42745098, 'blue': 0.003921569}, 'colorStyle': {'themeColor': 'ACCENT5'}}, {'series': {'sourceRange': {'sources': [{'sheetId': 1666134379, 'startRowIndex': 0, 'endRowIndex': 14, 'startColumnIndex': 3, 'endColumnIndex': 4}]}}, 'targetAxis': 'LEFT_AXIS', 'type': 'COLUMN', 'color': {'red': 0.9764706, 'green': 0.79607844, 'blue': 0.6117647}, 'colorStyle': {'rgbColor': {'red': 0.9764706, 'green': 0.79607844, 'blue': 0.6117647}}}, {'series': {'sourceRange': {'sources': [{'sheetId': 1666134379, 'startRowIndex': 0, 'endRowIndex': 14, 'startColumnIndex': 4, 'endColumnIndex': 5}]}}, 'targetAxis': 'LEFT_AXIS', 'type': 'COLUMN'}, {'series': {'sourceRange': {'sources': [{'sheetId': 1666134379, 'startRowIndex': 0, 'endRowIndex': 14, 'startColumnIndex': 5, 'endColumnIndex': 6}]}}, 'targetAxis': 'RIGHT_AXIS', 'type': 'COLUMN', 'color': {'red': 1}, 'colorStyle': {'rgbColor': {'red': 1}}}, {'series': {'sourceRange': {'sources': [{'sheetId': 1666134379, 'startRowIndex': 0, 'endRowIndex': 14, 'startColumnIndex': 6, 'endColumnIndex': 7}]}}, 'targetAxis': 'RIGHT_AXIS', 'type': 'COLUMN', 'color': {'red': 1, 'green': 0.42745098, 'blue': 0.003921569}, 'colorStyle': {'themeColor': 'ACCENT5'}}, {'series': {'sourceRange': {'sources': [{'sheetId': 1666134379, 'startRowIndex': 0, 'endRowIndex': 14, 'startColumnIndex': 7, 'endColumnIndex': 8}]}}, 'targetAxis': 'RIGHT_AXIS', 'type': 'COLUMN', 'color': {'red': 0.9764706, 'green': 0.79607844, 'blue': 0.6117647}, 'colorStyle': {'rgbColor': {'red': 0.9764706, 'green': 0.79607844, 'blue': 0.6117647}}}, {'series': {'sourceRange': {'sources': [{'sheetId': 1666134379, 'startRowIndex': 0, 'endRowIndex': 14, 'startColumnIndex': 8, 'endColumnIndex': 9}]}}, 'targetAxis': 'RIGHT_AXIS', 'type': 'COLUMN', 'color': {'red': 0.20392157, 'green': 0.65882355, 'blue': 0.3254902}, 'colorStyle': {'themeColor': 'ACCENT4'}}, {'series': {'sourceRange': {'sources': [{'sheetId': 1666134379, 'startRowIndex': 0, 'endRowIndex': 14, 'startColumnIndex': 9, 'endColumnIndex': 10}]}}, 'targetAxis': 'LEFT_AXIS', 'type': 'LINE', 'color': {}, 'colorStyle': {'themeColor': 'TEXT'}}], 'headerCount': 1, 'stackedType': 'STACKED'}, 'hiddenDimensionStrategy': 'SKIP_HIDDEN_ROWS_AND_COLUMNS', 'titleTextFormat': {'fontFamily': 'Roboto'}, 'fontName': 'Roboto'}

I took the liberty to report this behavior here: https://issuetracker.google.com/151918491

Related

Echarts draw a circle with dashed border on the geo map

I don't know how to convert the unit of the cirle radius, now it's meters but I need to convert it into pixel.
I also want to know how to make the border of the circle become dashed border, like the picture (the circle with the white dashed border)
Here is the code.
const map_data = [];
const current_map_data = [];
this.current_map = this.$echarts.init(document.getElementById('map_id'));
this.$echarts.registerMap('my_map', map_data);
const typhoon_points = [
{name: 0, value: [124.36, 23, 6]},
{name: 1, value: [122, 23.8, 6]},
{name: 2, value: [120, 24.4, 6]},
{name: 3, value: [118.5, 24.8, 6]},
{name: 4, value: [117.2, 25.5, 6]}
];
const typhoon_lines = [
{"point": [0, 1], "coords": [[124.36,23], [122, 23.8]]},
{"point": [1, 2], "coords": [[122, 23.8], [120, 24.4]]},
{"point": [2, 3], "coords": [[120, 24.4], [118.5, 24.8]]},
{"point": [3, 4], "coords": [[118.5, 24.8], [117.2,25.5]]},
];
const option = {
geo: [{
map: map_name,
roam: 'move',
boundingCoords:[ [118, 26.5], [122.4,21.5] ],
center: center,
layoutCenter: ['50%', '50%'],
aspectScale: 1,
scaleLimit: { min: 1.6, max: 12.0 },
left: '0%',
zoom: zoom,
itemStyle: {
areaColor: 'none',
borderColor : '#999',
borderWidth: 1,
emphasis: {
areaColor: 'inherit',
},
},
}],
series: [{
selectedMode: false,
name: 'current_map',
type: 'map',
geoIndex: 0,
data: current_map_data,
zlevel: 3
}, {
name: "",
type: "lines",
zlevel: 6,
lineStyle: {
type: 'solid',
width: 1,
opacity: 1,
curveness: 0,
orient: 'horizontal',
color: "#000",
},
data: typhoon_lines,
}, {
name: '',
type: 'scatter',
coordinateSystem: 'geo',
color: ['#000'],
itemStyle: {
borderType: 'dashed', // it's not working
borderWidth: 50, // The unit of the symbol size is pixel, I need to convert it into pixel.
borderColor: 'green',
color: '#000',
},
data: typhoon_points,
}],
};
I created a line & circle layer into series, but I don't know how to change the border style and the unit of the symbol size (I think it's the radius of the circle)

How to select (Highlight) each mapped item on Click in React Native

I have an Array of Strings that I have mapped using the Map funtion and rendered a Text with each item. Now if I click any mapped Text I want to highlight that clicked Text. Moreover, I want to keep on highlighting the next Text after some delay and so on.
How to do it efficiently? So far I have witten the following code and I am able to Highlight the clicked text with the help of an extra style based on the selected page and index clicked. Now I want to have to select the next mapped item automatically after some delay.
function QiratContainer() {
const [selectedIndex, setSelectedIndex] = useState<any>(2)
const [selectedPage, setSelectedPage] = useState<number>(1)
return (
<SafeAreaView >
<FlatList
data={quranData}
showsVerticalScrollIndicator={false}
renderItem={({ item, index }) => (
<View style={styles.pageContainer}>
<PageHeader surahName={item.firstSurahName} juzzNumber={item.juz} />
<View style={{ flex: 1 }}>
{item.ayahs.map((ayah: any, index: any) => (
<>
{ayah.name !== undefined &&
<SurahHeader ayah={ayah} />
}
<Text onPress={() => playAyah(ayah, index)} style={[styles.ayahStyle, selectedIndex === index && selectedPage === ayah?.page && styles.selectedAyah]}>{ayah?.text?.replace("بِسْمِ اللَّهِ الرَّحْمَٰنِ الرَّحِيمِ", "")}</Text>
</>
))}
</View>
<PageFooter pageNumber={item.page} />
</View>
)}
/>
</SafeAreaView>
)
function playAyah(ayah: any, index: any) {
console.log(ayah.audio)
//Setting the Selected Index and the specific page of that index to highlight the selected ayah...
console.log(index)
// console.log(ayah.page)
setSelectedIndex(index)
setSelectedAyah(ayah)
}
}
const styles = StyleSheet.create({
ayahStyle: {
fontSize: 24,
fontWeight: 'bold',
marginVertical: 8,
color: 'black'
},
selectedAyah: {
backgroundColor: 'grey'
},
pageContainer: {
width: width,
height: height - 20,
},
})
Following is my JSON Array that is used in the FlatList and Map
[
{
"juz": 1,
"page": 1,
"firstSurahName": "سورة الفاتحة",
"ayahs": [
{
"number": 1,
"name": "سورة الفاتحة",
"englishName": "Al-Faatiha",
"englishNameTranslation": "The Opening",
"revelationType": "Meccan",
"numberInPage": 0,
"ayahsNumber": 7
},
{
"number": 1,
"text": "بِسْمِ اللَّهِ الرَّحْمَٰنِ الرَّحِيمِ",
"numberInSurah": 1,
"juz": 1,
"page": 1,
"hizbQuarter": 1,
"ayahsNumber": 7,
"surahNumber": 1,
"numberInPage": 1,
"audio": "https://everyayah.com/data/ahmed_ibn_ali_al_ajamy_128kbps/001001.mp3"
},
{
"number": 2,
"text": "الْحَمْدُ لِلَّهِ رَبِّ الْعَالَمِينَ",
"numberInSurah": 2,
"juz": 1,
"page": 1,
"hizbQuarter": 1,
"ayahsNumber": 7,
"surahNumber": 1,
"numberInPage": 2,
"audio": "https://everyayah.com/data/ahmed_ibn_ali_al_ajamy_128kbps/001002.mp3"
},
{
"number": 3,
"text": "الرَّحْمَٰنِ الرَّحِيمِ",
"numberInSurah": 3,
"juz": 1,
"page": 1,
"hizbQuarter": 1,
"ayahsNumber": 7,
"surahNumber": 1,
"numberInPage": 3,
"audio": "https://everyayah.com/data/ahmed_ibn_ali_al_ajamy_128kbps/001003.mp3"
},
{
"number": 4,
"text": "مَالِكِ يَوْمِ الدِّينِ",
"numberInSurah": 4,
"juz": 1,
"page": 1,
"hizbQuarter": 1,
"ayahsNumber": 7,
"surahNumber": 1,
"numberInPage": 4,
"audio": "https://everyayah.com/data/ahmed_ibn_ali_al_ajamy_128kbps/001004.mp3"
},
{
"number": 5,
"text": "إِيَّاكَ نَعْبُدُ وَإِيَّاكَ نَسْتَعِينُ",
"numberInSurah": 5,
"juz": 1,
"page": 1,
"hizbQuarter": 1,
"ayahsNumber": 7,
"surahNumber": 1,
"numberInPage": 5,
"audio": "https://everyayah.com/data/ahmed_ibn_ali_al_ajamy_128kbps/001005.mp3"
},
{
"number": 6,
"text": "اهْدِنَا الصِّرَاطَ الْمُسْتَقِيمَ",
"numberInSurah": 6,
"juz": 1,
"page": 1,
"hizbQuarter": 1,
"ayahsNumber": 7,
"surahNumber": 1,
"numberInPage": 6,
"audio": "https://everyayah.com/data/ahmed_ibn_ali_al_ajamy_128kbps/001006.mp3"
},
{
"number": 7,
"text": "صِرَاطَ الَّذِينَ أَنْعَمْتَ عَلَيْهِمْ غَيْرِ الْمَغْضُوبِ عَلَيْهِمْ وَلَا الضَّالِّينَ",
"numberInSurah": 7,
"juz": 1,
"page": 1,
"hizbQuarter": 1,
"ayahsNumber": 7,
"surahNumber": 1,
"numberInPage": 7,
"audio": "https://everyayah.com/data/ahmed_ibn_ali_al_ajamy_128kbps/001007.mp3"
}
],
"number": 1,
"counter": 1
}
]
I always do this stuff by creating a state called "selected" and I save the ID of the selected .map child component in it.
In the .map children components I put classname={selected == id ? "cssSelected" : "cssNotSelected"}
And when I click on a .map child component: onClick={() => setSelected(id)}

Linear gradient in highcharts stockcharts according to full length date

Is there anywhere to make linear gradient on full date/year
https://jsfiddle.net/0712nw3g/64/
for example if i move/scroll the graph in 3 month zoom, color gradient should be the same as 1year/all
series: [{
type: 'line',
name: 'Volume',
id: 'stock',
data: volume,
yAxis: 0,
dataGrouping: {
units: groupingUnits
},
lineWidth: 10,
color: {
linearGradient: [0, 0, this.plotWidth, 0],
stops: [
[0, '#26A69A'],
[1, '#CE1510']
]
},
}
]
You can set the options xAxis.events.afterSetExtremes to modify the color gradient in the graph but the color in the navigator also changes.
https://jsfiddle.net/BlackLabel/j3ca7oyh/
Highcharts.getJSON('https://demo-live-data.highcharts.com/aapl-c.json', function(data) {
Highcharts.stockChart('container', {
xAxis: {
events: {
afterSetExtremes: function() {
const dataRange = this.dataMax - this.dataMin,
currentRange = this.max - this.min
this.series[0].update({
color: {
linearGradient: [0, 0, this.plotWidth, 0],
stops: [
[1 - currentRange / dataRange, 'blue'],
[1, 'yellow']
]
},
})
}
}
},
series: [{
name: 'AAPL',
data: data,
color: {
linearGradient: [0, 0, this.plotWidth, 0],
stops: [
[0, 'blue'],
[1, 'yellow']
]
},
}]
});
});
Another way will be adding a series inside the navigator and trying to calculate gradient color.
https://jsfiddle.net/BlackLabel/qLp61uft/
Highcharts.getJSON('https://demo-live-data.highcharts.com/aapl-c.json', function(data) {
Highcharts.stockChart('container', {
xAxis: {
events: {
afterSetExtremes: function() {
const dataRange = this.dataMax - this.dataMin,
currentRange = this.max - this.min
this.series[0].update({
color: {
linearGradient: [0, 0, this.plotWidth, 0],
stops: [
[0, 'red'],
[1, 'yellow']
]
},
})
}
}
},
navigator: {
series: {
name: 'AAPL',
data: data,
fillColor: {
linearGradient: [0, 0, this.plotWidth, 0],
stops: [
[0, 'blue'],
[1, 'yellow']
]
},
}
},
series: [{
name: 'AAPL',
data: data,
color: {
linearGradient: [0, 0, this.plotWidth, 0],
stops: [
[0, 'blue'],
[1, 'yellow']
]
},
}]
});
});

Select bands in ee.ImageCollection.toBands()

Using Colab, I am trying to compute an index (e.g., NDVI), but I'd like to improve the selection of the bands from ee.ImageCollection.toBands().
I am using the exact names to call the bands from the stack, but I’d like to use the band's position in the stack or another way.
Is there any possibility?
geometry = ee.Geometry.Polygon([-42.68383865527343,-14.294442457842383,-42.64263992480468,-14.294442457842383,-42.64263992480468,-14.259340569775649,-42.68383865527343,-14.259340569775649,-42.68383865527343,-14.294442457842383])
img_colec = ee.ImageCollection("COPERNICUS/S2_SR")\
.filterDate("2019-03-07", "2019-03-17")\
.select("B8","B4","B2")\
.filterBounds(geometry)
composite = img_colec.toBands()
index = composite.normalizedDifference(['20190313T131241_20190313T131238_T23LQE_B2','20190313T131241_20190313T131238_T23LQE_B4'])
The composite is like that:
{'bands': [{'crs': 'EPSG:32723',
'crs_transform': [10, 0, 699960, 0, -10, 8500000],
'data_type': {'max': 65535,
'min': 0,
'precision': 'int',
'type': 'PixelType'},
'dimensions': [10980, 10980],
'id': '20190308T131239_20190308T131240_T23LQE_B8'},
{'crs': 'EPSG:32723',
'crs_transform': [10, 0, 699960, 0, -10, 8500000],
'data_type': {'max': 65535,
'min': 0,
'precision': 'int',
'type': 'PixelType'},
'dimensions': [10980, 10980],
'id': '20190308T131239_20190308T131240_T23LQE_B4'},
{'crs': 'EPSG:32723',
'crs_transform': [10, 0, 699960, 0, -10, 8500000],
'data_type': {'max': 65535,
'min': 0,
'precision': 'int',
'type': 'PixelType'},
'dimensions': [10980, 10980],
'id': '20190308T131239_20190308T131240_T23LQE_B2'},
{'crs': 'EPSG:32723',
'crs_transform': [10, 0, 699960, 0, -10, 8500000],
'data_type': {'max': 65535,
'min': 0,
'precision': 'int',
'type': 'PixelType'},
'dimensions': [10980, 10980],
'id': '20190313T131241_20190313T131238_T23LQE_B8'},
{'crs': 'EPSG:32723',
'crs_transform': [10, 0, 699960, 0, -10, 8500000],
'data_type': {'max': 65535,
'min': 0,
'precision': 'int',
'type': 'PixelType'},
'dimensions': [10980, 10980],
'id': '20190313T131241_20190313T131238_T23LQE_B4'},
{'crs': 'EPSG:32723',
'crs_transform': [10, 0, 699960, 0, -10, 8500000],
'data_type': {'max': 65535,
'min': 0,
'precision': 'int',
'type': 'PixelType'},
'dimensions': [10980, 10980],
'id': '20190313T131241_20190313T131238_T23LQE_B2'}],
'type': 'Image'}

Vue-apexcharts toolbar : selection tool not working

I created a line graph with vue apexcharts and I'm trying to enable the selection tool in the toolbar (as explain here :https://apexcharts.com/docs/options/chart/toolbar/ )
But even if I set :
selection: true,
It doesn't appear on the graph.
Here is my vue component :
<template>
<div class="container">
<apexchart :type="typechart" height="350" :options="options" :series="series"></apexchart>
</div>
</template>
<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
import VueApexCharts from "vue-apexcharts";
Vue.component("apexchart", VueApexCharts);
#Component({
components: { MyPlot }
})
export default class MyPlot extends Vue {
witdhgraph: string = "500";
typechart: string = "line";
options: any = {
chart: {
id: "vuechart-example",
toolbar: {
show: true,
offsetX: 0,
offsetY: 0,
tools: {
download: true,
selection: true,
zoom: true,
zoomin: true,
zoomout: true,
pan: true
}
},
autoSelected: "selection"
},
stroke: {
curve: "smooth"
},
colors: ["#00205b"],
xaxis: {
type: "numeric",
categories: [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49
]
},
annotations: {
position: "back",
xaxis: [
{
x: 28,
x2: 32,
strokeDashArray: 1,
borderColor: "#c2c2c2",
fillColor: "#c2c2c2",
opacity: 0.3,
offsetX: 0,
offsetY: 0,
label: {
borderColor: "#c2c2c2",
borderWidth: 1,
borderRadius: 2,
text: "test ",
textAnchor: "middle",
position: "top",
orientation: "horizontal",
offsetX: 0,
offsetY: 0,
style: {
background: "#fff",
color: "#777",
fontSize: "12px",
fontWeight: 400,
fontFamily: undefined,
cssClass: "apexcharts-xaxis-annotation-label"
}
}
}
]
}
};
series: any = [
{
name: "series-1",
data: [
67,
93,
4,
39,
31,
62,
39,
4,
63,
51,
28,
73,
75,
80,
47,
17,
6,
55,
36,
18,
85,
64,
99,
21,
100,
14,
18,
12,
70,
44,
44,
87,
8,
37,
72,
67,
20,
7,
5,
33,
36,
41,
30,
30,
88,
31,
47,
77,
74,
35
]
}
];
}
</script>
You also need to enable
chart: {
selection: {
enabled: true
}
}
This was not mentioned in the docs which have been corrected now: https://apexcharts.com/docs/options/chart/toolbar/#selection