Skip to content

Instantly share code, notes, and snippets.

@joelcoxokc
Last active September 7, 2016 23:44
Show Gist options
  • Save joelcoxokc/7d7b0cbfc24a2fabb07f86b7838c8526 to your computer and use it in GitHub Desktop.
Save joelcoxokc/7d7b0cbfc24a2fabb07f86b7838c8526 to your computer and use it in GitHub Desktop.
graph
body {
background: #333;
}
.x-axis .tick {
stroke: white;
opacity: .25 !important;
}
.x-axis .tick line {
stroke: white;
opacity: 0 !important;
}
.y-axis .tick:first-child {
stroke: white;
opacity: 0 !important;
}
.x-axis path {
stroke-width: 2 !important;
/* opacity: .75; */
}
.y-axis .tick {
stroke: white;
opacity: 0.25 !important;
}
.y-axis .tick:first-child {
stroke: white;
}
.y-axis path {
stroke-width: 0;
opacity: 0 !important;
}
.y-axis .tick text {
font-size: 12px;
}
.x-axis .tick text {
font-size: 12px;
}
.js-report-sparkline {
width: 708px;
height: 250px;
margin: 50px auto;
font-family: "Proxima Nova", sans-serif;
position: relative;
* {
box-sizing: border-box;
}
g {
}
path {
stroke-width: 3;
fill: none;
}
path.area {
stroke-width: 0;
fill: red;
}
.point {
stroke-width: 2;
transition: all .3s;
opacity:0;
}
.point.end {
opacity:1;
}
.bar-rect {
fill: transparent;
stroke: none;
}
.point.hover {
stroke-width: 7;
opacity:1;
}
.point.end.hover {
stroke-width: 5;
opacity: 1;
}
.chart-container {
position: relative;
}
.chart-tooltip {
position: absolute;
background: white;
color: #999;
left: 0;
/* display: none; */
padding: 6px 8px 5px 8px;
font-size: 12px;
font-weight: 600;
border-radius: 3px;
margin-left: -8px;
opacity: 0;
-webkit-transition: .25s;
.title {
z-index: 3;
text-transform: uppercase;
font-size: 13px;
}
}
.chart-tooltip.hover {
margin-top: -10px;
opacity: 1;
}
.chart-tooltip:after {
content: '';
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
width: 0;
height: 0;
border: 5px solid transparent;
border-top: 5px solid white;
}
.bullet {
width: 8px;
height: 8px;
border-radius: 50%;
display: block;
position: absolute;
right: 5px;
top: 13px;
}
}
<template>
<require from="./app.css"></require>
<require from="./filter-location"></require>
<div class="container">
<aside repeat.for="location of state.locations" class-name.bind="location.name">
<h1>${location.title}</h1>
<ul ref="location.element"></ul>
</aside>
</div>
</template>
import {state} from './state';
import {DraggableModel} from './draggable';
import './element';
export class App {
state = state;
attached() {
state.load().then(models => {
models.forEach(model => {
model.draggable = new DraggableModel(model, state.locations);
})
})
}
}
// Clamps a value to a min/max
function clamp(value, a, b) {
return value < a ? a : (value > b ? b : value);
}
// Changes an elements's position in array
function arrayMove(array, from, to, array2) {
array2 = array2 || array;
array.splice(to, 0, array2.splice(from, 1)[0]);
}
import {createTemplate} from './template';
const height = 40;
export class DraggableModel {
constructor(model, locations) {
const self = this;
const list = locations[model.location];
this.getLocations = ()=> locations;
this.model = model;
this.template = createTemplate(model);
this.template.temp = createTemplate(model, true);
this.element = this.template.element;
this.element.temp = this.template.temp.element;
this.element.getDraggable = ()=> this;
this.element.temp.getDraggable = ()=> this;
list.element.appendChild(this.element);
console.log(this.template);
this.animation = TweenLite.to(this.template.content, 0.3, {
boxShadow: "rgba(0,0,0,0.2) 0px 16px 32px 0px",
force3D: true,
scale: 1.1,
background: 'white',
paused: true,
})
this.dragger = new Draggable(this.element, {
onDragStart: function() {self.onDragStart(this)},
onRelease: function() {self.onRelease(this)},
onDrag: function() {self.onDrag(this)},
cursor: "move",
type: "x,y",
});
this.setIndex(list.indexOf(this.model));
}
setIndex(index) {
this.index = index;
this.template.setOrder(index)
if (!this.dragger.isDragging) {
if (this.parentChanged) {
this.template.temp.setOrder(index)
TweenLight.to(this.element.temp, 0.3, {y: this.index * height, autoAlpha:0});
} else {
TweenLite.to(this.element, 0.3, {y: this.index * height});
}
}
}
onDragStart(drag) {
this.startLocation = this.model.location;
this.animation.play();
drag.update();
}
onRelease(drag) {
this.animation.reverse();
if (this.parentChanged) {
this.parentChanged = false;
this.element.temp.parentNode.insertBefore(this.element, this.element.temp);
this.element.temp.parentNode.removeChild(this.element.temp);
TweenLite.set(this.element, {x:0});
TweenLite.to(this.element, {y:this.index * height});
} else {
TweenLite.to(this.element, 0.3, {x:0, y: this.index * height});
}
const locations = this.getLocations();
locations.forEach(list => {
Array.from(list.element.children).forEach((child, index) => {
const draggable = child.getDraggable();
if (draggable) draggable.setIndex(index);
})
})
}
onDrag(drag) {
const locations = this.getLocations();
const current = locations[this.model.location];
locations.forEach(list => {
const parent = list.element;
if (drag.hitTest(parent, '51%')) {
const nextIndex = clamp(Math.round(drag.y / height), 0, parent.children.length);
const childAtIndex = parent.children[nextIndex];
// if (list === current && this.index === nextIndex) return;
if (parent !== current.element) {
this.parentChanged = true;
if (list.name === this.startLocation) {
this.parentChanged = false;
if (this.element.temp.parentNode) {
this.element.temp.parentNode.removeChild(this.element.temp);
}
}
if (this.parentChanged) {
this.element.parentNode.appendChild(this.element);
Array.from(current.element.children)
.forEach((node, index) => {
const draggable = node.getDraggable();
if (draggable) {
draggable.setIndex(index);
}
})
}
}
if (this.parentChanged) {
parent.insertBefore(this.element.temp, childAtIndex);
} else {
parent.insertBefore(this.element, childAtIndex);
}
this.model.location = list.name;
}
Array.from(parent.children).forEach((node, index) => {
const draggable = node.getDraggable();
if (draggable) {
draggable.setIndex(index);
}
})
})
}
}
// Clamps a value to a min/max
function clamp(value, a, b) {
return value < a ? a : (value > b ? b : value);
}
Element.prototype.find = Element.prototype.querySelector;
export class FilterLocationValueConverter {
toView(list, location) {
return list.filter(model => model.location === location);
}
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body aurelia-app>
<h1>Loading...</h1>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/utils/Draggable.min.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script>
<script>
require(['aurelia-bootstrapper']);
</script>
</body>
</html>
var orderNumber = 100000;
export class Order {
location = null;
number = null;
index = null;
id = null;
element = null;
constructor(options) {
Object.assign(this, options);
this.number = createNumber();
this.id = createOrderId(this.number);
}
clone() {
const location = this.location;
const index = this.index;
let order = new Order({location, index});
order.id = this.id;
order.number = this.number;
return order;
}
}
function createNumber() {
return orderNumber++;
}
function createOrderId(number) {
return `order-${number}`;
}
import {Order} from './order';
var locations = ['north', 'east', 'south', 'west'];
var modelCount = 20;
export const state = {
models: [],
locations: [],
}
locations.forEach(name => {
const location = state.locations[name] = [];
state.locations.push(location);
location.name = name;
location.title = capitalize(name);
})
state.load = function() {
return new Promise(resolve => {
if (!this.models.length) {
for(var i = 0; i < modelCount; i++) {
createOrder();
}
}
resolve(this.models);
})
}
function createOrder() {
const location = randomLocation();
const listSet = state.locations[location]
const index = listSet.length;
const model = new Order({location, index});
state.models.push(model);
listSet.push(model);
}
function randomLocation() {
return locations[Math.floor(Math.random() * locations.length)];
}
function capitalize(s) {
return s.charAt(0).toUpperCase() + s.slice(1);
}
export function createTemplate(model, hidden) {
const element = document.createElement('LI');
element.id = model.id;
if (hidden) {
element.style.opacity = 0;
}
const content = document.createElement('SPAN');
content.className = 'content';
element.appendChild(content);
const order = document.createElement('SPAN');
order.className = 'order';
order.textContent = model.index;
content.appendChild(order);
const number = document.createElement('SPAN');
number.className = 'number';
number.textContent = model.number;
content.appendChild(number);
const template = {element, content, order, number};
template.setOrder = function(value) {
order.textContent = value;
}
template.setNumber = function(value) {
number.textContent = value;
}
template.update = function() {
template.setOrder(model.index);
template.setNumber(model.number);
}
return template;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment