Git Product home page Git Product logo

react-d3-ggplot's People

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

frankfanslc

react-d3-ggplot's Issues

Incorporate y_format & x_format

Sometimes we need to format our x or y values along the x or y axis.

 interface IContext {
  data: any[];
  aes: string[];
  dimensions?: { width: number; height: number; padding: number };
  x_format?: string;
  y_format?: string;
}

use-x-scale and use-y-scale hooks

// currently, these two hooks take no arguments
useXScale();
useYScale();

// consider adding a parameter in function definition to eliminate code and
// make it easier to maintain.
useScale("x")
useScale("y")

XGrid and YGrid

Allow user to change the color of the grid lines when using XGrid and YGrid as standalone units

Consider making dimensions property optional

Specifying the dimensions of the graph should be handled internally. We can also make the chart responsive by default.

Check out this discussion: https://stackoverflow.com/questions/17626555/responsive-d3-chart

// current API
const LineChart = () => {
  const [state, setState] = useState({
    data: [{ x: 0, y: 0 }, { x: 10, y: 10 }],
    aes: ["x", "y"],
    dimensions: { width: 500, height: 300, padding: 50 }
  });

  return (
    <GGPLOT {...state}>
      <Line />
    </GGPLOT>
  );
};

// suggested API
const ScatterPlot = () => {
  const [state, setState] = useState({
    data: [{ x: 0, y: 0 }, { x: 10, y: 10 }],
    aes: ["x", "y"]
  });

  return (
    <GGPLOT {...state}>
      <Points />
    </GGPLOT>
  );
};

Add placeholder chart for convenience

When we have no data to render, we need a placeholder chart that will adhere to the specified dimensions of the other charts that have been rendered to the DOM as we tab between different charts.

Instead of returning <h1>No Data</h1>, we can return a placeholder chart with a custom embedded message. This will make it so our content doesn't "jump" in height or width. Instead, we will maintain a consistent ui/ux.

XAxis & YAxis

When used as standalone components we should not remove the x or y axis path. Add new prop to give this control to the user

Refactor Application React Context

Remove generic used in this interface. Removing the generic will simplify how you use the interface throughout the codebase.

/*
    old code
*/
interface IAppContext<T> {
  data: T[];
  aes: [string, string];
  dimensions: { width: number; height: number; padding: number };
}

const ChartContext = createContext<IAppContext<string | number | object>>({
  data: [],
  aes: ["", ""],
  dimensions: { width: window.innerWidth, height: window.innerHeight, padding: 50 }
});

/*
    after refactor
*/
interface IAppContext {
  data: { [key: string]: object | string | number }[]
  aes: [string, string];
  dimensions?: { width: number; height: number; padding: number };
}

const ChartContext = createContext<IAppContext>({
  data: [],
  aes: ["", ""],
  dimensions: { width: window.innerWidth, height: window.innerHeight, padding: 50 }
});

TypeScript noImplicitAny

Before refactoring any more React components, change the no-implicit-any from false to true and begin removing implicit any's!

{
    "compilerOptions": {
       // Raise error on expressions and declarations with an implied 'any' type.
       "noImplicitAny": false 
     }
}

react-d3-ggplot/src/Rects/Rects.tsx

When using rects, and one switches the X and Y values, the scales don't change accordingly and will result in errors

    <g>
      {context.data.map((datum, index) => (
        <rect
          key={index}
          width={xScale.bandwidth()} // this works for ordinal scales but we need to account for time and number scales as well
          height={yScale.range()[0] - yScale(datum[context.aes[1]])}
          x={xScale(datum[context.aes[0]])}
          y={yScale(datum[context.aes[1]])}
          fill={!props.fill ? "cyan" : props.fill}
        />
      ))}
    </g>

<Background /> component

Change optional prop name from color to fill just to stay consistent with all the other components in the library.

// Change from color to fill
interface IProps {
  color?: string;
}

function Background(props: IProps) {
  const { dimensions } = useContext(ChartContext);

  return (
    <rect
      width={dimensions.width - dimensions.padding * 2}
      height={dimensions.height - dimensions.padding * 2}
      fill="#f1f1f1"
      transform={`translate(${dimensions.padding}, ${dimensions.padding})`}
    />
  );
}

FILE: https://github.com/Ll2NZ/react-d3-ggplot/blob/master/src/Background/Background.tsx

Update docs

Create new branch documentation for all future docs

react-d3-ggplot/src/FACETS/FACETS.js

Use a unique key other than index when rendering arrays into lists. The reason is that the index alone (so 0 to n, the length of the list) isn't "unique" enough to take full advantage of the optimization provided by React when using the key property for each item in the list.

react-d3-ggplot/src/XAxis/XAxis.ts

  1. Add type information to props
// 1. Add type information to props
function XAxis(props) {
  const context = useContext<IAppContext<string | number | object>>(ChartContext);
  const scale: AxisScale<AxisDomain> = useScale(context, "XAxis");

  useEffect(() => {
    const { dimensions, aes, data } = context;
    const axisLocation = `translate(0, ${dimensions.height - dimensions.padding})`;

    // select node returned by component and appends x-axis
    const node = select<SVGGElement, string | number | object>("g")
      .attr("transform", axisLocation)
      .call(axisBottom(scale));

    if (typeof data[0][aes[0]] === "number" && props.label !== undefined) {
      node.selectAll<SVGTextElement, number>("text").html(d => format(props.label)(d));
    }
  });

  return <g />;
}

Link to file: https://github.com/Ll2NZ/react-d3-ggplot/blob/master/src/XAxis/XAxis.tsx

xaxis, yaxis, line, rects, etc

These two components, XAxis and YAxis, have the same logic more or less. The same is true of the other components listed in the title of the issue.

The main difference is whether we use an x or y axis! Look into generalizing this structure throughout the listed components.

const XAxis = () => {
  const ref = useRef(null);
  const { aes, dimensions } = useContext(ChartContext);
  // aes contains two values representing either the x or y values we want to visualize
  const scale = useScale(aes[0]);
  // need to set the range to properly display our graph visually
  scale.range([dimensions.padding, dimensions.width - dimensions.padding]);

  useEffect(() => {
    const axisLocation = `translate(0, ${dimensions.height - dimensions.padding})`;
    const node = select(ref.current).attr('transform', axisLocation);
    node.call(axisBottom(scale));
  }, [dimensions.height, dimensions.padding, scale]);

  return <g ref={ref} />;
};

const YAxis = () => {
  const ref = useRef(null);
  const { aes, dimensions } = useContext(ChartContext);
  // aes contains two values representing either the x or values we want to visualize
  const scale = useScale(aes[1]);
  // need to set the range to properly display our graph visually
  scale.range([dimensions.height - dimensions.padding, dimensions.padding]);

  useEffect(() => {
    const axisLocation = `translate(${dimensions.padding}, 0)`;
    const node = select(ref.current).attr('transform', axisLocation);
    node.call(axisLeft(scale));
  }, [dimensions.padding, scale]);

  return <g ref={ref} />;
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.