Commit e3841e82 authored by Vasily Belolapotkov's avatar Vasily Belolapotkov

handle preview y scale independently

parent fee16c6a
......@@ -7,11 +7,13 @@ import {
IRange,
Timestamp,
} from './types';
import { adjustRange, getAdjustedYRange } from '../utils/state';
export function makeChartState(chartData: IChartData): IChartState {
const yLabelsCount = 6;
const { xAxis, dataSets } = chartData;
const xTotalRange = getXTotalRange();
const dataSetsYRange: IRange[] = getDataSetsYRange();
const yTotalRange = getYTotalRange();
const yLabels = getYLabels(yTotalRange);
......@@ -30,9 +32,10 @@ export function makeChartState(chartData: IChartData): IChartState {
inspectorIsActive: false,
inspectorValues: getInspectorValues(),
xScale: 0.3,
yScale: 1,
xOffset: 0.7,
yScale: 1,
yOffset: 0,
previewYScale: 1,
};
updateYViewRange();
......@@ -46,6 +49,10 @@ export function makeChartState(chartData: IChartData): IChartState {
return { start, end, distance };
}
function getDataSetsYRange() {
return dataSets.map(dataSet => getAdjustedYRange(dataSet, yLabelsCount));
}
function getYTotalRange(startIndex?: number, endIndex?: number): IRange {
let start = 0;
let end = 1;
......@@ -74,23 +81,7 @@ export function makeChartState(chartData: IChartData): IChartState {
const distance = end - start;
const range = { start, end, distance };
return adjustYRange(range);
}
function adjustYRange(range: IRange) {
const roughLabelStep = range.distance / yLabelsCount;
const y = Math.ceil(Math.log10(roughLabelStep) - 1);
const pow10y = Math.pow(10, y);
const labelStep = Math.ceil(roughLabelStep / pow10y) * pow10y;
const adjustedStart = labelStep * Math.floor(range.start / labelStep);
const adjustedEnd = adjustedStart + labelStep * yLabelsCount;
return {
start: adjustedStart,
end: adjustedEnd,
distance: adjustedEnd - adjustedStart,
};
return adjustRange(range, yLabelsCount);
}
function getYLabels(range: IRange): number[] {
......@@ -142,6 +133,44 @@ export function makeChartState(chartData: IChartData): IChartState {
const currentDataSet = dataSets.find(dS => dS.id === dataSet.id);
currentDataSet.isVisible = !currentDataSet.isVisible;
updateYViewRange();
updatePreviewYScale();
}
function updatePreviewYScale() {
const range = getYPreviewRange();
state.previewYScale = range.distance / yTotalRange.distance;
}
function getYPreviewRange(): IRange {
let range: IRange;
state.dataSets.forEach((dataSet, index) => {
if (!dataSet.isVisible) {
return;
}
const dataSetRange = dataSetsYRange[index];
if (!range) {
range = dataSetRange;
return;
}
range.start = Math.min(range.start, dataSetRange.start);
range.end = Math.max(range.end, dataSetRange.end);
});
if (!range) {
range = {
start: 0,
end: 1,
distance: 1,
};
} else {
range.distance = range.end - range.start;
}
return range;
}
function updateYViewRange(): void {
......
......@@ -40,8 +40,8 @@ export const makePreviewPlots: ChartComponentFactory<ISize> = function(
size: plotSize,
xScale: 1,
xOffset: 0,
yScale: chartState.yScale,
yOffset: chartState.yOffset,
yScale: chartState.previewYScale,
yOffset: 0,
});
plots.renderDataSets(chartState.xAxis, chartState.dataSets);
}
......@@ -64,8 +64,8 @@ export const makePreviewPlots: ChartComponentFactory<ISize> = function(
}
function handleDataSetVisibilityChanged() {
const { dataSets, yScale, yOffset } = stateController.getState();
const { dataSets, previewYScale } = stateController.getState();
plots.updateDataSetsVisibility(dataSets);
plots.setYViewRange(yScale, yOffset);
plots.setYViewRange(previewYScale, 0);
}
};
......@@ -18,9 +18,12 @@ export interface IDataSet {
isVisible: boolean;
}
export interface IRange {
export interface IBaseRange {
start: number;
end: number;
}
export interface IRange extends IBaseRange {
distance: number;
}
......@@ -41,16 +44,6 @@ export interface ISize {
height: number;
}
export interface IZoomConfig {
x: boolean;
y: boolean;
}
export interface IAxesConfig {
x: boolean;
y: boolean;
}
export interface ICoordinates {
x: number;
y: number;
......@@ -65,6 +58,7 @@ export interface IChartState {
xOffset: number;
yScale: number;
yOffset: number;
previewYScale: number;
yLabels: number[];
inspectorIsActive: boolean;
inspectorValues: IInspectorValues;
......
import { IBaseRange, IDataSet, IRange } from '../chart-components/types';
export function getDataSetMinMax(
dataSet: IDataSet,
startIndex?: number,
endIndex?: number,
): IBaseRange {
let start = 0;
let end = 1;
const startAt = typeof startIndex === 'number' ? Math.max(startIndex, 0) : 0;
const maxIndex = dataSet.values.length - 1;
const endAt =
typeof endIndex === 'number' ? Math.min(endIndex, maxIndex) : maxIndex;
for (let i = startAt; i < endAt + 1; i = i + 1) {
const value = dataSet.values[i];
if (value < start) {
start = value;
}
if (value > end) {
end = value;
}
}
return { start, end };
}
export function getAdjustedYRange(dataSet: IDataSet, stepsCount: number): IRange {
const { start, end } = getDataSetMinMax(dataSet);
const distance = end - start;
return adjustRange({ start, end, distance }, stepsCount);
}
export function adjustRange(range: IRange, stepsCount: number) {
const roughLabelStep = range.distance / stepsCount;
const y = Math.ceil(Math.log10(roughLabelStep) - 1);
const pow10y = Math.pow(10, y);
const labelStep = Math.ceil(roughLabelStep / pow10y) * pow10y;
const adjustedStart = labelStep * Math.floor(range.start / labelStep);
const adjustedEnd = adjustedStart + labelStep * stepsCount;
return {
start: adjustedStart,
end: adjustedEnd,
distance: adjustedEnd - adjustedStart,
};
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment