1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
import React = require("react");
import { action, computed, reaction } from "mobx";
import { observer } from "mobx-react";
import { Utils as DashUtils } from '../../../Utils';
import { NominalVisualBinRange } from "../model/binRanges/NominalVisualBinRange";
import "../utils/Extensions";
import { StyleConstants } from "../utils/StyleContants";
import { HistogramBox } from "./HistogramBox";
import "./HistogramLabelPrimitives.scss";
import { HistogramPrimitivesProps } from "./HistogramBoxPrimitives";
@observer
export class HistogramLabelPrimitives extends React.Component<HistogramPrimitivesProps> {
componentDidMount() {
reaction(() => [this.props.HistoBox.props.PanelWidth(), this.props.HistoBox.SizeConverter.LeftOffset, this.props.HistoBox.VisualBinRanges.length],
(fields) => HistogramLabelPrimitives.computeLabelAngle(fields[0], fields[1], this.props.HistoBox), { fireImmediately: true });
}
@action
static computeLabelAngle(panelWidth: number, leftOffset: number, histoBox: HistogramBox) {
const textWidth = 30;
if (panelWidth > 0 && histoBox.VisualBinRanges.length && histoBox.VisualBinRanges[0] instanceof NominalVisualBinRange) {
let space = (panelWidth - leftOffset * 2) / histoBox.VisualBinRanges[0].GetBins().length;
histoBox.SizeConverter.SetLabelAngle(Math.min(Math.PI / 2, Math.max(Math.PI / 6, textWidth / space * Math.PI / 2)));
} else if (histoBox.SizeConverter.LabelAngle) {
histoBox.SizeConverter.SetLabelAngle(0);
}
}
@computed get xaxislines() { return this.renderGridLinesAndLabels(0); }
@computed get yaxislines() { return this.renderGridLinesAndLabels(1); }
private renderGridLinesAndLabels(axis: number) {
let sc = this.props.HistoBox.SizeConverter;
let vb = this.props.HistoBox.VisualBinRanges;
if (!vb.length || !sc.Initialized) {
return (null);
}
let dim = (axis === 0 ? this.props.HistoBox.props.PanelWidth() : this.props.HistoBox.props.PanelHeight()) / ((axis === 0 && vb[axis] instanceof NominalVisualBinRange) ?
(12 + 5) : // (<number>FontStyles.AxisLabel.fontSize + 5)));
sc.MaxLabelSizes[axis].coords[axis] + 5);
let labels = vb[axis].GetLabels();
return labels.reduce((prims, binLabel, i) => {
let r = sc.DataToScreenRange(binLabel.minValue!, binLabel.maxValue!, axis);
if (i % Math.ceil(labels.length / dim) === 0 && binLabel.label) {
const label = binLabel.label.Truncate(StyleConstants.MAX_CHAR_FOR_HISTOGRAM_LABELS, "...");
const textHeight = 14; const textWidth = 30;
let xStart = (axis === 0 ? r.xFrom + (r.xTo - r.xFrom) / 2.0 : r.xFrom - 10 - textWidth);
let yStart = (axis === 1 ? r.yFrom - textHeight / 2 : r.yFrom);
if (axis === 0 && vb[axis] instanceof NominalVisualBinRange) {
let space = (r.xTo - r.xFrom) / sc.RenderDimension * this.props.HistoBox.props.PanelWidth();
xStart += Math.max(textWidth / 2, (1 - textWidth / space) * textWidth / 2) - textHeight / 2;
}
let xPercent = axis === 1 ? `${xStart}px` : `${xStart / sc.RenderDimension * 100}%`;
let yPercent = axis === 0 ? `${this.props.HistoBox.props.PanelHeight() - sc.BottomOffset - textHeight}px` : `${yStart / sc.RenderDimension * 100}%`;
prims.push(
<div className="histogramLabelPrimitives-placer" key={DashUtils.GenerateGuid()} style={{ transform: `translate(${xPercent}, ${yPercent})` }}>
<div className="histogramLabelPrimitives-gridlabel" style={{ transform: `rotate(${axis === 0 ? sc.LabelAngle : 0}rad)` }}>
{label}
</div>
</div>
);
}
return prims;
}, [] as JSX.Element[]);
}
render() {
let xaxislines = this.xaxislines;
let yaxislines = this.yaxislines;
return <div className="histogramLabelPrimitives-container">
{xaxislines}
{yaxislines}
</div>;
}
}
|