Skip to content

Commit

Permalink
feat: don't use temp tables so that we can use multiple connections
Browse files Browse the repository at this point in the history
  • Loading branch information
domoritz authored and jheer committed Oct 23, 2024
1 parent b0f3e09 commit be9f288
Show file tree
Hide file tree
Showing 33 changed files with 43 additions and 44 deletions.
2 changes: 1 addition & 1 deletion dev/bundle.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
setConnector();

const queries = [
`CREATE TEMP TABLE IF NOT EXISTS flights AS SELECT * FROM read_parquet('data/flights-200k.parquet')`,
`CREATE TABLE IF NOT EXISTS flights AS SELECT * FROM read_parquet('data/flights-200k.parquet')`,
`SELECT count(*) FROM "flights"`
]

Expand Down
2 changes: 1 addition & 1 deletion dev/query/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
} else {
await coordinator().exec(
`DROP TABLE IF EXISTS ${tableName};
CREATE TEMP TABLE ${tableName} AS ${input.value}`
CREATE TABLE ${tableName} AS ${input.value}`
);
coordinator.clear({ catalog: true });
output.replaceChildren(vg.table({ from: tableName, height: 500 }));
Expand Down
10 changes: 5 additions & 5 deletions docs/api/sql/data-loading.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The supported _options_ are:

``` js
// Loads file.csv into the table "table1" with default options:
// CREATE TEMP TABLE IF NOT EXISTS table1 AS
// CREATE TABLE IF NOT EXISTS table1 AS
// SELECT *
// FROM read_csv('file.csv', auto_detect=true, sample_size=-1)
loadCSV("table1", "file.csv");
Expand All @@ -51,7 +51,7 @@ The supported _options_ are:

``` js
// Loads file.json into the table "table1" with default options:
// CREATE TEMP TABLE IF NOT EXISTS table1 AS
// CREATE TABLE IF NOT EXISTS table1 AS
// SELECT *
// FROM read_json('file.json', auto_detect=true, json_format='auto')
loadJSON("table1", "file.json");
Expand All @@ -75,7 +75,7 @@ The supported _options_ are:

```js
// Load named columns from a parquet file, filtered upon load:
// CREATE TEMP TABLE IF NOT EXISTS table1 AS
// CREATE TABLE IF NOT EXISTS table1 AS
// SELECT foo, bar, value
// FROM read_parquet('file.parquet')
// WHERE value > 1
Expand All @@ -99,7 +99,7 @@ The supported _options_ are:
- _replace_: A boolean flag (default `false`) indicating that the file contents should replace any existing table or view with the same name. The default behavior is to do nothing if a name conflict exists.

``` js
// CREATE TEMP TABLE IF NOT EXISTS table3 AS
// CREATE TABLE IF NOT EXISTS table3 AS
// (SELECT 1 AS "foo", 2 AS "bar") UNION ALL
// (SELECT 3 AS "foo", 4 AS "bar") UNION ALL ...
const q = loadObjects("table3", [
Expand Down Expand Up @@ -128,7 +128,7 @@ The supported _options_ are:

``` js
// Loads us-states.json into the table "table1":
// CREATE TEMP TABLE IF NOT EXISTS table1 AS
// CREATE TABLE IF NOT EXISTS table1 AS
// SELECT *
// FROM st_read('us-states.json', layer="states")
loadSpatial("table1", "us-states.json", "states");
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/weather.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# Seattle Weather

An interactive view of Seattles weather, including maximum temperature, amount of precipitation, and type of weather. By dragging on the scatter plot, you can see the proportion of days in that range that have sun, fog, drizzle, rain, or snow.
An interactive view of Seattle's weather, including maximum temperature, amount of precipitation, and type of weather. By dragging on the scatter plot, you can see the proportion of days in that range that have sun, fog, drizzle, rain, or snow.

<Example spec="/specs/yaml/weather.yaml" />

Expand Down
2 changes: 1 addition & 1 deletion docs/public/specs/esm/airline-travelers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
vg.loadParquet("travelers", "data/travelers.parquet"),
`CREATE TEMP TABLE IF NOT EXISTS endpoint AS SELECT * FROM travelers ORDER BY date DESC LIMIT 1`
`CREATE TABLE IF NOT EXISTS endpoint AS SELECT * FROM travelers ORDER BY date DESC LIMIT 1`
]);

export default vg.plot(
Expand Down
2 changes: 1 addition & 1 deletion docs/public/specs/esm/flights-10m.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
`CREATE TEMP TABLE IF NOT EXISTS flights10m AS SELECT GREATEST(-60, LEAST(ARR_DELAY, 180))::DOUBLE AS delay, DISTANCE AS distance, DEP_TIME AS time FROM 'https://idl.uw.edu/mosaic-datasets/data/flights-10m.parquet'`
`CREATE TABLE IF NOT EXISTS flights10m AS SELECT GREATEST(-60, LEAST(ARR_DELAY, 180))::DOUBLE AS delay, DISTANCE AS distance, DEP_TIME AS time FROM 'https://idl.uw.edu/mosaic-datasets/data/flights-10m.parquet'`
]);

const $brush = vg.Selection.crossfilter();
Expand Down
2 changes: 1 addition & 1 deletion docs/public/specs/esm/gaia.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
`CREATE TEMP TABLE IF NOT EXISTS gaia AS -- compute u and v with natural earth projection
`CREATE TABLE IF NOT EXISTS gaia AS -- compute u and v with natural earth projection
WITH prep AS (
SELECT
radians((-l + 540) % 360 - 180) AS lambda,
Expand Down
2 changes: 1 addition & 1 deletion docs/public/specs/esm/linear-regression-10m.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
`CREATE TEMP TABLE IF NOT EXISTS flights10m AS SELECT GREATEST(-60, LEAST(ARR_DELAY, 180))::DOUBLE AS delay, DISTANCE AS distance, DEP_TIME AS time FROM 'https://idl.uw.edu/mosaic-datasets/data/flights-10m.parquet'`
`CREATE TABLE IF NOT EXISTS flights10m AS SELECT GREATEST(-60, LEAST(ARR_DELAY, 180))::DOUBLE AS delay, DISTANCE AS distance, DEP_TIME AS time FROM 'https://idl.uw.edu/mosaic-datasets/data/flights-10m.parquet'`
]);

const $query = vg.Selection.intersect();
Expand Down
2 changes: 1 addition & 1 deletion docs/public/specs/esm/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
vg.loadParquet("stocks", "data/stocks.parquet"),
`CREATE TEMP TABLE IF NOT EXISTS labels AS SELECT MAX(Date) as Date, ARGMAX(Close, Date) AS Close, Symbol FROM stocks GROUP BY Symbol`
`CREATE TABLE IF NOT EXISTS labels AS SELECT MAX(Date) as Date, ARGMAX(Close, Date) AS Close, Symbol FROM stocks GROUP BY Symbol`
]);

const $point = vg.Param.value(new Date("2013-05-13"));
Expand Down
2 changes: 1 addition & 1 deletion docs/public/specs/esm/nyc-taxi-rides.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ await vg.coordinator().exec([
"ST_Transform(ST_Point(dropoff_latitude, dropoff_longitude), 'EPSG:4326', 'ESRI:102718') AS drop"
]
}),
`CREATE TEMP TABLE IF NOT EXISTS trips AS SELECT
`CREATE TABLE IF NOT EXISTS trips AS SELECT
(HOUR(datetime) + MINUTE(datetime)/60) AS time,
ST_X(pick) AS px, ST_Y(pick) AS py,
ST_X(drop) AS dx, ST_Y(drop) AS dy
Expand Down
2 changes: 1 addition & 1 deletion docs/public/specs/esm/unemployment.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ await vg.coordinator().exec([
vg.loadExtension("spatial"),
vg.loadSpatial("counties", "data/us-counties-10m.json", {layer: "counties"}),
vg.loadParquet("rates", "data/us-county-unemployment.parquet"),
`CREATE TEMP TABLE IF NOT EXISTS combined AS SELECT a.geom AS geom, b.rate AS rate FROM counties AS a, rates AS b WHERE a.id = b.id`
`CREATE TABLE IF NOT EXISTS combined AS SELECT a.geom AS geom, b.rate AS rate FROM counties AS a, rates AS b WHERE a.id = b.id`
]);

export default vg.vconcat(
Expand Down
2 changes: 1 addition & 1 deletion docs/public/specs/json/weather.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"meta": {
"title": "Seattle Weather",
"description": "An interactive view of Seattles weather, including maximum temperature, amount of precipitation, and type of weather. By dragging on the scatter plot, you can see the proportion of days in that range that have sun, fog, drizzle, rain, or snow.\n",
"description": "An interactive view of Seattle's weather, including maximum temperature, amount of precipitation, and type of weather. By dragging on the scatter plot, you can see the proportion of days in that range that have sun, fog, drizzle, rain, or snow.\n",
"credit": "Based on a [Vega-Lite/Altair example](https://vega.github.io/vega-lite/examples/interactive_seattle_weather.html) by Jake Vanderplas."
},
"data": {
Expand Down
2 changes: 1 addition & 1 deletion docs/public/specs/yaml/weather.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta:
title: Seattle Weather
description: >
An interactive view of Seattles weather, including maximum temperature, amount of precipitation, and type of weather.
An interactive view of Seattle's weather, including maximum temperature, amount of precipitation, and type of weather.
By dragging on the scatter plot, you can see the proportion of days in that range that have sun, fog, drizzle, rain, or snow.
credit: Based on a [Vega-Lite/Altair example](https://vega.github.io/vega-lite/examples/interactive_seattle_weather.html) by Jake Vanderplas.
data:
Expand Down
6 changes: 3 additions & 3 deletions docs/sql/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,13 @@ Data loading helpers generate query strings for loading data from external CSV,
import { loadCSV, loadParquet } from "@uwdata/mosaic-sql";

// Loads file.csv into the table "table1" with default options:
// CREATE TEMP TABLE IF NOT EXISTS table1 AS
// CREATE TABLE IF NOT EXISTS table1 AS
// SELECT *
// FROM read_csv('file.csv', auto_detect=true, sample_size=-1)
const q1 = loadCSV("table1", "file.csv");

// Load named columns from a parquet file, filtered upon load:
// CREATE TEMP TABLE IF NOT EXISTS table2 AS
// CREATE TABLE IF NOT EXISTS table2 AS
// SELECT foo, bar, value
// FROM read_parquet('file.parquet')
// WHERE value > 1
Expand All @@ -165,7 +165,7 @@ Meanwhile, the `loadObjects` method takes an array of JavaScript objects and gen
``` js
import { loadObjects } from "@uwdata/mosaic-sql";

// CREATE TEMP TABLE IF NOT EXISTS table3 AS
// CREATE TABLE IF NOT EXISTS table3 AS
// (SELECT 1 AS "foo", 2 AS "bar") UNION ALL
// (SELECT 3 AS "foo", 4 AS "bar") UNION ALL ...
const q = loadObjects("table3", [
Expand Down
2 changes: 1 addition & 1 deletion packages/duckdb-server-rust/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ async fn handle_post(

pub fn app() -> Result<Router> {
// Database and state setup
let db = ConnectionPool::new(":memory:", 1)?; // TODO: we can only use one connection since temp tables are scoped per connection
let db = ConnectionPool::new(":memory:", 10)?;
let cache = lru::LruCache::new(1000.try_into()?);

let state = Arc::new(AppState {
Expand Down
4 changes: 2 additions & 2 deletions packages/duckdb-server-rust/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ pub async fn load(
}
drop(cache_lock);

// Load precomputed temp tables into the database
// Load precomputed tables into the database
for table in &manifest.tables {
let file = bundle_dir.join(format!("{table}.parquet"));
db.execute(&format!(
"CREATE TEMP TABLE IF NOT EXISTS {} AS SELECT * FROM '{}'",
"CREATE TABLE IF NOT EXISTS {} AS SELECT * FROM '{}'",
table,
file.display()
))
Expand Down
2 changes: 1 addition & 1 deletion packages/duckdb-server-rust/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ async fn create_and_load_bundle() -> Result<()> {
let cache = &Mutex::new(lru::LruCache::new(10.try_into()?));

let queries = vec![
Query {sql: r#"CREATE TEMP TABLE IF NOT EXISTS flights AS SELECT * FROM read_parquet("data/flights-200k.parquet")"#.to_string(), alias: None},
Query {sql: r#"CREATE TABLE IF NOT EXISTS flights AS SELECT * FROM read_parquet("data/flights-200k.parquet")"#.to_string(), alias: None},
Query {sql: r#"SELECT count(*) FROM "flights""#.to_string(), alias: None},
];

Expand Down
4 changes: 2 additions & 2 deletions packages/duckdb-server/pkg/bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def load_bundle(con, cache, directory):
data = f.read()
cache[key] = ujson.loads(data) if json_file else data

# Load precomputed temp tables into the database
# Load precomputed tables into the database
for table in manifest["tables"]:
file = directory / f"{table}.parquet"
con.execute(f"CREATE TEMP TABLE IF NOT EXISTS {table} AS SELECT * FROM '{file}'")
con.execute(f"CREATE TABLE IF NOT EXISTS {table} AS SELECT * FROM '{file}'")
2 changes: 1 addition & 1 deletion packages/duckdb-server/pkg/tests/test_bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_bundle(bundle_dir):
con = duckdb.connect()

queries = [
'CREATE TEMP TABLE IF NOT EXISTS flights AS SELECT * FROM read_parquet("data/flights-200k.parquet")',
'CREATE TABLE IF NOT EXISTS flights AS SELECT * FROM read_parquet("data/flights-200k.parquet")',
'SELECT count(*) FROM "flights"',
]

Expand Down
4 changes: 2 additions & 2 deletions packages/duckdb/src/load/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ export async function loadBundle(db, cache, dir) {
cache.set(key, json ? JSON.parse(data) : data);
}

// load precomputed temp tables into the database
// load precomputed tables into the database
for (const table of manifest.tables) {
const file = path.resolve(dir, `${table}.parquet`);
await db.exec(`CREATE TEMP TABLE IF NOT EXISTS ${table} AS SELECT * FROM '${file}'`);
await db.exec(`CREATE TABLE IF NOT EXISTS ${table} AS SELECT * FROM '${file}'`);
}
}
2 changes: 1 addition & 1 deletion packages/duckdb/test/duckdb.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { loadJSON } from '../src/index.js';
describe('DuckDB', () => {
beforeAll(async () => {
const file = path.resolve(__dirname, '../../../data/penguins.csv');
await db.exec(`CREATE TEMP TABLE penguins AS SELECT * FROM '${file}'`);
await db.exec(`CREATE TABLE penguins AS SELECT * FROM '${file}'`);
});

afterAll(async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/sql/src/load/create.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export function create(name, query, {
replace = false,
temp = true,
temp = false,
view = false
} = {}) {
return 'CREATE'
Expand Down
5 changes: 2 additions & 3 deletions packages/sql/test/load.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ describe('loadCSV', () => {
where: 'colX > 5'
};
expect(loadCSV('table', 'data.csv', base)).toBe(
`CREATE TEMP TABLE IF NOT EXISTS table AS SELECT colA, colB FROM read_csv('data.csv', auto_detect=true, sample_size=-1) WHERE colX > 5`
`CREATE TABLE IF NOT EXISTS table AS SELECT colA, colB FROM read_csv('data.csv', auto_detect=true, sample_size=-1) WHERE colX > 5`
);

const ext = {
...base,
view: true,
temp: false,
replace: true
};
expect(loadCSV('table', 'data.csv', ext)).toBe(
Expand All @@ -33,7 +32,7 @@ describe('loadCSV', () => {
skip: 2
};
expect(loadCSV('table', 'data.csv', opt)).toBe(
`CREATE TEMP TABLE IF NOT EXISTS table AS SELECT * FROM read_csv('data.csv', auto_detect=false, sample_size=-1, all_varchar=true, columns={'line': 'VARCHAR'}, force_not_null=['line'], new_line='\\n', header=false, skip=2)`
`CREATE TABLE IF NOT EXISTS table AS SELECT * FROM read_csv('data.csv', auto_detect=false, sample_size=-1, all_varchar=true, columns={'line': 'VARCHAR'}, force_not_null=['line'], new_line='\\n', header=false, skip=2)`
);
});
});
2 changes: 1 addition & 1 deletion specs/esm/airline-travelers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
vg.loadParquet("travelers", "data/travelers.parquet"),
`CREATE TEMP TABLE IF NOT EXISTS endpoint AS SELECT * FROM travelers ORDER BY date DESC LIMIT 1`
`CREATE TABLE IF NOT EXISTS endpoint AS SELECT * FROM travelers ORDER BY date DESC LIMIT 1`
]);

export default vg.plot(
Expand Down
2 changes: 1 addition & 1 deletion specs/esm/flights-10m.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
`CREATE TEMP TABLE IF NOT EXISTS flights10m AS SELECT GREATEST(-60, LEAST(ARR_DELAY, 180))::DOUBLE AS delay, DISTANCE AS distance, DEP_TIME AS time FROM 'https://idl.uw.edu/mosaic-datasets/data/flights-10m.parquet'`
`CREATE TABLE IF NOT EXISTS flights10m AS SELECT GREATEST(-60, LEAST(ARR_DELAY, 180))::DOUBLE AS delay, DISTANCE AS distance, DEP_TIME AS time FROM 'https://idl.uw.edu/mosaic-datasets/data/flights-10m.parquet'`
]);

const $brush = vg.Selection.crossfilter();
Expand Down
2 changes: 1 addition & 1 deletion specs/esm/gaia.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
`CREATE TEMP TABLE IF NOT EXISTS gaia AS -- compute u and v with natural earth projection
`CREATE TABLE IF NOT EXISTS gaia AS -- compute u and v with natural earth projection
WITH prep AS (
SELECT
radians((-l + 540) % 360 - 180) AS lambda,
Expand Down
2 changes: 1 addition & 1 deletion specs/esm/linear-regression-10m.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
`CREATE TEMP TABLE IF NOT EXISTS flights10m AS SELECT GREATEST(-60, LEAST(ARR_DELAY, 180))::DOUBLE AS delay, DISTANCE AS distance, DEP_TIME AS time FROM 'https://idl.uw.edu/mosaic-datasets/data/flights-10m.parquet'`
`CREATE TABLE IF NOT EXISTS flights10m AS SELECT GREATEST(-60, LEAST(ARR_DELAY, 180))::DOUBLE AS delay, DISTANCE AS distance, DEP_TIME AS time FROM 'https://idl.uw.edu/mosaic-datasets/data/flights-10m.parquet'`
]);

const $query = vg.Selection.intersect();
Expand Down
2 changes: 1 addition & 1 deletion specs/esm/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
vg.loadParquet("stocks", "data/stocks.parquet"),
`CREATE TEMP TABLE IF NOT EXISTS labels AS SELECT MAX(Date) as Date, ARGMAX(Close, Date) AS Close, Symbol FROM stocks GROUP BY Symbol`
`CREATE TABLE IF NOT EXISTS labels AS SELECT MAX(Date) as Date, ARGMAX(Close, Date) AS Close, Symbol FROM stocks GROUP BY Symbol`
]);

const $point = vg.Param.value(new Date("2013-05-13"));
Expand Down
2 changes: 1 addition & 1 deletion specs/esm/nyc-taxi-rides.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ await vg.coordinator().exec([
"ST_Transform(ST_Point(dropoff_latitude, dropoff_longitude), 'EPSG:4326', 'ESRI:102718') AS drop"
]
}),
`CREATE TEMP TABLE IF NOT EXISTS trips AS SELECT
`CREATE TABLE IF NOT EXISTS trips AS SELECT
(HOUR(datetime) + MINUTE(datetime)/60) AS time,
ST_X(pick) AS px, ST_Y(pick) AS py,
ST_X(drop) AS dx, ST_Y(drop) AS dy
Expand Down
2 changes: 1 addition & 1 deletion specs/esm/unemployment.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ await vg.coordinator().exec([
vg.loadExtension("spatial"),
vg.loadSpatial("counties", "data/us-counties-10m.json", {layer: "counties"}),
vg.loadParquet("rates", "data/us-county-unemployment.parquet"),
`CREATE TEMP TABLE IF NOT EXISTS combined AS SELECT a.geom AS geom, b.rate AS rate FROM counties AS a, rates AS b WHERE a.id = b.id`
`CREATE TABLE IF NOT EXISTS combined AS SELECT a.geom AS geom, b.rate AS rate FROM counties AS a, rates AS b WHERE a.id = b.id`
]);

export default vg.vconcat(
Expand Down
2 changes: 1 addition & 1 deletion specs/json/weather.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"meta": {
"title": "Seattle Weather",
"description": "An interactive view of Seattles weather, including maximum temperature, amount of precipitation, and type of weather. By dragging on the scatter plot, you can see the proportion of days in that range that have sun, fog, drizzle, rain, or snow.\n",
"description": "An interactive view of Seattle's weather, including maximum temperature, amount of precipitation, and type of weather. By dragging on the scatter plot, you can see the proportion of days in that range that have sun, fog, drizzle, rain, or snow.\n",
"credit": "Based on a [Vega-Lite/Altair example](https://vega.github.io/vega-lite/examples/interactive_seattle_weather.html) by Jake Vanderplas."
},
"data": {
Expand Down
2 changes: 1 addition & 1 deletion specs/ts/weather.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Spec } from '@uwdata/mosaic-spec';
export const spec : Spec = {
"meta": {
"title": "Seattle Weather",
"description": "An interactive view of Seattles weather, including maximum temperature, amount of precipitation, and type of weather. By dragging on the scatter plot, you can see the proportion of days in that range that have sun, fog, drizzle, rain, or snow.\n",
"description": "An interactive view of Seattle's weather, including maximum temperature, amount of precipitation, and type of weather. By dragging on the scatter plot, you can see the proportion of days in that range that have sun, fog, drizzle, rain, or snow.\n",
"credit": "Based on a [Vega-Lite/Altair example](https://vega.github.io/vega-lite/examples/interactive_seattle_weather.html) by Jake Vanderplas."
},
"data": {
Expand Down
2 changes: 1 addition & 1 deletion specs/yaml/weather.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta:
title: Seattle Weather
description: >
An interactive view of Seattles weather, including maximum temperature, amount of precipitation, and type of weather.
An interactive view of Seattle's weather, including maximum temperature, amount of precipitation, and type of weather.
By dragging on the scatter plot, you can see the proportion of days in that range that have sun, fog, drizzle, rain, or snow.
credit: Based on a [Vega-Lite/Altair example](https://vega.github.io/vega-lite/examples/interactive_seattle_weather.html) by Jake Vanderplas.
data:
Expand Down

0 comments on commit be9f288

Please sign in to comment.