032 / GOOGLE CHARTS / BAR & COLUMN

Google Column Bar Chart

Google Charts

Google ColumnChart with clean vertical bars, transparent background, and dark theme grid lines.

SPEC
#032
ENGINE
Google Charts
FAMILY
Bar & Column
RENDERER
google-runtime
STATUS
stable

Installation

PLOTCN/REGISTRY/GOOGLE-BAR/SOURCE
pnpm dlx shadcn@latest add @plotcn/google-bar

Checking public registry…

View local registry JSON
REGISTRY direct URL·ENGINE Google Charts·FILES 1·DEPENDENCIES 2

Copied as source. No Plotcn runtime required.

× 340Container width
Measuring preview...
GOOGLE · GOOGLE-RUNTIME · 0 × 340pxMotion enabled · ResizeObserver
Component Specifications
BEST FOR
Google Column Bar Chart visual analytics and bar category telemetry.
DATA MODEL
Normalized bar records matching canonical dataShape.
INTERACTION
Pointer hover and focus crosshairs
RESPONSIVE
Container-aware ResizeObserver
ANIMATION
Static immediate draw
RUNTIME
Google Charts google-runtime
01 / Component Usage

Basic & Interactive Integration

Import GoogleBar directly into your React client component. Provide an array of observations conforming to the data shape.

page.tsx
import { GoogleBar } from "@/components/charts/google/google-bar"

const data = [
  {
    "label": "Jan",
    "value": 186
  },
  {
    "label": "Feb",
    "value": 305
  },
  {
    "label": "Mar",
    "value": 237
  }
]

export default function ChartDemo() {
  return (
    <div className="w-full max-w-xl h-80">
      <GoogleBar data={data} color="#10b981" />
    </div>
  )
}

Requires a client context ('use client') for DOM lifecycle and container measurement.

Expected ResultLive 220px
Container-aware width · 200px height
02 / Data Contract

Input Schema & Coordinates

Input data format for Google Column Bar Chart. Records should provide required coordinates and metrics.

Chart data contract
FieldTypeRequiredMeaning
labelstringYesCategory label or horizontal axis timestamp
valuenumberYesMetric numerical magnitude
Null / Missing Value Policy:

Missing values are gracefully handled or skipped depending on interpolation rules.

Coordinate Ordering Policy:

Records should follow monotonic sorting for sequential coordinate plots.

Example Observation Payload:
[
  {
    "label": "Jan",
    "value": 186
  },
  {
    "label": "Feb",
    "value": 305
  },
  {
    "label": "Mar",
    "value": 237
  }
]
03 / Component API & Styling

Props Reference & Interactive Prop Explorer

Inspect every component property, customize semantic color roles live with instant visual feedback, and copy production-ready code with active prop configurations.

Colors & Appearance Configuration

Customize primary, reference, or annotation series colors. Defaults derive from Plotcn theme tokens.

Generated Usage Code (Live Props):
<GoogleBar
  data={data}
  xKey="date"
  seriesKey="value"
/>
Interactive Prop Preview Lab
colorstring

Primary theme stroke or fill color. Accepts CSS variables or color values.

Select value to preview live:#10b981
Active: color="#10b981"Default: "var(--chart-1, #10b981)"
All Properties (4)
Component properties
PropertyTypeDefaultRequiredDescription
dataReq
Record<string, any>[]Yes

Array of structured observations or datum objects to visualize.

Best for: Primary dataset

string"var(--chart-1, #10b981)"No

Primary theme stroke or fill color. Accepts CSS variables or color values.

Best for: Theming and visual branding

number | string320No

Container height in pixels or standard CSS dimension strings.

stringundefinedNo

Tailwind CSS classes or custom stylesheet class applied to container wrapper.

04 / Cookbook & States

Component Variants & Edge States

Production cookbooks showcasing configuration variants alongside verified handling of loading, empty data, and network error states.

Google Column Bar Chart (Default)

Standard presentation with Plotcn dark theme tokens.

<GoogleBar data={data} color="#10b981" />
Lifecycle & Exception States
01. Loading State

Skeletons indicate runtime fetch or pending data queries.

02. Empty Data State

Handles empty collections ([]) gracefully without crashing.

03. Error State

Graceful failure banner when data source or script fails.

05 / Responsive Lab

Container-Driven Breakpoints

Scales gracefully according to container width, recalculating layout bounds.

Desktop
1100px+

Full horizontal scale and complete axis tick labeling.

Tablet
768px

Tighter margins with optimized coordinate grid spacing.

Mobile
390px

Compact labels and touch-friendly interaction.

Tablet Preview (768px Container Constraint)
Mobile Preview (390px Container Constraint)
06 / Assistive Technology

Accessibility & Navigation Standards

Accessible visualization presenting Google Column Bar Chart data with semantic contrast.

Semantic Role & Landmark

Container mounts as figure[role="region"] with explicit assistive label.

Color-Independent Legibility

Coordinate baselines and labels preserve data legibility regardless of color perception.

Screen Reader Summary

Embeds visually hidden summary (.sr-only) declaring: “Google Column Bar Chart data visualization

Reduced Motion Support

Suppresses transitions when user prefers reduced motion.

Keyboard Interaction Model
Keyboard interaction model
KeyAction
TabFocus chart container and navigate through interactive regions.
07 / Source Anatomy

Internal Architecture & File Dependencies

Source-first ownership model. Inspect the exact component call tree, dependencies, and full implementation below.

Component Architecture Call Tree
GoogleBar(Component Entry)
└──Google Charts Engine Layer[google-runtime]

Visualization calculations and rendering via Google Charts.

Involved Source Files & Registry Assets
registry/google/google-bar.tsx
Primary component source implementation.
registry/google/google-bar.tsx
"use client"import * as React from "react"import {  loadGoogleChartsPackages,  resolveGoogleColor,  escapeGoogleTooltipText,  type GoogleChartsLoaderState,  type GoogleVisualizationChart,} from "./google-chart-loader"import { GoogleChartContainer } from "./google-chart-container"export interface GoogleBarDatum {  label: string  value: number  [key: string]: unknown}export interface GoogleBarProps {  data: GoogleBarDatum[]  valueKey?: string  labelKey?: string  color?: string  height?: number | string  className?: string}export function GoogleBar({  data,  valueKey = "value",  labelKey = "label",  color = "var(--chart-2)",  height = 320,  className,}: GoogleBarProps) {  const chartRef = React.useRef<HTMLDivElement>(null)  const chartInstanceRef = React.useRef<GoogleVisualizationChart | null>(null)  const [status, setStatus] = React.useState<GoogleChartsLoaderState>("loading")  React.useEffect(() => {    loadGoogleChartsPackages(["corechart"])      .then(() => setStatus("ready"))      .catch(() => setStatus("error"))  }, [])  const drawChart = React.useCallback(() => {    if (status !== "ready" || !chartRef.current || !window.google?.visualization) return    const css = getComputedStyle(chartRef.current)    const resolvedColor = resolveGoogleColor(color, chartRef.current, "#f4f4f5")    const axisColor = css.getPropertyValue("--chart-axis").trim() || "#a1a1aa"    const gridColor = css.getPropertyValue("--chart-grid").trim() || "rgba(255,255,255,0.08)"    const dataTable = new window.google.visualization.DataTable()    dataTable.addColumn("string", "Label")    dataTable.addColumn("number", "Value")    dataTable.addColumn({ type: "string", role: "tooltip", p: { html: true } })    data.forEach((item) => {      const label = String(item[labelKey])      const safeLabel = escapeGoogleTooltipText(label)      const val = Number(item[valueKey])      const displayVal = Number.isFinite(val) ? val.toLocaleString() : String(item[valueKey])      const tooltipHtml = `        <div class="plotcn-tooltip-card">          <div class="plotcn-tooltip-header">            <span class="plotcn-tooltip-indicator" style="background-color: ${resolvedColor};"></span>            <span class="plotcn-tooltip-title">${safeLabel}</span>          </div>          <div class="plotcn-tooltip-metric">            <span class="plotcn-tooltip-label">${valueKey}</span>            <span class="plotcn-tooltip-value">${displayVal}</span>          </div>        </div>      `.trim()      dataTable.addRow([label, val, tooltipHtml])    })    const options = {      backgroundColor: "transparent",      colors: [resolvedColor],      legend: "none",      hAxis: {        textStyle: { color: axisColor, fontSize: 11 },        baselineColor: gridColor,        gridlines: { color: "transparent" },      },      vAxis: {        textStyle: { color: axisColor, fontSize: 11 },        baselineColor: gridColor,        gridlines: { color: gridColor },      },      tooltip: {        isHtml: true,      },      chartArea: { width: "85%", height: "75%" },    }    if (!chartInstanceRef.current) {      chartInstanceRef.current = new window.google.visualization.ColumnChart(chartRef.current)    }    chartInstanceRef.current.draw(dataTable, options)  }, [status, data, labelKey, valueKey, color])  // Redraw chart on prop update  React.useEffect(() => {    drawChart()  }, [drawChart])  // ResizeObserver for responsive redraw  React.useEffect(() => {    if (!chartRef.current) return    let frame = 0    const observer = new ResizeObserver(() => {      cancelAnimationFrame(frame)      frame = requestAnimationFrame(drawChart)    })    observer.observe(chartRef.current)    return () => {      observer.disconnect()      cancelAnimationFrame(frame)    }  }, [drawChart])  // Unmount cleanup ONLY  React.useEffect(() => {    return () => {      chartInstanceRef.current?.clearChart?.()      chartInstanceRef.current = null    }  }, [])  React.useEffect(() => {    const surface = chartRef.current?.closest("[data-theme]")    const observer = new MutationObserver(drawChart)    if (surface) observer.observe(surface, { attributes: true, attributeFilter: ["data-theme"] })    if (typeof document !== "undefined") {      observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class", "data-theme"] })    }    const media = window.matchMedia("(prefers-color-scheme: dark)")    media.addEventListener("change", drawChart)    return () => { observer.disconnect(); media.removeEventListener("change", drawChart) }  }, [drawChart])  return (    <GoogleChartContainer      status={status}      height={height}      className={className}      chartRef={chartRef}      title="Google Bar Chart"    >      <span className="sr-only">Bar chart rendered with Google Charts corechart package.</span>    </GoogleChartContainer>  )}