aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsrichman333 <sarah_n_richman@brown.edu>2023-07-11 12:49:18 -0400
committersrichman333 <sarah_n_richman@brown.edu>2023-07-11 12:49:18 -0400
commite3b5e9fd819a394051c760b37ca14bb8c759f72b (patch)
tree9b88e4b50716108a067b4856ea1cb7e715ff573c /src
parent32f8cd2c70e77fa13f6b9d1fed73dc5c1af11189 (diff)
cleaner + bottom axis shows bigger numbers (like years) better
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/DataVizBox/components/Histogram.tsx83
1 files changed, 50 insertions, 33 deletions
diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
index 14063a068..c7850d8c1 100644
--- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx
+++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
@@ -14,6 +14,8 @@ import { PinProps, PresBox } from "../../trails";
import { Docs } from "../../../../documents/Documents";
import { List } from "../../../../../fields/List";
import './Chart.scss';
+import { minMaxRange } from "../utils/D3Utils";
+import e from "connect-flash";
export interface HistogramProps {
rootDoc: Doc;
@@ -37,6 +39,7 @@ export class Histogram extends React.Component<HistogramProps> {
private _disposers: { [key: string]: IReactionDisposer } = {};
private _histogramRef: React.RefObject<HTMLDivElement> = React.createRef();
private _histogramSvg: d3.Selection<SVGGElement, unknown, null, undefined> | undefined;
+ private numericalData: boolean = false;
@observable _currSelected: SelectedDataPoint | undefined = undefined;
// TODO: nda - some sort of mapping that keeps track of the annotated points so we can easily remove when annotations list updates
@@ -44,12 +47,15 @@ export class Histogram extends React.Component<HistogramProps> {
if (this.props.axes.length < 1) return [];
if (this.props.axes.length < 2) {
var ax0 = this.props.axes[0];
+ if (+this.props.pairs[0][this.props.axes[0]]) { this.numericalData = true;}
return this.props.pairs
?.filter(pair => (!this.incomingLinks.length ? true : Array.from(Object.keys(pair)).some(key => pair[key] && key.startsWith('select'))))
.map(pair => ({ [ax0]: (pair[this.props.axes[0]])}))
};
+
var ax0 = this.props.axes[0];
var ax1 = this.props.axes[1];
+ if (+this.props.pairs[0][this.props.axes[0]]) { this.numericalData = true;}
return this.props.pairs
?.filter(pair => (!this.incomingLinks.length ? true : Array.from(Object.keys(pair)).some(key => pair[key] && key.startsWith('select'))))
.map(pair => ({ [ax0]: (pair[this.props.axes[0]]), [ax1]: (pair[this.props.axes[1]]) }))
@@ -73,6 +79,13 @@ export class Histogram extends React.Component<HistogramProps> {
.map(dvb => dvb.pairs?.filter((pair: { [x: string]: any; }) => pair['select' + dvb.rootDoc[Id]])) // get all the datapoints they have selected field set by incoming anchor
.lastElement();
}
+ @computed get rangeVals(): { xMin?: number; xMax?: number; yMin?: number; yMax?: number } {
+ if (this.numericalData){
+ const data = this.data(this._histogramData);
+ return {xMin: Math.min.apply(null, data), xMax: Math.max.apply(null, data), yMin:0, yMax:0}
+ }
+ return {xMin:0, xMax:0, yMin:0, yMax:0}
+ }
componentWillUnmount() {
Array.from(Object.keys(this._disposers)).forEach(key => this._disposers[key]());
}
@@ -207,26 +220,7 @@ export class Histogram extends React.Component<HistogramProps> {
this.props.pairs.forEach(pair => (pair.selected = pair[this.props.axes[0]] === x && pair[this.props.axes[1]] === y ? true : undefined));
}
- drawDataPoints(data: DataPoint[], idx: number, xScale: d3.ScaleLinear<number, number, never>, yScale: d3.ScaleLinear<number, number, never>) {
- if (this._histogramSvg) {
- const circleClass = '.circle-' + idx;
- this._histogramSvg
- .selectAll(circleClass)
- .data(data)
- .join('circle') // enter append
- .attr('class', `${circleClass} datapoint`)
- .attr('r', '3') // radius
- .attr('cx', d => xScale(d.x))
- .attr('cy', d => yScale(d.y))
- .attr('data-x', d => d.x)
- .attr('data-y', d => d.y);
- }
- }
-
- drawChart = (dataSet: any, width: number, height: number) => {
- d3.select(this._histogramRef.current).select('svg').remove();
- d3.select(this._histogramRef.current).select('.tooltip').remove();
-
+ data = (dataSet: any) => {
var validData = dataSet.filter((d: { [x: string]: unknown; }) => {
var valid = true;
Object.keys(dataSet[0]).map(key => {
@@ -236,13 +230,24 @@ export class Histogram extends React.Component<HistogramProps> {
})
var field = Object.keys(dataSet[0])[0]
const data = validData.map((d: { [x: string]: any; }) => {
- if (+d[field]) {return +d[field] }
+ if (this.numericalData) {return +d[field] }
return d[field]
})
+ return data;
+ }
+
+ drawChart = (dataSet: any, width: number, height: number) => {
+ d3.select(this._histogramRef.current).select('svg').remove();
+ d3.select(this._histogramRef.current).select('.tooltip').remove();
+ var field = Object.keys(dataSet[0])[0]
+ const data = this.data(dataSet);
+
let uniqueArr = [...new Set(data)]
var numBins = uniqueArr.length
- if (+d3.max(data)!) numBins = +d3.max(data)!
+ if (this.numericalData) numBins = this.rangeVals.xMax! - this.rangeVals.xMin! + 1;
+ var startingPoint = this.numericalData==true? this.rangeVals.xMin: 0;
+ console.log(startingPoint)
const svg = (this._histogramSvg = d3
.select(this._histogramRef.current)
@@ -254,19 +259,32 @@ export class Histogram extends React.Component<HistogramProps> {
.attr("transform",
"translate(" + this.props.margin.left + "," + this.props.margin.top + ")"));
- var x = d3.scaleLinear()
- .domain([0, numBins])
- .range([0, width]);
+ var x: any;
+ if (this.numericalData){
+ x = d3.scaleLinear()
+ .domain([this.rangeVals.xMin!, this.rangeVals.xMax!])
+ .range([0, width-(width/numBins)]);
+ }
+ else {
+ x = d3.scaleLinear()
+ .domain([0, numBins])
+ .range([0, width]);
+ }
+
var xAxis = d3.axisBottom(x)
- .ticks(numBins)
- var translateXAxis = 0;
+ .ticks(numBins-1)
+ var translateXAxis = (width/numBins) / 2;
var histogram = d3.histogram()
.value(function(d) {return d})
- .domain([0, numBins])
+ .domain([startingPoint!, numBins+startingPoint!])
.thresholds(x.ticks(numBins))
var bins = histogram(data)
- if (!+d3.max(data)!) { // if the data is strings rather than numbers
+ console.log(this._histogramData)
+ console.log(data)
+ console.log(bins)
+ console.log(this.rangeVals.xMin, this.rangeVals.xMax, numBins)
+ if (!this.numericalData) { // if the data is strings rather than numbers
uniqueArr.sort()
for (let i=0; i<data.length; i++){
var index = 0
@@ -277,10 +295,9 @@ export class Histogram extends React.Component<HistogramProps> {
}
bins[index].push(data[i])
}
- bins.forEach(d => d.x0 = d.x0!+1)
+ bins.forEach(d => d.x0 = d.x0!)
xAxis = d3.axisBottom(x)
- .ticks(numBins)
- .tickValues([0, 1, 2, 3, 4])
+ .ticks(numBins-1)
.tickFormat( i => uniqueArr[i])
.tickPadding(10)
translateXAxis = (width/numBins) / 2;
@@ -316,7 +333,7 @@ export class Histogram extends React.Component<HistogramProps> {
.enter()
.append("rect")
.attr("x", 1)
- .attr("transform", function(d) { return "translate(" + x(d.x0! - 1) + "," + y(d.length) + ")"; })
+ .attr("transform", function(d) { return "translate(" + x(d.x0!) + "," + y(d.length) + ")"; })
.attr("width", width/(numBins))
.attr("height", function(d) { return height - y(d.length); })
.attr("style", "outline: thin solid black;")