M ChartM Chart
Users
Highcharts
Developers
Download
GitHub
Users
Highcharts
Developers
Download
GitHub
  • Developer Guide

    • Developer Guide
    • PHP Hooks & Filters
    • JavaScript Events
    • Admin UI JavaScript Hooks
    • Migrating to v2

PHP Hooks & Filters

These WordPress action and filter hooks are available for plugins and themes to customize M Chart behavior on the server side.

Action Hooks

m_chart_update_post_meta

Fires after chart post meta is saved.

add_action( 'm_chart_update_post_meta', function( $post_id, $post_meta, $meta ) {
	// Do something after chart data is saved
}, 10, 3 );

Parameters:

  • $post_id (int) — The chart post ID
  • $post_meta (array) — The parsed, sanitized post meta that was saved
  • $meta (array) — The raw post meta as submitted (before parsing)

m_chart_get_chart_start

Fires at the start of chart output generation, before any HTML is rendered.

add_action( 'm_chart_get_chart_start', function( $post_id, $args ) {
	// Runs before chart HTML is generated
}, 10, 2 );

Parameters:

  • $post_id (int) — The chart post ID
  • $args (array) — Display arguments: show (string), width (string), share (string)

m_chart_get_chart_end

Fires at the end of chart output generation, after all HTML has been rendered.

add_action( 'm_chart_get_chart_end', function( $post_id, $args ) {
	// Runs after chart HTML is generated
}, 10, 2 );

Parameters:

  • $post_id (int) — The chart post ID
  • $args (array) — Display arguments: show (string), width (string), share (string)

m_chart_after_chart_args

Fires after the Chart.js chart arguments array has been fully assembled. Use this to inspect or log chart args at the PHP level. To modify chart args, use the m_chart_chart_args filter instead.

add_action( 'm_chart_after_chart_args', function( $post_id, $args, $instance ) {
	// Inspect chart args for this post
}, 10, 3 );

Parameters:

  • $post_id (int) — The chart post ID
  • $args (array) — Display arguments: show (string), width (string), share (string)
  • $instance (int) — The chart instance counter, incremented for each chart on the page

Output context is inside a <script> block

This hook fires inside the front-end inline <script> block that bootstraps the chart. Anything echoed by a callback lands as JavaScript, not HTML. For logging, prefer error_log() over echo. If you must emit values into the script, run them through wp_json_encode() first — esc_html() / esc_attr() are the wrong tools in a JS context and will not protect against script injection.


m_chart_admin_scripts

Fires in the admin footer after M Chart has enqueued its scripts. Use to enqueue additional scripts for the chart edit screen.

add_action( 'm_chart_admin_scripts', function( $library, $post_id ) {
	if ( 'chartjs' !== $library ) {
		return;
	}

	wp_enqueue_script( 'my-chartjs-extension', get_template_directory_uri() . '/js/my-extension.js' );
}, 10, 2 );

Parameters:

  • $library (string) — The active charting library slug (e.g. 'chartjs', 'highcharts')
  • $post_id (int) — The chart post ID

m_chart_admin_footer_javascript

Fires inside the admin footer <script> block for the chart edit screen. Use this to emit additional JavaScript that runs after M Chart's admin UI has loaded.

add_action( 'm_chart_admin_footer_javascript', function() {
	// Emit JS that runs alongside the M Chart admin
	echo 'console.log( "My extension loaded" );';
} );

No parameters.

Output context is inside a <script> block

This hook fires inside an admin-side inline <script> block. Anything echoed lands as JavaScript, not HTML. Run any dynamic value through wp_json_encode() before emitting — esc_html() / esc_attr() are the wrong tools in a JS context and will not protect against script injection. A callback that echoes unescaped user-submitted data here is a stored-XSS hole in admin.


m_chart_settings_admin

Fires at the bottom of the plugin settings form, just before the Save Changes button. Use this to add custom settings fields to the M Chart settings screen.

add_action( 'm_chart_settings_admin', function() {
	$value = get_option( 'my_plugin_option', '' );
	echo '<h3>My Plugin Settings</h3>';
	echo '<label>My Option <input type="text" name="my_plugin_option" value="' . esc_attr( $value ) . '" /></label>';
} );

No parameters.


m_chart_after_chartjs_plugins

Fires inside the front-end <script> block after Chart.js plugins are registered with Chart.register(). Use this to register additional Chart.js plugins before the chart instance is created.

add_action( 'm_chart_after_chartjs_plugins', function( $post_id, $args, $instance ) {
	echo 'Chart.register( MyChartJsPlugin );';
}, 10, 3 );

Parameters:

  • $post_id (int) — The chart post ID
  • $args (array) — Display arguments: show (string), width (string), share (string)
  • $instance (int) — The chart instance counter

Output context is inside a <script> block

Anything echoed by a callback is written as JavaScript, not HTML. If you interpolate dynamic values, run them through wp_json_encode() first — esc_html() / esc_attr() are the wrong tools in a JS context. Emitting unescaped user input here is script injection.

Only fires in the interactive front-end render path

This hook does not fire when the chart is served as an image (show=image, AMP context, or m_chart_show_image forced to true), since no Chart.js code runs in those cases. Use m_chart_chart_args if you need to influence both interactive and image renders.


m_chart_screen_reader_text

Fires inside a .screen-reader-text container in the rendered chart output, after any data-table fallback. Use this to append additional accessibility context (data sources, methodology, trend descriptions, summary text) that helps screen-reader users understand the chart beyond the raw data values.

The hook fires in three rendering contexts:

  1. Interactive Chart.js front end — inside the always-present <div id="...-desc" class="screen-reader-text"> that's wired to the canvas via aria-describedby. The data table from build_table() is emitted immediately before this hook fires, so a callback in this context can reference the table.
  2. Image-mode output (non-AMP) — inside a .screen-reader-text wrapper that only renders when has_action() returns true. No data table is emitted in this context, so callbacks cannot assume one is present.
  3. AMP image-mode output — same as non-AMP image mode, wrapped in <figure class="m-chart-image-figure"> alongside an <amp-img> tag.
add_action( 'm_chart_screen_reader_text', function( $post_id, $args ) {
	$source = get_post_meta( $post_id, 'data_source', true );

	if ( ! empty( $source ) ) {
		printf(
			'<p>%s</p>',
			esc_html( sprintf( __( 'Data source: %s', 'my-plugin' ), $source ) )
		);
	}
}, 10, 2 );

Parameters:

  • $post_id (int) — The chart post ID
  • $args (array) — Display arguments: show (string), width (string), share (string)

Escape your output

The hook fires inside an unescaped output context. Callbacks may emit HTML, but you are responsible for escaping any dynamic values you include — use esc_html(), esc_attr(), wp_kses_post(), or similar.

AMP validity

On AMP pages this hook fires inside an AMP-validated document. Callback output is not sanitized for AMP, so emitting <script>, inline event handlers, <iframe>, or non-AMP media tags will invalidate the document. Stick to text and basic inline HTML (<p>, <strong>, <a>, lists) when AMP is in scope.

Don't assume the data table is present

Callbacks that say "see the table above" only work in the interactive front-end render. In image-mode and AMP-image-mode contexts no data table is emitted, so write callbacks that stand alone — describe the chart's content rather than referring to surrounding markup.


m_chart_get_chart_begin

Fires just before the chart template is included, after the output buffer has been opened. This is the last action that fires before chart HTML is written. It is distinct from m_chart_get_chart_start, which fires before the output buffer is opened.

add_action( 'm_chart_get_chart_begin', function( $post_id, $args ) {
	// Runs just before the chart template is included
}, 10, 2 );

Parameters:

  • $post_id (int) — The chart post ID
  • $args (array) — Display arguments: show (string), width (string), share (string)

Filter Hooks

m_chart_chart_args

Filters the complete Chart.js chart arguments array before it is passed to JavaScript.

add_filter( 'm_chart_chart_args', function( $chart_args, $post, $post_meta, $args ) {
	// Add a custom plugin option
	$chart_args['options']['plugins']['myPlugin']['enabled'] = true;
	return $chart_args;
}, 10, 4 );

Parameters:

  • $chart_args (array) — The Chart.js args array
  • $post (WP_Post) — The chart post object
  • $post_meta (array) — The chart post meta
  • $args (array) — Display arguments passed to get_chart()

m_chart_chartjs_colors

Filters the array of colors used by the active Chart.js theme. Each entry is a hex color string applied to a series in order — first series gets the first color, second the second, and so on.

add_filter( 'm_chart_chartjs_colors', function( $colors, $post ) {
	return [ '#ff0000', '#00ff00', '#0000ff' ];
}, 10, 2 );

Parameters:

  • $colors (array) — Array of hex color strings from the active theme
  • $post (WP_Post) — The chart post object

m_chart_chartjs_points

Filters the array of point style definitions used by the active Chart.js theme. Each entry is an array of the form [ 'point' => [ 'pointStyle' => '<style>' ] ] and is applied to one series in order. Valid pointStyle values are the strings Chart.js accepts: 'circle', 'rectRot' (diamond), 'rect', 'triangle', 'cross', 'star', etc.

add_filter( 'm_chart_chartjs_points', function( $points, $post ) {
	return [
		[ 'point' => [ 'pointStyle' => 'circle' ] ],
		[ 'point' => [ 'pointStyle' => 'triangle' ] ],
		[ 'point' => [ 'pointStyle' => 'rect' ] ],
	];
}, 10, 2 );

Parameters:

  • $points (array) — Array of point style definitions from the active theme
  • $post (WP_Post) — The chart post object

m_chart_chartjs_themes

Filters the list of Chart.js theme entries returned to admin consumers — the chart-editor theme dropdown and the Default Theme select on the settings page. Extensions append entries here to make custom themes selectable.

add_filter( 'm_chart_chartjs_themes', function( $themes ) {
	$themes[] = (object) [
		'slug'    => 'corporate',
		'name'    => 'Corporate',
		'file'    => '',
		'options' => [],
	];
	return $themes;
} );

Parameters:

  • $themes (array of objects) — Theme entries shaped like the built-ins

Callback requirements:

  • Each entry must be a PHP object (e.g. stdClass or a cast array), not an associative array. The consumers access properties with arrow syntax ($theme->slug, $theme->name); returning an array entry will trigger a warning and silently produce an empty <option>.
  • slug and name are required and must be non-empty strings. Both feed the dropdown.
  • file and options can be empty when the theme is applied via the m_chart_chart_args filter rather than a theme file on disk — see the gotcha below.
  • Don't pre-escape values. The consumers escape with esc_attr() / esc_html() at render time.

Filter-only themes need a paired m_chart_chart_args callback

The theme dropdown reads from this filter, but M_Chart_Chartjs::get_theme() (the function that looks up a theme's options at render time) reads directly from the theme directories — it does not consult this filter. A filter-only theme will appear in dropdowns and can become the persisted Default Theme, but its options won't be applied unless an extension also hooks m_chart_chart_args to inject them based on the active theme slug.


m_chart_treemap_dataset_defaults

Filters the default Chart.js dataset configuration applied to treemap charts (spacing, border, captions, label styling, etc.) before the dataset is built. Fires twice for treemap charts — once with the hierarchical defaults and once with the flat defaults — so you can target the layout you care about by inspecting $post's post meta or by checking which keys are present in the defaults array.

add_filter( 'm_chart_treemap_dataset_defaults', function( $defaults, $post, $args ) {
	$defaults['borderColor'] = '#000000';
	$defaults['borderWidth'] = 2;
	return $defaults;
}, 10, 3 );

Parameters:

  • $defaults (array) — Default dataset config keys (spacing, borderWidth, borderColor, hoverBorderWidth, hoverBorderColor, captions, labels)
  • $post (WP_Post) — The chart post object
  • $args (array) — Display arguments passed to get_chart()

m_chart_show_image

Filters whether to show an image instead of an interactive chart. Return true to force image output.

add_filter( 'm_chart_show_image', function( $show_image, $post_id, $args ) {
	// Force image output on mobile
	return wp_is_mobile();
}, 10, 3 );

Parameters:

  • $show_image (bool) — Whether the renderer already plans to emit an image
  • $post_id (int) — The chart post ID
  • $args (array) — Display arguments: show (string), width (string), share (string)

m_chart_image_support

Filters whether image generation is supported by the active library. Library plugins use this to advertise image support. Return 'no' to disable image generation even when the library supports it.

add_filter( 'm_chart_image_support', function( $supports, $library ) {
	// Disable image generation for all libraries
	return 'no';
}, 10, 2 );

Parameters:

  • $supports (string) — 'yes' or 'no'
  • $library (string) — The active library slug

m_chart_instant_preview_support

Filters whether instant chart preview is supported by the active library. Library plugins use this to advertise instant preview support. Return 'no' to disable live preview updates.

add_filter( 'm_chart_instant_preview_support', function( $supports, $library ) {
	// Disable instant preview for a specific library
	if ( 'my-library' === $library ) {
		return 'no';
	}
	return $supports;
}, 10, 2 );

Parameters:

  • $supports (string) — 'yes' or 'no'
  • $library (string) — The active library slug

Library Plugin Integration

These filters are the primary extension points for charting library plugins such as M Chart Highcharts Library.

m_chart_get_libraries

Filters the array of registered charting libraries. Library plugins add their slug and display name here so they appear in the Library select on the plugin settings screen. This is the registration hook for library plugins.

add_filter( 'm_chart_get_libraries', function( $libraries ) {
	$libraries['my-library'] = 'My Library';
	return $libraries;
} );

Parameters:

  • $libraries (array) — Associative array of [ 'slug' => 'Display Name' ]

m_chart_library_class

Filters the library class instance returned by m_chart()->library(). Library plugins return their own class instance here. This is the primary PHP integration point for library plugins.

add_filter( 'm_chart_library_class', function( $library_class, $library ) {
	if ( 'my-library' === $library ) {
		return new My_Library_Chart_Class();
	}
	return $library_class;
}, 10, 2 );

Parameters:

  • $library_class (object) — The current library class instance
  • $library (string) — The active library slug (e.g. 'chartjs', 'my-library')

m_chart_default_settings

Filters the plugin's default settings array. Library plugins add their own setting keys and default values here so those keys survive the settings save validation loop.

add_filter( 'm_chart_default_settings', function( $settings ) {
	$settings['my_library_option'] = 'default_value';
	return $settings;
} );

Parameters:

  • $settings (array) — The plugin's default settings

m_chart_validated_settings

Fires at the end of settings save validation, after all core settings have been validated and sanitized. Library plugins use this to validate and save their own custom settings from the submitted form data.

add_filter( 'm_chart_validated_settings', function( $validated_settings, $submitted_settings ) {
	if ( isset( $submitted_settings['my_library_option'] ) ) {
		$validated_settings['my_library_option'] = sanitize_text_field( $submitted_settings['my_library_option'] );
	}
	return $validated_settings;
}, 10, 2 );

Parameters:

  • $validated_settings (array) — Already-validated core settings
  • $submitted_settings (array) — Raw $_POST data from the settings form

m_chart_get_settings

Filters the full plugin settings array on every call to get_settings(), after default values have been merged in. Use this for computed or environment-based overrides.

add_filter( 'm_chart_get_settings', function( $settings ) {
	// Force a specific setting in a particular environment
	if ( defined( 'MY_ENV' ) && MY_ENV === 'staging' ) {
		$settings['performance'] = 'no-images';
	}
	return $settings;
} );

Parameters:

  • $settings (array) — The fully merged settings array

m_chart_chart_template

Filters the path to the front-end chart template file. Library plugins use this to substitute their own template (containing the markup and <script> block for their library).

add_filter( 'm_chart_chart_template', function( $template, $library, $post_id ) {
	if ( 'my-library' === $library ) {
		return plugin_dir_path( __FILE__ ) . 'templates/my-library-chart.php';
	}
	return $template;
}, 10, 3 );

Parameters:

  • $template (string) — Absolute path to the template file
  • $library (string) — The active library slug
  • $post_id (int) — The chart post ID

m_chart_table_template

Filters the path to the data table template file. Fires when show=table is requested. Library plugins can substitute their own table template here.

add_filter( 'm_chart_table_template', function( $template, $library, $post_id ) {
	if ( 'my-library' === $library ) {
		return plugin_dir_path( __FILE__ ) . 'templates/my-library-table.php';
	}
	return $template;
}, 10, 3 );

Parameters:

  • $template (string) — Absolute path to the template file
  • $library (string) — The active library slug
  • $post_id (int) — The chart post ID

m_chart_share_template

Filters the path to the share link template rendered below embedded iframes when share=show.

add_filter( 'm_chart_share_template', function( $template ) {
	return plugin_dir_path( __FILE__ ) . 'templates/my-share.php';
} );

Parameters:

  • $template (string) — Absolute path to the share template file

m_chart_iframe_scripts

Filters the array of script handles passed to wp_print_scripts() in the iframe embed page. Library plugins use this to inject their own scripts into the iframe rendering context.

add_filter( 'm_chart_iframe_scripts', function( $scripts, $post_id ) {
	$scripts[] = 'my-library-script';
	return $scripts;
}, 10, 2 );

Parameters:

  • $scripts (array) — Script handles to print in the iframe
  • $post_id (int) — The chart post ID

m_chart_iframe_styles

Filters the array of stylesheet URLs that get injected as <link rel="stylesheet"> tags in the iframe <head>. Useful for extensions that need to load external CSS inside the iframe (e.g. Google Fonts, Adobe Typekit), since iframes don't inherit parent-page font or style loads.

add_filter( 'm_chart_iframe_styles', function( $styles, $post_id ) {
	$styles[] = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap';
	return $styles;
}, 10, 2 );

Parameters:

  • $styles (array) — Stylesheet URLs to inject. Default is an empty array.
  • $post_id (int) — The chart post ID

CSP host allowlist

The iframe response sets a Content-Security-Policy header that restricts which origins stylesheets can load from. Google Fonts (fonts.googleapis.com / fonts.gstatic.com) and Adobe Typekit (use.typekit.net / p.typekit.net) are allowlisted by default. Other origins are auto-allowlisted when you add them via this filter — the iframe template walks the URLs you register and adds their hosts to style-src / font-src automatically. If you need extra origins that don't go through this filter (e.g. for fonts loaded via @import in a stylesheet you don't control), see m_chart_iframe_csp_style_src and m_chart_iframe_csp_font_src.

Non-HTTPS URLs are silently dropped

Each URL passed through this filter is run through esc_url($url, [ 'https' ]) before being emitted. Anything that isn't https:// (including http://, protocol-relative //host/..., or unparseable strings) returns an empty string and the <link> tag is skipped. If a stylesheet you registered isn't loading, check that you passed a full HTTPS URL.


m_chart_iframe_inline_styles

Filters an array of raw CSS strings that get rendered into the iframe <head> as separate <style> blocks. Use this when you need to inject CSS that doesn't fit a stylesheet <link> (use m_chart_iframe_styles) and can't be expressed as a structured @font-face descriptor (use m_chart_iframe_fonts) — for example, a small block of layout CSS specific to a chart's iframe context, or a producer-authored @font-face rule with non-standard descriptors.

add_filter( 'm_chart_iframe_inline_styles', function( $styles, $post_id ) {
	$styles[] = '.m-chart-image-figure { padding: 1em; }';
	return $styles;
}, 10, 2 );

Parameters:

  • $styles (array) — Array of raw CSS strings. Default is an empty array. Empty/whitespace-only strings are skipped.
  • $post_id (int) — The chart post ID

Each string is emitted unescaped

Strings returned through this filter are written verbatim inside a <style>...</style> block — there is no further escaping. Callbacks must produce valid CSS and must not interpolate untrusted input. CSS allows \HHHHHH (Unicode) and \c escape sequences that can encode any character, which defeats substring-based sanitizers. If you must interpolate dynamic values, sanitize at the source (a strict allowlist of known-safe values) rather than at the output stage.

Prefer m_chart_iframe_fonts when you're injecting @font-face rules — that filter validates each descriptor field against an allowlist and emits CSS from a known-safe template, eliminating the escape-sequence surface entirely.


m_chart_iframe_fonts

Filters an array of @font-face font descriptors that get rendered into the iframe <head> as <style> blocks. This is the safe path for injecting custom self-hosted fonts — every field is validated against an allowlist so callers can't smuggle arbitrary CSS through.

For fonts loaded from Google Fonts or Adobe Typekit (which work via a stylesheet <link> URL), use m_chart_iframe_styles instead — Typekit and Google Fonts are already allowlisted by the default CSP.

For other cases where you need to emit raw CSS that doesn't fit the structured @font-face descriptor shape, see m_chart_iframe_inline_styles.

add_filter( 'm_chart_iframe_fonts', function( $fonts, $post_id ) {
	$fonts[] = [
		'family'  => 'MyFont',
		'src'     => [
			[ 'url' => 'https://example.com/fonts/myfont.woff2', 'format' => 'woff2' ],
			[ 'url' => 'https://example.com/fonts/myfont.woff',  'format' => 'woff'  ],
		],
		'weight'  => '400',     // '100'-'900' in hundreds, or 'normal' | 'bold'
		'style'   => 'normal',  // 'normal' | 'italic' | 'oblique'
		'display' => 'swap',    // 'auto' | 'block' | 'swap' | 'fallback' | 'optional'
	];

	return $fonts;
}, 10, 2 );

Parameters:

  • $fonts (array) — Array of font descriptors. Default is an empty array.
  • $post_id (int) — The chart post ID

Font descriptor shape:

  • family (string) — Required. Stripped to [A-Za-z0-9 _-] only. An empty result after stripping drops the entire block.
  • src (array) — Required. Array of [ 'url' => string, 'format' => string ] pairs. URLs must be HTTPS (other schemes are silently dropped via esc_url($url, ['https'])). format is lowercased and stripped to [a-z0-9-]. If no valid source URLs remain after validation, the block is dropped.
  • weight (string) — Optional. Default '400'. Allowed: '100'–'900' (hundreds only) or 'normal' / 'bold'. Invalid values fall back to '400'.
  • style (string) — Optional. Default 'normal'. Allowed: 'normal', 'italic', 'oblique'. Invalid values fall back to 'normal'.
  • display (string) — Optional. Default 'swap'. Allowed: 'auto', 'block', 'swap', 'fallback', 'optional'. Invalid values fall back to 'swap'.

The host portion of each src.url is automatically added to the iframe's CSP font-src allowlist — no need to also register the host via the CSP filters below.


m_chart_iframe_csp_style_src

Filters the list of hosts allowed in the iframe response's CSP style-src directive. The host part of each entry should be a bare hostname (e.g. fonts.googleapis.com, not https://fonts.googleapis.com).

add_filter( 'm_chart_iframe_csp_style_src', function( $hosts, $post_id ) {
	$hosts[] = 'fonts.fontspring.com';
	return $hosts;
}, 10, 2 );

Parameters:

  • $hosts (array) — Hostnames allowed to serve stylesheets. Default: [ 'fonts.googleapis.com', 'use.typekit.net' ]. Hosts of any URLs passed through m_chart_iframe_styles are auto-added on top of this list.
  • $post_id (int) — The chart post ID

Characters outside the CSP source-expression allowlist are silently dropped

Before the CSP header is built, each host string is stripped to characters in [A-Za-z0-9.\-_:/*'+=@]. Anything else (commas, internationalized hostname characters, ~, control characters) is removed without error. This protects against header injection (CRLF, semicolons) but means a hostname with unexpected characters can silently fail to allowlist. Stick to standard ASCII hostnames, or use Punycode for IDN hosts.


m_chart_iframe_csp_font_src

Filters the list of hosts allowed in the iframe response's CSP font-src directive. Used when a stylesheet loads @font-face rules pointing at a different host than the stylesheet itself (Google Fonts: stylesheet from fonts.googleapis.com, fonts from fonts.gstatic.com).

add_filter( 'm_chart_iframe_csp_font_src', function( $hosts, $post_id ) {
	$hosts[] = 'static.fontspring.com';
	return $hosts;
}, 10, 2 );

Parameters:

  • $hosts (array) — Hostnames allowed to serve font files. Default: [ 'fonts.gstatic.com', 'use.typekit.net', 'p.typekit.net' ]. Hosts of any font src URLs passed through m_chart_iframe_fonts are auto-added on top of this list.
  • $post_id (int) — The chart post ID

Same character-class restriction as style-src

Hostnames are stripped to characters in [A-Za-z0-9.\-_:/*'+=@] before the CSP header is built. See the note under m_chart_iframe_csp_style_src for details.


m_chart_iframe_frame_ancestors

Filters the iframe response's CSP frame-ancestors directive — controls which origins are allowed to embed the iframe page. Defends against clickjacking by limiting which sites can put the chart iframe inside their own <iframe>.

add_filter( 'm_chart_iframe_frame_ancestors', function( $ancestors, $post_id ) {
	$ancestors[] = 'https://syndication.example.com';
	return $ancestors;
}, 10, 2 );

Parameters:

  • $ancestors (array) — Origin tokens for the frame-ancestors directive. Default: [ "'self'" ] (same-origin embedding only). Use CSP-syntax tokens: 'self', 'none', or full origins like https://example.com.
  • $post_id (int) — The chart post ID

Don't mix 'none' with other tokens

'none' is exclusive — when present, browsers treat the directive as blocking all framing regardless of what else is in the list. A result like frame-ancestors 'self' 'none'; is a CSP error and the iframe will refuse to embed anywhere. Return either [ "'none'" ] alone or a list of allowed origins, never both.


m_chart_defer_rendering_observer_options

Filters the options passed to the IntersectionObserver that watches for charts entering the viewport when the Defer Rendering setting is enabled. Use this to tune the trigger margin (how early before the chart enters the viewport rendering kicks in) or the visibility threshold.

add_filter( 'm_chart_defer_rendering_observer_options', function( $options, $post_id, $args ) {
	// Start rendering 300px before the chart scrolls into view
	$options['rootMargin'] = '300px';
	return $options;
}, 10, 3 );

Parameters:

  • $options (array) — IntersectionObserver options. Default is [ 'rootMargin' => '100px', 'threshold' => 0 ].
  • $post_id (int) — The chart post ID
  • $args (array) — Display arguments passed to get_chart()

m_chart_multi_sheet_types

Filters the PHP-side array of chart types that show the multi-sheet tab bar. This is the PHP-side counterpart to the m_chart.multi_sheet_types JavaScript filter — the return value of this filter is passed to window.m_chart_admin.multi_sheet_types so the React admin UI stays in sync.

add_filter( 'm_chart_multi_sheet_types', function( $types ) {
	$types[] = 'my-custom-type';
	return $types;
} );

Parameters:

  • $types (array) — Chart type slugs that show multiple sheet tabs

Post Meta

m_chart_get_post_meta

Filters the chart post meta array after it has been retrieved from the database and normalized. Fires on every call to get_post_meta(), including during front-end rendering.

add_filter( 'm_chart_get_post_meta', function( $post_meta, $raw_post_meta, $post_id ) {
	// Inject a default value if not set
	if ( empty( $post_meta['my_key'] ) ) {
		$post_meta['my_key'] = 'default';
	}
	return $post_meta;
}, 10, 3 );

Parameters:

  • $post_meta (array) — The normalized post meta
  • $raw_post_meta (array) — The raw values returned by get_post_meta()
  • $post_id (int) — The chart post ID

m_chart_validate_post_meta

Fires at the end of validate_post_meta(), after all core meta fields have been validated and sanitized. Library plugins use this to validate and sanitize their own custom meta fields before the meta is saved.

add_filter( 'm_chart_validate_post_meta', function( $chart_meta, $meta ) {
	if ( isset( $meta['my_custom_field'] ) ) {
		$chart_meta['my_custom_field'] = sanitize_text_field( $meta['my_custom_field'] );
	}
	return $chart_meta;
}, 10, 2 );

Parameters:

  • $chart_meta (array) — The validated meta array
  • $meta (array) — The raw submitted meta

Rendering

m_chart_get_chart_image_tag

Filters the image data array just before the <img> tag is built for image-mode output. Note: width and height have already been halved for retina display at this point.

add_filter( 'm_chart_get_chart_image_tag', function( $image, $post_id, $args ) {
	// Add a CDN prefix to the image URL
	$image['url'] = 'https://cdn.example.com' . $image['url'];
	return $image;
}, 10, 3 );

Parameters:

  • $image (array) — Image data with these keys:
    • url (string) — Image URL
    • file (string) — Basename of the image URL
    • name (string) — The attachment title used as <img alt>
    • width (int) — Display width (already halved for retina)
    • height (int) — Display height (already halved for retina)
  • $post_id (int) — The chart post ID
  • $args (array) — Display arguments

Preserve all five keys

Callbacks that only need to tweak url should still return the full array unchanged for the other keys. Dropping file, name, width, or height can break downstream consumers that rely on them — the name value, for example, ends up as the <img> alt text.


m_chart_value_labels

Filters the value labels array after it has been built from the spreadsheet data, before data set collection begins.

add_filter( 'm_chart_value_labels', function( $value_labels, $value_labels_position, $data ) {
	return $value_labels;
}, 10, 3 );

Parameters:

  • $value_labels (array) — The parsed labels array
  • $value_labels_position (string) — Where labels were found: first_row, first_column, both, or none
  • $data (array) — The raw data grid

m_chart_set_data

Filters the processed (numeric) data array after parsing. This is the data array used for chart rendering.

add_filter( 'm_chart_set_data', function( $set_data_array, $data, $parse_in ) {
	return $set_data_array;
}, 10, 3 );

Parameters:

  • $set_data_array (array) — The processed, numeric data
  • $data (array) — The raw data grid
  • $parse_in (string) — Data orientation: rows or columns

m_chart_raw_data

Filters the raw (label) data array alongside m_chart_set_data. Both filters run at the same point in the parse cycle.

add_filter( 'm_chart_raw_data', function( $raw_data_array, $data, $parse_in ) {
	return $raw_data_array;
}, 10, 3 );

Parameters:

  • $raw_data_array (array) — The unprocessed label data
  • $data (array) — The raw data grid
  • $parse_in (string) — Data orientation: rows or columns
Last Updated: 5/21/26, 12:29 AM
Contributors: Jamie Poitra
Prev
Developer Guide
Next
JavaScript Events