-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathcreate.go
More file actions
145 lines (122 loc) · 4.84 KB
/
create.go
File metadata and controls
145 lines (122 loc) · 4.84 KB
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package visualization
import (
"encoding/json"
"fmt"
"github.com/duneanalytics/cli/cmdutil"
"github.com/duneanalytics/cli/output"
"github.com/duneanalytics/duneapi-client-go/models"
"github.com/spf13/cobra"
)
func newCreateCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "Create a new visualization on an existing query",
Long: `Create a visualization attached to an existing saved query.
IMPORTANT: Visualizations can only be attached to saved (non-temporary) queries.
If you created the query with --temp, you must recreate it without --temp first.
The --options flag is required for a working visualization. Without proper options,
the visualization will fail to render. The options format depends on the
visualization type.
Visualization types: chart, table, counter, pivot, cohort, funnel, choropleth,
sankey, sunburst_sequence, word_cloud.
For chart type, set globalSeriesType to: column, line, area, scatter, or pie.
COUNTER (simplest — shows a single number):
--type counter --options '{
"counterColName": "<column>",
"rowNumber": 1,
"stringDecimal": 0,
"stringPrefix": "",
"stringSuffix": "",
"counterLabel": "My Label",
"coloredPositiveValues": false,
"coloredNegativeValues": false
}'
TABLE (displays query results as a table):
--type table --options '{
"itemsPerPage": 25,
"columns": [
{"name": "<column>", "title": "Display Name", "type": "normal",
"alignContent": "left", "isHidden": false}
]
}'
COLUMN/LINE/AREA/SCATTER CHART:
--type chart --options '{
"globalSeriesType": "line",
"sortX": true,
"legend": {"enabled": true},
"series": {"stacking": null},
"xAxis": {"title": {"text": "Date"}},
"yAxis": [{"title": {"text": "Value"}}],
"columnMapping": {"<x_column>": "x", "<y_column>": "y"},
"seriesOptions": {
"<y_column>": {"type": "line", "yAxis": 0, "zIndex": 0}
}
}'
PIE CHART:
--type chart --options '{
"globalSeriesType": "pie",
"sortX": true,
"showDataLabels": true,
"columnMapping": {"<category_column>": "x", "<value_column>": "y"},
"seriesOptions": {
"<value_column>": {"type": "pie", "yAxis": 0, "zIndex": 0}
}
}'
Column names in options must match actual query result columns exactly.
Examples:
# Counter showing row count
dune viz create --query-id 12345 --name "Total Count" --type counter \
--options '{"counterColName":"count","rowNumber":1,"stringDecimal":0}'
# Line chart of daily volume
dune viz create --query-id 12345 --name "Daily Volume" --type chart \
--options '{"globalSeriesType":"line","sortX":true,"columnMapping":{"day":"x","volume":"y"},"seriesOptions":{"volume":{"type":"line","yAxis":0,"zIndex":0}},"xAxis":{"title":{"text":"Day"}},"yAxis":[{"title":{"text":"Volume"}}],"legend":{"enabled":true},"series":{"stacking":null}}'
# Simple table
dune viz create --query-id 12345 --name "Results" --type table \
--options '{"itemsPerPage":25,"columns":[{"name":"address","title":"Address","type":"normal","alignContent":"left","isHidden":false},{"name":"balance","title":"Balance","type":"normal","alignContent":"right","isHidden":false}]}'`,
RunE: runCreate,
}
cmd.Flags().Int("query-id", 0, "ID of the query to attach the visualization to (required)")
cmd.Flags().String("name", "", "visualization name, max 300 characters (required)")
cmd.Flags().String("type", "table", "visualization type: chart, table, counter")
cmd.Flags().String("description", "", "visualization description, max 1000 characters")
cmd.Flags().String("options", "", `visualization options JSON (required for working visualizations, see --help for format per type)`)
_ = cmd.MarkFlagRequired("query-id")
_ = cmd.MarkFlagRequired("name")
_ = cmd.MarkFlagRequired("options")
output.AddFormatFlag(cmd, "text")
return cmd
}
func runCreate(cmd *cobra.Command, _ []string) error {
client := cmdutil.ClientFromCmd(cmd)
queryID, _ := cmd.Flags().GetInt("query-id")
name, _ := cmd.Flags().GetString("name")
vizType, _ := cmd.Flags().GetString("type")
description, _ := cmd.Flags().GetString("description")
optionsStr, _ := cmd.Flags().GetString("options")
var options map[string]any
if err := json.Unmarshal([]byte(optionsStr), &options); err != nil {
return fmt.Errorf("invalid --options JSON: %w", err)
}
resp, err := client.CreateVisualization(models.CreateVisualizationRequest{
QueryID: queryID,
Name: name,
Type: vizType,
Description: description,
Options: options,
})
if err != nil {
return err
}
url := fmt.Sprintf("https://dune.com/embeds/%d/%d", queryID, resp.ID)
w := cmd.OutOrStdout()
switch output.FormatFromCmd(cmd) {
case output.FormatJSON:
return output.PrintJSON(w, map[string]any{
"id": resp.ID,
"url": url,
})
default:
fmt.Fprintf(w, "Created visualization %d on query %d\n%s\n", resp.ID, queryID, url)
return nil
}
}