Skip to content

Commit

Permalink
Merge pull request #75 from geostreams/scatterplot-component
Browse files Browse the repository at this point in the history
Scatterplot addition
  • Loading branch information
lmarini authored Jun 22, 2022
2 parents e701698 + a7a7cbf commit 4a6ece5
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 17 deletions.
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## 3.9.2 - 2022-02-24

### Fixed
- Use `basename` attribute of Router to set the context path for the app.
- In template, deploy app at context path when using webpack dev server.
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@geostreams/core",
"version": "3.9.2",
"version": "3.9.4",
"main": "src/index.jsx",
"publishConfig": {
"access": "public"
Expand Down
7 changes: 5 additions & 2 deletions packages/geostreaming/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## 3.9.3 - 2022-03-07
## 3.9.4 - 2022-06-22
### Added
- New scatter plot visualization.

## 3.9.3 - 2022-03-07
### Fixed
- Search page would not show sensor markers on first render.

## 3.9.2 - 2022-02-24

### Fixed
- Switched Map SelectClusterInteraction from flat to spiral. Solves a problem
with cluster whose locations have the same lat/lon.

## 3.9.1
### Fixed
- Fix filename for Vega StackedBoxWhisker.

## 3.9.0 - 2021-10-07
Expand Down
2 changes: 1 addition & 1 deletion packages/geostreaming/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@geostreams/geostreaming",
"version": "3.9.3",
"version": "3.9.4",
"main": "src/index.jsx",
"author": "NCSA",
"publishConfig": {
Expand Down
170 changes: 170 additions & 0 deletions packages/geostreaming/src/components/vega/ScatterPlot.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import React from 'react';
import { VegaLite } from 'react-vega';
import type { ParameterValue } from '../../../utils/flowtype';

type Props = {
data: ParameterValue[];
width: Number,
height: Number,
startAtZero: Boolean,
startDate?: Date,
endDate?: Date
}


function ScatterPlot(props: Props){
const { data, width, height, startAtZero, startDate, endDate, yLabel, regressionLine } = props;

let dateRange = {};
if(startDate && endDate){
dateRange = { domain: [startDate.getTime(), endDate.getTime()] };
}

const spec = {
width,
height,
data: { name: 'table' },
transform: [
{ calculate: 'datum.average', as: 'value' }
],
encoding:{
x:{
field:'date',
type:'temporal',
timeUnit: 'yearmonthdate',
axis: { grid: false, title: false },
scale: { ...dateRange }
}
},
layer:[
{
encoding:{
y:{
field:'value',
type:'quantitative',
scale: { zero: startAtZero },
axis: { grid: false },
title: yLabel
}
},
layer:[
{
mark: { type:'point' , filled: true , size: 35, opacity: 0.4 }
},
{
transform:[
{
filter:{
param:'hover',
empty:false
}
}
],
mark:'point'
}
]
},
{
mark: {
type: 'boxplot',
extent: 'min-max',
median: { color: 'black' },
rule: false
},
encoding: {
y: {
field: 'value',
type: 'quantitative',
scale: { zero: false },
axis: { grid: false },
title: yLabel
},
x: {},
opacity: {
value: 0.3
},
size: {
value: width
}
}
},
{
mark:'rule',
encoding:{
opacity:{
condition:{
value:0.3,
param:'hover',
empty:false
},
value:0
},
tooltip:[
{
field:'value',
type:'quantitative',
title: yLabel
},
{
field:'date',
type:'temporal',
title: 'Date-Time'
}
]
},
params:[
{
name:'hover',
select:{
type:'point',
fields:[
'date'
],
nearest:true,
on:'mouseover',
clear:'mouseout'
}
}
]
}
]
};
if (regressionLine){
const line_spec = {
mark: {
type: 'line',
color: 'firebrick'
},
transform: [
{
regression: 'value',
on: 'date'
}],
encoding: {
x: {
field: 'date',
type: 'temporal'
},
y: {
field: 'value',
type: 'quantitative'
}
}
};
spec.layer.push(line_spec);

}
return(<VegaLite spec={spec} data={{ table : data }} actions={{ export: true, source: false, compiled: false }} />);
}

ScatterPlot.defaultProps = {
width: 800,
height: 300,
keyName: 'key',
startAtZero: false,
yLabel: 'value',
startDate: undefined,
endDate: undefined
};

export default ScatterPlot;
31 changes: 19 additions & 12 deletions packages/geostreaming/src/containers/Sensor/Detail/Parameters.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import D3StackedBarChart from './StackedBarChartWrapper';
import VegaMultiLineChart from './VegaMultiLineChartWrapper';
import VegaLineChart from './VegaLineChartWrapper';
import VegaLineChartWithError from './VegaLineChartWithError'
import VegaScatterChartWrapper from "./VegaScatterChartWrapper";

const useStyle = makeStyles({
chartContainer: {
Expand Down Expand Up @@ -141,18 +142,24 @@ const Parameters = (props: Props) => {
let content;
switch (visualization) {
case 'time':
content = forceVega ?
<VegaLineChart
{...chartProps} />
:
<D3LineChart
{...chartProps}
classes={{
chartContainer: classes.chartContainer,
chartDownloadIcon: classes.chartDownloadIcon
}}
tooltipContainerRef={tooltipContainerRef}
/>
content = forceVega ?
<VegaLineChart
{...chartProps} />
:
<D3LineChart
{...chartProps}
classes={{
chartContainer: classes.chartContainer,
chartDownloadIcon: classes.chartDownloadIcon
}}
tooltipContainerRef={tooltipContainerRef}
/>
break;
case 'scatter':
content = <VegaScatterChartWrapper {...chartProps} />;
break;
case 'scatter_with_regression':
content = <VegaScatterChartWrapper {...chartProps} regressionLine />;
break;
case 'stacked_bar':
content = <D3StackedBarChart
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// @flow
import * as React from 'react';
import { Grid } from '@material-ui/core';
import ScatterPlot from '../../../components/vega/ScatterPlot';
import BoxWhisker from '../../../components/vega/BoxWhisker';

import type { ParameterValue } from '../../../utils/flowtype';

type Props = {
label: string;
unit: string;
data: ParameterValue[];
startAtZero: Boolean,
sameTimeScale: Boolean,
startDate: Date,
endDate: Date,
regressionLine: Boolean
}


const ScatterChartWrapper = (props : Props) => {
const {
data,
label,
startDate,
endDate,
startAtZero,
regressionLine
} = props;

const chartData = data.map(({date, average, count})=> ({average, date, count }))

return (
<>
<Grid item xs={10}>
<ScatterPlot
startAtZero={startAtZero}
data={chartData}
width={900}
startDate={startDate}
endDate={endDate}
yLabel = {label}
regressionLine = {regressionLine}
/>
</Grid>
<Grid item xs={2}>
<BoxWhisker
data={chartData}
width={130}
/>
</Grid>
</>
);
};

export default ScatterChartWrapper;

0 comments on commit 4a6ece5

Please sign in to comment.