Merge pull request #14 from foretold-app/improvements/1100
Improvements/1100
This commit is contained in:
commit
f1f75df73b
|
@ -78,7 +78,7 @@ module Menu = {
|
||||||
<Item href={routeToPath(DistBuilder)} key="dist-builder">
|
<Item href={routeToPath(DistBuilder)} key="dist-builder">
|
||||||
{"Dist Builder" |> E.ste}
|
{"Dist Builder" |> E.ste}
|
||||||
</Item>
|
</Item>
|
||||||
<Item href={routeToPath(DistBuilder2)} key="dist-builder">
|
<Item href={routeToPath(DistBuilder2)} key="dist-builder-2">
|
||||||
{"Dist Builder 2" |> E.ste}
|
{"Dist Builder 2" |> E.ste}
|
||||||
</Item>
|
</Item>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
|
@ -38,7 +38,7 @@ module DemoDist = {
|
||||||
let continuous: DistTypes.xyShape = {xs, ys};
|
let continuous: DistTypes.xyShape = {xs, ys};
|
||||||
<Antd.Card title={"Distribution" |> E.ste}>
|
<Antd.Card title={"Distribution" |> E.ste}>
|
||||||
<div className=Styles.spacer />
|
<div className=Styles.spacer />
|
||||||
<DistributionPlot height=200 continuous />
|
<DistributionPlot continuous />
|
||||||
</Antd.Card>;
|
</Antd.Card>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -208,4 +208,4 @@ let make = (~distPlus: DistTypes.distPlus) => {
|
||||||
);
|
);
|
||||||
<div> chart chart2 {table(distPlus, x)} </div>;
|
<div> chart chart2 {table(distPlus, x)} </div>;
|
||||||
// chart
|
// chart
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,15 +12,14 @@ export class CdfChartD3 {
|
||||||
this.attrs = {
|
this.attrs = {
|
||||||
svgWidth: 400,
|
svgWidth: 400,
|
||||||
svgHeight: 400,
|
svgHeight: 400,
|
||||||
|
|
||||||
marginTop: 5,
|
marginTop: 5,
|
||||||
marginBottom: 5,
|
marginBottom: 5,
|
||||||
marginRight: 50,
|
marginRight: 50,
|
||||||
marginLeft: 5,
|
marginLeft: 5,
|
||||||
|
|
||||||
container: null,
|
container: null,
|
||||||
minX: false,
|
minX: null,
|
||||||
maxX: false,
|
maxX: null,
|
||||||
scale: 'linear',
|
scale: 'linear',
|
||||||
timeScale: null,
|
timeScale: null,
|
||||||
showDistributionLines: true,
|
showDistributionLines: true,
|
||||||
|
@ -54,11 +53,20 @@ export class CdfChartD3 {
|
||||||
this.formatDates = this.formatDates.bind(this);
|
this.formatDates = this.formatDates.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} name
|
||||||
|
* @param value
|
||||||
|
* @returns {CdfChartD3}
|
||||||
|
*/
|
||||||
set(name, value) {
|
set(name, value) {
|
||||||
_.set(this.attrs, [name], value);
|
_.set(this.attrs, [name], value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param data
|
||||||
|
* @returns {CdfChartD3}
|
||||||
|
*/
|
||||||
data(data) {
|
data(data) {
|
||||||
this.attrs.data = data;
|
this.attrs.data = data;
|
||||||
this.attrs.data.continuous = data.continuous || {
|
this.attrs.data.continuous = data.continuous || {
|
||||||
|
@ -78,6 +86,42 @@ export class CdfChartD3 {
|
||||||
console.error('Container for D3 is not defined.');
|
console.error('Container for D3 is not defined.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!['log', 'linear'].includes(this.attrs.scale)) {
|
||||||
|
console.error('Scale should be either "log" or "linear".');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log Scale.
|
||||||
|
if (this.attrs.scale === 'log') {
|
||||||
|
this.logFilter('continuous');
|
||||||
|
this.logFilter('discrete');
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
this.attrs.scale === 'log'
|
||||||
|
&& this.attrs.minX !== null
|
||||||
|
&& this.attrs.minX < 0
|
||||||
|
) {
|
||||||
|
console.warn('minX should be positive.');
|
||||||
|
this.attrs.minX = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fields.
|
||||||
|
const fields = [
|
||||||
|
'marginLeft', 'marginRight',
|
||||||
|
'marginTop', 'marginBottom',
|
||||||
|
'svgWidth', 'svgHeight',
|
||||||
|
'yMaxContinuousDomainFactor',
|
||||||
|
'yMaxDiscreteDomainFactor',
|
||||||
|
'logBase',
|
||||||
|
];
|
||||||
|
for (const field of fields) {
|
||||||
|
if (!_.isNumber(this.attrs[field])) {
|
||||||
|
console.error(`${field} should be a number.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sets the width from the DOM element.
|
// Sets the width from the DOM element.
|
||||||
const containerRect = this._container.node().getBoundingClientRect();
|
const containerRect = this._container.node().getBoundingClientRect();
|
||||||
if (containerRect.width > 0) {
|
if (containerRect.width > 0) {
|
||||||
|
@ -134,6 +178,12 @@ export class CdfChartD3 {
|
||||||
const yMin = d3.min(this.attrs.data.continuous.ys);
|
const yMin = d3.min(this.attrs.data.continuous.ys);
|
||||||
const yMax = d3.max(this.attrs.data.continuous.ys);
|
const yMax = d3.max(this.attrs.data.continuous.ys);
|
||||||
|
|
||||||
|
// Errors.
|
||||||
|
if (!_.isFinite(xMin)) return console.error('xMin is undefined');
|
||||||
|
if (!_.isFinite(xMax)) return console.error('xMax is undefined');
|
||||||
|
if (!_.isFinite(yMin)) return console.error('yMin is undefined');
|
||||||
|
if (!_.isFinite(yMax)) return console.error('yMax is undefined');
|
||||||
|
|
||||||
// X-domains.
|
// X-domains.
|
||||||
const yMaxDomainFactor = _.get(this.attrs, 'yMaxContinuousDomainFactor', 1);
|
const yMaxDomainFactor = _.get(this.attrs, 'yMaxContinuousDomainFactor', 1);
|
||||||
const xMinDomain = xMin;
|
const xMinDomain = xMin;
|
||||||
|
@ -142,7 +192,7 @@ export class CdfChartD3 {
|
||||||
const yMaxDomain = yMax * yMaxDomainFactor;
|
const yMaxDomain = yMax * yMaxDomainFactor;
|
||||||
|
|
||||||
// X-scale.
|
// X-scale.
|
||||||
let xScale = this.attrs.scale === 'linear'
|
const xScale = this.attrs.scale === 'linear'
|
||||||
? d3.scaleLinear()
|
? d3.scaleLinear()
|
||||||
.domain([xMinDomain, xMaxDomain])
|
.domain([xMinDomain, xMaxDomain])
|
||||||
.range([0, this.calc.chartWidth])
|
.range([0, this.calc.chartWidth])
|
||||||
|
@ -210,16 +260,6 @@ export class CdfChartD3 {
|
||||||
// Y-axis.
|
// Y-axis.
|
||||||
const yAxis = d3.axisRight(yScale);
|
const yAxis = d3.axisRight(yScale);
|
||||||
|
|
||||||
// Objects.
|
|
||||||
const line = d3.line()
|
|
||||||
.x(d => xScale(d.x))
|
|
||||||
.y(d => yScale(d.y));
|
|
||||||
|
|
||||||
const area = d3.area()
|
|
||||||
.x(d => xScale(d.x))
|
|
||||||
.y1(d => yScale(d.y))
|
|
||||||
.y0(this.calc.chartHeight);
|
|
||||||
|
|
||||||
// Add axis.
|
// Add axis.
|
||||||
this.chart
|
this.chart
|
||||||
.createObject({ tag: 'g', selector: 'x-axis' })
|
.createObject({ tag: 'g', selector: 'x-axis' })
|
||||||
|
@ -233,6 +273,11 @@ export class CdfChartD3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw area.
|
// Draw area.
|
||||||
|
const area = d3.area()
|
||||||
|
.x(d => xScale(d.x))
|
||||||
|
.y1(d => yScale(d.y))
|
||||||
|
.y0(this.calc.chartHeight);
|
||||||
|
|
||||||
this.chart
|
this.chart
|
||||||
.createObjectsWithData({
|
.createObjectsWithData({
|
||||||
tag: 'path',
|
tag: 'path',
|
||||||
|
@ -245,6 +290,10 @@ export class CdfChartD3 {
|
||||||
|
|
||||||
// Draw line.
|
// Draw line.
|
||||||
if (this.attrs.showDistributionLines) {
|
if (this.attrs.showDistributionLines) {
|
||||||
|
const line = d3.line()
|
||||||
|
.x(d => xScale(d.x))
|
||||||
|
.y(d => yScale(d.y));
|
||||||
|
|
||||||
this.chart
|
this.chart
|
||||||
.createObjectsWithData({
|
.createObjectsWithData({
|
||||||
tag: 'path',
|
tag: 'path',
|
||||||
|
@ -454,7 +503,7 @@ export class CdfChartD3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {name} key
|
* @param {string} key
|
||||||
* @returns {{x: number[], y: number[]}}
|
* @returns {{x: number[], y: number[]}}
|
||||||
*/
|
*/
|
||||||
getDataPoints(key) {
|
getDataPoints(key) {
|
||||||
|
@ -473,6 +522,29 @@ export class CdfChartD3 {
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} key
|
||||||
|
* @returns {{x: number[], y: number[]}}
|
||||||
|
*/
|
||||||
|
logFilter(key) {
|
||||||
|
const xs = [];
|
||||||
|
const ys = [];
|
||||||
|
const emptyShape = { xs: [], ys: [] };
|
||||||
|
const data = _.get(this.attrs.data, key, emptyShape);
|
||||||
|
|
||||||
|
for (let i = 0, len = data.xs.length; i < len; i++) {
|
||||||
|
const x = data.xs[i];
|
||||||
|
const y = data.ys[i];
|
||||||
|
if (x > 0) {
|
||||||
|
xs.push(x);
|
||||||
|
ys.push(y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_.set(this.attrs.data, [key, 'xs'], xs);
|
||||||
|
_.set(this.attrs.data, [key, 'ys'], ys);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} key
|
* @param {string} key
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
|
|
|
@ -46,13 +46,13 @@ function CdfChartReact(props) {
|
||||||
.set('marginTop', 5)
|
.set('marginTop', 5)
|
||||||
.set('showDistributionLines', props.showDistributionLines)
|
.set('showDistributionLines', props.showDistributionLines)
|
||||||
.set('showDistributionYAxis', props.showDistributionYAxis)
|
.set('showDistributionYAxis', props.showDistributionYAxis)
|
||||||
.set('verticalLine', props.verticalLine)
|
.set('verticalLine', props.verticalLine || 110)
|
||||||
.set('showVerticalLine', props.showVerticalLine)
|
.set('showVerticalLine', props.showVerticalLine)
|
||||||
.set('container', containerRef.current)
|
.set('container', containerRef.current)
|
||||||
.set('scale', scale)
|
.set('scale', scale)
|
||||||
.set('timeScale', props.timeScale)
|
.set('timeScale', props.timeScale)
|
||||||
.set('yMaxContinuousDomainFactor', props.yMaxContinuousDomainFactor)
|
.set('yMaxContinuousDomainFactor', props.yMaxContinuousDomainFactor || 1)
|
||||||
.set('yMaxDiscreteDomainFactor', props.yMaxDiscreteDomainFactor)
|
.set('yMaxDiscreteDomainFactor', props.yMaxDiscreteDomainFactor || 1)
|
||||||
.data({
|
.data({
|
||||||
continuous: props.continuous,
|
continuous: props.continuous,
|
||||||
discrete: props.discrete,
|
discrete: props.discrete,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user