import _ from 'lodash'; import React, { forwardRef } from 'react'; import { Measure, withBluefish, withBluefishFn } from '../../../../bluefish'; import { Col } from '../../../../components/Col'; import { Group } from '../../../../components/Group'; import { Rect } from '../../../../components/Rect'; import { Row } from '../../../../components/Row'; import { Mark, PlotContext, plotMarkReified } from '../Plot'; import { Scale } from '../Scale'; import { Scale as ScaleFn } from '../Plot'; export const barY = (data: T[], { x, y, color }: { x: string; y: string; color: string }): Mark => ({ data, encodings: { x, y, color }, scale: ( channels: { X: number[]; Y: number[]; COLOR: string[] }, scales: { xScale: any; yScale: (y: number) => number; colorScale: (color: string) => string }, dimensions: any, ) => { const { X, Y, COLOR } = channels; const { xScale, yScale, colorScale } = scales; const indices = _.range(X.length); return { spacing: xScale.step() - xScale.bandwidth(), totalWidth: dimensions.width, points: indices.map((i) => ({ // height: yScale(Y[i]), height: Y[i], fill: colorScale(COLOR[i]), })), yScale: () => yScale, }; }, render: (data: { spacing: number; totalWidth: number; points: any[]; yScale: ScaleFn }) => { return ( {/* {data.points.map(({ height, fill }: { width: any; height: number; fill: string }) => ( ))} */} {data.points.map(({ height, fill }: { width: any; height: number; fill: string }) => ( ))} // stacked bars... // just have to combine it with a concat operator... // // {data.points.reverse().map(({ height, fill }: { width: any; height: number; fill: string }) => ( // // ))} // ); }, }); export const BarY: React.FC<{ data?: any[]; encodings: { x: string; y: string; color: string } }> = forwardRef( (props, ref) => { const context = React.useContext(PlotContext); const { encodings } = props; const data = props.data ?? context.data; const { x, y, color } = encodings; const mark = barY(data, { x, y, color }); return {plotMarkReified(mark, context.scales, context.dimensions)}; }, ); const groupMeasurePolicy: Measure = (measurables, constraints) => { const placeables = measurables.map((measurable, idx) => { // console.log('[set to] name', measurable.name); console.log(`measurable ${idx}`, measurable); const placeable = measurable.measure(constraints); console.log(`placed measurable ${idx}`, placeable); return placeable; }); // placeables.forEach((placeable, idx) => { // console.log(`placeable ${idx}`, placeable); // if (placeable.left === undefined) { // console.log('placeable.left set to before', placeable.left); // placeable.left = 0; // console.log('placeable.left set to after', placeable.left); // } // if (placeable.top === undefined) { // placeable.top = 0; // } // console.log(`group after: placed placeable ${idx}`, placeable); // }); // TODO: might need to preserve "natural" position so I can figure out what the translation should be. const left = _.min(_.map(placeables, 'left')) ?? 0; const top = _.min(_.map(placeables, 'top')) ?? 0; const right = _.max(_.map(placeables, 'right')) ?? 0; const bottom = _.max(_.map(placeables, 'bottom')) ?? 0; console.log('asdfs', 'left', _.map(placeables, 'left'), _.min(_.map(placeables, 'left'))); console.log('asdfs', 'group bbox', { left, top, right, bottom }); return { left, top, right, bottom, width: right - left, height: bottom - top, }; // const width = _.max(_.map(placeables, 'width')) ?? 0; // const height = _.max(_.map(placeables, 'height')) ?? 0; // return { width, height }; }; export const BarYWithBFN = withBluefish( groupMeasurePolicy, (props: { data?: any[]; encodings: { x: string; y: string; color: string } }, ref) => { const context = React.useContext(PlotContext); const { encodings } = props; const data = props.data ?? context.data; const { x, y, color } = encodings; const mark = barY(data, { x, y, color }); return {plotMarkReified(mark, context.scales, context.dimensions)}; }, ); // the marks need dimension information. this should be calculated during measurement and then // passed to the renderer // the problem is that I need the renderer to return a Bluefish component