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:
- Interactive Chart.js front end — inside the always-present
<div id="...-desc" class="screen-reader-text">that's wired to the canvas viaaria-describedby. The data table frombuild_table()is emitted immediately before this hook fires, so a callback in this context can reference the table. - Image-mode output (non-AMP) — inside a
.screen-reader-textwrapper that only renders whenhas_action()returns true. No data table is emitted in this context, so callbacks cannot assume one is present. - 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 toget_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.
stdClassor 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>. slugandnameare required and must be non-empty strings. Both feed the dropdown.fileandoptionscan be empty when the theme is applied via them_chart_chart_argsfilter 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 toget_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$_POSTdata 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 viaesc_url($url, ['https'])).formatis 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 throughm_chart_iframe_stylesare 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 fontsrcURLs passed throughm_chart_iframe_fontsare 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 theframe-ancestorsdirective. Default:[ "'self'" ](same-origin embedding only). Use CSP-syntax tokens:'self','none', or full origins likehttps://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) —IntersectionObserveroptions. Default is[ 'rootMargin' => '100px', 'threshold' => 0 ].$post_id(int) — The chart post ID$args(array) — Display arguments passed toget_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 byget_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 URLfile(string) — Basename of the image URLname(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, ornone$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:rowsorcolumns
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:rowsorcolumns
