如何用Plotly.js创建涨跌区分颜色的瀑布图?
I totally get what you're after—Plotly's default waterfall examples use value-range based colors, but we need to tie colors directly to whether each step is an increase or decrease from the previous value. Let’s walk through how to build this step by step:
Step 1: Prep Your Data & Calculate Changes
First, we need to take your raw dataset and compute the difference between each value and the one before it. This difference will tell us if we’re looking at an increase (positive number) or decrease (negative number).
For example, let’s use a sample dataset:
const rawData = [100, 120, 95, 110, 130]; const labels = ["Start", "Q1", "Q2", "Q3", "End"];
We’ll calculate the changes between consecutive points with a simple loop:
const changes = []; for (let i = 0; i < rawData.length; i++) { if (i === 0) { changes.push(rawData[i]); // First value is our starting baseline } else { changes.push(rawData[i] - rawData[i-1]); // Difference from prior value } }
Step 2: Assign Colors Based on Direction
Next, we’ll map each change to a color: green for positive increases, red for negative decreases. We’ll also use a neutral gray for the start and end totals (you can skip this if you want those to follow the same color logic):
const colors = changes.map((change, index) => { if (index === 0 || index === changes.length - 1) { return "#888888"; // Neutral color for start/end totals } return change > 0 ? "#2ecc71" : "#e74c3c"; // Green = up, Red = down });
Step 3: Build & Render the Chart
Now we’ll put it all together into a Plotly waterfall trace. We’ll use the measure array to define which points are absolute totals vs. relative changes, then apply our custom colors:
<!DOCTYPE html> <html> <head> <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> </head> <body> <div id="waterfall-chart"></div> <script> // Raw data and category labels const rawData = [100, 120, 95, 110, 130]; const labels = ["Start", "Q1", "Q2", "Q3", "End"]; // Calculate changes from the previous value const changes = []; for (let i = 0; i < rawData.length; i++) { if (i === 0) { changes.push(rawData[i]); } else { changes.push(rawData[i] - rawData[i-1]); } } // Assign colors based on increase/decrease direction const colors = changes.map((change, index) => { if (index === 0 || index === changes.length - 1) { return "#888888"; // Neutral for start/end } return change > 0 ? "#2ecc71" : "#e74c3c"; }); // Define measure types: absolute = totals, relative = changes const measure = labels.map((_, index) => { return (index === 0 || index === labels.length - 1) ? "absolute" : "relative"; }); // Create the waterfall trace const trace = { type: "waterfall", x: labels, y: changes, measure: measure, text: changes.map(c => c >= 0 ? `+${c}` : c), // Show + sign for positive changes textposition: "outside", marker: { color: colors } }; // Configure chart layout const layout = { title: "Waterfall Chart: Up (Green) / Down (Red)", showlegend: false, yaxis: { title: "Value" } }; // Render the chart in the target div Plotly.newPlot('waterfall-chart', [trace], layout); </script> </body> </html>
Quick Tips to Tweak It:
- Adjust the hex color codes to match your brand or preferences.
- Remove the
index === 0 || index === changes.length - 1condition if you want the start/end points to follow the same up/down color logic. - Modify the
textformatting to show absolute values instead of changes if that’s more useful for your use case.
This setup ensures every bar’s color directly reflects whether it’s an increase or decrease from the prior value—exactly what you needed!
内容的提问来源于stack exchange,提问作者Vipul Sharma

