| |
| <?php
|
| <?php
|
|
|
| function load_d3_js() {
|
| echo '<script src="https://d3js.org/d3.v7.min.js"></script>';
|
| }
|
| add_action('wp_head', 'load_d3_js');
|
|
|
|
|
| function accuracy_gauge_css() {
|
| ?>
|
| <style>
|
| .accuracy-gauge {
|
| width: 100%;
|
| max-width: 600px;
|
| aspect-ratio: 1;
|
| margin: 0 auto;
|
| }
|
| .accuracy-gauge svg {
|
| width: 100%;
|
| height: 100%;
|
| }
|
| .accuracy-gauge .background {
|
| opacity: 0.1;
|
| }
|
| .accuracy-gauge text {
|
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
| }
|
| .accuracy-gauge .spec-text {
|
| font-weight: 500;
|
| }
|
| .accuracy-gauge .gauge-value,
|
| .accuracy-gauge .plus-minus,
|
| .accuracy-gauge .percentage {
|
| font-weight: bold;
|
| }
|
| </style>
|
| <?php
|
| }
|
| add_action('wp_head', 'accuracy_gauge_css');
|
|
|
|
|
| function accuracy_gauge_js() {
|
| ?>
|
| <script>
|
| class AccuracyGauge {
|
| constructor(selector) {
|
| this.selector = selector;
|
| this.width = 400;
|
| this.height = 400;
|
| this.radius = 180;
|
| this.padding = 40;
|
| this.initialized = false;
|
| this.currentValue = 0;
|
| this.maxValue = 1.0;
|
| this.oscillationAngle = 0;
|
| }
|
|
|
| initialize() {
|
| try {
|
| const container = d3.select(this.selector);
|
| container.selectAll('*').remove();
|
|
|
| const containerRect = container.node().getBoundingClientRect();
|
| const minDimension = Math.min(containerRect.width, containerRect.height);
|
| this.width = minDimension;
|
| this.height = minDimension;
|
| this.radius = minDimension * 0.4;
|
|
|
| const svg = container.append('svg')
|
| .attr('viewBox', `0 0 ${this.width} ${this.height}`)
|
| .attr('width', '100%')
|
| .attr('height', '100%')
|
| .attr('preserveAspectRatio', 'xMidYMid meet')
|
| .append('g')
|
| .attr('transform', `translate(${this.width/2},${this.height/2})`);
|
|
|
|
|
| const gradient = svg.append('defs')
|
| .append('linearGradient')
|
| .attr('id', 'gaugeGradient')
|
| .attr('gradientUnits', 'userSpaceOnUse')
|
| .attr('x1', -this.radius).attr('y1', 0)
|
| .attr('x2', this.radius).attr('y2', 0);
|
|
|
| gradient.append('stop')
|
| .attr('offset', '0%')
|
| .attr('stop-color', '#1f77b4');
|
|
|
| gradient.append('stop')
|
| .attr('offset', '100%')
|
| .attr('stop-color', '#9ecae1');
|
|
|
|
|
| const backgroundArc = d3.arc()
|
| .innerRadius(this.radius - 40)
|
| .outerRadius(this.radius)
|
| .startAngle(-Math.PI / 2)
|
| .endAngle(Math.PI / 2);
|
|
|
| svg.append('path')
|
| .attr('class', 'background')
|
| .attr('d', backgroundArc)
|
| .style('fill', '#f0f0f0');
|
|
|
|
|
| this.foreground = svg.append('path')
|
| .attr('class', 'foreground')
|
| .style('fill', 'url(#gaugeGradient)');
|
|
|
|
|
| this.oscillatingPath = svg.append('path')
|
| .attr('class', 'oscillating')
|
| .style('fill', '#9ecae1')
|
| .style('opacity', 0.2);
|
|
|
|
|
| const valueGroup = svg.append('g')
|
| .attr('class', 'value-group')
|
| .attr('transform', 'translate(0, 0)');
|
|
|
|
|
| valueGroup.append('text')
|
| .attr('class', 'plus-minus')
|
| .attr('x', -this.radius * 0.2)
|
| .attr('y', 0)
|
| .attr('text-anchor', 'end')
|
| .style('font-size', `${this.radius * 0.25}px`)
|
| .style('font-weight', 'bold')
|
| .style('fill', '#1f77b4')
|
| .text('±');
|
|
|
|
|
| this.valueText = valueGroup.append('text')
|
| .attr('class', 'gauge-value')
|
| .attr('x', -this.radius * 0.15)
|
| .attr('y', 0)
|
| .attr('text-anchor', 'start')
|
| .style('font-size', `${this.radius * 0.25}px`)
|
| .style('font-weight', 'bold')
|
| .style('fill', '#333333');
|
|
|
|
|
| valueGroup.append('text')
|
| .attr('class', 'percentage')
|
| .attr('x', this.radius * 0.25)
|
| .attr('y', 0)
|
| .attr('text-anchor', 'start')
|
| .style('font-size', `${this.radius * 0.2}px`)
|
| .style('font-weight', 'bold')
|
| .style('fill', '#333333')
|
| .text('%');
|
|
|
|
|
| svg.append('text')
|
| .attr('class', 'spec-text')
|
| .attr('y', this.radius * 0.6)
|
| .attr('text-anchor', 'middle')
|
| .style('font-size', `${this.radius * 0.1}px`)
|
| .style('fill', '#1f77b4')
|
| .style('opacity', 0)
|
| .text('Ground-Free Voltage Measurement')
|
| .transition()
|
| .duration(800)
|
| .delay(1200)
|
| .style('opacity', 1);
|
|
|
|
|
| svg.append('text')
|
| .attr('class', 'spec-text')
|
| .attr('y', this.radius * 0.75)
|
| .attr('text-anchor', 'middle')
|
| .style('font-size', `${this.radius * 0.1}px`)
|
| .style('fill', '#333333')
|
| .style('opacity', 0)
|
| .text('Full Coverage: 4kV to 240kV')
|
| .transition()
|
| .duration(800)
|
| .delay(1400)
|
| .style('opacity', 1);
|
|
|
| this.initialized = true;
|
| this.startAnimation();
|
| } catch (error) {
|
| console.error('Error initializing gauge:', error);
|
| }
|
| }
|
|
|
| startAnimation() {
|
| const animate = () => {
|
| try {
|
| this.oscillationAngle += 0.02;
|
| this.currentValue = (Math.sin(this.oscillationAngle) + 1) * 0.5;
|
|
|
| const angle = ((this.currentValue / this.maxValue) * Math.PI) - (Math.PI / 2);
|
|
|
| const arc = d3.arc()
|
| .innerRadius(this.radius - 60)
|
| .outerRadius(this.radius - 20)
|
| .startAngle(-Math.PI / 2)
|
| .endAngle(angle);
|
|
|
| this.foreground.attr('d', arc);
|
|
|
| const oscillatingArc = d3.arc()
|
| .innerRadius(this.radius - 50)
|
| .outerRadius(this.radius - 30)
|
| .startAngle(-Math.PI / 2)
|
| .endAngle(angle + (Math.sin(this.oscillationAngle * 2) * 0.1));
|
|
|
| this.oscillatingPath.attr('d', oscillatingArc);
|
|
|
| this.valueText.text(this.currentValue.toFixed(1));
|
|
|
| if (this.initialized) {
|
| requestAnimationFrame(animate);
|
| }
|
| } catch (error) {
|
| console.error('Error in animation:', error);
|
| }
|
| };
|
|
|
| animate();
|
| }
|
| }
|
|
|
|
|
| document.addEventListener('DOMContentLoaded', function() {
|
| const gaugeContainer = document.createElement('div');
|
| gaugeContainer.id = 'accuracy-gauge';
|
| gaugeContainer.className = 'accuracy-gauge';
|
| document.querySelector('.entry-content').appendChild(gaugeContainer);
|
|
|
| const gauge = new AccuracyGauge('#accuracy-gauge');
|
| gauge.initialize();
|
| });
|
| </script>
|
| <?php
|
| }
|
| add_action('wp_footer', 'accuracy_gauge_js');
|
| ?>
|
| |
| |
Comments