Browse Source

Merge branch 'time-value-order-#5' into 'main'

Draft:  time/value order change attempt

See merge request chartwerk/line-pod!8
merge-requests/8/merge
Alexey Velikiy 3 years ago
parent
commit
bbb8d2745a
  1. 6
      examples/demo.html
  2. 12
      examples/demo_live.html
  3. 4
      examples/demo_vertical.html
  4. 2
      package.json
  5. 90
      src/index.ts

6
examples/demo.html

@ -12,9 +12,9 @@
<script type="text/javascript"> <script type="text/javascript">
const startTime = 1590590148; const startTime = 1590590148;
const arrayLength = 20; const arrayLength = 20;
const data1 = Array.from({ length: arrayLength }, (el, idx) => [Math.floor(Math.random() * 40), startTime + idx * 10000]); const data1 = Array.from({ length: arrayLength }, (el, idx) => [startTime + idx * 10000, Math.floor(Math.random() * 40)]);
const data2 = Array.from({ length: arrayLength }, (el, idx) => [Math.floor(Math.random() * 100), startTime + idx * 10000]); const data2 = Array.from({ length: arrayLength }, (el, idx) => [startTime + idx * 10000, Math.floor(Math.random() * 100)]);
const data3 = Array.from({ length: arrayLength }, (el, idx) => [Math.floor(Math.random() * 20) + 90, startTime + idx * 10000]); const data3 = Array.from({ length: arrayLength }, (el, idx) => [startTime + idx * 10000, Math.floor(Math.random() * 20) + 90]);
const zoomIn = (ranges) => { const range = ranges[0]; options.axis.x.range = range; pod.updateData(undefined, options) } const zoomIn = (ranges) => { const range = ranges[0]; options.axis.x.range = range; pod.updateData(undefined, options) }
const zoomOut = (ranges) => { console.log('zoomout'); options.axis.x.range = undefined; pod.updateData(undefined, options) } const zoomOut = (ranges) => { console.log('zoomout'); options.axis.x.range = undefined; pod.updateData(undefined, options) }
let options = { let options = {

12
examples/demo_live.html

@ -14,9 +14,9 @@
<script type="text/javascript"> <script type="text/javascript">
const startTime = 1590590148; const startTime = 1590590148;
const arrayLength = 100; const arrayLength = 100;
const data1 = Array.from({ length: arrayLength }, (el, idx) => [Math.floor(Math.random() * 40), startTime + idx * 10000]); const data1 = Array.from({ length: arrayLength }, (el, idx) => [startTime + idx * 10000, Math.floor(Math.random() * 40)]);
const data2 = Array.from({ length: arrayLength }, (el, idx) => [Math.floor(Math.random() * 100), startTime + idx * 10000]); const data2 = Array.from({ length: arrayLength }, (el, idx) => [startTime + idx * 10000, Math.floor(Math.random() * 100)]);
const data3 = Array.from({ length: arrayLength }, (el, idx) => [Math.floor(Math.random() * 20) + 90, startTime + idx * 10000]); const data3 = Array.from({ length: arrayLength }, (el, idx) => [startTime + idx * 10000, Math.floor(Math.random() * 20) + 90]);
let options = { renderLegend: false, usePanning: false, axis: { y: { invert: false, range: [0, 350] }, x: { format: 'time' } } }; let options = { renderLegend: false, usePanning: false, axis: { y: { invert: false, range: [0, 350] }, x: { format: 'time' } } };
var pod = new LinePod( var pod = new LinePod(
document.getElementById('chart'), document.getElementById('chart'),
@ -31,9 +31,9 @@
let rerenderIdx = arrayLength; let rerenderIdx = arrayLength;
var test = setInterval(() => { var test = setInterval(() => {
rerenderIdx += 1; rerenderIdx += 1;
const d1 = [Math.floor(Math.random() * 40), startTime + rerenderIdx * 10000]; const d1 = [startTime + rerenderIdx * 10000, Math.floor(Math.random() * 20) + 90];
const d2 = [Math.floor(Math.random() * 100), startTime + rerenderIdx * 10000]; const d2 = [startTime + rerenderIdx * 10000, Math.floor(Math.random() * 100)];
const d3 = [Math.floor(Math.random() * 20) + 90, startTime + rerenderIdx * 10000]; const d3 = [startTime + rerenderIdx * 10000, Math.floor(Math.random() * 20) + 90];
console.time('rerender'); console.time('rerender');
pod.appendData([d1, d2, d3]); pod.appendData([d1, d2, d3]);

4
examples/demo_vertical.html

@ -66,8 +66,8 @@
function createDatapoints(arrayLength, startTime, randomValue, randomOffset = 0) { function createDatapoints(arrayLength, startTime, randomValue, randomOffset = 0) {
return Array.from({ length: arrayLength }, (el, idx) => [ return Array.from({ length: arrayLength }, (el, idx) => [
startTime + idx * 10000, // y axis Math.floor(Math.random() * randomValue) + randomOffset, // x axis
Math.floor(Math.random() * randomValue) + randomOffset // x axis startTime + idx * 10000 // y axis
]); ]);
} }

2
package.json

@ -15,7 +15,7 @@
"author": "CorpGlory", "author": "CorpGlory",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@chartwerk/core": "^0.1.1" "@chartwerk/core": "^0.2.0"
}, },
"devDependencies": { "devDependencies": {
"@types/d3": "5.16.4", "@types/d3": "5.16.4",

90
src/index.ts

@ -67,8 +67,8 @@ export class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
initLineGenerator(): void { initLineGenerator(): void {
this.lineGenerator = this.d3.line() this.lineGenerator = this.d3.line()
.x(d => this.xScale(d[1])) .x(d => this.xScale(d[0]))
.y(d => this.yScale(d[0])); .y(d => this.yScale(d[1]));
} }
public appendData(data: [number, number][]): void { public appendData(data: [number, number][]): void {
@ -93,8 +93,8 @@ export class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
if(this.series[idx].renderDots === true) { if(this.series[idx].renderDots === true) {
this.metricContainer.selectAll(`.metric-circle-${idx}`) this.metricContainer.selectAll(`.metric-circle-${idx}`)
.data(this.series[idx].datapoints) .data(this.series[idx].datapoints)
.attr('cx', d => this.xScale(d[1])) .attr('cx', d => this.xScale(d[0]))
.attr('cy', d => this.yScale(d[0])); .attr('cy', d => this.yScale(d[1]));
this._renderDots([data[idx]], idx); this._renderDots([data[idx]], idx);
} }
@ -114,8 +114,8 @@ export class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
.attr('fill', this.getSerieColor(serieIdx)) .attr('fill', this.getSerieColor(serieIdx))
.attr('r', METRIC_CIRCLE_RADIUS) .attr('r', METRIC_CIRCLE_RADIUS)
.style('pointer-events', 'none') .style('pointer-events', 'none')
.attr('cx', d => this.xScale(d[1])) .attr('cx', d => this.xScale(d[0]))
.attr('cy', d => this.yScale(d[0])); .attr('cy', d => this.yScale(d[1]));
} }
_renderLines(datapoints: number[][], serieIdx: number): void { _renderLines(datapoints: number[][], serieIdx: number): void {
@ -153,10 +153,10 @@ export class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
.data(dataPairs) .data(dataPairs)
.enter() .enter()
.append('line') .append('line')
.attr('x1', d => this.xScale(d[0][1])) .attr('x1', d => this.xScale(d[0][0]))
.attr('x2', d => this.xScale(d[1][1])) .attr('x2', d => this.xScale(d[1][0]))
.attr('y1', d => this.yScale(d[0][0])) .attr('y1', d => this.yScale(d[0][1]))
.attr('y2', d => this.yScale(d[1][0])) .attr('y2', d => this.yScale(d[1][1]))
.attr('stroke-opacity', 0.7) .attr('stroke-opacity', 0.7)
.style('stroke-width', 1) .style('stroke-width', 1)
.style('stroke', d => { .style('stroke', d => {
@ -178,52 +178,6 @@ export class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
if(metricOptions.renderDots === true) { if(metricOptions.renderDots === true) {
this._renderDots(datapoints, metricOptions.serieIdx); this._renderDots(datapoints, metricOptions.serieIdx);
} }
let upperBoundDatapoints = [];
let lowerBoundDatapoints = [];
if(
this.options.bounds !== undefined &&
this.options.bounds.upper !== undefined &&
this.options.bounds.lower !== undefined
) {
this.series.forEach(serie => {
if(serie.target === this.formatedBound(this.options.bounds.upper, metricOptions.target)) {
upperBoundDatapoints = serie.datapoints;
}
if(serie.target === this.formatedBound(this.options.bounds.lower, metricOptions.target)) {
lowerBoundDatapoints = serie.datapoints;
}
});
}
if(upperBoundDatapoints.length > 0 && lowerBoundDatapoints.length > 0) {
const zip = (arr1, arr2) => arr1.map((k, i) => [k[0],k[1], arr2[i][0]]);
const data = zip(upperBoundDatapoints, lowerBoundDatapoints);
this.metricContainer.append('path')
.datum(data)
.attr('fill', metricOptions.color)
.attr('stroke', 'none')
.attr('opacity', '0.3')
.attr('d', this.d3.area()
.x((d: number[]) => this.xScale(d[1]))
.y0((d: number[]) => this.yScale(d[0]))
.y1((d: number[]) => this.yScale(d[2]))
)
}
if(metricOptions.confidence > 0) {
this.metricContainer.append('path')
.datum(datapoints)
.attr('fill', metricOptions.color)
.attr('stroke', 'none')
.attr('opacity', '0.3')
.attr('d', this.d3.area()
.x((d: [number, number]) => this.xScale(d[1]))
.y0((d: [number, number]) => this.yScale(d[0] + metricOptions.confidence))
.y1((d: [number, number]) => this.yScale(d[0] - metricOptions.confidence))
)
}
} }
updateCrosshair(): void { updateCrosshair(): void {
@ -324,16 +278,16 @@ export class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
} }
getClosestIndex(datapoints: [number, number][], xValue: number, yValue: number): number { getClosestIndex(datapoints: [number, number][], xValue: number, yValue: number): number {
let columnIdx; // 0 for y value, 1 for x value let columnIdx; // 1 for y value, 0 for x value
let value; // xValue ot y Value let value; // xValue ot y Value
switch(this.options.crosshair.orientation) { switch(this.options.crosshair.orientation) {
case CrosshairOrientation.HORIZONTAL: case CrosshairOrientation.HORIZONTAL:
columnIdx = 0; columnIdx = 0;
value = yValue; value = xValue;
break; break;
case CrosshairOrientation.VERTICAL: case CrosshairOrientation.VERTICAL:
columnIdx = 1; columnIdx = 1;
value = xValue; value = yValue;
break; break;
case CrosshairOrientation.BOTH: case CrosshairOrientation.BOTH:
// TODO: maybe use voronoi // TODO: maybe use voronoi
@ -364,7 +318,7 @@ export class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
} }
getValueInterval(columnIdx: number): number | undefined { getValueInterval(columnIdx: number): number | undefined {
// columnIdx: 0 for y, 1 for x // columnIdx: 1 for y, 0 for x
// inverval: x/y value interval between data points // inverval: x/y value interval between data points
// TODO: move it to base/state instead of timeInterval // TODO: move it to base/state instead of timeInterval
const intervals = _.map(this.series, serie => { const intervals = _.map(this.series, serie => {
@ -429,8 +383,8 @@ export class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
return; return;
} }
const yPosition = this.yScale(closestDatapoint[0]); const xPosition = this.xScale(closestDatapoint[0]);
const xPosition = this.xScale(closestDatapoint[1]); const yPosition = this.yScale(closestDatapoint[1]);
this.moveCrosshairCircle(xPosition, yPosition, serieIdx); this.moveCrosshairCircle(xPosition, yPosition, serieIdx);
points.push({ points.push({
@ -448,20 +402,20 @@ export class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
if(useOutOfRange === false) { if(useOutOfRange === false) {
return false; return false;
} }
let columnIdx; // 0 for y value, 1 for x value let columnIdx; // 1 for y value, 0 for x value
let value; // xValue ot y Value let value; // xValue ot y Value
switch(this.options.crosshair.orientation) { switch(this.options.crosshair.orientation) {
case CrosshairOrientation.HORIZONTAL: case CrosshairOrientation.VERTICAL:
columnIdx = 0; columnIdx = 0;
value = yValue; value = xValue;
break; break;
case CrosshairOrientation.VERTICAL: case CrosshairOrientation.HORIZONTAL:
columnIdx = 1; columnIdx = 1;
value = xValue; value = yValue;
break; break;
case CrosshairOrientation.BOTH: case CrosshairOrientation.BOTH:
// TODO: maybe use voronoi // TODO: maybe use voronoi
columnIdx = 0; columnIdx = 1;
value = yValue; value = yValue;
default: default:
throw new Error(`Unknown type of crosshair orientaion: ${this.options.crosshair.orientation}`); throw new Error(`Unknown type of crosshair orientaion: ${this.options.crosshair.orientation}`);

Loading…
Cancel
Save