XYFrame - nteract/semiotic GitHub Wiki

A <Frame> that displays continuous data along the x and y axis. Examples include time series charts, scatterplots, line, and area charts. <XYFrame> charts render points, lines, and/or area elements. Rendering and styling is based on each element's corresponding properties. XYFrame data elements are accessible by tabbing to the data group (points, lines or areas) and hitting enter to arrow-key navigate through the data elements.

import { XYFrame } from 'semiotic'

<XYFrame
   points={[{price: 1.25, size: 15}, {price: 2.25, size: 12}, ...]}
   pointStyle={{ fill: "blue" }}
   xAccessor={"price"}
   yAccessor={"size"}
/>

<API Reference>

Table of Contents

General Properties

size: { [width, height] }

If size is specified, sets the width and height of the frame from the array of values. The array must contain two numbers which represents the width and height, respectively. Size defaults to [500,500].

Note: Margin will not be added to the frame size. It's more like CSS padding.

<XYFrame size={ [500,500] } ... />

xAccessor: { string | function }

If xAccessor is specified, determines how x values are accessed from the data array. In the case the data consists of an array of objects, a string can be used to access the x value(s). A function can also be used to access the x value(s).

/* String option
e.g. data=[{x: 1, y: 2}, {x:2, y: 4}, ... ] */
<XYFrame xAccessor={ "x" } ... />

/* Function option
e.g. data=[[1, 2], [2, 4], ... ] */
<XYFrame xAccessor={ d => d[0] } ... />

yAccessor: { string | function }

If yAccessor is specified, determines how y values are accessed from the data array. In the case the data consists of an array of objects, a string can be used to assess the y value(s). A function can also be used to access the y value(s).

/*String option
e.g. data=[{x: 1, y: 2}, {x: 2, y: 4}, ... ] */
<XYFrame yAccessor={ "y" } ... />

/*Function option
e.g. data=[[1, 2], [2, 4], ... ] */
<XYFrame yAccessor={ d => d[1] } ... />

title: { string | JSX }

If title is specified, sets the text for the chart title, which appears centered at the top of the chart. The title can be either a string or JSX object.

/*String option */
<XYFrame title={ "Chart Title" } ... />

/*JSX option */
<XYFrame title={ <text fontSize={30} fill="gold">"Chart Title"</text> } ... />

margin: { number | object }

If margin is specified, sets the margin(s) on the frame. The margin can be set to one number, which is applied equally to all sides, or as an object.

/*Single number option */
<XYFrame margin={ 10 } ... />

/*Object option */
<XYFrame margin={ { top: 5, bottom: 10, left: 15, right: 20 } } ... />

xScaleType: { d3-scale }

Custom D3 scale for the x axis. Defaults to scaleLinear().

<XYFrame xScaleType={ d3.scaleTime() } ... />

yScaleType: { d3-scale }

Custom D3 scale for the y axis. Defaults to scaleLinear().

<XYFrame yScaleType={ d3.scaleLinear() } ... />

xExtent: { [min, max] }

If xExtent is specified, sets the min and/or max value(s) for the x axis. The array may contain two numbers, or it can contain a number and an undefined value, if you only want to set the min or max extent. The extent exposes an onChange callback function that updates with the calculated extent value.

/*min and max values set */
<XYFrame xExtent={ [20,250] } ... />

/*only min value set */
<XYFrame xExtent={ [20, undefined] } ... />

/*onChange without setting extent */
<XYFrame xExtent={ { onChange: d => { console.log(d) } } } ... />

/*onChange with setting extent */
<XYFrame xExtent={ { extent: [20, undefined], onChange: d => { console.log(d) } } } ... />

yExtent: { [min, max] }

If yExtent is specified, sets the min and/or max value(s) for the y axis. The array may contain two numbers, or it can contain a number and an undefined value, if you only want to set the min or max extent.

/*min and max values set */
<XYFrame yExtent={ [0,500] } ... />

/*only max value set */
<XYFrame yExtent={ [undefined, 350] } ... />

/*onChange without setting extent */
<XYFrame yExtent={ { onChange: d => { console.log(d) } } } ... />

/*onChange with setting extent */
<XYFrame yExtent={ { extent: [undefined, 350], onChange: d => { console.log(d) } } } ... />

invertX: { boolean }

If invertX is specified, inverts the x axis such that the min and max values are transposed.

<XYFrame invertX={ true } ... />

invertY: { boolean }

If invertY is specified, inverts the y axis such that the min and max values are transposed.

<XYFrame invertY={ true } ... />

showLinePoints: { boolean }

If showLinePoints is specified, displays the points that make up the line and/or area elements. These points will be styled just like points that are added to the points array using pointStyle or pointClass with the only difference being that points will have a parentLine or parentArea property that will point to the line or area that this point is a part of.

<XYFrame showLinePoints={ true } ... />

baseMarkProps: { object }

If baseMarkProps is specified, the object sent will be spread to all marks that are generated in the frame. This is useful for any props that might be shared by all pieces, and especially useful to set the animation duration for the marks if you want to adjust from the default 1s duration.

<XYFrame 
 baseMarkProps={{ transitionDuration: { default: 500, fill: 2500 }}}
/>

Point Rendering

points: { [data] }

An array of arrays or objects representing individual points on a chart. If you want to show points on a line or area chart, use the showLinePoints property.

var points = [[1,2], [3,4], [5,8], [7,16], [9,32], [11,64], [13,128]];

function MyScatterPlot() {
  return <XYFrame 
           xAccessor={ d => d[0] } 
           yAccessor={ d => d[1] }
           points={ points } />;
}

pointStyle: { object | function }

If pointStyle is specified, sets the inline css style of each point element. This can be a JSX style object or a function that is passed the point data and returns a JSX style object.

/*Object option */
<XYFrame pointStyle={ { fill: "red", stroke: "grey", strokeWidth: 1 } } ... />

/*Function option */
<XYFrame
  ... 
  pointStyle={ d => ({ fill: d.fill, stroke: d.stroke, strokeWidth: d.strWidth }) } 
/>

pointClass: { string | function }

If pointClass is specified, sets the css class of each point element. This can be a string class name or a function that takes the point data and returns a string.

/*String option */
<XYFrame pointClass={ "scatter-points" } ... />

/*Function option */
<XYFrame pointClass={ d => d.className } ... />

canvasPoints: { boolean | function }

If canvasPoints is specified, determines whether or not to render points to Canvas instead of SVG. The canvasPoints attribute accepts a boolean or a function that evaluates each point and returns a boolean.

/*Boolean option */
<XYFrame canvasPoints={ true } ... />

/*Function option rendering only points with a size value of smaller than 5 with canvas */
<XYFrame canvasPoints={ d => d.size < 5 } ... />

customPointMark: { JSX | function }

If customPointMark is specified, renders a JSX <Mark> for each point, otherwise points use <Mark markType="circle" />. The customPointMark attribute accepts a JSX object or function that returns a JSX object as the marker for each point.

Note: The value(s) of the pointStyle attribute is then applied to the custom mark, but only at the top level. So if you want to make multipart graphical objects, have the customPointMark declare the style.

/*JSX option */
<XYFrame customPointMark={ <Mark markType="rect" /> } ... />

/*Function option */
<XYFrame customPointMark={ d => (<Mark markType="rect" />) } ... />

Line Rendering

lines: { [data] }

An array of arrays or objects representing individual points along a line. If you want to show points along the line, use the showLinePoints property.

var lines = [[[1,2], [3,4], [5,8], [7,16], [9,32], [11,64], [13,128]]];

function MyLineChart() {
  return <XYFrame 
           xAccessor={ d => d[0] } 
           yAccessor={ d => d[1] }
           lines={ lines } />;
}

lineDataAccessor: { string | function }

If lineDataAccessor is specified, determines how line coordinates are accessed from the data array passed to the lines attribute. Defaults to coordinates.

/*String option */
<XYFrame lineDataAccessor={ "lineValues" } ... />

/*Function option */
<XYFrame lineDataAccessor={ d => d.lineValues } ... />

lineType: { string | object }

If lineType is specified, renders one of the supported line types. The attribute accepts a string corresponding to one of the supported line types or an object with a type key and string value corresponding to one of the supported line types. An optional options key on the object that determines how the lines are generated is also supported.

/*String option */
<XYFrame lineType={ "stackedarea" } ... />

/*Object option */
<XYFrame lineType={ { type: "stackedarea", sort: (a,b) => a.level - b.level } } ... />

lineStyle: { object | function }

Required to set the inline css style of each line element. This can be a JSX style object or a function that takes the line data and returns a JSX style object.

/*Object option */
<XYFrame lineStyle={ { stroke: "#e3e3e3", strokeWidth: 2 } } ... />

/*Function option */
<XYFrame
  ... 
  lineStyle={ d => ({ stroke: d.stroke, strokeWidth: d.strWidth }) } 
/>

lineClass: { string | function }

If lineClass is specified, sets the css class of each line element. This can take a string or a function that evaluates the line data and returns a string.

/*String option */
<XYFrame lineClass={ "line" } ... />

/*Function option */
<XYFrame lineClass={ d => d.className } ... />

lineIDAccessor: { string | function }

If lineIDAccessor is specified, sets the id of the corresponding line. The lineIDAccessor accepts a string or a function that returns a string indicating the id name. Defaults to "semioticLineID". The ID value is used to place annotations relative along the line.

/*String option */
<XYFrame lineIDAccessor={ "myLineId" } ... />

/*Function option */
<XYFrame lineIDAccessor={ d => d.id } ... />

customLineMark: { function }

Is customLineMark is specified, renders a custom JSX element for each line. For example, <DividedLine> can be used in place of normal lines or other line generators taking advantage of the <Frame>'s settings. The customLineMark attribute accepts a function that returns a JSX object

<XYFrame customLineMark={ d => (<DividedLines ... />) } ... />

canvasLines: { boolean | function }

If canvasLines is specified, renders line elements in Canvas. The canvasLines attribute accepts a boolean or a function that evaluates a line and returns a boolean that determines whether or not to render the line to Canvas instead of SVG.

/*Boolean option */
<XYFrame canvasLines={ true } ... />

/*Function option drawing only the even lines with canvas */
<XYFrame canvasLines={ (d, i) => i%2 === 0 } ... />

defined: { function }

If defined is specified, sets the accessor function that controls where the line is defined. Similar to D3's line.defined API. Lines will be rendered with gaps where there is no defined data.

<XYFrame defined={ d => !isNaN(d[1]) } ... />

Area Rendering

areas: { [data] }

An array of arrays or objects representing individual points on a chart. If you want to show points on an area chart, use the showLinePoints property.

var points = [[1,2], [3,4], [5,8], [7,16], [9,32], [11,64], [13,128]];

function MyAreaChart() {
  return <XYFrame 
           xAccessor={ d => d[0] } 
           yAccessor={ d => d[1] }
           areas={ points } />;
}

areaDataAccessor: { string | function }

If areaDataAccessor is specified, determines how area coordinates are accessed from the data array passed to the areas attribute. Defaults to coordinates.

/*String option */
<XYFrame areaDataAccessor={ "areaValues" } ... />

/*Function option */
<XYFrame areaDataAccessor={ d => d.areaValues } ... />

areaStyle: { function | object }

If areaStyle is specified, sets the inline css style of each area element.

/*Object option */
<XYFrame areaStyle={ { fill: "#e3e3e3", stroke: "#e3e3e3" } } ... />

/*Function option */
<XYFrame
  ... 
  areaStyle={ d => ({ fill: d.fill, stroke: d.stroke }) } 
/>

areaClass: { string | function }

If areaClass is specified, sets the css class of each area element.

/*String option */
<XYFrame areaClass={ "area" } ... />

/*Function option */
<XYFrame areaClass={ d => d.className } ... />

canvasAreas: { boolean | function }

If canvasAreas is specified, renders area elements in Canvas. The canvasAreas attribute accepts a boolean or a function that evaluates an area and returns a boolean that determines whether or not to render the area to Canvas instead of SVG.

/*Boolean option */
<XYFrame canvasAreas={ true } ... />

/*Function option */
<XYFrame canvasAreas={ (d, i) => } ... />

Annotation and Decoration

tooltipContent: { function }

A function returning JSX HTML to display in the tooltip (only active if hoverAnnotation is set to true). The tooltip is passed the data point (which if part of a line or area will be decorated with a corresponding parentLine or parentArea pointer to that object). The content is placed on and directly above the hovered point, so take that into account when using CSS to style the position and any additional elements. You can drop any HTML into this floating div, including another frame, if you want to have data visualization in your data visualization so you can visualize while you visualize.

axes: { array }

An array of objects that defines axes. These objects roughly correspond to the options in D3 array, with extended options such as label.

legend: bool or object

A boolean or object determining whether to turn on a legend. Currently only works with line data. If set to true, will place a legend on the upper right corner of the chart area. Legends are 100px wide, so you can account for this in your right-hand margin. Can also take an object with { position } that can be set to "right" to get the default behavior or "left" to place it on the top left corner or an array of exact XY position for the legend. The legend will automatically have items for each line, labeled with the string value that corresponds to the lineIDAccessor of the line.

/*boolean option */
<XYFrame legend={true} />
/*object option */
<XYFrame legend={{
        legendGroups: [
          {
            styleFn: d => ({ fill: d.color, stroke: "black" }),
            items: [
              { label: "Area 1", color: "red" },
              { label: "Area 2", color: "blue" }
            ]
          }
        ]
      }} ... />

annotations: { array }

An array of objects to be processed using the frame's built-in annotation rules or the custom defined rules. Annotations need to have the same data properties that your data has, so if your data has xAccessor="day" then your annotations will need a corresponding day value.

/*boolean option */
<XYFrame annotations={[
   { type: "xy", label: "A sample XY Annotation", day: 5, value: 105 },
   { type: "x", label: "A sample X Threshold Annotation", day: 5 },
   { type: "y", label: "A sample Y Threshold Annotation", value: 105 }
]} />

svgAnnotationRules: { function }

A function that takes an annotation object and returns a JSX SVG element. The function is sent { d, i, screenCoordinates, xScale, yScale, xAccessor, yAccessor, xyFrameProps, xyFrameState, areas, points, lines }

<XYFrame svgAnnotationRules={({ d, screenCoordinates }) => {
   if (d.type === "myCustomType") {
      return <g transform={`translate(${screenCoordinates})`}>
      <circle r={10} fill="red" />
      <text>{d.customLabelOrSomething}</text>
   }

   // Always return null if you want the default rules to be processed for types not defined in your custom rules
   return null
   } 
} />

htmlAnnotationRules: { function }

A function that takes an annotation object and returns a JSX HTML element. The function is sent { d, i, screenCoordinates, xScale, yScale, xAccessor, yAccessor, xyFrameProps, xyFrameState, areas, points, lines }. Elements can be placed using CSS left and top and will overlay on the chart. Internally, the default annotation for tooltips uses this method.

<XYFrame svgAnnotationRules={({ d, screenCoordinates }) => {
   if (d.type === "myCustomType") {
      return <div style={{ left: `${screenCoordinates[0]}px`, bottom: `${screenCoordinates[1]}px` }}>{d.customLabelOrSomething}</div>
   }

   // Always return null if you want the default rules to be processed for types not defined in your custom rules
   return null
   } 
} />

annotationSettings: { object }

An object with { layout, pointSizeFunction, labelSizeFunction } containing custom annotation settings to enable annotations bumping out of each others' way or placing them in the margins.

<XYFrame
annotationSettings={{
    layout: {
      type: "marginalia",
      orient: "nearest",
      characterWidth: 8,
      lineWidth: 20,
      padding: 2,
      iterations: 1000,
      pointSizeFunction: () => 2
    }
  }}
/>

matte: { boolean }

Whether to turn on a matte (a border that covers the margin area to hide overflow) or a JSX custom matte.

<XYFrame
matte={true}
/>

backgroundGraphics: { array | JSX }

A JSX or array of JSX to display behind the chart.

<XYFrame
backgroundGraphics={<image src="amazing.gif" />}
/>

foregroundGraphics: { array | JSX }

A JSX or array of JSX to display in front of the chart.

<XYFrame
   foregroundGraphics={<image src="copyright.png" />}
/>

canvasPostProcess: { "chuckClose" | function }

Any HTML5 canvas processing that you might want to do to your canvas rendered elements. It has a built in transformation that makes your dataviz look like a Chuck Close painting or you can write a custom function.

//Chuck Close
<XYFrame
   canvasPostProcess="chuckClose"
/>

//function option creating a glowing effect
<XYFrame
   canvasPostProcess={(canvas, context, size) => {
  const dataURL = canvas.toDataURL("image/png")
  const baseImage = document.createElement("img")

  baseImage.src = dataURL
  baseImage.onload = () => {
    context.clearRect(0, 0, size[0] + 120, size[1] + 120)
    context.filter = "blur(10px)"
    context.drawImage(baseImage, 0, 0)
    context.filter = "blur(5px)"
    context.drawImage(baseImage, 0, 0)
    context.filter = "none"
    context.drawImage(baseImage, 0, 0)
  }
}}
/>

Interaction

hoverAnnotation: { bool | array }

Turn on automatic tooltips with a voronoi overlay to improve interaction. If you pass true, it will generate a simple SVG circle and a tooltip with content customized via the tooltipContent prop. If you pass an array you can pass any number of annotation objects that will have the properties filled with the props of the hovered item, which is good for creating complex highlighting behavior.

// boolean
<XYFrame
hoverAnnotation={true}
/>

// boolean
<XYFrame
hoverAnnotation={[
   { type: "frame-hover" },
   { type: "highlight" },
   { type: "y" }
]}
/>

customHoverBehavior: { function }

A function to fire on hover that passes the data being hovered over.

<XYFrame
   customHoverBehavior={d => {this.setState({ hoveredOn: d })}}
/>

customClickBehavior: { function }

A function to fire on click that passes the data being hovered over.

<XYFrame
   customClickBehavior={d => {this.setState({ clickedOn: d })}}
/>

customDoubleClickBehavior: { function }

A function to fire on doubleclick that passes the data being hovered over.

<XYFrame
   customDoubleClickBehavior={d => {this.setState({ doubleclicked: d })}}
/>

interaction: { object }

An object passed to the interaction layer that is currently only used to determine whether to activate the XY brush, its settings, and the actions to fire on its start, brush and end events. Used under the hood in MinimapXYFrame to enable the functionality in the minimap.

<XYFrame
    interaction={{
      start: startBrushingFunction,
      during: whileBrushingFunction,
      end: endBrushingFunction,
      brush: "xBrush", //xBrush, yBrush or xyBrush
      extent: extent //optional set starting extent
    }}
/>

Miscellaneous

dataVersion: { string }

A simple optimization option. If you set dataVersion (a string) then XYFrame will not update the visualization layer until it receives a different string. This allows you to manage rendering when your code is making React re-render your chart all the time. This is a crude method and what you should do for optimization is make sure that any functions or data you're sending to your frame only change when they have actually changed (which means not creating arrays or functions inline or in your render function but up the chain somewhere).

name: { string }

Used internally to identify frames, which comes in handy when you need to link frames together.

additionalDefs: { JSX }

A JSX or array of JSX to be injected into the visualization layer's SVG defs. This is useful for defining patterns that you want to use as fills, or markers or gradients or other SVG material typically defined in defs.

<XYFrame
   additionalDefs={<linearGradient y2="1" id="paleWoodGradient">
        <stop stopColor="#8E0E00" offset="0%" />
        <stop stopColor="#1F1C18" offset="100%" />
      </linearGradient>}
/>

download: { bool }

Enable a download button to download the data as a CSV

downloadFields: { array }

The field keys to download from each datapoint. By default, the CSV download only shows the x and y values.

⚠️ **GitHub.com Fallback** ⚠️