@flourish/chart-layout
Advanced tools
Comparing version 9.5.0 to 9.5.1
{ | ||
"name": "@flourish/chart-layout", | ||
"version": "9.5.0", | ||
"version": "9.5.1", | ||
"description": "Create axes", | ||
@@ -5,0 +5,0 @@ "main": "chart-layout.js", |
@@ -0,1 +1,4 @@ | ||
# 9.5.1 | ||
* Give margin variables an initial value | ||
# 9.5.0 | ||
@@ -2,0 +5,0 @@ * Add yml tag properties to settings |
@@ -39,27 +39,62 @@ import { prepareState } from "./state"; | ||
/* | ||
* Creates and returns a chart-layout instance | ||
* "target" should be an SVG node, d3-selection of an SVG node or a CSS query selector. | ||
* All the generated SVG content will be appended to the SVG node referenced by "target". | ||
* "state" should be an object with optional keys "x", "y", "y2" and "background" | ||
* whose values are objects. | ||
*/ | ||
function initChartLayout(target, state) { | ||
state = prepareState(state); | ||
var instance = {}; | ||
var instance = {}; // this is the object returned at the end of this function | ||
var containers = getContainers(target); | ||
Object.defineProperty(instance, "svg", { get: containers.getSvg }); | ||
// "container" may be an SVG element or a descendant of one | ||
instance.container = containers.container; | ||
// "chart" is the root node for our chart layout that is added as a child of "container" | ||
instance.chart = addChart(instance); | ||
/* | ||
* "data_background" and "data_foreground" are container groups intended to be filled with visual | ||
* representations of data - eg the circles in a scatter plot or the rectangles of a bar chart. | ||
* The "data_background" group lies behind the gridlines and axes while the "data_foreground" | ||
* group lies on top of these elements. | ||
*/ | ||
instance.data_background = instance.chart.select("g.fl-data-background"); | ||
instance.data_foreground = instance.chart.select("g.fl-data-foreground"); | ||
/* The "identifier" gets/sets a string to be used when constructing clip-path ids. | ||
* Getting and, occasionally, setting this can be useful if you want to inspect clip paths | ||
* but mostly this is for internal use. | ||
* It's not used as an id itself (though maybe it should be?). | ||
*/ | ||
instance.identifier = initIdentifier(instance); | ||
/* | ||
* Debug mode draws a colored box around the caluclated bounds of the chart-layout instance. | ||
* This can be useful, eg, when trying to position multiple chart-layout instances in a grid. | ||
*/ | ||
instance.debug = initDebug(instance); | ||
instance.debugColor = initDebugColor(instance); | ||
// Use "clip" to specify how/if data that runs outside the bounds of the plot area should be clipped | ||
instance.clip = initClip(instance); | ||
instance.animationDuration = initAnimationDuration(instance); | ||
var dimensions = initDimensions(instance); | ||
// Methods for setting and getting "width" and "height" of the chart-layout instance in pixels | ||
instance.width = dimensions.width; | ||
instance.height = dimensions.height; | ||
// Method for setting and getting the aspect ratio (width/height) of the plot area | ||
instance.plotAspect = dimensions.plotAspect; | ||
// Read-only width and height of the plot area | ||
Object.defineProperty(instance, "plot_width", { get: dimensions.plotWidth }); | ||
Object.defineProperty(instance, "plot_height", { get: dimensions.plotHeight }); | ||
// Calculated coordinates of the corners of the plot area. | ||
// Coordinates are relative to the top-left of the chart-layout instance | ||
Object.defineProperty(instance, "x_left", { get: dimensions.xLeft }); | ||
@@ -70,10 +105,27 @@ Object.defineProperty(instance, "x_right", { get: dimensions.xRight }); | ||
// Offsets to apply to the chart-layout instance to position it relative to its container. | ||
// Use these functions to arrange a grid of chart-layout instances in a single container. | ||
instance.offsetLeft = initOffsetLeft(instance); | ||
instance.offsetTop = initOffsetTop(instance); | ||
// Get the currently-in-use margins. These are usually calculated but can be overidden via the | ||
// options object that can be passed into the "update" method. | ||
instance.margins = initMargins(instance, state); | ||
/* | ||
* The *Data methods allow the developer to associate data with an axis such that this component | ||
* can both determine what sort of data will be plotted along the given axis - numbers, strings | ||
* or datetimes - and also what the default axis domains and tick labels should look be. | ||
* These methods, when called without any arguments (ie as getters) return an 'enhanced array' | ||
* https://www.npmjs.com/package/@flourish/enhanced-arrays. | ||
* In short, the values are stored in a frozen array that is accessible via the "values" property | ||
* while other properties and methods give access to additional information about the array such | ||
* as the min and max values and sorted values. | ||
*/ | ||
instance.xData = initData(instance); | ||
instance.yData = initData(instance); | ||
instance.y2Data = initData(instance); | ||
// Format functions tell the component how to format tick-labels for display while the parse | ||
// functions tell the component how to parse user input, eg in a custom date range. | ||
instance.xFormat = initFormat(instance); | ||
@@ -88,26 +140,46 @@ instance.yFormat = initFormat(instance); | ||
instance.y2DatetimeParse = initDatetimeParse(instance); | ||
// Axis titles | ||
instance.xTitle = initXTitle(instance, state); // Implicitly adds instance.xAutoTitle | ||
instance.yTitle = initYTitle(instance, state); // Implicitly adds instance.yAutoTitle | ||
instance.y2Title = initY2Title(instance, state); // Implicitly adds instance.y2AutoTitle | ||
// Methods for retrieving an array of the ticks used last time the "update" method was called | ||
instance.xTicks = initXTicks(instance, state); | ||
instance.yTicks = initYTicks(instance, state); | ||
instance.y2Ticks = initY2Ticks(instance, state); | ||
// Methods for customising which ticks should be used when the Flourish user asks for auto ticks | ||
instance.xAutoTicks = initXAutoTicks(instance); | ||
instance.yAutoTicks = initYAutoTicks(instance); | ||
instance.y2AutoTicks = initY2AutoTicks(instance); | ||
// Methods for obtaining copies of the d3 scales used in the construction of the axes | ||
instance.xScale = initXScale(instance, state); | ||
instance.yScale = initYScale(instance, state); | ||
instance.y2Scale = initY2Scale(instance, state); | ||
// Methods for specifying additional space to add at the ends of axes. | ||
// Can be useful for ensuring the visual representations of data points don't extend outside the | ||
// plotting area. | ||
instance.xPadding = initXPadding(instance); | ||
instance.yPadding = initYPadding(instance); | ||
instance.y2Padding = initY2Padding(instance); | ||
// These methods return the minimum on-screen distance between *Data points of an axis. | ||
// Useful when constructing bar charts (ie how wide can a bar be before it overlaps?). | ||
instance.xMinStep = initXMinStep(instance); | ||
instance.yMinStep = initYMinStep(instance); | ||
instance.y2MinStep = initY2MinStep(instance); | ||
// Invert the direction of an axis, eg from bottom->top to top->bottom | ||
instance.xFlipAxis = initFlipAxis(instance); | ||
instance.yFlipAxis = initFlipAxis(instance); | ||
instance.y2FlipAxis = initFlipAxis(instance); | ||
// Should 0 be included in the domain when the user has selected the auto option for the domain? | ||
instance.xZeroAxis = initZeroAxis(instance); | ||
instance.yZeroAxis = initZeroAxis(instance); | ||
instance.y2ZeroAxis = initZeroAxis(instance); | ||
// Use these methods to programatically hide an axis | ||
instance.xHide = initHide(instance); | ||
@@ -117,6 +189,9 @@ instance.yHide = initHide(instance); | ||
// Hide the y2 axis by default | ||
instance.y2Hide(true); | ||
// The update method does the hard work of actually constructing scales, axes and the like | ||
instance.update = initUpdate(instance, state); | ||
// Finally, return our new chart-layout instance | ||
return instance; | ||
@@ -123,0 +198,0 @@ } |
@@ -209,2 +209,3 @@ import { remToPx, getFont } from "../common"; | ||
var top, right, bottom, left; | ||
top = right = bottom = left = 0; | ||
@@ -211,0 +212,0 @@ var updateMargins = function(overrides) { |
@@ -11,2 +11,4 @@ import { updateRemToPx } from "../common"; | ||
function initUpdate(instance, state) { | ||
// Function that applies transform to all the content created by the instance | ||
// Transform is based on parameters specified by offset* methods. | ||
var updateTransform = function() { | ||
@@ -30,3 +32,8 @@ var transform = null; | ||
return function(opts) { | ||
// "opts" object is often omitted but can be used to specify margin overrides (eg when) positioning | ||
// charts close together and whether to skip rendering at all and just do calculations. | ||
opts = opts || {}; | ||
// Update function for converting froms rems to pixels. The conversion relies on getting computed | ||
// styles from the root element of the page which can be time-consuming so this is done once at the | ||
// start of the updating procedure | ||
updateRemToPx(); | ||
@@ -37,7 +44,10 @@ updateTransform(); | ||
updateMargins(opts.margins); | ||
// Stop here if we don't actually want to render anything | ||
if (opts.skip_rendering) return instance; | ||
updateClip(); | ||
updateBackground(); | ||
// Actually (re)draw the axes and gridlines | ||
var measurements = updateAxes(); | ||
updateGridlines(measurements); | ||
return instance; | ||
@@ -44,0 +54,0 @@ }; |
Sorry, the diff of this file is too big to display
436512
10532