Skip to content

1.5.0

Latest

Choose a tag to compare

@iliaal iliaal released this 07 Jul 22:38
1.5.0
2d10be7

Added

  • Chart::setPngCompressionLevel(): zlib level 0-9 for PNG output; the default stays at libpng's 6.
  • drawSvgFragment() takes an optional $idPrefix, so fragments from several charts can be stitched without gradient/clip id collisions.
  • addHorizontalLine() / addVerticalLine() and the band variants render on Waterfall and ParetoChart.
  • config.w32 gained an opt-in pdfio block, so Windows builds can enable the PDF backend.

Changed

  • Series arrays with holes (array_filter(), unset()) compact in key order instead of becoming NaN gaps with dropped tail values.
  • setSeries() throws a ValueError past the 8-series cap instead of silently truncating; setStrict(true) throws on malformed entries.
  • getImageMapAreas() reports each area's index as the position in the original input, even when earlier entries were skipped.
  • SVG color handles resolve through a hash table: a 4096-point scatter with per-point colors renders ~6x faster.
  • PNG rows use the fixed UP filter instead of adaptive filtering: ~40% faster renderPng() at effectively unchanged file size.
  • WordCloud collision tests are pruned through a spatial bucket grid: ~30% faster at 200 words with byte-identical output.
  • Solid and alpha SVG colors format through dedicated integer emitters instead of snprintf(): ~40% faster on dense documents.
  • setShowValues(?string $format = null): null/omitted keeps the current format, '' resets; the advertised %g default never applied.
  • Render-time "canvas too small" errors throw ValueError across chart families, matching the Symbol family.
  • renderToFile() writes plain paths via a same-directory temp file plus rename; a failed write no longer truncates an existing file.
  • A labeled empty series gets a legend entry on LineChart too, matching Area/Bar/Scatter.
  • addOverlaySeries() values parse into typed arrays at setter time instead of being re-read from the PHP array on every render.
  • Text runs decompose each glyph once per draw instead of twice, and layout measures only the category labels the axis will draw.

Fixed

  • An out-of-memory bailout inside a libpng / libjpeg / libwebp / plutovg / pdfio session no longer leaks the library's internal state.
  • setYAxisRange() no longer draws tick labels outside the forced bounds, and a finer-than-ladder interval strides to span the range.
  • Per-role font-size overrides are honored during layout measurement, so an oversized title no longer overlaps the plot area.
  • PDF output keeps the 96-DPI layout baseline like SVG; setDpi(200) previously inflated the reserved margins 2x.
  • renderWebp() rejects dimensions past WebP's 16383px limit before rasterizing, with a message naming the offending size.
  • Invalid UTF-8 bytes measure as U+FFFD, matching how they render; text with malformed sequences no longer misaligns.
  • Rotated axis labels (setXAxisLabelAngle(45) / (90)) anchor at their tick in paths mode and raster/PDF; wide labels drifted left.
  • BarChart::setFloating() with setStacked() or STACK_LAYER renders side by side instead of emitting negative-width rects.
  • PieChart::setImageMap() and setExplode() stay aligned to their setSlices() indices when setOtherThreshold() folds slices.
  • AreaChart band mode ignores the secondary Y axis (matching stream mode); right-flagged boundaries no longer flat-line or throw.
  • addOverlaySeries('area') fill polygons cover every data point; the old fixed 1024-point cap closed a self-crossing shape on longer series.
  • JPEG encoding streams through a custom destination manager, closing a jpeg_mem_dest double-free after internal buffer growth.
  • Closed the remaining UB float-cast paths on finite-but-extreme input in Calendar, Contour, Pareto, Polar, Sankey, and Stock charts.
  • Treemap::setItems() caps values at FASTCHART_MAX_DATA_MAG, so two near-DBL_MAX values can't overflow the total to +Inf and blank the chart.
  • Funnel::setStyle(STYLE_CONE) arcs round symmetrically (lround), fixing a 1px left/right asymmetry.
  • Hardened latent overflow paths: INT_MAX guards in the SVG rasterizer, saturating clip/gradient ids, and a guarded jpeg_destroy_compress.
  • StockChart::setOhlcv() clears native indicator panes computed from the replaced candles; caller-supplied addIndicatorPane() data is kept.
  • Funnel::setStages() honors setStrict(true) (invalid stages throw TypeError); the flat style rejects a canvas too short for its stages.
  • AreaChart stream mode (setStreamMode(true)) with only gap/NaN input raises the no-numeric-values error instead of rendering an empty chart.
  • addOverlaySeries('area') fills break at gaps instead of painting across the missing category (categorical and horizontal-bar).
  • BarChart radial orientation honors per-point colors, matching the vertical and horizontal paths.
  • BubbleChart renders an all-zero size dimension as minimum-size markers instead of half-maximum bubbles that read as real magnitude.
  • PopulationPyramid clamps the center gap to the plot width, so one very long category label degrades to overlap instead of blanking the chart.
  • ScatterChart skips the linear trend line when every point shares one x (zero fit denominator) instead of drawing a spurious y=0 line.
  • LinearMeter value labels format through a right-sized buffer, so a high-precision format (%.999f) is no longer silently truncated.
  • Extended the UB float-cast hardening to Heatmap / Surface normalization, Scatter / Vector mapping, and the stock volume bar.
  • The shared UTF-8 walker rejects overlong, surrogate, and out-of-range sequences, substituting one U+FFFD and advancing a single byte.
  • Treemap skips degenerate cells (x1 < x0) that a plot rect smaller than the item count can produce, instead of emitting negative-size rects.
  • Waterfall renders a negative TOTAL bar below the zero baseline instead of at its absolute height (a loss no longer looks like a gain).
  • Axis tick labels keep their fractional part for 2.5x10^N and 0.25-family steps (7.5 no longer labels as "8").
  • ScatterChart delegates its x-axis to the shared drawer: SVG is DPI-invariant again and setXAxisVisible(false) is honored.
  • 24 chart families ignored setTransparentBackground() and setBackgroundImage(), and wiped the host canvas when compositing.
  • BarChart bars drifted from their category labels at high category counts (~99px at 100 categories), both orientations.
  • GaugeChart::setRange() accepted finite bounds whose span overflows to Inf, reaching (int)NaN casts in the renderer.
  • PDF: fully transparent colors painted opaque, band-gradient alpha was discarded, and thick polylines showed notches at vertices.
  • StockChart STYLE_VECTOR marked the first bar as a volume climax, and ZigZag missed reversals on non-positive prices.
  • setVolumeColors() misaligned sparse arrays.
  • Valid PNGs with more than 1024 chunks were rejected as background/icon images.
  • Overlay values kept a hidden reference to the user array, making chart-to-data reference cycles uncollectable.
  • PolarChart::addVectors() color validation truncated to 32-bit before range-checking on LLP64/Windows.