announce x-axis date properly
This commit is contained in:
parent
f8e5396d57
commit
a99ee96f5c
|
@ -15,6 +15,7 @@ import {
|
||||||
buildVegaSpec,
|
buildVegaSpec,
|
||||||
DistributionChartSpecOptions,
|
DistributionChartSpecOptions,
|
||||||
} from "../lib/distributionSpecBuilder";
|
} from "../lib/distributionSpecBuilder";
|
||||||
|
import { buildDateVegaSpec } from "../lib/dateDistributionSpecBuilder";
|
||||||
import { NumberShower } from "./NumberShower";
|
import { NumberShower } from "./NumberShower";
|
||||||
import { Plot, parsePlot } from "../lib/plotParser";
|
import { Plot, parsePlot } from "../lib/plotParser";
|
||||||
import { flattenResult } from "../lib/utility";
|
import { flattenResult } from "../lib/utility";
|
||||||
|
@ -30,6 +31,7 @@ export type DistributionChartProps = {
|
||||||
plot: Plot;
|
plot: Plot;
|
||||||
width?: number;
|
width?: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
xAxis?: "number" | "dateTime";
|
||||||
} & DistributionPlottingSettings;
|
} & DistributionPlottingSettings;
|
||||||
|
|
||||||
export function defaultPlot(distribution: Distribution): Plot {
|
export function defaultPlot(distribution: Distribution): Plot {
|
||||||
|
@ -45,8 +47,102 @@ export function makePlot(record: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DateDistributionChart: React.FC<DistributionChartProps> = (props) => {
|
||||||
|
const {
|
||||||
|
plot,
|
||||||
|
height,
|
||||||
|
showSummary,
|
||||||
|
width,
|
||||||
|
logX,
|
||||||
|
actions = false,
|
||||||
|
xAxis = "dateTime",
|
||||||
|
} = props;
|
||||||
|
// const [xAxis, setXAxis] = React.useState<"dateAndTime" | "numbers">("dateAndTime")
|
||||||
|
const [sized] = useSize((size) => {
|
||||||
|
const shapes = flattenResult(
|
||||||
|
plot.distributions.map((x) =>
|
||||||
|
resultMap(x.distribution.pointSet(), (shape) => ({
|
||||||
|
name: x.name,
|
||||||
|
// color: x.color, // not supported yet
|
||||||
|
continuous: shape.continuous,
|
||||||
|
discrete: shape.discrete,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (shapes.tag === "Error") {
|
||||||
|
return (
|
||||||
|
<ErrorAlert heading="Distribution Error">
|
||||||
|
{distributionErrorToString(shapes.value)}
|
||||||
|
</ErrorAlert>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const spec = buildDateVegaSpec(props);
|
||||||
|
|
||||||
|
let widthProp = width ? width : size.width;
|
||||||
|
if (widthProp < 20) {
|
||||||
|
console.warn(
|
||||||
|
`Width of Distribution is set to ${widthProp}, which is too small`
|
||||||
|
);
|
||||||
|
widthProp = 20;
|
||||||
|
}
|
||||||
|
const domain = shapes.value.flatMap((shape) =>
|
||||||
|
shape.discrete.concat(shape.continuous)
|
||||||
|
);
|
||||||
|
|
||||||
|
const dateData = {
|
||||||
|
name: "default",
|
||||||
|
continuous: [],
|
||||||
|
discrete: [
|
||||||
|
{ dateTime: new Date().getTime() - 1000000, y: 0.3 },
|
||||||
|
{ dateTime: new Date().getTime(), y: 0.5 },
|
||||||
|
{ dateTime: new Date().getTime() + 1000000, y: 0.7 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const dateDomain = [
|
||||||
|
{ dateTime: new Date().getTime() - 1000000, y: 0.2 },
|
||||||
|
{ dateTime: new Date().getTime(), y: 0.5 },
|
||||||
|
{ dateTime: new Date().getTime() + 1000000, y: 0.7 },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ width: widthProp }}>
|
||||||
|
{logX && shapes.value.some(hasMassBelowZero) ? (
|
||||||
|
<ErrorAlert heading="Log Domain Error">
|
||||||
|
Cannot graph distribution with negative values on logarithmic scale.
|
||||||
|
</ErrorAlert>
|
||||||
|
) : (
|
||||||
|
<Vega
|
||||||
|
spec={spec}
|
||||||
|
data={{ data: dateData, domain: dateDomain }}
|
||||||
|
width={widthProp - 10}
|
||||||
|
height={height}
|
||||||
|
actions={actions}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div className="flex justify-center">
|
||||||
|
{showSummary && plot.distributions.length === 1 && (
|
||||||
|
<SummaryTable distribution={plot.distributions[0].distribution} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return sized;
|
||||||
|
};
|
||||||
|
|
||||||
export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
||||||
const { plot, height, showSummary, width, logX, actions = false } = props;
|
const {
|
||||||
|
plot,
|
||||||
|
height,
|
||||||
|
showSummary,
|
||||||
|
width,
|
||||||
|
logX,
|
||||||
|
actions = false,
|
||||||
|
xAxis = "number",
|
||||||
|
} = props;
|
||||||
// const [xAxis, setXAxis] = React.useState<"dateAndTime" | "numbers">("dateAndTime")
|
// const [xAxis, setXAxis] = React.useState<"dateAndTime" | "numbers">("dateAndTime")
|
||||||
const [sized] = useSize((size) => {
|
const [sized] = useSize((size) => {
|
||||||
const shapes = flattenResult(
|
const shapes = flattenResult(
|
||||||
|
@ -81,7 +177,6 @@ export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
||||||
shape.discrete.concat(shape.continuous)
|
shape.discrete.concat(shape.continuous)
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log({domain, data: shapes.value})
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: widthProp }}>
|
<div style={{ width: widthProp }}>
|
||||||
{logX && shapes.value.some(hasMassBelowZero) ? (
|
{logX && shapes.value.some(hasMassBelowZero) ? (
|
||||||
|
@ -89,13 +184,26 @@ export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
||||||
Cannot graph distribution with negative values on logarithmic scale.
|
Cannot graph distribution with negative values on logarithmic scale.
|
||||||
</ErrorAlert>
|
</ErrorAlert>
|
||||||
) : (
|
) : (
|
||||||
<Vega
|
<>
|
||||||
spec={spec}
|
<Vega
|
||||||
data={{ data: shapes.value, domain }}
|
spec={spec}
|
||||||
width={widthProp - 10}
|
data={{ data: shapes.value, domain }}
|
||||||
height={height}
|
width={widthProp - 10}
|
||||||
actions={actions}
|
height={height}
|
||||||
/>
|
actions={actions}
|
||||||
|
/>
|
||||||
|
<div id="CONORDELETETHIS">
|
||||||
|
<DateDistributionChart
|
||||||
|
plot={plot}
|
||||||
|
height={height}
|
||||||
|
showSummary={showSummary}
|
||||||
|
width={width}
|
||||||
|
logX={logX}
|
||||||
|
actions={actions}
|
||||||
|
expY={props.expY}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
{showSummary && plot.distributions.length === 1 && (
|
{showSummary && plot.distributions.length === 1 && (
|
||||||
|
|
361
packages/components/src/lib/dateDistributionSpecBuilder.ts
Normal file
361
packages/components/src/lib/dateDistributionSpecBuilder.ts
Normal file
|
@ -0,0 +1,361 @@
|
||||||
|
import { VisualizationSpec } from "react-vega";
|
||||||
|
import type { LogScale, LinearScale, PowScale, TimeScale } from "vega";
|
||||||
|
|
||||||
|
export type DistributionChartSpecOptions = {
|
||||||
|
/** Set the x scale to be logarithmic by deault */
|
||||||
|
logX: boolean;
|
||||||
|
/** Set the y scale to be exponential by deault */
|
||||||
|
expY: boolean;
|
||||||
|
/** The minimum x coordinate shown on the chart */
|
||||||
|
minX?: number;
|
||||||
|
/** The maximum x coordinate shown on the chart */
|
||||||
|
maxX?: number;
|
||||||
|
/** The title of the chart */
|
||||||
|
title?: string;
|
||||||
|
/** The formatting of the ticks */
|
||||||
|
format?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const timeXScale: TimeScale = {
|
||||||
|
name: "xscale",
|
||||||
|
clamp: true,
|
||||||
|
type: "time",
|
||||||
|
range: "width",
|
||||||
|
nice: false,
|
||||||
|
domain: { data: "domain", field: "dateTime" },
|
||||||
|
};
|
||||||
|
export const timeYScale: TimeScale = {
|
||||||
|
name: "yscale",
|
||||||
|
type: "time",
|
||||||
|
range: "height",
|
||||||
|
domain: { data: "domain", field: "y" },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const defaultTickFormat = "%b %d, %Y %H:%M";
|
||||||
|
|
||||||
|
export function buildDateVegaSpec(
|
||||||
|
specOptions: DistributionChartSpecOptions
|
||||||
|
): VisualizationSpec {
|
||||||
|
const {
|
||||||
|
format = defaultTickFormat,
|
||||||
|
title,
|
||||||
|
minX,
|
||||||
|
maxX,
|
||||||
|
logX,
|
||||||
|
expY,
|
||||||
|
} = specOptions;
|
||||||
|
|
||||||
|
let xScale = timeXScale;
|
||||||
|
if (minX !== undefined && Number.isFinite(minX)) {
|
||||||
|
xScale = { ...xScale, domainMin: minX };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxX !== undefined && Number.isFinite(maxX)) {
|
||||||
|
xScale = { ...xScale, domainMax: maxX };
|
||||||
|
}
|
||||||
|
|
||||||
|
const spec: VisualizationSpec = {
|
||||||
|
$schema: "https://vega.github.io/schema/vega/v5.json",
|
||||||
|
description: "Squiggle plot chart",
|
||||||
|
width: 500,
|
||||||
|
height: 100,
|
||||||
|
padding: 5,
|
||||||
|
data: [{ name: "data" }, { name: "domain" }],
|
||||||
|
signals: [
|
||||||
|
{
|
||||||
|
name: "hover",
|
||||||
|
value: null,
|
||||||
|
on: [
|
||||||
|
{ events: "mouseover", update: "datum" },
|
||||||
|
{ events: "mouseout", update: "null" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "position",
|
||||||
|
value: "[0, 0]",
|
||||||
|
on: [
|
||||||
|
{ events: "mousemove", update: "xy() " },
|
||||||
|
{ events: "mouseout", update: "null" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "position_scaled",
|
||||||
|
value: null,
|
||||||
|
update: "isArray(position) ? invert('xscale', position[0]) : ''",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
scales: [
|
||||||
|
xScale,
|
||||||
|
timeYScale,
|
||||||
|
{
|
||||||
|
name: "color",
|
||||||
|
type: "ordinal",
|
||||||
|
domain: {
|
||||||
|
data: "data",
|
||||||
|
field: "name",
|
||||||
|
},
|
||||||
|
range: { scheme: "blues" },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
axes: [
|
||||||
|
{
|
||||||
|
orient: "bottom",
|
||||||
|
scale: "xscale",
|
||||||
|
labelColor: "#727d93",
|
||||||
|
tickColor: "#fff",
|
||||||
|
tickOpacity: 0.0,
|
||||||
|
domainColor: "#fff",
|
||||||
|
domainOpacity: 0.0,
|
||||||
|
format: format,
|
||||||
|
tickCount: 3,
|
||||||
|
labelOverlap: "greedy",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
marks: [
|
||||||
|
{
|
||||||
|
name: "sample_distributions",
|
||||||
|
type: "group",
|
||||||
|
from: {
|
||||||
|
facet: {
|
||||||
|
name: "distribution_facet",
|
||||||
|
data: "domain",
|
||||||
|
groupby: ["name"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
marks: [
|
||||||
|
{
|
||||||
|
name: "samples",
|
||||||
|
type: "rect",
|
||||||
|
from: { data: "distribution_facet" },
|
||||||
|
encode: {
|
||||||
|
enter: {
|
||||||
|
x: { scale: "xscale", field: "dateTime" },
|
||||||
|
width: { value: 0.5 },
|
||||||
|
|
||||||
|
y: { value: 25, offset: { signal: "height" } },
|
||||||
|
height: { value: 5 },
|
||||||
|
fill: { value: "steelblue" },
|
||||||
|
fillOpacity: { value: 0.8 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "all_distributions",
|
||||||
|
type: "group",
|
||||||
|
from: {
|
||||||
|
facet: {
|
||||||
|
name: "distribution_facet",
|
||||||
|
data: "data",
|
||||||
|
groupby: ["name"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
marks: [
|
||||||
|
{
|
||||||
|
name: "continuous_distribution",
|
||||||
|
type: "group",
|
||||||
|
from: {
|
||||||
|
facet: {
|
||||||
|
name: "continuous_facet",
|
||||||
|
data: "distribution_facet",
|
||||||
|
field: "continuous",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
encode: {
|
||||||
|
update: {},
|
||||||
|
},
|
||||||
|
marks: [
|
||||||
|
{
|
||||||
|
name: "continuous_area",
|
||||||
|
type: "area",
|
||||||
|
from: {
|
||||||
|
data: "continuous_facet",
|
||||||
|
},
|
||||||
|
encode: {
|
||||||
|
update: {
|
||||||
|
// interpolate: { value: "linear" },
|
||||||
|
x: {
|
||||||
|
scale: "xscale",
|
||||||
|
field: "dateTime",
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
scale: "yscale",
|
||||||
|
field: "y",
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
scale: "color",
|
||||||
|
field: { parent: "name" },
|
||||||
|
},
|
||||||
|
y2: {
|
||||||
|
scale: "yscale",
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
fillOpacity: {
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "discrete_distribution",
|
||||||
|
type: "group",
|
||||||
|
from: {
|
||||||
|
facet: {
|
||||||
|
name: "discrete_facet",
|
||||||
|
data: "distribution_facet",
|
||||||
|
field: "discrete",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
marks: [
|
||||||
|
{
|
||||||
|
type: "rect",
|
||||||
|
from: {
|
||||||
|
data: "discrete_facet",
|
||||||
|
},
|
||||||
|
encode: {
|
||||||
|
enter: {
|
||||||
|
width: {
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
x: {
|
||||||
|
scale: "xscale",
|
||||||
|
field: "dateTime",
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
scale: "yscale",
|
||||||
|
field: "y",
|
||||||
|
},
|
||||||
|
y2: {
|
||||||
|
scale: "yscale",
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
scale: "color",
|
||||||
|
field: { parent: "name" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "symbol",
|
||||||
|
from: {
|
||||||
|
data: "discrete_facet",
|
||||||
|
},
|
||||||
|
encode: {
|
||||||
|
enter: {
|
||||||
|
shape: {
|
||||||
|
value: "circle",
|
||||||
|
},
|
||||||
|
size: [{ value: 100 }],
|
||||||
|
tooltip: {
|
||||||
|
signal:
|
||||||
|
"{ probability: datum.y, value: datetime(datum.dateTime) }",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
x: {
|
||||||
|
scale: "xscale",
|
||||||
|
field: "dateTime",
|
||||||
|
offset: 0.5, // if this is not included, the circles are slightly left of center.
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
scale: "yscale",
|
||||||
|
field: "y",
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
scale: "color",
|
||||||
|
field: { parent: "name" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
interactive: false,
|
||||||
|
encode: {
|
||||||
|
enter: {
|
||||||
|
text: {
|
||||||
|
signal: "",
|
||||||
|
},
|
||||||
|
x: { signal: "width", offset: 1 },
|
||||||
|
fill: { value: "black" },
|
||||||
|
fontSize: { value: 20 },
|
||||||
|
align: { value: "right" },
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
text: {
|
||||||
|
signal:
|
||||||
|
"position_scaled ? utcyear(position_scaled) + '-' + utcmonth(position_scaled) + '-' + utcdate(position_scaled) + 'T' + utchours(position_scaled)+':' +utcminutes(position_scaled) : ''",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "rule",
|
||||||
|
encode: {
|
||||||
|
enter: {
|
||||||
|
x: { value: 0 },
|
||||||
|
y: { scale: "yscale", value: 0 },
|
||||||
|
|
||||||
|
y2: {
|
||||||
|
signal: "height",
|
||||||
|
offset: 2,
|
||||||
|
},
|
||||||
|
strokeDash: { value: [5, 5] },
|
||||||
|
},
|
||||||
|
|
||||||
|
update: {
|
||||||
|
x: {
|
||||||
|
signal:
|
||||||
|
"position ? position[0] < 0 ? null : position[0] > width ? null : position[0]: null",
|
||||||
|
},
|
||||||
|
|
||||||
|
opacity: { signal: "position ? 1 : 0" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
legends: [
|
||||||
|
{
|
||||||
|
fill: "color",
|
||||||
|
orient: "top",
|
||||||
|
labelFontSize: 12,
|
||||||
|
encode: {
|
||||||
|
symbols: {
|
||||||
|
update: {
|
||||||
|
fill: [
|
||||||
|
{ test: "length(domain('color')) == 1", value: "transparent" },
|
||||||
|
{ scale: "color", field: "value" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
labels: {
|
||||||
|
interactive: true,
|
||||||
|
update: {
|
||||||
|
fill: [
|
||||||
|
{ test: "length(domain('color')) == 1", value: "transparent" },
|
||||||
|
{ value: "black" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
...(title && {
|
||||||
|
title: {
|
||||||
|
text: title,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
return spec;
|
||||||
|
}
|
|
@ -83,39 +83,29 @@ export function buildVegaSpec(
|
||||||
width: 500,
|
width: 500,
|
||||||
height: 100,
|
height: 100,
|
||||||
padding: 5,
|
padding: 5,
|
||||||
data: [
|
data: [{ name: "data" }, { name: "domain" }],
|
||||||
{name: "data",},
|
|
||||||
{ name: "domain",},
|
|
||||||
],
|
|
||||||
signals: [
|
signals: [
|
||||||
{
|
{
|
||||||
"name": "hover",
|
name: "hover",
|
||||||
"value": null,
|
value: null,
|
||||||
"on": [
|
on: [
|
||||||
{"events": "mouseover", "update": "datum"},
|
{ events: "mouseover", update: "datum" },
|
||||||
{"events": "mouseout", "update": "null"}
|
{ events: "mouseout", update: "null" },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "position",
|
name: "position",
|
||||||
"value": "[0, 0]",
|
value: "[0, 0]",
|
||||||
"on": [
|
on: [
|
||||||
{ "events": "mousemove", "update": "xy() "},
|
{ events: "mousemove", update: "xy() " },
|
||||||
{ "events": "mouseout", "update": "null"},
|
{ events: "mouseout", update: "null" },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "position_scaled",
|
name: "position_scaled",
|
||||||
"value": 0,
|
value: 0,
|
||||||
"update": "position ? invert('xscale', position[0]) : null"
|
update: "position ? invert('xscale', position[0]) : null",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "announcer",
|
|
||||||
"value": "",
|
|
||||||
"update": "hover ? 'Value: ' + hover.x : ''"
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
],
|
],
|
||||||
scales: [
|
scales: [
|
||||||
xScale,
|
xScale,
|
||||||
|
@ -147,7 +137,7 @@ export function buildVegaSpec(
|
||||||
marks: [
|
marks: [
|
||||||
{
|
{
|
||||||
name: "sample_distributions",
|
name: "sample_distributions",
|
||||||
"type": "group",
|
type: "group",
|
||||||
from: {
|
from: {
|
||||||
facet: {
|
facet: {
|
||||||
name: "distribution_facet",
|
name: "distribution_facet",
|
||||||
|
@ -157,22 +147,22 @@ export function buildVegaSpec(
|
||||||
},
|
},
|
||||||
marks: [
|
marks: [
|
||||||
{
|
{
|
||||||
"name": "samples",
|
name: "samples",
|
||||||
"type": "rect",
|
type: "rect",
|
||||||
"from": {"data": "distribution_facet"},
|
from: { data: "distribution_facet" },
|
||||||
"encode": {
|
encode: {
|
||||||
"enter": {
|
enter: {
|
||||||
"x": {"scale": "xscale", "field":"x"},
|
x: { scale: "xscale", field: "x" },
|
||||||
"width": {"value": 0.5},
|
width: { value: 0.5 },
|
||||||
|
|
||||||
"y": {"value": 25, "offset": {"signal": "height"}},
|
y: { value: 25, offset: { signal: "height" } },
|
||||||
"height": {"value": 5},
|
height: { value: 5 },
|
||||||
"fill": {"value": "steelblue"},
|
fill: { value: "steelblue" },
|
||||||
"fillOpacity": {"value": 0.8}
|
fillOpacity: { value: 0.8 },
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "all_distributions",
|
name: "all_distributions",
|
||||||
|
@ -185,7 +175,6 @@ export function buildVegaSpec(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
marks: [
|
marks: [
|
||||||
|
|
||||||
{
|
{
|
||||||
name: "continuous_distribution",
|
name: "continuous_distribution",
|
||||||
type: "group",
|
type: "group",
|
||||||
|
@ -244,7 +233,6 @@ export function buildVegaSpec(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
marks: [
|
marks: [
|
||||||
|
|
||||||
{
|
{
|
||||||
type: "rect",
|
type: "rect",
|
||||||
from: {
|
from: {
|
||||||
|
@ -283,7 +271,6 @@ export function buildVegaSpec(
|
||||||
},
|
},
|
||||||
encode: {
|
encode: {
|
||||||
enter: {
|
enter: {
|
||||||
|
|
||||||
shape: {
|
shape: {
|
||||||
value: "circle",
|
value: "circle",
|
||||||
},
|
},
|
||||||
|
@ -314,42 +301,46 @@ export function buildVegaSpec(
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "text",
|
type: "text",
|
||||||
"interactive": false,
|
interactive: false,
|
||||||
"encode": {
|
encode: {
|
||||||
"enter": {
|
enter: {
|
||||||
"x": {"signal": "width", "offset": 1},
|
x: { signal: "width", offset: 1 },
|
||||||
"fill": {"value": "black"},
|
fill: { value: "black" },
|
||||||
"fontSize": {"value": 20},
|
fontSize: { value: 20 },
|
||||||
"align": {"value": "right"}
|
align: { value: "right" },
|
||||||
},
|
},
|
||||||
"update": {
|
update: {
|
||||||
"text": {"signal": "position_scaled ? format(position_scaled, ',.4r') : ''", }
|
text: {
|
||||||
}
|
signal: "position_scaled ? format(position_scaled, ',.4r') : ''",
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "rule",
|
type: "rule",
|
||||||
"encode": {
|
encode: {
|
||||||
"enter": {
|
enter: {
|
||||||
x: {value: 0},
|
x: { value: 0 },
|
||||||
"y": {"scale": "yscale", "value":0},
|
y: { scale: "yscale", value: 0 },
|
||||||
|
|
||||||
y2: {
|
y2: {
|
||||||
signal: "height",
|
signal: "height",
|
||||||
offset: 2
|
offset: 2,
|
||||||
},
|
},
|
||||||
"strokeDash": {"value": [5, 5]},
|
strokeDash: { value: [5, 5] },
|
||||||
},
|
|
||||||
|
|
||||||
"update": {
|
|
||||||
"x": {"signal": "position ? position[0] < 0 ? null : position[0] > width ? null : position[0]: null"},
|
|
||||||
|
|
||||||
"opacity": {"signal": "position ? 1 : 0"}
|
|
||||||
},
|
},
|
||||||
}
|
|
||||||
|
|
||||||
}
|
update: {
|
||||||
|
x: {
|
||||||
|
signal:
|
||||||
|
"position ? position[0] < 0 ? null : position[0] > width ? null : position[0]: null",
|
||||||
|
},
|
||||||
|
|
||||||
|
opacity: { signal: "position ? 1 : 0" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
legends: [
|
legends: [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user