class AbstractSparklinesGraphicsComponentProvider extends ComponentProvider<JLabel> {

    protected static final Color SELECTED_BACKGROUND = UIManager.getColor("Table.selectionBackground");
    protected static final Color UNSELECTED_BACKGROUND = UIManager.getColor("Table.background");
    protected final Color lineColor;

    protected final GraphModelProvider graphModelProvider;
    protected final JXTable table;
    protected JRendererLabel rendererLabel;

    public AbstractSparklinesGraphicsComponentProvider(GraphModelProvider graphModelProvider, JXTable table) {
        super(null, JLabel.LEADING);
        this.graphModelProvider = graphModelProvider;
        this.table = table;

        if (UIUtils.isDarkLookAndFeel()) {
            lineColor = Color.LIGHT_GRAY;
        } else {
            lineColor = Color.BLUE;
        }
    }

    public abstract String getTextFromValue(Object value);

    @Override
    protected void format(CellContext context) {<FILL_FUNCTION_BODY>}

    @Override
    protected void configureState(CellContext context) {
    }

    @Override
    protected JLabel createRendererComponent() {
        return rendererLabel = new JRendererLabel();
    }

    public void setImagePainter(Object value, boolean isSelected) {
        if (value == null) {
            rendererLabel.setPainter(null);
            return;
        }

        Number[][] values = getSparklinesXAndYNumbers(value);
        Number[] xValues = values[0];
        Number[] yValues = values[1];

        //If there is less than 1 element, don't show anything.
        if (yValues.length < 1) {
            rendererLabel.setPainter(null);
            return;
        }

        if (yValues.length == 1) {
            //SparklineGraph needs at least 2 values, duplicate the only one we have to get a sparkline with a single line showing that the value does not change over time
            xValues = null;
            yValues = new Number[] {yValues[0], yValues[0]};
        }

        Color background;
        if (isSelected) {
            background = SELECTED_BACKGROUND;
        } else {
            background = UNSELECTED_BACKGROUND;
        }

        //Note: Can't use interactive SparklineComponent because TableCellEditors don't receive mouse events.
        final SparklineParameters sparklineParameters = new SparklineParameters(
            rendererLabel.getWidth() - 1,
            rendererLabel.getHeight() - 1,
            lineColor,
            background,
            Color.RED,
            Color.GREEN,
            null
        );
        final BufferedImage image = SparklineGraph.draw(xValues, yValues, sparklineParameters);

        rendererLabel.setPainter(new ImagePainter(image));
    }

    public abstract Number[][] getSparklinesXAndYNumbers(Object value);
}

        //Set image or text
        int witdth = table.getColumnModel().getColumn(context.getColumn()).getWidth();
        int height = table.getRowHeight(context.getRow());

        String text = getTextFromValue(context.getValue());

        rendererLabel.setSize(witdth, height);
        rendererLabel.setToolTipText(text);
        rendererLabel.setBorder(null);

        setImagePainter(context.getValue(), context.isSelected());
    
<no_super_class>