diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..379b59a Binary files /dev/null and b/.DS_Store differ diff --git a/src/HelloWorld.js b/src/HelloWorld.js index 828d7e1..d8f69bf 100644 --- a/src/HelloWorld.js +++ b/src/HelloWorld.js @@ -23,10 +23,18 @@ */ import React, { useEffect, useState, useContext, useCallback } from 'react' -import { ComponentsProvider, Card, CardContent, Flex, FlexItem, Tree, TreeItem, Space, SpaceVertical, Heading} from '@looker/components' +import { + ComponentsProvider, + Card, CardContent, + Flex, FlexItem, + Tree, TreeItem, + Space, SpaceVertical, + Heading, ToggleSwitch + } from '@looker/components' import { ExtensionContext } from '@looker/extension-sdk-react' -import { LookerEmbedSDK, LookerEmbedLook } from '@looker/embed-sdk' +import { LookerEmbedSDK } from '@looker/embed-sdk' import styled from "styled-components" +import { paddingBottom } from 'styled-system' const EmbedContainer = styled.div` width: 100%; @@ -40,8 +48,12 @@ export const HelloWorld = () => { const { core40SDK, extensionSDK } = useContext(ExtensionContext) const [qid, setQid] = useState(); const [geos, setGeos] = useState(); + const [state, setState] = useState(); + const [explore, setExplore] = useState(); + const [on, setOn] = React.useState(false) + - useEffect(() => { +useEffect(() => { const initialize = async () => { try { const states = await core40SDK.ok(core40SDK.run_inline_query( @@ -60,7 +72,7 @@ export const HelloWorld = () => { )) setGeos( states.map((state )=>{ - return { getQid(state['users.state']) }} icon="FieldLocation"> + return { setState(state['users.state']) }} icon="FieldLocation"> {state['users.state']} }) @@ -72,10 +84,22 @@ export const HelloWorld = () => { getQid('California') initialize() },[]) - const getQid = async (state) => { + +//Listens for changes in the state variable (which changes onclick of the tree) and updates the embed query filters +useEffect(() => { + if (state && explore) { + explore.updateFilters({'users.state': state}) + explore.run() + } + } +, [state]) + +/* +Uses the state variable to call Looker's API and get a new qid. +Also internally uses the `on` variable to determine the measure field visualized +*/ +const getQid = async (state) => { let visconfig = { - "series_types": {}, - "type": "looker_map", "map_plot_mode": "points", "heatmap_gridlines": false, "heatmap_gridlines_empty": false, @@ -83,7 +107,7 @@ export const HelloWorld = () => { "show_region_field": true, "draw_map_labels_above_data": true, "map_tile_provider": "light", - "map_position": "fit_data", + "map_zoom": 6, "map_scale_indicator": "off", "map_pannable": true, "map_zoomable": true, @@ -92,56 +116,114 @@ export const HelloWorld = () => { "map_marker_radius_mode": "proportional_value", "map_marker_units": "meters", "map_marker_proportional_scale_type": "linear", - "map_marker_color_mode": "fixed", + "map_marker_color_mode": "value", "show_view_names": false, "show_legend": true, "quantize_map_value_colors": false, "reverse_map_value_colors": false, - "defaults_version": 1 + "type": "looker_map", + "x_axis_gridlines": false, + "y_axis_gridlines": true, + "show_y_axis_labels": true, + "show_y_axis_ticks": true, + "y_axis_tick_density": "default", + "y_axis_tick_density_custom": 5, + "show_x_axis_label": true, + "show_x_axis_ticks": true, + "y_axis_scale_mode": "linear", + "x_axis_reversed": false, + "y_axis_reversed": false, + "plot_size_by_field": false, + "trellis": "", + "stacking": "", + "limit_displayed_rows": false, + "legend_position": "center", + "point_style": "none", + "show_value_labels": false, + "label_density": 25, + "x_axis_scale": "auto", + "y_axis_combined": true, + "ordering": "none", + "show_null_labels": false, + "show_totals_labels": false, + "show_silhouette": false, + "totals_color": "#808080", + "defaults_version": 1, + "hidden_fields": [ + "users.id" + ], + "series_types": {} } const response = await core40SDK.ok( core40SDK.create_query({ view:'order_items', model:'join20', - fields:['users.location', 'order_items.count'], + fields: [ + on ? "order_items.total_profit" : "order_items.count", + "users.location", + "users.id" + ], filters:{'users.state':state}, + sorts:['order_items.total_profit desc'], vis_config: visconfig }) ) setQid(response.client_id) } - const embedCtrRef = useCallback((el) => { - const hostUrl = extensionSDK.lookerHostData.hostUrl - if (el && hostUrl && qid) { - el.innerHTML = '' - LookerEmbedSDK.init(hostUrl) - LookerEmbedSDK.createExploreWithUrl(`${hostUrl}/embed/query/join20/order_items?qid=${qid}&sdk=2&embed_domain=${hostUrl}&sandboxed_host=true`) - .appendTo(el) - .on('drillmenu:click',(e) => {console.log(e)}) - .build() - .connect() - .then() - .catch((error) => { - console.error('Connection error', error) - }) + +//Listens to the toggle switch `on` state variable and cyles the qid with the other measure +useEffect(() => { + const cycleQid = async () => { + if (state) { + getQid(state) } - },[qid]) + } + cycleQid() + } +, [on]) + +// Embed iframe builder, listens to changes in the qid (Which currently only changes on pageload) +const embedCtrRef = useCallback((el) => { + const hostUrl = extensionSDK.lookerHostData.hostUrl + if (el && hostUrl && qid) { + el.innerHTML = '' + LookerEmbedSDK.init(hostUrl) + LookerEmbedSDK.createExploreWithUrl(`${hostUrl}/embed/query/join20/order_items?qid=${qid}&sdk=2&embed_domain=${hostUrl}&sandboxed_host=true`) + .appendTo(el) + .on('drillmenu:click',(e) => {console.log(e)}) + .build() + .connect() + .then(setExplore) + .catch((error) => { + console.error('Connection error', error) + }) + } +},[qid]) return ( <> -
- State Sales Explorer - +
+ + + + Best Customers by Region + + + + - + {geos} +
+ By Volume setOn(event.target.checked)} on={on} id="switch" /> By Profit +