Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new responsive charts and new color settings #143

Closed
wants to merge 12 commits into from
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
<img src="logo/logo.png" width="200">
</p>

# Falcon: Interactive Visual Analysis for Big Data
### Shapelets falcon fork

[![npm version](https://img.shields.io/npm/v/falcon-vis.svg)](https://www.npmjs.com/package/falcon-vis) [![Build Status](https://travis-ci.com/uwdata/falcon.svg?branch=master)](https://travis-ci.com/uwdata/falcon) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=rounded)](https://github.com/prettier/prettier) [![Greenkeeper badge](https://badges.greenkeeper.io/uwdata/falcon.svg)](https://greenkeeper.io/)
This fork allows you to use falcon responsive and change fill color of the bar. Thanks to Dominik Moritz for his support from the original falcon repository.

[![npm version](https://img.shields.io/npm/v/shapelets-falcon.svg)](https://www.npmjs.com/package/shapelets-falcon)

Crossfilter millions of records without latencies. This project is work in progress and not documented yet. Please get in touch if you have questions.

Expand Down
3 changes: 3 additions & 0 deletions flights-responsive/app.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#app {
height: 100vh;
}
21 changes: 21 additions & 0 deletions flights-responsive/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="icon" type="image/png" href="../logo/favicon.png" />
<title>Explore Flights in Falcon</title>

<link href="./app.scss" rel="stylesheet">
</head>

<body>
<div id="loading">Loading data. Please wait...</div>
<div id="app"></div>
<div id="version"></div>
<script src="./index.ts"></script>
</body>

</html>
104 changes: 104 additions & 0 deletions flights-responsive/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { App, ArrowDB, Logger, Views } from "../src";
import { createElement } from "./utils";

document.getElementById("app")!.innerText = "";

type ViewName =
| "DEP_TIME"
| "ARR_TIME";

type DimensionName =
| "ARR_TIME"
| "DEP_TIME";

const views: Views<ViewName, DimensionName> = new Map();

views.set("ARR_TIME", {
title: "Arrival Time",
type: "1D",
el: createElement("arrival", 2),
dimension: {
name: "ARR_TIME",
bins: 24,
extent: [0, 24],
format: ".1f"
}
});
views.set("DEP_TIME", {
title: "Departure Time",
type: "1D",
el: createElement("departure", 2),
dimension: {
name: "DEP_TIME",
bins: 24,
extent: [0, 24],
format: ".1f"
}
});

const url = require("../data/flights-10k.arrow");
// const url =
// "https://media.githubusercontent.com/media/uwdata/flights-arrow/master/flights-10m.arrow";
const db = new ArrowDB<ViewName, DimensionName>(url);

let logger: Logger<ViewName> | undefined;

//=============
// timeline vis logger

// logger = new TimelineLogger(createElement("logs"), views);

//=============
// simple logger as demo

// logger = new SimpleLogger<ViewName>();

const iPad = !!navigator.userAgent.match(/iPad/i);

new App(views, db, {
config: {
barWidth: 600,
fillColor: '#00f0ff',
responsive: true,
...(iPad
? {
barWidth: 450,
histogramWidth: 450,
histogramHeight: 120,
heatmapWidth: 300,
prefetchOn: "mousedown"
}
: {})
},
logger: logger,
cb: _app => {
document.getElementById("loading")!.style.display = "none";

//=============
// benchmark

// function animationframe() {
// return new Promise(resolve => requestAnimationFrame(resolve));
// }

// async function benchmark() {
// _app.prefetchView("AIR_TIME", false);

// console.time("Brushes");
// const step = 25;
// for (let start = 0; start < 500; start += step) {
// for (let end = start + step; end < 500 + step; end += step) {
// _app
// .getVegaView("AIR_TIME")
// .signal("brush", [start, end])
// .run();

// await animationframe();
// }
// }
// console.timeEnd("Brushes");
// }

// window.setTimeout(benchmark, 1000);
}
});
14 changes: 14 additions & 0 deletions flights-responsive/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { version } from "../src";

document.getElementById(
"version"
)!.innerHTML = `Powered by <a href="https://github.com/uwdata/falcon">Falcon</a> ${version}`;

export function createElement(id: string, numOfElements: number) {
const el = document.createElement("div");
el.setAttribute("id", id);
el.style.height = `calc(100% / ${numOfElements})`;
el.style.width = '100%';
document.getElementById("app")!.appendChild(el);
return el;
}
20 changes: 11 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
{
"name": "falcon-vis",
"version": "0.14.3",
"description": "Big data crossfilter",
"name": "shapelets-falcon",
"version": "0.14.5",
"description": "Big data crossfilter fork from falcon",
"main": "build/falcon.js",
"module": "build/src/index",
"types": "build/src/index.d.ts",
"scripts": {
"start:flights-responsive": "parcel flights-responsive/index.html",
"start:flights": "parcel flights/index.html",
"start:flights-mapd": "parcel flights-mapd/index.html",
"start:weather": "parcel weather/index.html",
"start:gaia-mapd": "parcel gaia-mapd/index.html",
"start": "yarn start:flights",
"clean": "rm -rf dist && rm -rf .cache && rm -rf build",
"build": "tsc && rollup -c",
"build:demos": "parcel build --public-url '/falcon/' flights/index.html flights-mapd/index.html weather/index.html --detailed-report",
"build": "tsc --declaration && rollup -c",
"build:demos": "parcel build --public-url '/falcon/' flights/index.html flights-responsive/index.html flights-mapd/index.html weather/index.html --detailed-report",
"deploy:demos": "yarn clean && yarn build:demos && gh-pages -d dist",
"test": "jest",
"prettierbase": "prettier '{src,test}/**/*.{ts,html,scss}'",
Expand All @@ -23,14 +24,14 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/uwdata/falcon.git"
"url": "git+https://github.com/shapelets/falcon"
},
"author": "Dominik Moritz",
"author": "José Sánchez Aranda",
"license": "BSD-3-Clause",
"bugs": {
"url": "https://github.com/uwdata/falcon/issues"
"url": "https://github.com/shapelets/falcon/issues"
},
"homepage": "https://github.com/uwdata/falcon#readme",
"homepage": "https://github.com/shapelets/falcon#readme",
"dependencies": {
"@apache-arrow/es2015-esm": "^0.14.1",
"@mapd/connector": "^4.7.2",
Expand All @@ -42,6 +43,7 @@
"ndarray-linear-interpolate": "^1.0.0",
"ndarray-ops": "^1.2.2",
"ndarray-prefix-sum": "^1.0.0",
"resize-detector": "^0.2.0",
"vega": "^5.4.0"
},
"devDependencies": {
Expand Down
15 changes: 15 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
createVerticalBarView
} from "./views";
// import imshow from "ndarray-imshow";
import * as resizeDetector from "resize-detector";

const interp2d = interpolate.d2;

Expand Down Expand Up @@ -271,13 +272,23 @@ export class App<V extends string, D extends string> {
const el = view.el!;
let vegaView: VgView;

if (this.config.responsive) {
resizeDetector.addListener(el, () => {
vegaView.width(el.offsetWidth - 10);
vegaView.height(el.offsetHeight - 20);
vegaView.runAsync();
});
}

if (view.type === "0D") {
vegaView = (this.config.zeroD === "text"
? createTextView
: this.config.zeroD === "hbar"
? createHorizontalBarView
: createVerticalBarView)(el, view, this.config);

vegaView.width(el.offsetWidth - 10);
vegaView.height(el.offsetHeight - 20);
await vegaView.runAsync();
this.vegaViews.set(name, vegaView);

Expand All @@ -293,6 +304,8 @@ export class App<V extends string, D extends string> {

vegaView = createHistogramView(el, view, this.config, !!this.logger);

vegaView.width(el.offsetWidth - 10);
vegaView.height(el.offsetHeight - 20);
await vegaView.runAsync();
this.vegaViews.set(name, vegaView);

Expand Down Expand Up @@ -343,6 +356,8 @@ export class App<V extends string, D extends string> {

vegaView = createHeatmapView(el, view, this.config);

vegaView.width(el.offsetWidth - 10);
vegaView.height(el.offsetHeight - 20);
await vegaView.runAsync();
this.vegaViews.set(name, vegaView);

Expand Down
2 changes: 2 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export const DEFAULT_CONFIG = {
heatmapHeight: null,
maxCircleSize: 700,
yAxisExtent: 50,
fillColor: "#4c78a8",
responsive: false,

//----------
// debugging
Expand Down
4 changes: 2 additions & 2 deletions src/views/hbar.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Config } from "./../config";
import { EncodeEntry, parse, Spec, View, Warn } from "vega";
import { View0D } from "../api";
import { darkerBlue, loadingMarks } from "./histogram";
import { loadingMarks } from "./histogram";

export function createHorizontalBarView(
el: Element,
Expand Down Expand Up @@ -91,7 +91,7 @@ export function createHorizontalBarView(
encode: {
enter: {
...barEnterEncodeBase,
fill: { value: darkerBlue }
fill: { value: config.fillColor }
},
update: {
...barUpdateEncodeBase,
Expand Down
6 changes: 3 additions & 3 deletions src/views/heatmap.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { parse, Spec, View, Mark, Warn } from "vega";
import { View2D } from "../api";
import { Config } from "../config";
import { darkerBlue, loadingMarks } from "./histogram";
import { loadingMarks } from "./histogram";

export function createHeatmapView<D extends string>(
el: Element,
Expand Down Expand Up @@ -116,7 +116,7 @@ export function createHeatmapView<D extends string>(
encode: {
enter: {
shape: { value: "circle" },
fill: { value: darkerBlue }
fill: { value: config.fillColor }
},
update: {
x: {
Expand Down Expand Up @@ -570,7 +570,7 @@ export function createHeatmapView<D extends string>(
...(config.circleHeatmap
? {
size: "size",
symbolFillColor: darkerBlue,
symbolFillColor: config.fillColor,
symbolStrokeWidth: 0
}
: {
Expand Down
29 changes: 24 additions & 5 deletions src/views/histogram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import { View1D } from "../api";
import { Config } from "../config";
import { extent, repeatInvisible } from "../util";

export const darkerBlue = "#4c78a8";

export function loadingMarks(heightSignal: string, rotate = false) {
return [
{
Expand Down Expand Up @@ -213,7 +211,7 @@ export function createHistogramView<D extends string>(
from: { data: "table" },
encode: {
enter: {
fill: { value: darkerBlue }
fill: { value: config.fillColor }
},
update: {
opacity: { signal: "approximate ? 0.7 : 1" },
Expand Down Expand Up @@ -415,7 +413,17 @@ export function createHistogramView<D extends string>(
];

const signals: Signal[] = [
{ name: "histHeight", value: config.histogramHeight },
// { name: "width", value: "", on: [{ events: { source: "window", type: "resize" }, update: "containerSize()[0]" }] },
{
name: "height",
value: config.histogramHeight,
on: [
{
events: { source: "window", type: "resize" },
update: "containerSize()[1]"
}
]
},
{ name: "pending", value: false },
{ name: "approximate", value: false },
{ name: "bin", value: dimension.binConfig },
Expand Down Expand Up @@ -539,6 +547,16 @@ export function createHistogramView<D extends string>(
}
];

if (config.responsive) {
signals.push({
name: "histHeight",
value: config.histogramHeight,
update: "height - 20"
});
} else {
signals.push({ name: "histHeight", value: config.histogramHeight });
}

if (config.zoom) {
signals.push(
...([
Expand Down Expand Up @@ -646,8 +664,9 @@ export function createHistogramView<D extends string>(

const vgSpec: Spec = {
$schema: "https://vega.github.io/schema/vega/v4.0.json",
autosize: "pad",
autosize: "fit",
width: config.histogramWidth,
height: config.histogramHeight,
padding: 5,
data: data,
signals: signals,
Expand Down
4 changes: 2 additions & 2 deletions src/views/vbar.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Config } from "./../config";
import { EncodeEntry, parse, Spec, View, Warn } from "vega";
import { View0D } from "../api";
import { darkerBlue, loadingMarks } from "./histogram";
import { loadingMarks } from "./histogram";

export function createVerticalBarView(
el: Element,
Expand Down Expand Up @@ -85,7 +85,7 @@ export function createVerticalBarView(
name: "bar",
encode: {
enter: {
fill: { value: darkerBlue }
fill: { value: config.fillColor }
},
update: {
...barEncodeBase,
Expand Down