| name | Data Visualization |
| description | Creating graphical representations of data to communicate insights, patterns, and trends effectively |
| license | MIT |
| compatibility | universal |
| audience | developers, analysts, designers |
| category | interdisciplinary |
Data Visualization
What I Do
I transform complex datasets into clear, insightful visual representations that help decision-makers understand patterns, trends, and anomalies. I combine statistical knowledge with design principles to create visualizations that tell compelling data stories.
When to Use Me
- Exploring datasets to find patterns and insights
- Communicating findings to stakeholders
- Creating dashboards for monitoring metrics
- Building reports with data-driven narratives
- Designing interactive data exploration tools
- Choosing appropriate chart types for data stories
Core Concepts
- Chart Selection: Matching visualization types to data characteristics
- Data-Ink Ratio: Maximizing information, minimizing decoration
- Color Theory: Sequential, diverging, and categorical palettes
- Visual Encoding: Position, length, area, color, angle as data channels
- Scales and Axes: Linear, logarithmic, time, ordinal scales
- Interactivity: Filtering, drilling, linking multiple views
- Accessibility in Viz: Colorblind-safe palettes, alternative text
- Dashboard Design: Layout, hierarchy, and information density
- Animation: Transitions for understanding changes over time
- Storytelling: Narrative structures for data communication
Code Examples
D3 Visualization Builder
class VisualizationBuilder {
constructor(container, data) {
this.container = container;
this.data = data;
this.width = 800;
this.height = 400;
this.margin = { top: 20, right: 30, bottom: 40, left: 50 };
this.svg = null;
}
initialize() {
this.svg = d3.select(this.container)
.append('svg')
.attr('width', this.width)
.attr('height', this.height)
.append('g')
.attr('transform', `translate(${this.margin.left},${this.margin.top})`);
}
() {
x = d3.()
.(d3.(., (d[xKey])))
.([, . - .. - ..]);
y = d3.()
.([, d3.(., d[yKey])])
.([. - .. - .., ]);
..()
.(.)
.(, )
.(, )
.(, )
.(, d3.()
.( ( (d[xKey])))
.( (d[yKey]))
);
.(x, y);
;
}
() {
x = d3.()
.(..( d[xKey]))
.([, . - .. - ..])
.();
y = d3.()
.([, d3.(., d[yKey])])
.([. - .. - .., ]);
..()
.(.)
.()
.(, (d[xKey]))
.(, (d[yKey]))
.(, x.())
.(, . - .. - .. - (d[yKey]))
.(, );
.(x, y, );
;
}
() {
..()
.(, )
.(d3.(x).());
..()
.(d3.(y));
}
() {
tooltip = d3.(.)
.()
.(, )
.(, )
.(, )
.(, )
.(, )
.(, )
.(, )
.(, );
..()
.(, {
tooltip.().().(, );
tooltip.();
})
.(, {
tooltip.().().(, );
});
}
}
Chart Configuration Generator
class ChartConfigurator {
constructor() {
this.chartTypes = {
line: { bestFor: ['time series', 'trends'], limits: ['continuous data'] },
bar: { bestFor: ['categorical comparisons', 'rankings'], limits: ['time series'] },
scatter: { bestFor: ['correlations', 'outliers'], limits: ['few data points'] },
pie: { bestFor: ['part-to-whole', 'few categories'], limits: ['many categories'] },
heatmap: { bestFor: ['patterns', 'density'], limits: ['precise values'] },
boxplot: { bestFor: ['distributions', 'comparisons'], limits: ['single distributions'] }
};
}
recommendChartType(data, goal) {
const dataCharacteristics = this.analyzeData(data);
let candidates = Object.entries(this.)
.(
config..( goal.().(g))
);
candidates = candidates.(
!config..(
dataCharacteristics..(limit)
)
);
candidates[]?.[] || ;
}
() {
(!data.) { : };
sample = data[];
keys = .(sample);
types = {
: keys.( sample[k] === ),
: keys.(
sample[k] ||
!(.(sample[k]))
),
: keys.( sample[k] === )
};
{
: types.. > ,
: types.. > ,
: types.. > ,
: []
};
}
() {
baseConfig = {
: ,
: ,
: {
: { : , : },
: {
: ,
: ,
:
}
},
: .(type, data)
};
{ type, data, : { ...baseConfig, ...options } };
}
() {
([, , ].(type)) {};
{
: {
: { : },
: { : }
},
: {
: ,
: { : }
}
};
}
}
Real-time Data Stream Visualizer
class StreamVisualizer {
constructor(container, options = {}) {
this.container = container;
this.buffer = [];
this.maxPoints = options.maxPoints || 100;
this.updateInterval = options.interval || 1000;
this.isRunning = false;
}
start(dataStream) {
this.dataStream = dataStream;
this.isRunning = true;
this.render();
setInterval(() => {
if (this.isRunning) {
this.addDataPoint(this.dataStream());
this.update();
}
}, this.updateInterval);
}
addDataPoint(point) {
this.buffer.push({
timestamp: new Date(),
: point
});
(.. > .) {
..();
}
}
() {
.. = ;
. = .();
.. = ..;
.. = ..;
..(.);
. = ..();
}
() {
(!.) ;
{ width, height } = .;
..(, , width, height);
padding = ;
graphWidth = width - padding * ;
graphHeight = height - padding * ;
maxValue = .(.....( d.));
minValue = .(.....( d.));
..();
.. = ;
.. = ;
..( {
x = padding + (index / (. - )) * graphWidth;
y = padding + graphHeight -
((point. - minValue) / (maxValue - minValue)) * graphHeight;
(index === ) {
..(x, y);
} {
..(x, y);
}
});
..();
.. = ;
..();
..(padding, padding);
..(padding, height - padding);
..(width - padding, height - padding);
..();
lastPoint = .[.. - ];
.. = ;
..(
,
width - ,
padding +
);
}
() {
. = ;
}
}
Best Practices
- Choose the right chart type for your data and message
- Start axes at zero for accurate comparison (except time series)
- Use clear titles, labels, and legends
- Apply color meaningfully and consistently
- Remove chart junk and maximize data-ink ratio
- Provide context through reference lines and benchmarks
- Make visualizations accessible with colorblind-safe palettes
- Consider mobile and responsive visualization needs
- Animate changes thoughtfully to aid understanding
- Iterate based on user testing and feedback