use of javafx.scene.effect.DropShadow in project Board-Instrumentation-Framework by intel.
the class SimpleLineChartSkin method drawForeground.
// ******************** Private Methods ***********************************
private void drawForeground() {
ctxFg.clearRect(0, 0, width, height);
ctxFg.setStroke(getSkinnable().getSeriesStroke());
ctxFg.setLineCap(StrokeLineCap.ROUND);
ctxFg.setLineJoin(StrokeLineJoin.ROUND);
ctxFg.setLineWidth(0.025 * height);
ctxFg.save();
ctxFg.translate(0, sectionMinimum * heightFactor);
widthFactor = width / (getSkinnable().getSeries().getData().size());
int noOfDataPoints = getSkinnable().getSeries().getData().size();
if (noOfDataPoints > 2) {
for (int i = 0; i < noOfDataPoints - 1; i++) {
XYChart.Data p1 = (XYChart.Data) getSkinnable().getSeries().getData().get(i);
XYChart.Data p2 = (XYChart.Data) getSkinnable().getSeries().getData().get(i + 1);
ctxFg.strokeLine(widthFactor / 2 + i * widthFactor, height - (Double) p1.getYValue() * heightFactor, widthFactor / 2 + (i + 1) * widthFactor, height - (Double) p2.getYValue() * heightFactor);
drawBullet(ctxFg, widthFactor / 2 + i * widthFactor, height - (Double) p1.getYValue() * heightFactor, getSkinnable().getBulletFill());
}
drawBullet(ctxFg, widthFactor / 2 + (noOfDataPoints - 1) * widthFactor, height - (Double) (getSkinnable().getSeries().getData().get(noOfDataPoints - 1)).getYValue() * heightFactor, getSkinnable().getBulletFill());
}
ctxFg.save();
ctxFg.applyEffect(new DropShadow(0.025 * height, 0, 0.025 * height, Color.rgb(0, 0, 0, 0.65)));
ctxFg.restore();
// draw from and to text
ctxFg.setFill(Color.WHITE);
ctxFg.setFont(Fonts.robotoLight(0.1 * height));
ctxFg.setTextBaseline(VPos.BOTTOM);
ctxFg.setTextAlign(TextAlignment.LEFT);
ctxFg.fillText(getSkinnable().getFrom(), 2, height - 2);
ctxFg.setTextAlign(TextAlignment.RIGHT);
ctxFg.fillText(getSkinnable().getTo(), width - 2, height - 2);
// draw title text
if (getSkinnable().isTitleVisible()) {
ctxFg.setTextBaseline(VPos.TOP);
ctxFg.setTextAlign(TextAlignment.CENTER);
ctxFg.fillText(getSkinnable().getSeries().getName(), width * 0.5, 2);
}
ctxFg.restore();
}
use of javafx.scene.effect.DropShadow in project Board-Instrumentation-Framework by intel.
the class ClockSkin method initGraphics.
private void initGraphics() {
pane = new Pane();
background = new Region();
if (Clock.Design.IOS6 == getSkinnable().getDesign()) {
background.getStyleClass().setAll("background-ios6");
} else if (Clock.Design.DB == getSkinnable().getDesign()) {
background.getStyleClass().setAll("background-db");
} else if (Clock.Design.BRAUN == getSkinnable().getDesign()) {
background.getStyleClass().setAll("background-braun");
} else if (Clock.Design.BOSCH == getSkinnable().getDesign()) {
background.getStyleClass().setAll("background-bosch");
}
logoLayer = new Canvas(PREFERRED_WIDTH, PREFERRED_HEIGHT);
ctx = logoLayer.getGraphicsContext2D();
String majorTickStyleClass;
String minorTickStyleClass;
if (Clock.Design.IOS6 == getSkinnable().getDesign()) {
majorTickStyleClass = "major-tick-ios6";
minorTickStyleClass = "minor-tick-ios6";
} else if (Clock.Design.DB == getSkinnable().getDesign()) {
majorTickStyleClass = "major-tick-db";
minorTickStyleClass = "minor-tick-db";
} else if (Clock.Design.BOSCH == getSkinnable().getDesign()) {
majorTickStyleClass = "major-tick-bosch";
minorTickStyleClass = "minor-tick-bosch";
} else {
majorTickStyleClass = "major-tick-braun";
minorTickStyleClass = "minor-tick-braun";
}
int tickLabelCounter = 1;
for (double angle = 0; angle < 360; angle += 6) {
Region tick = new Region();
if (angle % 30 == 0) {
tick.getStyleClass().setAll(majorTickStyleClass);
Text tickLabel = new Text(Integer.toString(tickLabelCounter));
tickLabel.getStyleClass().setAll("tick-label-braun");
tickLabels.add(tickLabel);
tickLabelCounter++;
} else {
tick.getStyleClass().setAll(minorTickStyleClass);
}
ticks.add(tick);
}
DropShadow dropShadow = new DropShadow();
dropShadow.setColor(Color.rgb(0, 0, 0, 0.65));
dropShadow.setRadius(1.5);
dropShadow.setBlurType(BlurType.TWO_PASS_BOX);
dropShadow.setOffsetY(1);
tickMarkGroup = new Group();
tickMarkGroup.setEffect(dropShadow);
tickMarkGroup.getChildren().setAll(ticks);
tickLabelGroup = new Group();
tickLabelGroup.setEffect(dropShadow);
tickLabelGroup.getChildren().setAll(tickLabels);
tickLabelGroup.setOpacity(Clock.Design.BRAUN == getSkinnable().getDesign() ? 1 : 0);
minutePointer = new Region();
if (Clock.Design.IOS6 == getSkinnable().getDesign()) {
minutePointer.getStyleClass().setAll("hour-pointer-ios6");
} else if (Clock.Design.DB == getSkinnable().getDesign()) {
minutePointer.getStyleClass().setAll("hour-pointer-db");
} else if (Clock.Design.BRAUN == getSkinnable().getDesign()) {
minutePointer.getStyleClass().setAll("hour-pointer-braun");
} else if (Clock.Design.BOSCH == getSkinnable().getDesign()) {
minutePointer.getStyleClass().setAll("hour-pointer-bosch");
}
minutePointer.getTransforms().setAll(minuteRotate);
minutePointerFlour = new Region();
minutePointerFlour.getStyleClass().setAll("hour-pointer-braun-flour");
if (Clock.Design.BRAUN == getSkinnable().getDesign()) {
minutePointerFlour.setOpacity(1);
} else {
minutePointerFlour.setOpacity(0);
}
minutePointerFlour.getTransforms().setAll(minuteRotate);
hourPointer = new Region();
if (Clock.Design.IOS6 == getSkinnable().getDesign()) {
hourPointer.getStyleClass().setAll("minute-pointer-ios6");
} else if (Clock.Design.DB == getSkinnable().getDesign()) {
hourPointer.getStyleClass().setAll("minute-pointer-db");
} else if (Clock.Design.BRAUN == getSkinnable().getDesign()) {
hourPointer.getStyleClass().setAll("minute-pointer-braun");
} else if (Clock.Design.BOSCH == getSkinnable().getDesign()) {
hourPointer.getStyleClass().setAll("minute-pointer-bosch");
}
hourPointer.getTransforms().setAll(hourRotate);
hourPointerFlour = new Region();
hourPointerFlour.getStyleClass().setAll("minute-pointer-braun-flour");
if (Clock.Design.BRAUN == getSkinnable().getDesign()) {
hourPointerFlour.setOpacity(1);
} else {
hourPointerFlour.setOpacity(0);
}
hourPointerFlour.getTransforms().setAll(hourRotate);
DropShadow pointerShadow = new DropShadow();
pointerShadow.setColor(Color.rgb(0, 0, 0, 0.45));
pointerShadow.setRadius(12);
pointerShadow.setBlurType(BlurType.TWO_PASS_BOX);
pointerShadow.setOffsetY(6);
pointerGroup = new Group();
pointerGroup.setEffect(pointerShadow);
pointerGroup.getChildren().setAll(hourPointerFlour, hourPointer, minutePointerFlour, minutePointer);
secondPointer = new Region();
secondPointer.setOpacity(1);
if (Clock.Design.IOS6 == getSkinnable().getDesign()) {
secondPointer.getStyleClass().setAll("second-pointer-ios6");
} else if (Clock.Design.DB == getSkinnable().getDesign()) {
secondPointer.getStyleClass().setAll("second-pointer-db");
} else if (Clock.Design.BRAUN == getSkinnable().getDesign()) {
secondPointer.getStyleClass().setAll("second-pointer-braun");
} else if (Clock.Design.BOSCH == getSkinnable().getDesign()) {
secondPointer.setOpacity(0);
}
secondPointer.getTransforms().setAll(secondRotate);
InnerShadow secondPointerInnerShadow = new InnerShadow();
secondPointerInnerShadow.setColor(Color.rgb(0, 0, 0, 0.3));
secondPointerInnerShadow.setRadius(1);
secondPointerInnerShadow.setBlurType(BlurType.TWO_PASS_BOX);
secondPointerInnerShadow.setOffsetY(-1);
InnerShadow secondPointerInnerHighlight = new InnerShadow();
secondPointerInnerHighlight.setColor(Color.rgb(255, 255, 255, 0.3));
secondPointerInnerHighlight.setRadius(1);
secondPointerInnerHighlight.setBlurType(BlurType.TWO_PASS_BOX);
secondPointerInnerHighlight.setOffsetY(1);
secondPointerInnerHighlight.setInput(secondPointerInnerShadow);
DropShadow secondPointerShadow = new DropShadow();
secondPointerShadow.setColor(Color.rgb(0, 0, 0, 0.45));
secondPointerShadow.setRadius(12);
secondPointerShadow.setBlurType(BlurType.TWO_PASS_BOX);
secondPointerShadow.setOffsetY(6);
secondPointerShadow.setInput(secondPointerInnerHighlight);
secondPointerGroup = new Group();
secondPointerGroup.setEffect(secondPointerShadow);
secondPointerGroup.getChildren().setAll(secondPointer);
secondPointerGroup.setOpacity(getSkinnable().isSecondPointerVisible() ? 1 : 0);
centerKnob = new Region();
if (Clock.Design.IOS6 == getSkinnable().getDesign()) {
centerKnob.getStyleClass().setAll("center-knob-ios6");
} else if (Clock.Design.DB == getSkinnable().getDesign()) {
centerKnob.getStyleClass().setAll("center-knob-db");
} else if (Clock.Design.BRAUN == getSkinnable().getDesign()) {
centerKnob.getStyleClass().setAll("center-knob-braun");
} else if (Clock.Design.BOSCH == getSkinnable().getDesign()) {
centerKnob.getStyleClass().setAll("center-knob-bosch");
}
foreground = new Region();
if (Clock.Design.IOS6 == getSkinnable().getDesign()) {
foreground.getStyleClass().setAll("foreground-ios6");
} else if (Clock.Design.DB == getSkinnable().getDesign()) {
foreground.getStyleClass().setAll("foreground-db");
} else if (Clock.Design.BRAUN == getSkinnable().getDesign()) {
foreground.getStyleClass().setAll("foreground-braun");
} else if (Clock.Design.BOSCH == getSkinnable().getDesign()) {
foreground.getStyleClass().setAll("foreground-bosch");
}
foreground.setOpacity(getSkinnable().isHighlightVisible() ? 1 : 0);
pane.getChildren().setAll(background, logoLayer, tickMarkGroup, tickLabelGroup, pointerGroup, secondPointerGroup, centerKnob, foreground);
getChildren().setAll(pane);
updateDesign();
}
use of javafx.scene.effect.DropShadow in project Board-Instrumentation-Framework by intel.
the class Led method draw.
// ******************** Resize/Redraw *************************************
private void draw() {
double size = getWidth() < getHeight() ? getWidth() : getHeight();
canvas.setWidth(size);
canvas.setHeight(size);
ctx.clearRect(0, 0, size, size);
if (isFrameVisible()) {
// frame
Paint frame = new LinearGradient(0.14 * size, 0.14 * size, 0.84 * size, 0.84 * size, false, CycleMethod.NO_CYCLE, new Stop(0.0, Color.rgb(20, 20, 20, 0.65)), new Stop(0.15, Color.rgb(20, 20, 20, 0.65)), new Stop(0.26, Color.rgb(41, 41, 41, 0.65)), new Stop(0.26, Color.rgb(41, 41, 41, 0.64)), new Stop(0.85, Color.rgb(200, 200, 200, 0.41)), new Stop(1.0, Color.rgb(200, 200, 200, 0.35)));
ctx.setFill(frame);
ctx.fillOval(0, 0, size, size);
}
InnerShadow innerShadow = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.65), 0.07 * size, 0, 0, 0);
if (isOn()) {
// on
ctx.save();
Paint on = new LinearGradient(0.25 * size, 0.25 * size, 0.74 * size, 0.74 * size, false, CycleMethod.NO_CYCLE, new Stop(0.0, ((Color) ledColor.get()).deriveColor(0d, 1d, 0.77, 1d)), new Stop(0.49, ((Color) ledColor.get()).deriveColor(0d, 1d, 0.5, 1d)), new Stop(1.0, ((Color) ledColor.get())));
innerShadow.setInput(new DropShadow(BlurType.TWO_PASS_BOX, (Color) ledColor.get(), 0.36 * size, 0, 0, 0));
ctx.setEffect(innerShadow);
ctx.setFill(on);
ctx.fillOval(0.14 * size, 0.14 * size, 0.72 * size, 0.72 * size);
ctx.restore();
} else {
// off
ctx.save();
Paint off = new LinearGradient(0.25 * size, 0.25 * size, 0.74 * size, 0.74 * size, false, CycleMethod.NO_CYCLE, new Stop(0.0, ((Color) ledColor.get()).deriveColor(0d, 1d, 0.20, 1d)), new Stop(0.49, ((Color) ledColor.get()).deriveColor(0d, 1d, 0.13, 1d)), new Stop(1.0, ((Color) ledColor.get()).deriveColor(0d, 1d, 0.2, 1d)));
ctx.setEffect(innerShadow);
ctx.setFill(off);
ctx.fillOval(0.14 * size, 0.14 * size, 0.72 * size, 0.72 * size);
ctx.restore();
}
// highlight
Paint highlight = new RadialGradient(0, 0, 0.3 * size, 0.3 * size, 0.29 * size, false, CycleMethod.NO_CYCLE, new Stop(0.0, Color.WHITE), new Stop(1.0, Color.TRANSPARENT));
ctx.setFill(highlight);
ctx.fillOval(0.21 * size, 0.21 * size, 0.58 * size, 0.58 * size);
}
use of javafx.scene.effect.DropShadow in project Board-Instrumentation-Framework by intel.
the class LedOne method recalc.
// ******************** Resize/Redraw *************************************
private void recalc() {
width = getWidth();
height = getHeight();
if (width <= 0 || height <= 0)
return;
size = width < height ? width : height;
offsetX = 0;
offsetY = 0;
if (width > height) {
offsetX = 0.5 * (width - size);
} else if (height > width) {
offsetY = 0.5 * (height - size);
}
ledOffShadow = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.65), 0.07 * size, 0, 0, 0);
ledOnShadow = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.65), 0.07 * size, 0, 0, 0);
ledOnShadow.setInput(new DropShadow(BlurType.TWO_PASS_BOX, ledColor.get(), 0.36 * size, 0, 0, 0));
frameGradient = new LinearGradient(offsetX + 0.14 * size, offsetY + 0.14 * size, offsetX + 0.84 * size, offsetY + 0.84 * size, false, CycleMethod.NO_CYCLE, new Stop(0.0, Color.rgb(20, 20, 20, 0.65)), new Stop(0.15, Color.rgb(20, 20, 20, 0.65)), new Stop(0.26, Color.rgb(41, 41, 41, 0.65)), new Stop(0.26, Color.rgb(41, 41, 41, 0.64)), new Stop(0.85, Color.rgb(200, 200, 200, 0.41)), new Stop(1.0, Color.rgb(200, 200, 200, 0.35)));
ledOnGradient = new LinearGradient(offsetX + 0.25 * size, offsetY + 0.25 * size, offsetX + 0.74 * size, offsetY + 0.74 * size, false, CycleMethod.NO_CYCLE, new Stop(0.0, ledColor.get().deriveColor(0d, 1d, 0.77, 1d)), new Stop(0.49, ledColor.get().deriveColor(0d, 1d, 0.5, 1d)), new Stop(1.0, ledColor.get()));
ledOffGradient = new LinearGradient(offsetX + 0.25 * size, offsetY + 0.25 * size, offsetX + 0.74 * size, offsetY + 0.74 * size, false, CycleMethod.NO_CYCLE, new Stop(0.0, ledColor.get().deriveColor(0d, 1d, 0.20, 1d)), new Stop(0.49, ledColor.get().deriveColor(0d, 1d, 0.13, 1d)), new Stop(1.0, ledColor.get().deriveColor(0d, 1d, 0.2, 1d)));
highlightGradient = new RadialGradient(0, 0, offsetX + 0.3 * size, offsetY + 0.3 * size, 0.29 * size, false, CycleMethod.NO_CYCLE, new Stop(0.0, Color.WHITE), new Stop(1.0, Color.TRANSPARENT));
draw();
}
use of javafx.scene.effect.DropShadow in project Board-Instrumentation-Framework by intel.
the class TButtonSkin method initGraphics.
private void initGraphics() {
frame = new Region();
frame.getStyleClass().setAll("frame");
off = new Region();
off.getStyleClass().setAll("off");
offInnerShadow = new InnerShadow();
offInnerShadow.setOffsetX(0);
offInnerShadow.setOffsetY(-5.0 / 144.0 * PREFERRED_SIZE);
offInnerShadow.setRadius(2.0 / 144.0 * PREFERRED_SIZE);
offInnerShadow.setColor(Color.web("0x00000080"));
offInnerShadow.setBlurType(BlurType.TWO_PASS_BOX);
offInnerShadow1 = new InnerShadow();
offInnerShadow1.setOffsetX(0.0);
offInnerShadow1.setOffsetY(0.0);
offInnerShadow1.setRadius(3.0 / 144.0 * PREFERRED_SIZE);
offInnerShadow1.setColor(Color.web("0x0000004d"));
offInnerShadow1.setBlurType(BlurType.TWO_PASS_BOX);
offInnerShadow1.setInput(offInnerShadow);
offDropShadow = new DropShadow();
offDropShadow.setOffsetX(0);
offDropShadow.setOffsetY(10.0 / 144.0 * PREFERRED_SIZE);
offDropShadow.setRadius(10.0 / 144.0 * PREFERRED_SIZE);
offDropShadow.setColor(Color.web("0x000000bf"));
offDropShadow.setBlurType(BlurType.TWO_PASS_BOX);
offDropShadow.setInput(offInnerShadow1);
off.setEffect(offDropShadow);
off.setVisible(!getSkinnable().isSelected());
ledOff = new Region();
ledOff.getStyleClass().setAll("off-led");
ledOff.setMouseTransparent(true);
ledOff.setVisible(!getSkinnable().isSelected());
ledOffInnerShadow = new InnerShadow();
ledOffInnerShadow.setOffsetX(0);
ledOffInnerShadow.setOffsetY(2.0 / 144.0 * PREFERRED_SIZE);
ledOffInnerShadow.setRadius(1.0 / 144.0 * PREFERRED_SIZE);
ledOffInnerShadow.setColor(Color.web("0x0000004d"));
ledOffInnerShadow.setBlurType(BlurType.TWO_PASS_BOX);
ledOffInnerShadow1 = new InnerShadow();
ledOffInnerShadow1.setOffsetX(0);
ledOffInnerShadow1.setOffsetY(-2.0);
ledOffInnerShadow1.setRadius(1.0 / 144.0 * PREFERRED_SIZE);
ledOffInnerShadow1.setColor(Color.web("0xffffffa6"));
ledOffInnerShadow1.setBlurType(BlurType.TWO_PASS_BOX);
ledOffInnerShadow1.setInput(ledOffInnerShadow);
ledOff.setEffect(ledOffInnerShadow1);
on = new Region();
on.getStyleClass().setAll("on");
onInnerShadow = new InnerShadow();
onInnerShadow.setOffsetX(0);
onInnerShadow.setOffsetY(-2.0 / 144.0 * PREFERRED_SIZE);
onInnerShadow.setRadius(2.0 / 144.0 * PREFERRED_SIZE);
onInnerShadow.setColor(Color.web("0x00000080"));
onInnerShadow.setBlurType(BlurType.TWO_PASS_BOX);
onInnerShadow1 = new InnerShadow();
onInnerShadow1.setOffsetX(0);
onInnerShadow1.setOffsetY(5.0 / 144.0 * PREFERRED_SIZE);
onInnerShadow1.setRadius(2.0 / 144.0 * PREFERRED_SIZE);
onInnerShadow1.setColor(Color.web("0x90909080"));
onInnerShadow1.setBlurType(BlurType.TWO_PASS_BOX);
onInnerShadow1.setInput(onInnerShadow);
onDropShadow = new DropShadow();
onDropShadow.setOffsetX(0);
onDropShadow.setOffsetY(1.0);
onDropShadow.setRadius(1.0 / 144.0 * PREFERRED_SIZE);
onDropShadow.setColor(Color.web("0x000000bf"));
onDropShadow.setBlurType(BlurType.TWO_PASS_BOX);
onDropShadow.setInput(onInnerShadow1);
on.setEffect(onDropShadow);
on.setVisible(getSkinnable().isSelected());
ledOn = new Region();
ledOn.getStyleClass().setAll("on-led");
ledOn.setMouseTransparent(true);
ledOn.setVisible(getSkinnable().isSelected());
ledOnInnerShadow = new InnerShadow();
ledOnInnerShadow.setOffsetX(1.4142135623730951);
ledOnInnerShadow.setOffsetY(1.414213562373095);
ledOnInnerShadow.setRadius(1.0 / 144.0 * PREFERRED_SIZE);
ledOnInnerShadow.setColor(getSkinnable().getLedColor().darker().darker().darker());
ledOnInnerShadow.setBlurType(BlurType.TWO_PASS_BOX);
ledOnInnerShadow1 = new InnerShadow();
ledOnInnerShadow1.setOffsetX(-2.457456132866976);
ledOnInnerShadow1.setOffsetY(-1.7207293090531375);
ledOnInnerShadow1.setRadius(2.0 / 144.0 * PREFERRED_SIZE);
ledOnInnerShadow1.setColor(getSkinnable().getLedColor().darker());
ledOnInnerShadow1.setBlurType(BlurType.TWO_PASS_BOX);
ledOnInnerShadow1.setInput(ledOnInnerShadow);
ledOnGlow = new DropShadow();
ledOnGlow.setOffsetX(0.0);
ledOnGlow.setOffsetY(0.0);
ledOnGlow.setRadius(9.0 / 144.0 * PREFERRED_SIZE);
ledOnGlow.setColor(getSkinnable().getLedColor());
ledOnGlow.setBlurType(BlurType.TWO_PASS_BOX);
ledOnGlow.setInput(ledOnInnerShadow1);
ledOn.setEffect(ledOnGlow);
// "OpenSans"
Font.loadFont(getClass().getResourceAsStream("/eu/hansolo/enzo/fonts/opensans-semibold.ttf"), (28.0 / 144.0 * PREFERRED_SIZE));
font = Font.font("Open Sans", FontWeight.BOLD, FontPosture.REGULAR, 28.0 / 144.0 * PREFERRED_SIZE);
text = new Text(getSkinnable().getText());
text.setFont(font);
text.setTextOrigin(VPos.TOP);
text.getStyleClass().add("text");
text.setMouseTransparent(true);
textInnerShadow = new InnerShadow();
textInnerShadow.setOffsetX(0);
textInnerShadow.setOffsetY(-1.0 / 144.0 * PREFERRED_SIZE);
textInnerShadow.setRadius(1.0 / 144.0 * PREFERRED_SIZE);
textInnerShadow.setColor(Color.web("0x90909080"));
textInnerShadow.setBlurType(BlurType.TWO_PASS_BOX);
textInnerShadow1 = new InnerShadow();
textInnerShadow1.setOffsetX(0);
textInnerShadow1.setOffsetY(1.0 / 144.0 * PREFERRED_SIZE);
textInnerShadow1.setRadius(1.0 / 144.0 * PREFERRED_SIZE);
textInnerShadow1.setColor(Color.web("0x00000080"));
textInnerShadow1.setBlurType(BlurType.TWO_PASS_BOX);
textInnerShadow1.setInput(textInnerShadow);
text.setEffect(textInnerShadow1);
pane.getChildren().setAll(frame, off, ledOff, on, ledOn, text);
getChildren().setAll(pane);
resize();
}
Aggregations